Skip to content

Commit 95a348e

Browse files
authored
fix(coderd): improve use case handling in notifier for appearance fetchers (coder#15242)
Fixing coder#15241 & add tests.
1 parent 03940f5 commit 95a348e

File tree

2 files changed

+239
-0
lines changed

2 files changed

+239
-0
lines changed

coderd/notifications/fetcher.go

+8
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ func (n *notifier) fetchAppName(ctx context.Context) (string, error) {
3838
}
3939
return "", xerrors.Errorf("get application name: %w", err)
4040
}
41+
42+
if appName == "" {
43+
appName = notificationsDefaultAppName
44+
}
4145
return appName, nil
4246
}
4347

@@ -49,5 +53,9 @@ func (n *notifier) fetchLogoURL(ctx context.Context) (string, error) {
4953
}
5054
return "", xerrors.Errorf("get logo URL: %w", err)
5155
}
56+
57+
if logoURL == "" {
58+
logoURL = notificationsDefaultLogoURL
59+
}
5260
return logoURL, nil
5361
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
package notifications
2+
3+
import (
4+
"context"
5+
"database/sql"
6+
"testing"
7+
"text/template"
8+
9+
"github.com/stretchr/testify/require"
10+
"go.uber.org/mock/gomock"
11+
"golang.org/x/xerrors"
12+
13+
"github.com/coder/coder/v2/coderd/database/dbmock"
14+
)
15+
16+
func TestNotifier_FetchHelpers(t *testing.T) {
17+
t.Parallel()
18+
19+
t.Run("ok", func(t *testing.T) {
20+
t.Parallel()
21+
22+
ctrl := gomock.NewController(t)
23+
dbmock := dbmock.NewMockStore(ctrl)
24+
25+
n := &notifier{
26+
store: dbmock,
27+
helpers: template.FuncMap{},
28+
}
29+
30+
dbmock.EXPECT().GetApplicationName(gomock.Any()).Return("ACME Inc.", nil)
31+
dbmock.EXPECT().GetLogoURL(gomock.Any()).Return("https://example.com/logo.png", nil)
32+
33+
ctx := context.Background()
34+
helpers, err := n.fetchHelpers(ctx)
35+
require.NoError(t, err)
36+
37+
appName, ok := helpers["app_name"].(func() string)
38+
require.True(t, ok)
39+
require.Equal(t, "ACME Inc.", appName())
40+
41+
logoURL, ok := helpers["logo_url"].(func() string)
42+
require.True(t, ok)
43+
require.Equal(t, "https://example.com/logo.png", logoURL())
44+
})
45+
46+
t.Run("failed to fetch app name", func(t *testing.T) {
47+
t.Parallel()
48+
49+
ctrl := gomock.NewController(t)
50+
dbmock := dbmock.NewMockStore(ctrl)
51+
52+
n := &notifier{
53+
store: dbmock,
54+
helpers: template.FuncMap{},
55+
}
56+
57+
dbmock.EXPECT().GetApplicationName(gomock.Any()).Return("", xerrors.New("internal error"))
58+
59+
ctx := context.Background()
60+
_, err := n.fetchHelpers(ctx)
61+
require.Error(t, err)
62+
require.ErrorContains(t, err, "get application name")
63+
})
64+
65+
t.Run("failed to fetch logo URL", func(t *testing.T) {
66+
t.Parallel()
67+
68+
ctrl := gomock.NewController(t)
69+
dbmock := dbmock.NewMockStore(ctrl)
70+
71+
n := &notifier{
72+
store: dbmock,
73+
helpers: template.FuncMap{},
74+
}
75+
76+
dbmock.EXPECT().GetApplicationName(gomock.Any()).Return("ACME Inc.", nil)
77+
dbmock.EXPECT().GetLogoURL(gomock.Any()).Return("", xerrors.New("internal error"))
78+
79+
ctx := context.Background()
80+
_, err := n.fetchHelpers(ctx)
81+
require.ErrorContains(t, err, "get logo URL")
82+
})
83+
}
84+
85+
func TestNotifier_FetchAppName(t *testing.T) {
86+
t.Parallel()
87+
88+
t.Run("ok", func(t *testing.T) {
89+
t.Parallel()
90+
91+
ctrl := gomock.NewController(t)
92+
dbmock := dbmock.NewMockStore(ctrl)
93+
94+
n := &notifier{
95+
store: dbmock,
96+
}
97+
98+
dbmock.EXPECT().GetApplicationName(gomock.Any()).Return("ACME Inc.", nil)
99+
100+
ctx := context.Background()
101+
appName, err := n.fetchAppName(ctx)
102+
require.NoError(t, err)
103+
require.Equal(t, "ACME Inc.", appName)
104+
})
105+
106+
t.Run("No rows", func(t *testing.T) {
107+
t.Parallel()
108+
ctrl := gomock.NewController(t)
109+
dbmock := dbmock.NewMockStore(ctrl)
110+
111+
n := &notifier{
112+
store: dbmock,
113+
}
114+
115+
dbmock.EXPECT().GetApplicationName(gomock.Any()).Return("", sql.ErrNoRows)
116+
117+
ctx := context.Background()
118+
appName, err := n.fetchAppName(ctx)
119+
require.NoError(t, err)
120+
require.Equal(t, notificationsDefaultAppName, appName)
121+
})
122+
123+
t.Run("Empty string", func(t *testing.T) {
124+
t.Parallel()
125+
126+
ctrl := gomock.NewController(t)
127+
dbmock := dbmock.NewMockStore(ctrl)
128+
129+
n := &notifier{
130+
store: dbmock,
131+
}
132+
133+
dbmock.EXPECT().GetApplicationName(gomock.Any()).Return("", nil)
134+
135+
ctx := context.Background()
136+
appName, err := n.fetchAppName(ctx)
137+
require.NoError(t, err)
138+
require.Equal(t, notificationsDefaultAppName, appName)
139+
})
140+
141+
t.Run("internal error", func(t *testing.T) {
142+
t.Parallel()
143+
144+
ctrl := gomock.NewController(t)
145+
dbmock := dbmock.NewMockStore(ctrl)
146+
147+
n := &notifier{
148+
store: dbmock,
149+
}
150+
151+
dbmock.EXPECT().GetApplicationName(gomock.Any()).Return("", xerrors.New("internal error"))
152+
153+
ctx := context.Background()
154+
_, err := n.fetchAppName(ctx)
155+
require.Error(t, err)
156+
})
157+
}
158+
159+
func TestNotifier_FetchLogoURL(t *testing.T) {
160+
t.Parallel()
161+
162+
t.Run("ok", func(t *testing.T) {
163+
t.Parallel()
164+
165+
ctrl := gomock.NewController(t)
166+
dbmock := dbmock.NewMockStore(ctrl)
167+
168+
n := &notifier{
169+
store: dbmock,
170+
}
171+
172+
dbmock.EXPECT().GetLogoURL(gomock.Any()).Return("https://example.com/logo.png", nil)
173+
174+
ctx := context.Background()
175+
logoURL, err := n.fetchLogoURL(ctx)
176+
require.NoError(t, err)
177+
require.Equal(t, "https://example.com/logo.png", logoURL)
178+
})
179+
180+
t.Run("No rows", func(t *testing.T) {
181+
t.Parallel()
182+
ctrl := gomock.NewController(t)
183+
dbmock := dbmock.NewMockStore(ctrl)
184+
185+
n := &notifier{
186+
store: dbmock,
187+
}
188+
189+
dbmock.EXPECT().GetLogoURL(gomock.Any()).Return("", sql.ErrNoRows)
190+
191+
ctx := context.Background()
192+
logoURL, err := n.fetchLogoURL(ctx)
193+
require.NoError(t, err)
194+
require.Equal(t, notificationsDefaultLogoURL, logoURL)
195+
})
196+
197+
t.Run("Empty string", func(t *testing.T) {
198+
t.Parallel()
199+
200+
ctrl := gomock.NewController(t)
201+
dbmock := dbmock.NewMockStore(ctrl)
202+
203+
n := &notifier{
204+
store: dbmock,
205+
}
206+
207+
dbmock.EXPECT().GetLogoURL(gomock.Any()).Return("", nil)
208+
209+
ctx := context.Background()
210+
logoURL, err := n.fetchLogoURL(ctx)
211+
require.NoError(t, err)
212+
require.Equal(t, notificationsDefaultLogoURL, logoURL)
213+
})
214+
215+
t.Run("internal error", func(t *testing.T) {
216+
t.Parallel()
217+
218+
ctrl := gomock.NewController(t)
219+
dbmock := dbmock.NewMockStore(ctrl)
220+
221+
n := &notifier{
222+
store: dbmock,
223+
}
224+
225+
dbmock.EXPECT().GetLogoURL(gomock.Any()).Return("", xerrors.New("internal error"))
226+
227+
ctx := context.Background()
228+
_, err := n.fetchLogoURL(ctx)
229+
require.Error(t, err)
230+
})
231+
}

0 commit comments

Comments
 (0)