diff --git a/site/src/pages/CreateUserPage/CreateUserPage.stories.tsx b/site/src/pages/CreateUserPage/CreateUserPage.stories.tsx new file mode 100644 index 0000000000..9bbb9f0ed9 --- /dev/null +++ b/site/src/pages/CreateUserPage/CreateUserPage.stories.tsx @@ -0,0 +1,73 @@ +import type { Meta, StoryObj } from "@storybook/react-vite"; +import { spyOn, userEvent, within } from "storybook/test"; +import { API } from "#/api/api"; +import { rolesQueryKey } from "#/api/queries/roles"; +import { authMethodsQueryKey } from "#/api/queries/users"; +import { + MockAuthMethodsPasswordOnly, + MockUserMember, + mockApiError, +} from "#/testHelpers/entities"; +import { withDashboardProvider, withToaster } from "#/testHelpers/storybook"; +import CreateUserPage from "./CreateUserPage"; + +const meta = { + title: "pages/CreateUserPage/CreateUserPage", + component: CreateUserPage, + decorators: [withToaster, withDashboardProvider], + parameters: { + queries: [ + { key: authMethodsQueryKey, data: MockAuthMethodsPasswordOnly }, + { key: rolesQueryKey, data: [] }, + ], + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const ShowsSuccessNotificationOnSubmit: Story = { + beforeEach: () => { + spyOn(API, "createUser").mockResolvedValue(MockUserMember); + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + const user = userEvent.setup(); + await fillForm(canvas, user); + await within(document.body).findByText( + 'User "someuser" created successfully.', + ); + }, +}; + +export const ShowsErrorWhenUserCreationFails: Story = { + beforeEach: () => { + spyOn(API, "createUser").mockRejectedValue( + mockApiError({ message: "Username already in use." }), + ); + }, + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + const user = userEvent.setup(); + await fillForm(canvas, user); + await canvas.findAllByText("Username already in use."); + }, +}; + +async function fillForm( + canvas: ReturnType, + user: ReturnType, +) { + await user.type(await canvas.findByLabelText("Username"), "someuser"); + await user.type(canvas.getByLabelText(/email/i), "someone@coder.com"); + + const body = within(document.body); + await user.click(canvas.getByTestId("login-type-input")); + await user.click(await body.findByRole("option", { name: /password/i })); + + await user.type( + await canvas.findByTestId("password-input"), + "SomeSecurePassword!", + ); + await user.click(canvas.getByRole("button", { name: /save/i })); +} diff --git a/site/src/pages/CreateUserPage/CreateUserPage.test.tsx b/site/src/pages/CreateUserPage/CreateUserPage.test.tsx deleted file mode 100644 index 1722cd2f92..0000000000 --- a/site/src/pages/CreateUserPage/CreateUserPage.test.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import { screen } from "@testing-library/react"; -import userEvent from "@testing-library/user-event"; -import { HttpResponse, http } from "msw"; -import { describe, expect, it } from "vitest"; -import { - renderWithAuth, - waitForLoaderToBeRemoved, -} from "#/testHelpers/renderHelpers"; -import { server } from "#/testHelpers/server"; -import CreateUserPage from "./CreateUserPage"; - -const fillForm = async ({ - username = "someuser", - email = "someone@coder.com", - password = "SomeSecurePassword!", -}: { - username?: string; - email?: string; - password?: string; -} = {}) => { - await userEvent.type(screen.getByLabelText("Username"), username); - await userEvent.type(screen.getByLabelText(/email/i), email); - - await userEvent.click(screen.getByTestId("login-type-input")); - await userEvent.click(screen.getByRole("option", { name: /password/i })); - - await userEvent.type(screen.getByTestId("password-input"), password); - - await userEvent.click(screen.getByRole("button", { name: /save/i })); -}; - -describe("CreateUserPage", () => { - it("shows a success notification and redirects to the users page on submit", async () => { - renderWithAuth(, { - extraRoutes: [ - { path: "/deployment/users", element:
Users Page
}, - ], - }); - await waitForLoaderToBeRemoved(); - await fillForm(); - await expect( - screen.findByText('User "someuser" created successfully.'), - ).resolves.toBeInTheDocument(); - }); - - it("shows an error alert when user creation fails", async () => { - server.use( - http.post("/api/v2/users", () => { - return HttpResponse.json( - { message: "Username already in use." }, - { status: 400 }, - ); - }), - ); - - renderWithAuth(, { - extraRoutes: [ - { path: "/deployment/users", element:
Users Page
}, - ], - }); - await waitForLoaderToBeRemoved(); - await fillForm(); - await expect( - screen.findByText("Username already in use."), - ).resolves.toBeInTheDocument(); - }); -});