Skip to content

Commit 208ed1e

Browse files
authored
chore(coderd/notifications): expand golden file testing for notifications (coder#15032)
This PR aims to close coder#14913. It expands the golden files for the notifier to include the entire payload serialised as JSON.
1 parent 9c8ecb8 commit 208ed1e

File tree

79 files changed

+2270
-209
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+2270
-209
lines changed

.github/workflows/typos.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,6 @@ extend-exclude = [
4141
"tailnet/testdata/**",
4242
"site/src/pages/SetupPage/countries.tsx",
4343
"provisioner/terraform/testdata/**",
44+
# notifications' golden files confuse the detector because of quoted-printable encoding
45+
"coderd/notifications/testdata/**"
4446
]
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
-- UserAccountCreated
2+
UPDATE notification_templates
3+
SET
4+
body_template = E'Hi {{.UserName}},\n\n' ||
5+
E'New user account **{{.Labels.created_account_name}}** has been created.\n\n' ||
6+
-- Mention the real name of the user who created the account:
7+
E'This new user account was created for **{{.Labels.created_account_user_name}}** by **{{.Labels.account_creator}}**.'
8+
WHERE
9+
id = '4e19c0ac-94e1-4532-9515-d1801aa283b2';
10+
11+
-- UserAccountDeleted
12+
UPDATE notification_templates
13+
SET
14+
body_template = E'Hi {{.UserName}},\n\n' ||
15+
E'User account **{{.Labels.deleted_account_name}}** has been deleted.\n\n' ||
16+
-- Mention the real name of the user who deleted the account:
17+
E'The deleted account belonged to **{{.Labels.deleted_account_user_name}}** and was deleted by **{{.Labels.account_deleter_user_name}}**.'
18+
WHERE
19+
id = 'f44d9314-ad03-4bc8-95d0-5cad491da6b6';
20+
21+
-- UserAccountSuspended
22+
UPDATE notification_templates
23+
SET
24+
body_template = E'Hi {{.UserName}},\n\n' || -- Add a \n
25+
E'User account **{{.Labels.suspended_account_name}}** has been suspended.\n\n' ||
26+
-- Mention the real name of the user who suspended the account:
27+
E'The newly suspended account belongs to **{{.Labels.suspended_account_user_name}}** and was suspended by **{{.Labels.account_suspender_user_name}}**.'
28+
WHERE
29+
id = 'b02ddd82-4733-4d02-a2d7-c36f3598997d';
30+
31+
-- YourAccountSuspended
32+
UPDATE notification_templates
33+
SET
34+
body_template = E'Hi {{.UserName}},\n\n' || -- Add a \n
35+
E'Your account **{{.Labels.suspended_account_name}}** has been suspended by **{{.Labels.account_suspender_user_name}}**.'
36+
WHERE
37+
id = '6a2f0609-9b69-4d36-a989-9f5925b6cbff';
38+
39+
40+
-- UserAccountActivated
41+
UPDATE notification_templates
42+
SET
43+
body_template = E'Hi {{.UserName}},\n\n' || -- Add a \n
44+
E'User account **{{.Labels.activated_account_name}}** has been activated.\n\n' ||
45+
E'The newly activated account belongs to **{{.Labels.activated_account_user_name}}** and was activated by **{{.Labels.account_activator_user_name}}**.'
46+
WHERE
47+
id = '9f5af851-8408-4e73-a7a1-c6502ba46689';
48+
49+
-- YourAccountActivated
50+
UPDATE notification_templates
51+
SET
52+
body_template = E'Hi {{.UserName}},\n\n' || -- Add a \n
53+
E'Your account **{{.Labels.activated_account_name}}** has been activated by **{{.Labels.account_activator_user_name}}**.'
54+
WHERE
55+
id = '1a6a6bea-ee0a-43e2-9e7c-eabdb53730e4';
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
-- UserAccountCreated
2+
UPDATE notification_templates
3+
SET
4+
body_template = E'Hi {{.UserName}},\n\n' ||
5+
E'New user account **{{.Labels.created_account_name}}** has been created.\n\n' ||
6+
-- Use the conventional initiator label:
7+
E'This new user account was created for **{{.Labels.created_account_user_name}}** by **{{.Labels.initiator}}**.'
8+
WHERE
9+
id = '4e19c0ac-94e1-4532-9515-d1801aa283b2';
10+
11+
-- UserAccountDeleted
12+
UPDATE notification_templates
13+
SET
14+
body_template = E'Hi {{.UserName}},\n\n' ||
15+
E'User account **{{.Labels.deleted_account_name}}** has been deleted.\n\n' ||
16+
-- Use the conventional initiator label:
17+
E'The deleted account belonged to **{{.Labels.deleted_account_user_name}}** and was deleted by **{{.Labels.initiator}}**.'
18+
WHERE
19+
id = 'f44d9314-ad03-4bc8-95d0-5cad491da6b6';
20+
21+
-- UserAccountSuspended
22+
UPDATE notification_templates
23+
SET
24+
body_template = E'Hi {{.UserName}},\n\n' || -- Add a \n
25+
E'User account **{{.Labels.suspended_account_name}}** has been suspended.\n\n' ||
26+
-- Use the conventional initiator label:
27+
E'The newly suspended account belongs to **{{.Labels.suspended_account_user_name}}** and was suspended by **{{.Labels.initiator}}**.'
28+
WHERE
29+
id = 'b02ddd82-4733-4d02-a2d7-c36f3598997d';
30+
31+
-- YourAccountSuspended
32+
UPDATE notification_templates
33+
SET
34+
body_template = E'Hi {{.UserName}},\n\n' || -- Add a \n
35+
-- Use the conventional initiator label:
36+
E'Your account **{{.Labels.suspended_account_name}}** has been suspended by **{{.Labels.initiator}}**.'
37+
WHERE
38+
id = '6a2f0609-9b69-4d36-a989-9f5925b6cbff';
39+
40+
-- UserAccountActivated
41+
UPDATE notification_templates
42+
SET
43+
body_template = E'Hi {{.UserName}},\n\n' || -- Add a \n
44+
E'User account **{{.Labels.activated_account_name}}** has been activated.\n\n' ||
45+
-- Use the conventional initiator label:
46+
E'The newly activated account belongs to **{{.Labels.activated_account_user_name}}** and was activated by **{{.Labels.initiator}}**.'
47+
WHERE
48+
id = '9f5af851-8408-4e73-a7a1-c6502ba46689';
49+
50+
-- YourAccountActivated
51+
UPDATE notification_templates
52+
SET
53+
body_template = E'Hi {{.UserName}},\n\n' || -- Add a \n
54+
-- Use the conventional initiator label:
55+
E'Your account **{{.Labels.activated_account_name}}** has been activated by **{{.Labels.initiator}}**.'
56+
WHERE
57+
id = '1a6a6bea-ee0a-43e2-9e7c-eabdb53730e4';

coderd/notifications/dispatch/smtp_test.go

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,8 @@ package dispatch_test
22

33
import (
44
"bytes"
5-
"crypto/tls"
6-
_ "embed"
75
"fmt"
86
"log"
9-
"net"
107
"sync"
118
"testing"
129

@@ -22,6 +19,7 @@ import (
2219
"github.com/coder/serpent"
2320

2421
"github.com/coder/coder/v2/coderd/notifications/dispatch"
22+
"github.com/coder/coder/v2/coderd/notifications/dispatch/smtptest"
2523
"github.com/coder/coder/v2/coderd/notifications/types"
2624
"github.com/coder/coder/v2/codersdk"
2725
"github.com/coder/coder/v2/testutil"
@@ -47,9 +45,9 @@ func TestSMTP(t *testing.T) {
4745
subject = "This is the subject"
4846
body = "This is the body"
4947

50-
caFile = "fixtures/ca.crt"
51-
certFile = "fixtures/server.crt"
52-
keyFile = "fixtures/server.key"
48+
caFile = "smtptest/fixtures/ca.crt"
49+
certFile = "smtptest/fixtures/server.crt"
50+
keyFile = "smtptest/fixtures/server.key"
5351
)
5452

5553
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true, IgnoredErrorIs: []error{}}).Leveled(slog.LevelDebug)
@@ -125,7 +123,7 @@ func TestSMTP(t *testing.T) {
125123

126124
Auth: codersdk.NotificationsEmailAuthConfig{
127125
Username: username,
128-
PasswordFile: "fixtures/password.txt",
126+
PasswordFile: "smtptest/fixtures/password.txt",
129127
},
130128
},
131129
toAddrs: []string{to},
@@ -341,14 +339,14 @@ func TestSMTP(t *testing.T) {
341339
cfg: codersdk.NotificationsEmailConfig{
342340
TLS: codersdk.NotificationsEmailTLSConfig{
343341
CAFile: caFile,
344-
CertFile: "fixtures/nope.cert",
342+
CertFile: "smtptest/fixtures/nope.cert",
345343
KeyFile: keyFile,
346344
},
347345
},
348346
// not using full error message here since it differs on *nix and Windows:
349347
// *nix: no such file or directory
350348
// Windows: The system cannot find the file specified.
351-
expectedErr: "open fixtures/nope.cert:",
349+
expectedErr: "open smtptest/fixtures/nope.cert:",
352350
retryable: true,
353351
},
354352
{
@@ -358,13 +356,13 @@ func TestSMTP(t *testing.T) {
358356
TLS: codersdk.NotificationsEmailTLSConfig{
359357
CAFile: caFile,
360358
CertFile: certFile,
361-
KeyFile: "fixtures/nope.key",
359+
KeyFile: "smtptest/fixtures/nope.key",
362360
},
363361
},
364362
// not using full error message here since it differs on *nix and Windows:
365363
// *nix: no such file or directory
366364
// Windows: The system cannot find the file specified.
367-
expectedErr: "open fixtures/nope.key:",
365+
expectedErr: "open smtptest/fixtures/nope.key:",
368366
retryable: true,
369367
},
370368
/**
@@ -417,7 +415,7 @@ func TestSMTP(t *testing.T) {
417415

418416
tc.cfg.ForceTLS = serpent.Bool(tc.useTLS)
419417

420-
backend := NewBackend(Config{
418+
backend := smtptest.NewBackend(smtptest.Config{
421419
AuthMechanisms: tc.authMechs,
422420

423421
AcceptedIdentity: tc.cfg.Auth.Identity.String(),
@@ -428,7 +426,7 @@ func TestSMTP(t *testing.T) {
428426
})
429427

430428
// Create a mock SMTP server which conditionally listens for plain or TLS connections.
431-
srv, listen, err := createMockSMTPServer(backend, tc.useTLS)
429+
srv, listen, err := smtptest.CreateMockSMTPServer(backend, tc.useTLS)
432430
require.NoError(t, err)
433431
t.Cleanup(func() {
434432
// We expect that the server has already been closed in the test
@@ -460,7 +458,7 @@ func TestSMTP(t *testing.T) {
460458

461459
// Wait for the server to become pingable.
462460
require.Eventually(t, func() bool {
463-
cl, err := pingClient(listen, tc.useTLS, tc.cfg.TLS.StartTLS.Value())
461+
cl, err := smtptest.PingClient(listen, tc.useTLS, tc.cfg.TLS.StartTLS.Value())
464462
if err != nil {
465463
t.Logf("smtp not yet dialable: %s", err)
466464
return false
@@ -522,19 +520,3 @@ func TestSMTP(t *testing.T) {
522520
})
523521
}
524522
}
525-
526-
func pingClient(listen net.Listener, useTLS bool, startTLS bool) (*smtp.Client, error) {
527-
tlsCfg := &tls.Config{
528-
// nolint:gosec // It's a test.
529-
InsecureSkipVerify: true,
530-
}
531-
532-
switch {
533-
case useTLS:
534-
return smtp.DialTLS(listen.Addr().String(), tlsCfg)
535-
case startTLS:
536-
return smtp.DialStartTLS(listen.Addr().String(), tlsCfg)
537-
default:
538-
return smtp.Dial(listen.Addr().String())
539-
}
540-
}

coderd/notifications/dispatch/smtp_util_test.go renamed to coderd/notifications/dispatch/smtptest/server.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package dispatch_test
1+
package smtptest
22

33
import (
44
"crypto/tls"
@@ -162,7 +162,7 @@ func (*Session) Reset() {}
162162
func (*Session) Logout() error { return nil }
163163

164164
// nolint:revive // Yes, useTLS is a control flag.
165-
func createMockSMTPServer(be *Backend, useTLS bool) (*smtp.Server, net.Listener, error) {
165+
func CreateMockSMTPServer(be *Backend, useTLS bool) (*smtp.Server, net.Listener, error) {
166166
// nolint:gosec
167167
tlsCfg := &tls.Config{
168168
GetCertificate: readCert,
@@ -203,3 +203,19 @@ func readCert(_ *tls.ClientHelloInfo) (*tls.Certificate, error) {
203203

204204
return &crt, nil
205205
}
206+
207+
func PingClient(listen net.Listener, useTLS bool, startTLS bool) (*smtp.Client, error) {
208+
tlsCfg := &tls.Config{
209+
// nolint:gosec // It's a test.
210+
InsecureSkipVerify: true,
211+
}
212+
213+
switch {
214+
case useTLS:
215+
return smtp.DialTLS(listen.Addr().String(), tlsCfg)
216+
case startTLS:
217+
return smtp.DialStartTLS(listen.Addr().String(), tlsCfg)
218+
default:
219+
return smtp.Dial(listen.Addr().String())
220+
}
221+
}

0 commit comments

Comments
 (0)