1package usecase_test
2
3import (
4 "errors"
5 "testing"
6
7 "github.com/bnema/dumber/internal/application/usecase"
8 "github.com/bnema/dumber/internal/domain/entity"
9 repomocks "github.com/bnema/dumber/internal/domain/repository/mocks"
10 "github.com/stretchr/testify/assert"
11 "github.com/stretchr/testify/mock"
12 "github.com/stretchr/testify/require"
13)
14
15func TestManageFavoritesUseCase_GetAllURLs_ReturnsURLSet(t *testing.T) {
16 ctx := testContext()
17
18 favoriteRepo := repomocks.NewMockFavoriteRepository(t)
19 folderRepo := repomocks.NewMockFolderRepository(t)
20 tagRepo := repomocks.NewMockTagRepository(t)
21
22 favorites := []*entity.Favorite{
23 {ID: 1, URL: "https://example.com"},
24 {ID: 2, URL: "https://github.com"},
25 {ID: 3, URL: "https://google.com"},
26 }
27
28 favoriteRepo.EXPECT().GetAll(mock.Anything).Return(favorites, nil)
29
30 uc := usecase.NewManageFavoritesUseCase(favoriteRepo, folderRepo, tagRepo)
31
32 urls, err := uc.GetAllURLs(ctx)
33 require.NoError(t, err)
34 require.NotNil(t, urls)
35
36 assert.Len(t, urls, 3)
37 _, hasExample := urls["https://example.com"]
38 _, hasGithub := urls["https://github.com"]
39 _, hasGoogle := urls["https://google.com"]
40 assert.True(t, hasExample)
41 assert.True(t, hasGithub)
42 assert.True(t, hasGoogle)
43}
44
45func TestManageFavoritesUseCase_GetAllURLs_ReturnsEmptySetWhenNoFavorites(t *testing.T) {
46 ctx := testContext()
47
48 favoriteRepo := repomocks.NewMockFavoriteRepository(t)
49 folderRepo := repomocks.NewMockFolderRepository(t)
50 tagRepo := repomocks.NewMockTagRepository(t)
51
52 favoriteRepo.EXPECT().GetAll(mock.Anything).Return([]*entity.Favorite{}, nil)
53
54 uc := usecase.NewManageFavoritesUseCase(favoriteRepo, folderRepo, tagRepo)
55
56 urls, err := uc.GetAllURLs(ctx)
57 require.NoError(t, err)
58 require.NotNil(t, urls)
59 assert.Empty(t, urls)
60}
61
62func TestManageFavoritesUseCase_GetAllURLs_ReturnsErrorOnRepoFailure(t *testing.T) {
63 ctx := testContext()
64
65 favoriteRepo := repomocks.NewMockFavoriteRepository(t)
66 folderRepo := repomocks.NewMockFolderRepository(t)
67 tagRepo := repomocks.NewMockTagRepository(t)
68
69 favoriteRepo.EXPECT().GetAll(mock.Anything).Return(nil, errors.New("db connection failed"))
70
71 uc := usecase.NewManageFavoritesUseCase(favoriteRepo, folderRepo, tagRepo)
72
73 urls, err := uc.GetAllURLs(ctx)
74 require.Error(t, err)
75 assert.Nil(t, urls)
76 assert.Contains(t, err.Error(), "failed to get favorites")
77}
78
79func TestManageFavoritesUseCase_Toggle_AddsWhenNotFavorite(t *testing.T) {
80 ctx := testContext()
81
82 favoriteRepo := repomocks.NewMockFavoriteRepository(t)
83 folderRepo := repomocks.NewMockFolderRepository(t)
84 tagRepo := repomocks.NewMockTagRepository(t)
85
86 // URL is not a favorite
87 favoriteRepo.EXPECT().FindByURL(mock.Anything, "https://example.com").Return(nil, nil)
88 favoriteRepo.EXPECT().Save(mock.Anything, mock.MatchedBy(func(f *entity.Favorite) bool {
89 return f.URL == "https://example.com" && f.Title == "Example"
90 })).Return(nil)
91
92 uc := usecase.NewManageFavoritesUseCase(favoriteRepo, folderRepo, tagRepo)
93
94 result, err := uc.Toggle(ctx, "https://example.com", "Example")
95 require.NoError(t, err)
96 require.NotNil(t, result)
97
98 assert.True(t, result.Added)
99 assert.Equal(t, "https://example.com", result.URL)
100 assert.Equal(t, "Example", result.Title)
101 assert.Equal(t, "Favorite added", result.Message)
102}
103
104func TestManageFavoritesUseCase_Toggle_RemovesWhenAlreadyFavorite(t *testing.T) {
105 ctx := testContext()
106
107 favoriteRepo := repomocks.NewMockFavoriteRepository(t)
108 folderRepo := repomocks.NewMockFolderRepository(t)
109 tagRepo := repomocks.NewMockTagRepository(t)
110
111 existingFav := &entity.Favorite{
112 ID: 42,
113 URL: "https://example.com",
114 Title: "Example Site",
115 }
116
117 // URL is already a favorite
118 favoriteRepo.EXPECT().FindByURL(mock.Anything, "https://example.com").Return(existingFav, nil)
119 favoriteRepo.EXPECT().Delete(mock.Anything, entity.FavoriteID(42)).Return(nil)
120
121 uc := usecase.NewManageFavoritesUseCase(favoriteRepo, folderRepo, tagRepo)
122
123 result, err := uc.Toggle(ctx, "https://example.com", "Example")
124 require.NoError(t, err)
125 require.NotNil(t, result)
126
127 assert.False(t, result.Added)
128 assert.Equal(t, "https://example.com", result.URL)
129 assert.Equal(t, "Example Site", result.Title) // Uses existing title
130 assert.Equal(t, "Favorite removed", result.Message)
131}
132
133func TestManageFavoritesUseCase_Toggle_EmptyURLReturnsError(t *testing.T) {
134 ctx := testContext()
135
136 favoriteRepo := repomocks.NewMockFavoriteRepository(t)
137 folderRepo := repomocks.NewMockFolderRepository(t)
138 tagRepo := repomocks.NewMockTagRepository(t)
139
140 uc := usecase.NewManageFavoritesUseCase(favoriteRepo, folderRepo, tagRepo)
141
142 result, err := uc.Toggle(ctx, "", "Title")
143 require.Error(t, err)
144 assert.Nil(t, result)
145 assert.Contains(t, err.Error(), "URL cannot be empty")
146}
147
148func TestManageFavoritesUseCase_Toggle_FindByURLErrorReturnsError(t *testing.T) {
149 ctx := testContext()
150
151 favoriteRepo := repomocks.NewMockFavoriteRepository(t)
152 folderRepo := repomocks.NewMockFolderRepository(t)
153 tagRepo := repomocks.NewMockTagRepository(t)
154
155 favoriteRepo.EXPECT().FindByURL(mock.Anything, "https://example.com").Return(nil, errors.New("db error"))
156
157 uc := usecase.NewManageFavoritesUseCase(favoriteRepo, folderRepo, tagRepo)
158
159 result, err := uc.Toggle(ctx, "https://example.com", "Example")
160 require.Error(t, err)
161 assert.Nil(t, result)
162 assert.Contains(t, err.Error(), "failed to check existing favorite")
163}
164
165func TestManageFavoritesUseCase_Toggle_SaveErrorReturnsError(t *testing.T) {
166 ctx := testContext()
167
168 favoriteRepo := repomocks.NewMockFavoriteRepository(t)
169 folderRepo := repomocks.NewMockFolderRepository(t)
170 tagRepo := repomocks.NewMockTagRepository(t)
171
172 favoriteRepo.EXPECT().FindByURL(mock.Anything, "https://example.com").Return(nil, nil)
173 favoriteRepo.EXPECT().Save(mock.Anything, mock.Anything).Return(errors.New("db error"))
174
175 uc := usecase.NewManageFavoritesUseCase(favoriteRepo, folderRepo, tagRepo)
176
177 result, err := uc.Toggle(ctx, "https://example.com", "Example")
178 require.Error(t, err)
179 assert.Nil(t, result)
180 assert.Contains(t, err.Error(), "failed to add favorite")
181}
182
183func TestManageFavoritesUseCase_Toggle_DeleteErrorReturnsError(t *testing.T) {
184 ctx := testContext()
185
186 favoriteRepo := repomocks.NewMockFavoriteRepository(t)
187 folderRepo := repomocks.NewMockFolderRepository(t)
188 tagRepo := repomocks.NewMockTagRepository(t)
189
190 existingFav := &entity.Favorite{ID: 42, URL: "https://example.com", Title: "Example"}
191 favoriteRepo.EXPECT().FindByURL(mock.Anything, "https://example.com").Return(existingFav, nil)
192 favoriteRepo.EXPECT().Delete(mock.Anything, entity.FavoriteID(42)).Return(errors.New("db error"))
193
194 uc := usecase.NewManageFavoritesUseCase(favoriteRepo, folderRepo, tagRepo)
195
196 result, err := uc.Toggle(ctx, "https://example.com", "Example")
197 require.Error(t, err)
198 assert.Nil(t, result)
199 assert.Contains(t, err.Error(), "failed to remove favorite")
200}