Skip to content

Commit 8af93fd

Browse files
committed
Fix stories
1 parent 025c633 commit 8af93fd

File tree

3 files changed

+67
-66
lines changed

3 files changed

+67
-66
lines changed

site/src/api/queries/notifications.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import type {
55
UpdateNotificationTemplateMethod,
66
UpdateUserNotificationPreferences,
77
} from "api/typesGenerated";
8-
import { displayError, displaySuccess } from "components/GlobalSnackbar/utils";
98
import type { QueryClient, UseMutationOptions } from "react-query";
109

1110
export const userNotificationPreferencesKey = (userId: string) => [
@@ -151,10 +150,8 @@ export const disableNotification = (
151150
});
152151
return result;
153152
},
154-
onSuccess: () => {
155-
queryClient.invalidateQueries(
156-
userNotificationPreferences(userId).queryKey,
157-
);
153+
onSuccess: (data) => {
154+
queryClient.setQueryData(userNotificationPreferencesKey(userId), data);
158155
},
159156
} satisfies UseMutationOptions<NotificationPreference[], unknown, string>;
160157
};
Lines changed: 64 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Meta, StoryObj } from "@storybook/react";
2-
import { spyOn, userEvent, waitFor, within } from "@storybook/test";
2+
import { spyOn, userEvent, waitFor, within, expect } from "@storybook/test";
33
import { API } from "api/api";
44
import {
55
notificationDispatchMethodsKey,
@@ -19,8 +19,9 @@ import {
1919
withGlobalSnackbar,
2020
} from "testHelpers/storybook";
2121
import { NotificationsPage } from "./NotificationsPage";
22+
import { reactRouterParameters } from "storybook-addon-remix-react-router";
2223

23-
const meta: Meta<typeof NotificationsPage> = {
24+
const meta = {
2425
title: "pages/UserSettingsPage/NotificationsPage",
2526
component: NotificationsPage,
2627
parameters: {
@@ -43,7 +44,7 @@ const meta: Meta<typeof NotificationsPage> = {
4344
permissions: { viewDeploymentValues: true },
4445
},
4546
decorators: [withGlobalSnackbar, withAuthProvider, withDashboardProvider],
46-
};
47+
} satisfies Meta<typeof NotificationsPage>;
4748

4849
export default meta;
4950
type Story = StoryObj<typeof NotificationsPage>;
@@ -78,72 +79,77 @@ export const NonAdmin: Story = {
7879
},
7980
};
8081

82+
// Ensure the selected notification template is enabled before attempting to
83+
// disable it.
84+
const enabledPreference = MockNotificationPreferences.find(
85+
(pref) => pref.disabled === false,
86+
);
87+
if (!enabledPreference) {
88+
throw new Error(
89+
"No enabled notification preference available to test the disabling action.",
90+
);
91+
}
92+
const templateToDisable = MockNotificationTemplates.find(
93+
(tpl) => tpl.id === enabledPreference.id,
94+
);
95+
if (!templateToDisable) {
96+
throw new Error(" No notification template matches the enabled preference.");
97+
}
98+
8199
export const DisableValidTemplate: Story = {
82100
parameters: {
83-
msw: {
84-
handlers: [
85-
http.put("/api/v2/users/:userId/notifications/preferences", () => {
86-
return HttpResponse.json([
87-
{ id: "valid-template-id", disabled: true },
88-
]);
101+
reactRouter: reactRouterParameters({
102+
location: {
103+
searchParams: { disabled: templateToDisable.id },
104+
},
105+
}),
106+
},
107+
decorators: [
108+
(Story) => {
109+
// Since the action occurs during the initial render, we need to spy on
110+
// the API call before the story is rendered. This is done using a
111+
// decorator to ensure the spy is set up in time.
112+
spyOn(API, "putUserNotificationPreferences").mockResolvedValue(
113+
MockNotificationPreferences.map((pref) => {
114+
if (pref.id === templateToDisable.id) {
115+
return {
116+
...pref,
117+
disabled: true,
118+
};
119+
}
120+
return pref;
89121
}),
90-
],
122+
);
123+
return <Story />;
91124
},
92-
},
125+
],
93126
play: async ({ canvasElement }) => {
94-
const canvas = within(canvasElement);
95-
96-
const validTemplateId = "valid-template-id";
97-
const validTemplateName = "Valid Template Name";
98-
99-
window.history.pushState({}, "", `?disabled=${validTemplateId}`);
100-
101-
await waitFor(
102-
async () => {
103-
const successMessage = await canvas.findByText(
104-
`${validTemplateName} notification has been disabled`,
105-
);
106-
expect(successMessage).toBeInTheDocument();
107-
},
108-
{ timeout: 10000 },
109-
);
110-
111-
await waitFor(
112-
async () => {
113-
const templateSwitch = await canvas.findByLabelText(validTemplateName);
114-
expect(templateSwitch).not.toBeChecked();
115-
},
116-
{ timeout: 10000 },
127+
await within(document.body).findByText("Notification has been disabled");
128+
const switchEl = await within(canvasElement).findByLabelText(
129+
templateToDisable.name,
117130
);
131+
expect(switchEl).not.toBeChecked();
118132
},
119133
};
120134

121135
export const DisableInvalidTemplate: Story = {
122136
parameters: {
123-
msw: {
124-
handlers: [
125-
http.put("/api/v2/users/:userId/notifications/preferences", () => {
126-
// Mock failed API response
127-
return new HttpResponse(null, { status: 400 });
128-
}),
129-
],
130-
},
131-
},
132-
play: async ({ canvasElement }) => {
133-
const canvas = within(canvasElement);
134-
135-
const invalidTemplateId = "invalid-template-id";
136-
137-
window.history.pushState({}, "", `?disabled=${invalidTemplateId}`);
138-
139-
await waitFor(
140-
async () => {
141-
const errorMessage = await canvas.findByText(
142-
"An error occurred when attempting to disable the requested notification",
143-
);
144-
expect(errorMessage).toBeInTheDocument();
137+
reactRouter: reactRouterParameters({
138+
location: {
139+
searchParams: { disabled: "invalid-template-id" },
145140
},
146-
{ timeout: 10000 },
147-
);
141+
}),
142+
},
143+
decorators: [
144+
(Story) => {
145+
// Since the action occurs during the initial render, we need to spy on
146+
// the API call before the story is rendered. This is done using a
147+
// decorator to ensure the spy is set up in time.
148+
spyOn(API, "putUserNotificationPreferences").mockRejectedValue({});
149+
return <Story />;
150+
},
151+
],
152+
play: async () => {
153+
await within(document.body).findByText("Error disabling notification");
148154
},
149155
};

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,7 @@ export const NotificationsPage: FC = () => {
8383
displaySuccess("Notification has been disabled");
8484
})
8585
.catch(() => {
86-
displayError(
87-
"An error occurred when attempting to disable the requested notification",
88-
);
86+
displayError("Error disabling notification");
8987
});
9088
}, [searchParams.delete, disabledId, disableMutation]);
9189

0 commit comments

Comments
 (0)