1package homepage
2
3import (
4 "context"
5 "encoding/json"
6 "testing"
7
8 "github.com/bnema/dumber/internal/application/dto"
9 "github.com/bnema/dumber/internal/application/port"
10 portmocks "github.com/bnema/dumber/internal/application/port/mocks"
11 "github.com/bnema/dumber/internal/domain/entity"
12 "github.com/stretchr/testify/mock"
13 "github.com/stretchr/testify/require"
14)
15
16func TestHandleFavoriteCreatePassesTagsOnlyPayload(t *testing.T) {
17 t.Parallel()
18
19 favorites := portmocks.NewMockHomepageFavorites(t)
20 favorites.EXPECT().
21 AddFavorite(mock.Anything, dto.FavoriteCreateInput{
22 URL: "https://example.com",
23 Title: "Example",
24 Tags: []entity.TagID{7, 9},
25 }).
26 Return(&entity.Favorite{ID: 1, URL: "https://example.com", Title: "Example"}, nil).
27 Once()
28
29 handler := NewFavoritesHandlers(favorites).HandleCreate()
30 got, err := handler.Handle(context.Background(), port.WebViewID(0), json.RawMessage(`{"requestId":"req-1","url":" https://example.com ","title":"Example","tags":[7,9]}`))
31 require.NoError(t, err)
32
33 resp, ok := got.(Response)
34 require.True(t, ok)
35 require.True(t, resp.Success)
36}
37
38func TestHandleFavoriteCreateRejectsInvalidTagIDs(t *testing.T) {
39 t.Parallel()
40
41 handler := NewFavoritesHandlers(portmocks.NewMockHomepageFavorites(t)).HandleCreate()
42 got, err := handler.Handle(context.Background(), port.WebViewID(0), json.RawMessage(`{"requestId":"req-2","url":"https://example.com","tags":[0]}`))
43 require.NoError(t, err)
44
45 resp, ok := got.(Response)
46 require.True(t, ok)
47 require.False(t, resp.Success)
48 require.Contains(t, resp.Error, "tag id must be positive")
49}
50
51func TestHandleFavoriteUpdatePassesTagsOnlyPayload(t *testing.T) {
52 t.Parallel()
53
54 shortcut := 4
55 favorites := portmocks.NewMockHomepageFavorites(t)
56 favorites.EXPECT().
57 UpdateFavorite(mock.Anything, dto.FavoriteUpdateInput{
58 ID: entity.FavoriteID(42),
59 Title: "Updated",
60 FaviconURL: "https://example.com/favicon.ico",
61 ShortcutKey: &shortcut,
62 ShortcutKeySet: true,
63 }).
64 Return(&entity.Favorite{ID: 42, URL: "https://example.com", Title: "Updated", ShortcutKey: &shortcut}, nil).
65 Once()
66
67 handler := NewFavoritesHandlers(favorites).HandleUpdate()
68 got, err := handler.Handle(context.Background(), port.WebViewID(0), json.RawMessage(`{"requestId":"req-3","id":42,"title":"Updated","favicon_url":"https://example.com/favicon.ico","shortcut_key":4}`))
69 require.NoError(t, err)
70
71 resp, ok := got.(Response)
72 require.True(t, ok)
73 require.True(t, resp.Success)
74}
75func TestHandleFavoriteUpdatePreservesShortcutWhenOmitted(t *testing.T) {
76 t.Parallel()
77
78 favorites := portmocks.NewMockHomepageFavorites(t)
79 favorites.EXPECT().
80 UpdateFavorite(mock.Anything, dto.FavoriteUpdateInput{
81 ID: entity.FavoriteID(42),
82 Title: "Updated",
83 FaviconURL: "https://example.com/favicon.ico",
84 }).
85 Return(&entity.Favorite{ID: 42, URL: "https://example.com", Title: "Updated"}, nil).
86 Once()
87
88 handler := NewFavoritesHandlers(favorites).HandleUpdate()
89 got, err := handler.Handle(context.Background(), port.WebViewID(0), json.RawMessage(`{"requestId":"req-4","id":42,"title":"Updated","favicon_url":"https://example.com/favicon.ico"}`))
90 require.NoError(t, err)
91
92 resp, ok := got.(Response)
93 require.True(t, ok)
94 require.True(t, resp.Success)
95}
96func TestHandleFavoriteUpdateClearsShortcutWhenExplicitNull(t *testing.T) {
97 t.Parallel()
98
99 favorites := portmocks.NewMockHomepageFavorites(t)
100 favorites.EXPECT().
101 UpdateFavorite(mock.Anything, dto.FavoriteUpdateInput{
102 ID: entity.FavoriteID(42),
103 Title: "Updated",
104 FaviconURL: "https://example.com/favicon.ico",
105 ShortcutKeySet: true,
106 }).
107 Return(&entity.Favorite{ID: 42, URL: "https://example.com", Title: "Updated"}, nil).
108 Once()
109
110 handler := NewFavoritesHandlers(favorites).HandleUpdate()
111 got, err := handler.Handle(context.Background(), port.WebViewID(0), json.RawMessage(`{"requestId":"req-5","id":42,"title":"Updated","favicon_url":"https://example.com/favicon.ico","shortcut_key":null}`))
112 require.NoError(t, err)
113
114 resp, ok := got.(Response)
115 require.True(t, ok)
116 require.True(t, resp.Success)
117}