Skip to content

feat(site): implement notification ui #14175

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
Aug 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
fc282e7
Add base notification settings page to deployment
BrunoQuaresma Jul 29, 2024
997e0d3
Add base notifications components
BrunoQuaresma Jul 29, 2024
73f8471
Bind notifications into the user account notifications page
BrunoQuaresma Aug 2, 2024
33c9ab0
Remove deployment notifications page
BrunoQuaresma Aug 2, 2024
bbc8cbb
Add test for toggling notifications
BrunoQuaresma Aug 2, 2024
7227a42
Update migration
BrunoQuaresma Aug 5, 2024
788de88
Update template notification methods
BrunoQuaresma Aug 5, 2024
1262f7b
Fix types
BrunoQuaresma Aug 5, 2024
e449e3d
Fix remaining type issues
BrunoQuaresma Aug 5, 2024
0154b94
Experience improvements
BrunoQuaresma Aug 5, 2024
aedf159
Fix validation
BrunoQuaresma Aug 5, 2024
1a2efae
Remove BE changes
BrunoQuaresma Aug 6, 2024
a1f363c
Fix FE types
BrunoQuaresma Aug 6, 2024
7412eb9
Fix notifications permissions
BrunoQuaresma Aug 6, 2024
1ff0973
Display webhook info
BrunoQuaresma Aug 6, 2024
2acde04
Merge branch 'main' of https://github.com/coder/coder into bq/user-no…
BrunoQuaresma Aug 6, 2024
7cc7bdb
Add tests to the notifications page
BrunoQuaresma Aug 6, 2024
4956409
Remove unecessary migration
BrunoQuaresma Aug 6, 2024
1c62242
Don't show deployment wide method
BrunoQuaresma Aug 6, 2024
a020619
Fix templates sorting
BrunoQuaresma Aug 6, 2024
0efc40d
Add nav tabs
BrunoQuaresma Aug 6, 2024
1aedb92
Update titles
BrunoQuaresma Aug 6, 2024
786b005
Add tests
BrunoQuaresma Aug 6, 2024
2ecbe5f
Improve product copy
BrunoQuaresma Aug 7, 2024
ec7ab40
Fix notifications visibility
BrunoQuaresma Aug 7, 2024
c986e51
Minor improvements
BrunoQuaresma Aug 7, 2024
e037423
Remove alerts
BrunoQuaresma Aug 8, 2024
341f550
Add alerts when SMTP or Webhook config are enabled but not set
BrunoQuaresma Aug 8, 2024
d97dd82
Apply a few Michaels suggestions
BrunoQuaresma Aug 8, 2024
4399cd6
Merge branch 'main' of https://github.com/coder/coder into bq/user-no…
BrunoQuaresma Aug 9, 2024
d403eed
Simplify state logic for the switch component
BrunoQuaresma Aug 9, 2024
fb02aec
Update copy
BrunoQuaresma Aug 9, 2024
013ccff
Apply PR comments
BrunoQuaresma Aug 9, 2024
7858a5a
Add docs
BrunoQuaresma Aug 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add test for toggling notifications
  • Loading branch information
BrunoQuaresma committed Aug 5, 2024
commit bbc8cbb00113cfa034f8459e379737bc3361d49b
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import { screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { http, HttpResponse } from "msw";
import type {
Experiments,
NotificationPreference,
NotificationTemplate,
UpdateUserNotificationPreferences,
} from "api/typesGenerated";
import { renderWithAuth } from "testHelpers/renderHelpers";
import { server } from "testHelpers/server";
import NotificationsPage from "./NotificationsPage";

test("can enable and disable notifications", async () => {
server.use(
http.get("/api/v2/experiments", () =>
HttpResponse.json(["notifications"] as Experiments),
),
http.get("/api/v2/users/:userId/notifications/preferences", () =>
HttpResponse.json(null),
),
http.get("/api/v2/notifications/templates/system", () =>
HttpResponse.json(notificationsTemplateSystemRes),
),
http.put<
{ userId: string },
UpdateUserNotificationPreferences,
NotificationPreference[]
>(
"/api/v2/users/:userId/notifications/preferences",
async ({ request }) => {
const body = await request.json();
const res: NotificationPreference[] = Object.entries(body).map(
([id, disabled]) => ({
disabled,
id,
updated_at: new Date().toISOString(),
}),
);
return HttpResponse.json(res);
},
),
);
renderWithAuth(<NotificationsPage />);
const user = userEvent.setup();
const workspaceGroupTemplates = notificationsTemplateSystemRes.filter(
(t) => t.group === "Workspace Events",
);

// Test notification groups
const workspaceGroupSwitch = await screen.findByLabelText("Workspace Events");
await user.click(workspaceGroupSwitch);
await screen.findByText("Notification preferences updated");
expect(workspaceGroupSwitch).not.toBeChecked();
for (const template of workspaceGroupTemplates) {
const templateSwitch = screen.getByLabelText(template.name);
expect(templateSwitch).not.toBeChecked();
}

await user.click(workspaceGroupSwitch);
await screen.findByText("Notification preferences updated");
expect(workspaceGroupSwitch).toBeChecked();
for (const template of workspaceGroupTemplates) {
const templateSwitch = screen.getByLabelText(template.name);
expect(templateSwitch).toBeChecked();
}

// Test individual notifications
const workspaceDeletedSwitch = screen.getByLabelText("Workspace Deleted");
await user.click(workspaceDeletedSwitch);
await screen.findByText("Notification preferences updated");
expect(workspaceDeletedSwitch).not.toBeChecked();

await user.click(workspaceDeletedSwitch);
await screen.findByText("Notification preferences updated");
expect(workspaceDeletedSwitch).toBeChecked();
});

const notificationsTemplateSystemRes: NotificationTemplate[] = [
{
id: "f517da0b-cdc9-410f-ab89-a86107c420ed",
name: "Workspace Deleted",
title_template: 'Workspace "{{.Labels.name}}" deleted',
body_template:
'Hi {{.UserName}}\n\nYour workspace **{{.Labels.name}}** was deleted.\nThe specified reason was "**{{.Labels.reason}}{{ if .Labels.initiator }} ({{ .Labels.initiator }}){{end}}**".',
actions:
'[{"url": "{{ base_url }}/workspaces", "label": "View workspaces"}, {"url": "{{ base_url }}/templates", "label": "View templates"}]',
group: "Workspace Events",
method: "",
kind: "system",
},
{
id: "381df2a9-c0c0-4749-420f-80a9280c66f9",
name: "Workspace Autobuild Failed",
title_template: 'Workspace "{{.Labels.name}}" autobuild failed',
body_template:
'Hi {{.UserName}}\nAutomatic build of your workspace **{{.Labels.name}}** failed.\nThe specified reason was "**{{.Labels.reason}}**".',
actions:
'[{"url": "{{ base_url }}/@{{.UserUsername}}/{{.Labels.name}}", "label": "View workspace"}]',
group: "Workspace Events",
method: "",
kind: "system",
},
{
id: "c34a0c09-0704-4cac-bd1c-0c0146811c2b",
name: "Workspace updated automatically",
title_template: 'Workspace "{{.Labels.name}}" updated automatically',
body_template:
"Hi {{.UserName}}\nYour workspace **{{.Labels.name}}** has been updated automatically to the latest template version ({{.Labels.template_version_name}}).",
actions:
'[{"url": "{{ base_url }}/@{{.UserUsername}}/{{.Labels.name}}", "label": "View workspace"}]',
group: "Workspace Events",
method: "",
kind: "system",
},
{
id: "0ea69165-ec14-4314-91f1-69566ac3c5a0",
name: "Workspace Marked as Dormant",
title_template: 'Workspace "{{.Labels.name}}" marked as dormant',
body_template:
"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.",
actions:
'[{"url": "{{ base_url }}/@{{.UserUsername}}/{{.Labels.name}}", "label": "View workspace"}]',
group: "Workspace Events",
method: "",
kind: "system",
},
{
id: "51ce2fdf-c9ca-4be1-8d70-628674f9bc42",
name: "Workspace Marked for Deletion",
title_template: 'Workspace "{{.Labels.name}}" marked for deletion',
body_template:
"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.",
actions:
'[{"url": "{{ base_url }}/@{{.UserUsername}}/{{.Labels.name}}", "label": "View workspace"}]',
group: "Workspace Events",
method: "",
kind: "system",
},
{
id: "4e19c0ac-94e1-4532-9515-d1801aa283b2",
name: "User account created",
title_template: 'User account "{{.Labels.created_account_name}}" created',
body_template:
"Hi {{.UserName}},\nNew user account **{{.Labels.created_account_name}}** has been created.",
actions:
'[{"url": "{{ base_url }}/deployment/users?filter=status%3Aactive", "label": "View accounts"}]',
group: "User Events",
method: "",
kind: "system",
},
];
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ const PreferenceSwitch: FC<PreferenceSwitchProps> = ({
await updatePreferences.mutateAsync({
template_disabled_map: onToggle(checked),
});
displaySuccess("Notification preference updated");
displaySuccess("Notification preferences updated");
}}
/>
);
Expand Down