Skip to content

Commit 95a348e

Browse files
authored
fix(coderd): improve use case handling in notifier for appearance fetchers (#15242)
Fixing #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

Lines changed: 8 additions & 0 deletions
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
}
Lines changed: 231 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy