Skip to content

Commit bbc8cbb

Browse files
committed
Add test for toggling notifications
1 parent 33c9ab0 commit bbc8cbb

File tree

2 files changed

+153
-1
lines changed

2 files changed

+153
-1
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import { screen } from "@testing-library/react";
2+
import userEvent from "@testing-library/user-event";
3+
import { http, HttpResponse } from "msw";
4+
import type {
5+
Experiments,
6+
NotificationPreference,
7+
NotificationTemplate,
8+
UpdateUserNotificationPreferences,
9+
} from "api/typesGenerated";
10+
import { renderWithAuth } from "testHelpers/renderHelpers";
11+
import { server } from "testHelpers/server";
12+
import NotificationsPage from "./NotificationsPage";
13+
14+
test("can enable and disable notifications", async () => {
15+
server.use(
16+
http.get("/api/v2/experiments", () =>
17+
HttpResponse.json(["notifications"] as Experiments),
18+
),
19+
http.get("/api/v2/users/:userId/notifications/preferences", () =>
20+
HttpResponse.json(null),
21+
),
22+
http.get("/api/v2/notifications/templates/system", () =>
23+
HttpResponse.json(notificationsTemplateSystemRes),
24+
),
25+
http.put<
26+
{ userId: string },
27+
UpdateUserNotificationPreferences,
28+
NotificationPreference[]
29+
>(
30+
"/api/v2/users/:userId/notifications/preferences",
31+
async ({ request }) => {
32+
const body = await request.json();
33+
const res: NotificationPreference[] = Object.entries(body).map(
34+
([id, disabled]) => ({
35+
disabled,
36+
id,
37+
updated_at: new Date().toISOString(),
38+
}),
39+
);
40+
return HttpResponse.json(res);
41+
},
42+
),
43+
);
44+
renderWithAuth(<NotificationsPage />);
45+
const user = userEvent.setup();
46+
const workspaceGroupTemplates = notificationsTemplateSystemRes.filter(
47+
(t) => t.group === "Workspace Events",
48+
);
49+
50+
// Test notification groups
51+
const workspaceGroupSwitch = await screen.findByLabelText("Workspace Events");
52+
await user.click(workspaceGroupSwitch);
53+
await screen.findByText("Notification preferences updated");
54+
expect(workspaceGroupSwitch).not.toBeChecked();
55+
for (const template of workspaceGroupTemplates) {
56+
const templateSwitch = screen.getByLabelText(template.name);
57+
expect(templateSwitch).not.toBeChecked();
58+
}
59+
60+
await user.click(workspaceGroupSwitch);
61+
await screen.findByText("Notification preferences updated");
62+
expect(workspaceGroupSwitch).toBeChecked();
63+
for (const template of workspaceGroupTemplates) {
64+
const templateSwitch = screen.getByLabelText(template.name);
65+
expect(templateSwitch).toBeChecked();
66+
}
67+
68+
// Test individual notifications
69+
const workspaceDeletedSwitch = screen.getByLabelText("Workspace Deleted");
70+
await user.click(workspaceDeletedSwitch);
71+
await screen.findByText("Notification preferences updated");
72+
expect(workspaceDeletedSwitch).not.toBeChecked();
73+
74+
await user.click(workspaceDeletedSwitch);
75+
await screen.findByText("Notification preferences updated");
76+
expect(workspaceDeletedSwitch).toBeChecked();
77+
});
78+
79+
const notificationsTemplateSystemRes: NotificationTemplate[] = [
80+
{
81+
id: "f517da0b-cdc9-410f-ab89-a86107c420ed",
82+
name: "Workspace Deleted",
83+
title_template: 'Workspace "{{.Labels.name}}" deleted',
84+
body_template:
85+
'Hi {{.UserName}}\n\nYour workspace **{{.Labels.name}}** was deleted.\nThe specified reason was "**{{.Labels.reason}}{{ if .Labels.initiator }} ({{ .Labels.initiator }}){{end}}**".',
86+
actions:
87+
'[{"url": "{{ base_url }}/workspaces", "label": "View workspaces"}, {"url": "{{ base_url }}/templates", "label": "View templates"}]',
88+
group: "Workspace Events",
89+
method: "",
90+
kind: "system",
91+
},
92+
{
93+
id: "381df2a9-c0c0-4749-420f-80a9280c66f9",
94+
name: "Workspace Autobuild Failed",
95+
title_template: 'Workspace "{{.Labels.name}}" autobuild failed',
96+
body_template:
97+
'Hi {{.UserName}}\nAutomatic build of your workspace **{{.Labels.name}}** failed.\nThe specified reason was "**{{.Labels.reason}}**".',
98+
actions:
99+
'[{"url": "{{ base_url }}/@{{.UserUsername}}/{{.Labels.name}}", "label": "View workspace"}]',
100+
group: "Workspace Events",
101+
method: "",
102+
kind: "system",
103+
},
104+
{
105+
id: "c34a0c09-0704-4cac-bd1c-0c0146811c2b",
106+
name: "Workspace updated automatically",
107+
title_template: 'Workspace "{{.Labels.name}}" updated automatically',
108+
body_template:
109+
"Hi {{.UserName}}\nYour workspace **{{.Labels.name}}** has been updated automatically to the latest template version ({{.Labels.template_version_name}}).",
110+
actions:
111+
'[{"url": "{{ base_url }}/@{{.UserUsername}}/{{.Labels.name}}", "label": "View workspace"}]',
112+
group: "Workspace Events",
113+
method: "",
114+
kind: "system",
115+
},
116+
{
117+
id: "0ea69165-ec14-4314-91f1-69566ac3c5a0",
118+
name: "Workspace Marked as Dormant",
119+
title_template: 'Workspace "{{.Labels.name}}" marked as dormant',
120+
body_template:
121+
"Hi {{.UserName}}\n\nYour workspace **{{.Labels.name}}** has been marked as [**dormant**](https://coder.com/docs/templates/schedule#dormancy-threshold-enterprise) because of {{.Labels.reason}}.\nDormant workspaces are [automatically deleted](https://coder.com/docs/templates/schedule#dormancy-auto-deletion-enterprise) after {{.Labels.timeTilDormant}} of inactivity.\nTo prevent deletion, use your workspace with the link below.",
122+
actions:
123+
'[{"url": "{{ base_url }}/@{{.UserUsername}}/{{.Labels.name}}", "label": "View workspace"}]',
124+
group: "Workspace Events",
125+
method: "",
126+
kind: "system",
127+
},
128+
{
129+
id: "51ce2fdf-c9ca-4be1-8d70-628674f9bc42",
130+
name: "Workspace Marked for Deletion",
131+
title_template: 'Workspace "{{.Labels.name}}" marked for deletion',
132+
body_template:
133+
"Hi {{.UserName}}\n\nYour workspace **{{.Labels.name}}** has been marked for **deletion** after {{.Labels.timeTilDormant}} of [dormancy](https://coder.com/docs/templates/schedule#dormancy-auto-deletion-enterprise) because of {{.Labels.reason}}.\nTo prevent deletion, use your workspace with the link below.",
134+
actions:
135+
'[{"url": "{{ base_url }}/@{{.UserUsername}}/{{.Labels.name}}", "label": "View workspace"}]',
136+
group: "Workspace Events",
137+
method: "",
138+
kind: "system",
139+
},
140+
{
141+
id: "4e19c0ac-94e1-4532-9515-d1801aa283b2",
142+
name: "User account created",
143+
title_template: 'User account "{{.Labels.created_account_name}}" created',
144+
body_template:
145+
"Hi {{.UserName}},\nNew user account **{{.Labels.created_account_name}}** has been created.",
146+
actions:
147+
'[{"url": "{{ base_url }}/deployment/users?filter=status%3Aactive", "label": "View accounts"}]',
148+
group: "User Events",
149+
method: "",
150+
kind: "system",
151+
},
152+
];

site/src/pages/UserSettingsPage/NotificationsPage/NotificationsPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ const PreferenceSwitch: FC<PreferenceSwitchProps> = ({
5353
await updatePreferences.mutateAsync({
5454
template_disabled_map: onToggle(checked),
5555
});
56-
displaySuccess("Notification preference updated");
56+
displaySuccess("Notification preferences updated");
5757
}}
5858
/>
5959
);

0 commit comments

Comments
 (0)