diff --git a/site/.eslintrc.yaml b/site/.eslintrc.yaml index ce32ef2cc38c1..1942b8a8120bb 100644 --- a/site/.eslintrc.yaml +++ b/site/.eslintrc.yaml @@ -32,6 +32,17 @@ plugins: - react-hooks - jest - unicorn + - testing-library +overrides: + - files: ["**/__tests__/**/*.[jt]s?(x)", "**/?(*.)+(spec|test).[jt]s?(x)"] + extends: ["plugin:testing-library/react", "plugin:testing-library/dom"] + rules: + # Occasionally, we must traverse the DOM when querying for an element to + # avoid the performance costs that come with using selectors like ByRole. + # You can read more about these performance costs here: + # https://coder.com/docs/v2/latest/contributing/frontend#tests-getting-too-slow. + testing-library/no-node-access: off + testing-library/no-container: off root: true rules: "@typescript-eslint/brace-style": @@ -145,6 +156,7 @@ rules: message: "Default React import not allowed", }, ] + settings: react: version: detect diff --git a/site/.storybook/preview.js b/site/.storybook/preview.js index 820ea2a346fde..6579da9bd5fa6 100644 --- a/site/.storybook/preview.js +++ b/site/.storybook/preview.js @@ -5,6 +5,7 @@ import { addDecorator } from "node_modules/@storybook/react" import { unstable_HistoryRouter as HistoryRouter } from "react-router-dom" import { dark } from "../src/theme" import "../src/theme/globalFonts" +import "../src/i18n" addDecorator((story) => ( diff --git a/site/package.json b/site/package.json index d279561ee0353..3e9e4b7df7044 100644 --- a/site/package.json +++ b/site/package.json @@ -53,6 +53,7 @@ "date-fns": "2.29.3", "dayjs": "1.11.4", "emoji-mart": "5.4.0", + "eslint-plugin-testing-library": "^5.10.2", "eventsourcemock": "2.0.0", "formik": "2.2.9", "front-matter": "4.0.2", @@ -97,8 +98,8 @@ "@storybook/react": "6.5.12", "@swc/core": "1.3.38", "@swc/jest": "0.2.24", - "@testing-library/jest-dom": "5.16.4", - "@testing-library/react": "13.4.0", + "@testing-library/jest-dom": "5.16.5", + "@testing-library/react": "14.0.0", "@testing-library/user-event": "14.4.3", "@types/jest": "29.4.0", "@types/node": "14.18.22", diff --git a/site/src/components/AppLink/AppLink.stories.tsx b/site/src/components/AppLink/AppLink.stories.tsx index b3784055081dc..90411afe6df34 100644 --- a/site/src/components/AppLink/AppLink.stories.tsx +++ b/site/src/components/AppLink/AppLink.stories.tsx @@ -3,7 +3,7 @@ import { MockWorkspace, MockWorkspaceAgent, MockWorkspaceApp, -} from "testHelpers/renderHelpers" +} from "testHelpers/entities" import { AppLink, AppLinkProps } from "./AppLink" export default { diff --git a/site/src/components/Dialogs/ConfirmDialog/ConfirmDialog.test.tsx b/site/src/components/Dialogs/ConfirmDialog/ConfirmDialog.test.tsx index 5448c516cf53e..03aa74c68fa4e 100644 --- a/site/src/components/Dialogs/ConfirmDialog/ConfirmDialog.test.tsx +++ b/site/src/components/Dialogs/ConfirmDialog/ConfirmDialog.test.tsx @@ -1,4 +1,4 @@ -import { fireEvent, render } from "@testing-library/react" +import { fireEvent, render, screen } from "@testing-library/react" import { FC } from "react" import { WrapperComponent } from "../../../testHelpers/renderHelpers" import { ConfirmDialog, ConfirmDialogProps } from "./ConfirmDialog" @@ -26,10 +26,10 @@ describe("ConfirmDialog", () => { } // When - const { getByRole } = render() + render() // Then - expect(getByRole("dialog")).toBeDefined() + expect(screen.getByRole("dialog")).toBeDefined() }) it("does not display cancel for info dialogs", () => { @@ -43,10 +43,10 @@ describe("ConfirmDialog", () => { } // When - const { queryByText } = render() + render() // Then - expect(queryByText("CANCEL")).toBeNull() + expect(screen.queryByText("CANCEL")).toBeNull() }) it("can display cancel when normally hidden", () => { @@ -61,10 +61,10 @@ describe("ConfirmDialog", () => { } // When - const { getByText } = render() + render() // Then - expect(getByText("CANCEL")).toBeDefined() + expect(screen.getByText("CANCEL")).toBeDefined() }) it("displays cancel for delete dialogs", () => { @@ -79,10 +79,10 @@ describe("ConfirmDialog", () => { } // When - const { getByText } = render() + render() // Then - expect(getByText("CANCEL")).toBeDefined() + expect(screen.getByText("CANCEL")).toBeDefined() }) it("can hide cancel when normally visible", () => { @@ -98,10 +98,10 @@ describe("ConfirmDialog", () => { } // When - const { queryByText } = render() + render() // Then - expect(queryByText("CANCEL")).toBeNull() + expect(screen.queryByText("CANCEL")).toBeNull() }) it("onClose is called when cancelled", () => { @@ -116,8 +116,8 @@ describe("ConfirmDialog", () => { } // When - const { getByText } = render() - fireEvent.click(getByText("CANCEL")) + render() + fireEvent.click(screen.getByText("CANCEL")) // Then expect(onCloseMock).toBeCalledTimes(1) @@ -138,8 +138,8 @@ describe("ConfirmDialog", () => { } // When - const { getByText } = render() - fireEvent.click(getByText("CONFIRM")) + render() + fireEvent.click(screen.getByText("CONFIRM")) // Then expect(onCloseMock).toBeCalledTimes(0) diff --git a/site/src/components/Dialogs/ResetPasswordDialog/ResetPasswordDialog.stories.tsx b/site/src/components/Dialogs/ResetPasswordDialog/ResetPasswordDialog.stories.tsx index 24c1711a23f6d..66d123bbfb9cc 100644 --- a/site/src/components/Dialogs/ResetPasswordDialog/ResetPasswordDialog.stories.tsx +++ b/site/src/components/Dialogs/ResetPasswordDialog/ResetPasswordDialog.stories.tsx @@ -1,6 +1,7 @@ import { action } from "@storybook/addon-actions" import { Story } from "@storybook/react" -import { MockUser } from "../../../testHelpers/renderHelpers" +import { MockUser } from "testHelpers/entities" + import { ResetPasswordDialog, ResetPasswordDialogProps, diff --git a/site/src/components/FormTextField/FormTextField.test.tsx b/site/src/components/FormTextField/FormTextField.test.tsx deleted file mode 100644 index 8c0d624730059..0000000000000 --- a/site/src/components/FormTextField/FormTextField.test.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import { fireEvent, render, screen } from "@testing-library/react" -import { useFormik } from "formik" -import { FC } from "react" -import * as yup from "yup" -import { FormTextField, FormTextFieldProps } from "./FormTextField" - -namespace Helpers { - export interface FormValues { - name: string - } - - export const requiredValidationMsg = "required" - - export const Component: FC< - React.PropsWithChildren< - Omit, "form" | "formFieldName"> - > - > = (props) => { - const form = useFormik({ - initialValues: { - name: "", - }, - onSubmit: (values, helpers) => { - return helpers.setSubmitting(false) - }, - validationSchema: yup.object({ - name: yup.string().required(requiredValidationMsg), - }), - }) - - return ( - {...props} form={form} formFieldName="name" /> - ) - } -} - -describe("FormTextField", () => { - describe("helperText", () => { - it("uses helperText prop when there are no errors", () => { - // Given - const props = { - helperText: "testing", - } - - // When - const { queryByText } = render() - - // Then - expect(queryByText(props.helperText)).toBeDefined() - }) - - it("uses validation message when there are errors", () => { - // Given - const props = {} - - // When - const { container } = render() - const el = container.firstChild - - // Then - expect(el).toBeDefined() - expect(screen.queryByText(Helpers.requiredValidationMsg)).toBeNull() - - // When - fireEvent.focus(el as Element) - - // Then - expect(screen.queryByText(Helpers.requiredValidationMsg)).toBeNull() - - // When - fireEvent.blur(el as Element) - - // Then - expect(screen.queryByText(Helpers.requiredValidationMsg)).toBeDefined() - }) - }) -}) diff --git a/site/src/components/FormTextField/FormTextField.tsx b/site/src/components/FormTextField/FormTextField.tsx deleted file mode 100644 index b73b723224b88..0000000000000 --- a/site/src/components/FormTextField/FormTextField.tsx +++ /dev/null @@ -1,163 +0,0 @@ -import TextField, { TextFieldProps } from "@material-ui/core/TextField" -import { FormikContextType } from "formik" -import { ReactElement } from "react" -import { PasswordField } from "../PasswordField/PasswordField" - -/** - * FormFieldProps are required props for creating form fields using a factory. - */ -interface FormFieldProps { - /** - * form is a reference to a form or subform and is used to compute common - * states such as error and helper text - */ - form: FormikContextType - /** - * formFieldName is a field name associated with the form schema. - */ - formFieldName: keyof T -} - -/** - * FormTextFieldProps extends form-related MUI TextFieldProps with Formik - * props. The passed in form is used to compute error states and configure - * change handlers. `formFieldName` represents the key of a Formik value - * that's associated to this component. - */ -export interface FormTextFieldProps - extends Pick< - TextFieldProps, - | "autoComplete" - | "autoFocus" - | "children" - | "className" - | "disabled" - | "fullWidth" - | "helperText" - | "id" - | "InputLabelProps" - | "InputProps" - | "inputProps" - | "label" - | "margin" - | "multiline" - | "onChange" - | "placeholder" - | "required" - | "rows" - | "select" - | "SelectProps" - | "style" - | "type" - >, - FormFieldProps { - /** - * eventTransform is an optional transformer on the event data before it is - * processed by formik. - * - * @example - * { - * return str.replace(" ", "-") - * }} - * /> - */ - eventTransform?: (value: string) => string - /** - * isPassword uses a PasswordField component when `true`; otherwise a - * TextField component is used. - */ - isPassword?: boolean - /** - * displayValueOverride allows displaying a different value in the field - * without changing the actual underlying value. - */ - displayValueOverride?: string - - variant?: "outlined" | "filled" | "standard" -} - -/** - * Factory function for creating a formik TextField - * - * @example - * interface FormValues { - * username: string - * } - * - * // Use the factory to create a FormTextField associated to this form - * const FormTextField = formTextFieldFactory() - * - * const MyComponent: React.FC = () => { - * const form = useFormik() - * - * return ( - * - * ) - * } - */ -export const FormTextField = ({ - children, - disabled, - displayValueOverride, - eventTransform, - form, - formFieldName, - helperText, - isPassword = false, - InputProps, - onChange, - type, - variant = "outlined", - ...rest -}: FormTextFieldProps): ReactElement => { - const isError = - form.touched[formFieldName] && Boolean(form.errors[formFieldName]) - - // Conversion to a string primitive is necessary as formFieldName is an in - // indexable type such as a string, number or enum. - const fieldId = String(formFieldName) - - const Component = isPassword ? PasswordField : TextField - const inputType = isPassword ? undefined : type - - return ( - { - if (typeof onChange !== "undefined") { - onChange(e) - } - - const event = e - if ( - typeof eventTransform !== "undefined" && - typeof event.target.value === "string" - ) { - event.target.value = eventTransform(e.target.value) - } - form.handleChange(event) - }} - type={inputType} - value={displayValueOverride || form.values[formFieldName]} - > - {children} - - ) -} diff --git a/site/src/components/Navbar/Navbar.test.tsx b/site/src/components/Navbar/Navbar.test.tsx index 70dc55ebd51b0..ca7001af5dad7 100644 --- a/site/src/components/Navbar/Navbar.test.tsx +++ b/site/src/components/Navbar/Navbar.test.tsx @@ -5,7 +5,7 @@ import { rest } from "msw" import { MockEntitlementsWithAuditLog, MockMemberPermissions, -} from "testHelpers/renderHelpers" +} from "testHelpers/entities" import { server } from "testHelpers/server" /** diff --git a/site/src/components/RuntimeErrorState/RuntimeErrorState.test.tsx b/site/src/components/RuntimeErrorState/RuntimeErrorState.test.tsx index d0c43d96ce331..13fbfddacc93a 100644 --- a/site/src/components/RuntimeErrorState/RuntimeErrorState.test.tsx +++ b/site/src/components/RuntimeErrorState/RuntimeErrorState.test.tsx @@ -6,19 +6,21 @@ import { RuntimeErrorState, } from "./RuntimeErrorState" -describe("RuntimeErrorState", () => { - beforeEach(() => { - // Given - const errorText = "broken!" - const errorStateProps = { - error: new Error(errorText), - } - - // When - render() - }) +const renderComponent = () => { + // Given + const errorText = "broken!" + const errorStateProps = { + error: new Error(errorText), + } + // When + return render() +} + +describe("RuntimeErrorState", () => { it("should show stack when encountering runtime error", () => { + renderComponent() + // Then const reportError = screen.getByText("broken!") expect(reportError).toBeDefined() @@ -29,6 +31,8 @@ describe("RuntimeErrorState", () => { }) it("should have a button bar", () => { + renderComponent() + // Then const copyCta = screen.getByText(ButtonLanguage.copyReport) expect(copyCta).toBeDefined() @@ -38,6 +42,8 @@ describe("RuntimeErrorState", () => { }) it("should have an email link", () => { + renderComponent() + // Then const emailLink = screen.getByText(RuntimeErrorStateLanguage.link) expect(emailLink.closest("a")).toHaveAttribute( diff --git a/site/src/components/SSHButton/SSHButton.stories.tsx b/site/src/components/SSHButton/SSHButton.stories.tsx index b277ed43d00ce..e841b95355e3c 100644 --- a/site/src/components/SSHButton/SSHButton.stories.tsx +++ b/site/src/components/SSHButton/SSHButton.stories.tsx @@ -1,8 +1,5 @@ import { Story } from "@storybook/react" -import { - MockWorkspace, - MockWorkspaceAgent, -} from "../../testHelpers/renderHelpers" +import { MockWorkspace, MockWorkspaceAgent } from "testHelpers/entities" import { SSHButton, SSHButtonProps } from "./SSHButton" export default { diff --git a/site/src/components/SignInForm/SignInForm.stories.tsx b/site/src/components/SignInForm/SignInForm.stories.tsx index c7dee4106346b..c0fd17d6f6d70 100644 --- a/site/src/components/SignInForm/SignInForm.stories.tsx +++ b/site/src/components/SignInForm/SignInForm.stories.tsx @@ -1,6 +1,6 @@ import { Story } from "@storybook/react" import { makeMockApiError } from "testHelpers/entities" -import { LoginErrors, SignInForm, SignInFormProps } from "./SignInForm" +import { SignInForm, SignInFormProps } from "./SignInForm" export default { title: "components/SignInForm", @@ -17,17 +17,16 @@ const Template: Story = (args: SignInFormProps) => ( export const SignedOut = Template.bind({}) SignedOut.args = { - isLoading: false, - loginErrors: {}, + isSigningIn: false, onSubmit: () => { return Promise.resolve() }, } -export const Loading = Template.bind({}) -Loading.args = { +export const SigningIn = Template.bind({}) +SigningIn.args = { ...SignedOut.args, - isLoading: true, + isSigningIn: true, authMethods: { password: { enabled: true }, github: { enabled: true }, @@ -35,67 +34,23 @@ Loading.args = { }, } -export const WithLoginError = Template.bind({}) -WithLoginError.args = { +export const WithError = Template.bind({}) +WithError.args = { ...SignedOut.args, - loginErrors: { - [LoginErrors.AUTH_ERROR]: makeMockApiError({ - message: "Email or password was invalid", - validations: [ - { - field: "password", - detail: "Password is invalid.", - }, - ], - }), - }, + error: makeMockApiError({ + message: "Email or password was invalid", + validations: [ + { + field: "password", + detail: "Password is invalid.", + }, + ], + }), initialTouched: { password: true, }, } -export const WithGetUserError = Template.bind({}) -WithGetUserError.args = { - ...SignedOut.args, - loginErrors: { - [LoginErrors.GET_USER_ERROR]: makeMockApiError({ - message: "You are logged out. Please log in to continue.", - detail: "API Key is invalid.", - }), - }, -} - -export const WithCheckPermissionsError = Template.bind({}) -WithCheckPermissionsError.args = { - ...SignedOut.args, - loginErrors: { - [LoginErrors.CHECK_PERMISSIONS_ERROR]: makeMockApiError({ - message: "Unable to fetch user permissions", - detail: "Resource not found or you do not have access to this resource.", - }), - }, -} - -export const WithAuthMethodsError = Template.bind({}) -WithAuthMethodsError.args = { - ...SignedOut.args, - loginErrors: { - [LoginErrors.GET_METHODS_ERROR]: new Error("Failed to fetch auth methods"), - }, -} - -export const WithGetUserAndAuthMethodsError = Template.bind({}) -WithGetUserAndAuthMethodsError.args = { - ...SignedOut.args, - loginErrors: { - [LoginErrors.GET_USER_ERROR]: makeMockApiError({ - message: "You are logged out. Please log in to continue.", - detail: "API Key is invalid.", - }), - [LoginErrors.GET_METHODS_ERROR]: new Error("Failed to fetch auth methods"), - }, -} - export const WithGithub = Template.bind({}) WithGithub.args = { ...SignedOut.args, diff --git a/site/src/components/TemplateStats/TemplateStats.stories.tsx b/site/src/components/TemplateStats/TemplateStats.stories.tsx index b53a9ee8c2d5b..a58e7a4eabf63 100644 --- a/site/src/components/TemplateStats/TemplateStats.stories.tsx +++ b/site/src/components/TemplateStats/TemplateStats.stories.tsx @@ -1,5 +1,5 @@ import { Story } from "@storybook/react" -import * as Mocks from "../../testHelpers/renderHelpers" +import { MockTemplate, MockTemplateVersion } from "testHelpers/entities" import { TemplateStats, TemplateStatsProps, @@ -16,33 +16,33 @@ const Template: Story = (args) => ( export const Example = Template.bind({}) Example.args = { - template: Mocks.MockTemplate, - activeVersion: Mocks.MockTemplateVersion, + template: MockTemplate, + activeVersion: MockTemplateVersion, } export const UsedByMany = Template.bind({}) UsedByMany.args = { template: { - ...Mocks.MockTemplate, + ...MockTemplate, active_user_count: 15, }, - activeVersion: Mocks.MockTemplateVersion, + activeVersion: MockTemplateVersion, } export const ActiveUsersNotLoaded = Template.bind({}) ActiveUsersNotLoaded.args = { template: { - ...Mocks.MockTemplate, + ...MockTemplate, active_user_count: -1, }, - activeVersion: Mocks.MockTemplateVersion, + activeVersion: MockTemplateVersion, } export const LongTemplateVersion = Template.bind({}) LongTemplateVersion.args = { - template: Mocks.MockTemplate, + template: MockTemplate, activeVersion: { - ...Mocks.MockTemplateVersion, + ...MockTemplateVersion, name: "thisisareallyreallylongnamefortesting", }, } @@ -52,8 +52,8 @@ LongTemplateVersion.parameters = { export const SmallViewport = Template.bind({}) SmallViewport.args = { - template: Mocks.MockTemplate, - activeVersion: Mocks.MockTemplateVersion, + template: MockTemplate, + activeVersion: MockTemplateVersion, } SmallViewport.parameters = { chromatic: { viewports: [600] }, diff --git a/site/src/components/TerminalLink/TerminalLink.stories.tsx b/site/src/components/TerminalLink/TerminalLink.stories.tsx index 12f1d6c71b814..f3bb5d0c4adec 100644 --- a/site/src/components/TerminalLink/TerminalLink.stories.tsx +++ b/site/src/components/TerminalLink/TerminalLink.stories.tsx @@ -1,5 +1,5 @@ import { Story } from "@storybook/react" -import { MockWorkspace } from "../../testHelpers/renderHelpers" +import { MockWorkspace } from "testHelpers/entities" import { TerminalLink, TerminalLinkProps } from "./TerminalLink" export default { diff --git a/site/src/components/UserCell/UserCell.stories.tsx b/site/src/components/UserCell/UserCell.stories.tsx index bd144f8ca07e1..feb2002697970 100644 --- a/site/src/components/UserCell/UserCell.stories.tsx +++ b/site/src/components/UserCell/UserCell.stories.tsx @@ -1,5 +1,5 @@ import { ComponentMeta, Story } from "@storybook/react" -import { MockUser, MockUserAgent } from "../../testHelpers/renderHelpers" +import { MockUser, MockUserAgent } from "testHelpers/entities" import { UserCell, UserCellProps } from "./UserCell" export default { diff --git a/site/src/components/UserCell/UserCell.test.tsx b/site/src/components/UserCell/UserCell.test.tsx index 3fdcd0bd5e375..95c1278f12988 100644 --- a/site/src/components/UserCell/UserCell.test.tsx +++ b/site/src/components/UserCell/UserCell.test.tsx @@ -1,10 +1,7 @@ import { fireEvent, render, screen } from "@testing-library/react" import { FC } from "react" -import { - MockUser, - MockUserAgent, - WrapperComponent, -} from "../../testHelpers/renderHelpers" +import { MockUser, MockUserAgent } from "testHelpers/entities" +import { WrapperComponent } from "../../testHelpers/renderHelpers" import { UserCell, UserCellProps } from "./UserCell" namespace Helpers { diff --git a/site/src/components/UsersTable/UsersTable.stories.tsx b/site/src/components/UsersTable/UsersTable.stories.tsx index a1f11d8e277c6..529bceb04672e 100644 --- a/site/src/components/UsersTable/UsersTable.stories.tsx +++ b/site/src/components/UsersTable/UsersTable.stories.tsx @@ -1,9 +1,9 @@ import { ComponentMeta, Story } from "@storybook/react" import { - MockAssignableSiteRoles, MockUser, MockUser2, -} from "../../testHelpers/renderHelpers" + MockAssignableSiteRoles, +} from "testHelpers/entities" import { UsersTable, UsersTableProps } from "./UsersTable" export default { diff --git a/site/src/components/VSCodeDesktopButton/VSCodeDesktopButton.stories.tsx b/site/src/components/VSCodeDesktopButton/VSCodeDesktopButton.stories.tsx index f87c59637e1f3..e86c2ffa38567 100644 --- a/site/src/components/VSCodeDesktopButton/VSCodeDesktopButton.stories.tsx +++ b/site/src/components/VSCodeDesktopButton/VSCodeDesktopButton.stories.tsx @@ -1,5 +1,5 @@ import { Story } from "@storybook/react" -import { MockWorkspace, MockWorkspaceAgent } from "testHelpers/renderHelpers" +import { MockWorkspace, MockWorkspaceAgent } from "testHelpers/entities" import { VSCodeDesktopButton, VSCodeDesktopButtonProps, diff --git a/site/src/components/WorkspaceBuildProgress/WorkspaceBuildProgress.stories.tsx b/site/src/components/WorkspaceBuildProgress/WorkspaceBuildProgress.stories.tsx index db06acd2b671b..7d74acb452d58 100644 --- a/site/src/components/WorkspaceBuildProgress/WorkspaceBuildProgress.stories.tsx +++ b/site/src/components/WorkspaceBuildProgress/WorkspaceBuildProgress.stories.tsx @@ -1,10 +1,10 @@ import { ComponentMeta, Story } from "@storybook/react" import dayjs from "dayjs" import { - MockProvisionerJob, MockStartingWorkspace, MockWorkspaceBuild, -} from "../../testHelpers/renderHelpers" + MockProvisionerJob, +} from "testHelpers/entities" import { WorkspaceBuildProgress, WorkspaceBuildProgressProps, diff --git a/site/src/components/WorkspaceStats/WorkspaceStats.stories.tsx b/site/src/components/WorkspaceStats/WorkspaceStats.stories.tsx index dff7b7ce6f567..2dc0f331d48ec 100644 --- a/site/src/components/WorkspaceStats/WorkspaceStats.stories.tsx +++ b/site/src/components/WorkspaceStats/WorkspaceStats.stories.tsx @@ -1,6 +1,5 @@ import { Story } from "@storybook/react" -import * as Mocks from "../../testHelpers/renderHelpers" -import { MockWorkspace } from "testHelpers/renderHelpers" +import { MockWorkspace } from "testHelpers/entities" import { WorkspaceStats, WorkspaceStatsProps, @@ -17,7 +16,7 @@ const Template: Story = (args) => ( export const Example = Template.bind({}) Example.args = { - workspace: Mocks.MockWorkspace, + workspace: MockWorkspace, } export const Outdated = Template.bind({}) diff --git a/site/src/components/WorkspaceStatusBadge/WorkspaceStatusBadge.stories.tsx b/site/src/components/WorkspaceStatusBadge/WorkspaceStatusBadge.stories.tsx index 67f1f7f957290..63959ab917fd4 100644 --- a/site/src/components/WorkspaceStatusBadge/WorkspaceStatusBadge.stories.tsx +++ b/site/src/components/WorkspaceStatusBadge/WorkspaceStatusBadge.stories.tsx @@ -10,7 +10,7 @@ import { MockStoppedWorkspace, MockStoppingWorkspace, MockWorkspace, -} from "testHelpers/renderHelpers" +} from "testHelpers/entities" import { WorkspaceStatusBadge, WorkspaceStatusBadgeProps, diff --git a/site/src/hooks/events.test.ts b/site/src/hooks/events.test.ts index 3c1bec639fc13..b9940b0d39adb 100644 --- a/site/src/hooks/events.test.ts +++ b/site/src/hooks/events.test.ts @@ -10,7 +10,7 @@ describe("useCustomEvent", () => { dispatchCustomEvent("testEvent", detail) await waitFor(() => { expect(callback).toBeCalledTimes(1) - expect(callback.mock.calls[0][0].detail).toBe(detail) }) + expect(callback.mock.calls[0][0].detail).toBe(detail) }) }) diff --git a/site/src/pages/AuditPage/AuditPage.test.tsx b/site/src/pages/AuditPage/AuditPage.test.tsx index 3305243739e47..29c341cd41faa 100644 --- a/site/src/pages/AuditPage/AuditPage.test.tsx +++ b/site/src/pages/AuditPage/AuditPage.test.tsx @@ -3,11 +3,13 @@ import userEvent from "@testing-library/user-event" import * as API from "api/api" import { rest } from "msw" import { - renderWithAuth, MockAuditLog, MockAuditLog2, - waitForLoaderToBeRemoved, MockEntitlementsWithAuditLog, +} from "testHelpers/entities" +import { + renderWithAuth, + waitForLoaderToBeRemoved, } from "testHelpers/renderHelpers" import { server } from "testHelpers/server" diff --git a/site/src/pages/CreateTemplatePage/CreateTemplatePage.test.tsx b/site/src/pages/CreateTemplatePage/CreateTemplatePage.test.tsx index 5768822a69c46..c338bc18ced1e 100644 --- a/site/src/pages/CreateTemplatePage/CreateTemplatePage.test.tsx +++ b/site/src/pages/CreateTemplatePage/CreateTemplatePage.test.tsx @@ -1,22 +1,22 @@ +import { renderWithAuth } from "testHelpers/renderHelpers" +import CreateTemplatePage from "./CreateTemplatePage" +import { screen, waitFor, within } from "@testing-library/react" +import userEvent from "@testing-library/user-event" +import * as API from "api/api" import { - MockOrganization, - MockProvisionerJob, - MockTemplate, MockTemplateExample, MockTemplateVersion, MockTemplateVersionVariable1, MockTemplateVersionVariable2, MockTemplateVersionVariable3, - renderWithAuth, -} from "testHelpers/renderHelpers" -import CreateTemplatePage from "./CreateTemplatePage" -import { screen, waitFor, within } from "@testing-library/react" -import userEvent from "@testing-library/user-event" -import * as API from "api/api" + MockTemplate, + MockOrganization, + MockProvisionerJob, +} from "testHelpers/entities" const renderPage = async () => { // Render with the example ID so we don't need to upload a file - const result = renderWithAuth(, { + const view = renderWithAuth(, { route: `/templates/new?exampleId=${MockTemplateExample.id}`, path: "/templates/new", // We need this because after creation, the user will be redirected to here @@ -25,7 +25,7 @@ const renderPage = async () => { // It is lazy loaded, so we have to wait for it to be rendered to not get an // act error await screen.findByLabelText("Icon", undefined, { timeout: 5000 }) - return result + return view } test("Create template with variables", async () => { diff --git a/site/src/pages/CreateWorkspacePage/CreateWorkspacePage.test.tsx b/site/src/pages/CreateWorkspacePage/CreateWorkspacePage.test.tsx index fa0a248369e13..31740ff193ee6 100644 --- a/site/src/pages/CreateWorkspacePage/CreateWorkspacePage.test.tsx +++ b/site/src/pages/CreateWorkspacePage/CreateWorkspacePage.test.tsx @@ -14,7 +14,10 @@ import { MockTemplateVersionParameter3, MockTemplateVersionGitAuth, } from "testHelpers/entities" -import { renderWithAuth } from "testHelpers/renderHelpers" +import { + renderWithAuth, + waitForLoaderToBeRemoved, +} from "testHelpers/renderHelpers" import CreateWorkspacePage from "./CreateWorkspacePage" const { t } = i18next @@ -147,15 +150,13 @@ describe("CreateWorkspacePage", () => { .spyOn(API, "getTemplateVersionRichParameters") .mockResolvedValueOnce([MockTemplateVersionParameter1]) - await waitFor(() => - renderWithAuth(, { - route: - "/templates/" + - MockTemplate.name + - `/workspace?param.${param}=${paramValue}`, - path: "/templates/:template/workspace", - }), - ) + renderWithAuth(, { + route: + "/templates/" + + MockTemplate.name + + `/workspace?param.${param}=${paramValue}`, + path: "/templates/:template/workspace", + }) await screen.findByDisplayValue(paramValue) }) @@ -168,7 +169,8 @@ describe("CreateWorkspacePage", () => { MockTemplateVersionParameter2, ]) - await waitFor(() => renderCreateWorkspacePage()) + renderCreateWorkspacePage() + await waitForLoaderToBeRemoved() const element = await screen.findByText("Create workspace") expect(element).toBeDefined() @@ -202,7 +204,8 @@ describe("CreateWorkspacePage", () => { MockTemplateVersionParameter3, ]) - await waitFor(() => renderCreateWorkspacePage()) + renderCreateWorkspacePage() + await waitForLoaderToBeRemoved() const element = await screen.findByText(createWorkspaceText) expect(element).toBeDefined() @@ -230,7 +233,8 @@ describe("CreateWorkspacePage", () => { .spyOn(API, "getTemplateVersionGitAuth") .mockResolvedValueOnce([MockTemplateVersionGitAuth]) - await waitFor(() => renderCreateWorkspacePage()) + renderCreateWorkspacePage() + await waitForLoaderToBeRemoved() const nameField = await screen.findByLabelText(nameLabelText) diff --git a/site/src/pages/StarterTemplatePage/StarterTemplatePage.test.tsx b/site/src/pages/StarterTemplatePage/StarterTemplatePage.test.tsx index 323164440d0d2..482a7d2e2c726 100644 --- a/site/src/pages/StarterTemplatePage/StarterTemplatePage.test.tsx +++ b/site/src/pages/StarterTemplatePage/StarterTemplatePage.test.tsx @@ -1,6 +1,6 @@ import { screen } from "@testing-library/react" +import { MockTemplateExample } from "testHelpers/entities" import { - MockTemplateExample, renderWithAuth, waitForLoaderToBeRemoved, } from "testHelpers/renderHelpers" diff --git a/site/src/pages/StarterTemplatesPage/StarterTemplatesPage.test.tsx b/site/src/pages/StarterTemplatesPage/StarterTemplatesPage.test.tsx index 63d5ed7ce18ad..ba3addc537753 100644 --- a/site/src/pages/StarterTemplatesPage/StarterTemplatesPage.test.tsx +++ b/site/src/pages/StarterTemplatesPage/StarterTemplatesPage.test.tsx @@ -1,7 +1,6 @@ import { screen } from "@testing-library/react" +import { MockTemplateExample, MockTemplateExample2 } from "testHelpers/entities" import { - MockTemplateExample, - MockTemplateExample2, renderWithAuth, waitForLoaderToBeRemoved, } from "testHelpers/renderHelpers" diff --git a/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPage.test.tsx b/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPage.test.tsx index bd2ab35e06ba2..7580f663bf3f9 100644 --- a/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPage.test.tsx +++ b/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPage.test.tsx @@ -3,12 +3,12 @@ import { TemplateLayout } from "components/TemplateLayout/TemplateLayout" import { rest } from "msw" import { ResizeObserver } from "resize-observer" import { - MockMemberPermissions, MockTemplate, - MockTemplateVersion, MockWorkspaceResource, - renderWithAuth, -} from "testHelpers/renderHelpers" + MockTemplateVersion, + MockMemberPermissions, +} from "testHelpers/entities" +import { renderWithAuth } from "testHelpers/renderHelpers" import { server } from "testHelpers/server" import * as CreateDayString from "util/createDayString" import { TemplateSummaryPage } from "./TemplateSummaryPage" diff --git a/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.stories.tsx b/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.stories.tsx index c4c82debb3048..b07447ad1dc6e 100644 --- a/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.stories.tsx +++ b/site/src/pages/TemplatePage/TemplateSummaryPage/TemplateSummaryPageView.stories.tsx @@ -1,5 +1,11 @@ import { Story } from "@storybook/react" -import * as Mocks from "testHelpers/renderHelpers" +import { + MockTemplate, + MockTemplateDAUResponse, + MockTemplateVersion, + MockWorkspaceResource, + MockWorkspaceResource2, +} from "testHelpers/entities" import { TemplateSummaryPageView, TemplateSummaryPageViewProps, @@ -16,31 +22,31 @@ const Template: Story = (args) => ( export const Example = Template.bind({}) Example.args = { - template: Mocks.MockTemplate, - activeVersion: Mocks.MockTemplateVersion, + template: MockTemplate, + activeVersion: MockTemplateVersion, data: { - resources: [Mocks.MockWorkspaceResource, Mocks.MockWorkspaceResource2], - versions: [Mocks.MockTemplateVersion], - daus: Mocks.MockTemplateDAUResponse, + resources: [MockWorkspaceResource, MockWorkspaceResource2], + versions: [MockTemplateVersion], + daus: MockTemplateDAUResponse, }, } export const NoIcon = Template.bind({}) NoIcon.args = { - template: { ...Mocks.MockTemplate, icon: "" }, - activeVersion: Mocks.MockTemplateVersion, + template: { ...MockTemplate, icon: "" }, + activeVersion: MockTemplateVersion, data: { - resources: [Mocks.MockWorkspaceResource, Mocks.MockWorkspaceResource2], - versions: [Mocks.MockTemplateVersion], - daus: Mocks.MockTemplateDAUResponse, + resources: [MockWorkspaceResource, MockWorkspaceResource2], + versions: [MockTemplateVersion], + daus: MockTemplateDAUResponse, }, } export const SmallViewport = Template.bind({}) SmallViewport.args = { - template: Mocks.MockTemplate, + template: MockTemplate, activeVersion: { - ...Mocks.MockTemplateVersion, + ...MockTemplateVersion, readme: `--- name:Template test --- @@ -54,9 +60,9 @@ SmallViewport.args = { `, }, data: { - resources: [Mocks.MockWorkspaceResource, Mocks.MockWorkspaceResource2], - versions: [Mocks.MockTemplateVersion], - daus: Mocks.MockTemplateDAUResponse, + resources: [MockWorkspaceResource, MockWorkspaceResource2], + versions: [MockTemplateVersion], + daus: MockTemplateDAUResponse, }, } SmallViewport.parameters = { diff --git a/site/src/pages/TemplateSettingsPage/TemplateGeneralSettingsPage/TemplateSettingsPageView.stories.tsx b/site/src/pages/TemplateSettingsPage/TemplateGeneralSettingsPage/TemplateSettingsPageView.stories.tsx index 2d16618c03dfe..d4fa5a847360d 100644 --- a/site/src/pages/TemplateSettingsPage/TemplateGeneralSettingsPage/TemplateSettingsPageView.stories.tsx +++ b/site/src/pages/TemplateSettingsPage/TemplateGeneralSettingsPage/TemplateSettingsPageView.stories.tsx @@ -1,7 +1,6 @@ import { action } from "@storybook/addon-actions" import { Story } from "@storybook/react" -import * as Mocks from "../../../testHelpers/renderHelpers" -import { makeMockApiError } from "../../../testHelpers/renderHelpers" +import { makeMockApiError, MockTemplate } from "testHelpers/entities" import { TemplateSettingsPageView, TemplateSettingsPageViewProps, @@ -11,7 +10,7 @@ export default { title: "pages/TemplateSettingsPageView", component: TemplateSettingsPageView, args: { - template: Mocks.MockTemplate, + template: MockTemplate, onSubmit: action("onSubmit"), onCancel: action("cancel"), }, diff --git a/site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateSchedulePageView.stories.tsx b/site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateSchedulePageView.stories.tsx index a9f5b94239bfc..762edfcd686e0 100644 --- a/site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateSchedulePageView.stories.tsx +++ b/site/src/pages/TemplateSettingsPage/TemplateSchedulePage/TemplateSchedulePageView.stories.tsx @@ -1,6 +1,6 @@ import { action } from "@storybook/addon-actions" import { Story } from "@storybook/react" -import * as Mocks from "../../../testHelpers/renderHelpers" +import { MockTemplate } from "testHelpers/entities" import { TemplateSchedulePageView, TemplateSchedulePageViewProps, @@ -11,7 +11,7 @@ export default { component: TemplateSchedulePageView, args: { canSetMaxTTL: true, - template: Mocks.MockTemplate, + template: MockTemplate, onSubmit: action("onSubmit"), onCancel: action("cancel"), }, diff --git a/site/src/pages/TemplateSettingsPage/TemplateVariablesPage/TemplateVariablesPage.test.tsx b/site/src/pages/TemplateSettingsPage/TemplateVariablesPage/TemplateVariablesPage.test.tsx index 1bc3f1b32998c..5ef8a3a2b70d4 100644 --- a/site/src/pages/TemplateSettingsPage/TemplateVariablesPage/TemplateVariablesPage.test.tsx +++ b/site/src/pages/TemplateSettingsPage/TemplateVariablesPage/TemplateVariablesPage.test.tsx @@ -1,12 +1,6 @@ import { screen } from "@testing-library/react" import userEvent from "@testing-library/user-event" import { - MockTemplate, - MockTemplateVersion2, - MockTemplateVersion, - MockTemplateVersionVariable1, - MockTemplateVersionVariable2, - MockTemplateVersionVariable5, renderWithTemplateSettingsLayout, waitForLoaderToBeRemoved, } from "testHelpers/renderHelpers" @@ -14,6 +8,14 @@ import * as API from "api/api" import i18next from "i18next" import TemplateVariablesPage from "./TemplateVariablesPage" import { Language as FooterFormLanguage } from "components/FormFooter/FormFooter" +import { + MockTemplate, + MockTemplateVersion, + MockTemplateVersionVariable1, + MockTemplateVersionVariable2, + MockTemplateVersion2, + MockTemplateVersionVariable5, +} from "testHelpers/entities" const { t } = i18next diff --git a/site/src/pages/TemplateVersionPage/TemplateVersionEditorPage/TemplateVersionEditorPage.test.tsx b/site/src/pages/TemplateVersionPage/TemplateVersionEditorPage/TemplateVersionEditorPage.test.tsx index 07886ec58f7d2..0f8e97c64f847 100644 --- a/site/src/pages/TemplateVersionPage/TemplateVersionEditorPage/TemplateVersionEditorPage.test.tsx +++ b/site/src/pages/TemplateVersionPage/TemplateVersionEditorPage/TemplateVersionEditorPage.test.tsx @@ -1,12 +1,12 @@ -import { - MockTemplateVersion, - MockWorkspaceBuildLogs, - renderWithAuth, -} from "testHelpers/renderHelpers" +import { renderWithAuth } from "testHelpers/renderHelpers" import TemplateVersionEditorPage from "./TemplateVersionEditorPage" import { screen, waitFor, within } from "@testing-library/react" import userEvent from "@testing-library/user-event" import * as api from "api/api" +import { + MockTemplateVersion, + MockWorkspaceBuildLogs, +} from "testHelpers/entities" // For some reason this component in Jest is throwing a MUI style warning so, // since we don't need it for this test, we can mock it out @@ -71,9 +71,9 @@ test("Use custom name and set it as active when publishing", async () => { expect(patchTemplateVersion).toBeCalledWith("new-version-id", { name: "v1.0", }) - expect(updateActiveTemplateVersion).toBeCalledWith("test-template", { - id: "new-version-id", - }) + }) + expect(updateActiveTemplateVersion).toBeCalledWith("test-template", { + id: "new-version-id", }) }) diff --git a/site/src/pages/TemplateVersionPage/TemplateVersionPage.test.tsx b/site/src/pages/TemplateVersionPage/TemplateVersionPage.test.tsx index fc79077f3ba5e..7655e7a6aa5ee 100644 --- a/site/src/pages/TemplateVersionPage/TemplateVersionPage.test.tsx +++ b/site/src/pages/TemplateVersionPage/TemplateVersionPage.test.tsx @@ -36,7 +36,7 @@ describe("TemplateVersionPage", () => { beforeEach(setup) it("shows files", () => { - expect(screen.queryByText(TERRAFORM_FILENAME)).toBeInTheDocument() - expect(screen.queryByText(README_FILENAME)).toBeInTheDocument() + expect(screen.getByText(TERRAFORM_FILENAME)).toBeInTheDocument() + expect(screen.getByText(README_FILENAME)).toBeInTheDocument() }) }) diff --git a/site/src/pages/TerminalPage/TerminalPage.test.tsx b/site/src/pages/TerminalPage/TerminalPage.test.tsx index 45fa937cd3116..cf63a0e2bcc8f 100644 --- a/site/src/pages/TerminalPage/TerminalPage.test.tsx +++ b/site/src/pages/TerminalPage/TerminalPage.test.tsx @@ -3,14 +3,10 @@ import "jest-canvas-mock" import WS from "jest-websocket-mock" import { rest } from "msw" import { Route, Routes } from "react-router-dom" +import { MockWorkspace, MockWorkspaceAgent } from "testHelpers/entities" import { TextDecoder, TextEncoder } from "util" import { ReconnectingPTYRequest } from "../../api/types" -import { - history, - MockWorkspace, - MockWorkspaceAgent, - render, -} from "../../testHelpers/renderHelpers" +import { history, render } from "../../testHelpers/renderHelpers" import { server } from "../../testHelpers/server" import TerminalPage, { Language } from "./TerminalPage" diff --git a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.test.tsx b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.test.tsx index 9d99bcc9849df..231a34516e4f9 100644 --- a/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.test.tsx +++ b/site/src/pages/UserSettingsPage/SSHKeysPage/SSHKeysPage.test.tsx @@ -1,12 +1,10 @@ import { fireEvent, screen, within } from "@testing-library/react" import * as API from "../../../api/api" -import { - MockGitSSHKey, - renderWithAuth, -} from "../../../testHelpers/renderHelpers" +import { renderWithAuth } from "../../../testHelpers/renderHelpers" import { Language as SSHKeysPageLanguage, SSHKeysPage } from "./SSHKeysPage" import { Language as SSHKeysPageViewLanguage } from "./SSHKeysPageView" import { i18n } from "i18n" +import { MockGitSSHKey } from "testHelpers/entities" const { t } = i18n diff --git a/site/src/pages/UsersPage/CreateUserPage/CreateUserPage.test.tsx b/site/src/pages/UsersPage/CreateUserPage/CreateUserPage.test.tsx index 375140a64d614..c55e574b8cfb2 100644 --- a/site/src/pages/UsersPage/CreateUserPage/CreateUserPage.test.tsx +++ b/site/src/pages/UsersPage/CreateUserPage/CreateUserPage.test.tsx @@ -90,7 +90,7 @@ describe("Create User Page", () => { it("shows success notification and redirects to users page", async () => { await renderCreateUserPage() await fillForm({}) - const successMessage = screen.findByText( + const successMessage = await screen.findByText( CreateUserLanguage.createUserSuccess, ) expect(successMessage).toBeDefined() diff --git a/site/src/pages/UsersPage/UsersPage.test.tsx b/site/src/pages/UsersPage/UsersPage.test.tsx index 2c0f274629a38..f476f1c445b76 100644 --- a/site/src/pages/UsersPage/UsersPage.test.tsx +++ b/site/src/pages/UsersPage/UsersPage.test.tsx @@ -2,18 +2,18 @@ import { fireEvent, screen, waitFor, within } from "@testing-library/react" import userEvent from "@testing-library/user-event" import { i18n } from "i18n" import { rest } from "msw" -import { Language as usersXServiceLanguage } from "xServices/users/usersXService" -import * as API from "../../api/api" -import { Role } from "../../api/typesGenerated" -import { Language as ResetPasswordDialogLanguage } from "../../components/Dialogs/ResetPasswordDialog/ResetPasswordDialog" import { - MockAuditorRole, - MockOwnerRole, MockUser, MockUser2, - renderWithAuth, SuspendedMockUser, -} from "../../testHelpers/renderHelpers" + MockAuditorRole, + MockOwnerRole, +} from "testHelpers/entities" +import { Language as usersXServiceLanguage } from "xServices/users/usersXService" +import * as API from "../../api/api" +import { Role } from "../../api/typesGenerated" +import { Language as ResetPasswordDialogLanguage } from "../../components/Dialogs/ResetPasswordDialog/ResetPasswordDialog" +import { renderWithAuth } from "../../testHelpers/renderHelpers" import { server } from "../../testHelpers/server" import { Language as UsersPageLanguage, UsersPage } from "./UsersPage" @@ -401,8 +401,8 @@ describe("UsersPage", () => { // Check if the select text was updated with the Auditor role await waitFor(() => { expect(userRow).toHaveTextContent(MockOwnerRole.display_name) - expect(userRow).toHaveTextContent(MockAuditorRole.display_name) }) + expect(userRow).toHaveTextContent(MockAuditorRole.display_name) // Check if the API was called correctly const currentRoles = MockUser.roles.map((r) => r.name) diff --git a/site/src/pages/UsersPage/UsersPageView.stories.tsx b/site/src/pages/UsersPage/UsersPageView.stories.tsx index babc1c1c3fd80..d25554a59a36c 100644 --- a/site/src/pages/UsersPage/UsersPageView.stories.tsx +++ b/site/src/pages/UsersPage/UsersPageView.stories.tsx @@ -1,10 +1,10 @@ import { ComponentMeta, Story } from "@storybook/react" import { createPaginationRef } from "components/PaginationWidget/utils" import { - MockAssignableSiteRoles, MockUser, MockUser2, -} from "../../testHelpers/renderHelpers" + MockAssignableSiteRoles, +} from "testHelpers/entities" import { UsersPageView, UsersPageViewProps } from "./UsersPageView" export default { diff --git a/site/src/pages/WorkspacePage/WorkspacePage.test.tsx b/site/src/pages/WorkspacePage/WorkspacePage.test.tsx index dbb2408be7cd6..68335cbabd9bc 100644 --- a/site/src/pages/WorkspacePage/WorkspacePage.test.tsx +++ b/site/src/pages/WorkspacePage/WorkspacePage.test.tsx @@ -3,24 +3,26 @@ import userEvent from "@testing-library/user-event" import EventSourceMock from "eventsourcemock" import i18next from "i18next" import { rest } from "msw" -import * as api from "../../api/api" -import { Workspace } from "../../api/typesGenerated" import { - MockBuilds, - MockCanceledWorkspace, - MockCancelingWorkspace, - MockDeletedWorkspace, - MockDeletingWorkspace, - MockFailedWorkspace, - MockOutdatedWorkspace, - MockStartingWorkspace, - MockStoppedWorkspace, - MockStoppingWorkspace, MockTemplate, - MockTemplateVersionParameter1, - MockTemplateVersionParameter2, MockWorkspace, MockWorkspaceBuild, + MockStoppedWorkspace, + MockStartingWorkspace, + MockOutdatedWorkspace, + MockTemplateVersionParameter1, + MockTemplateVersionParameter2, + MockStoppingWorkspace, + MockFailedWorkspace, + MockCancelingWorkspace, + MockCanceledWorkspace, + MockDeletingWorkspace, + MockDeletedWorkspace, + MockBuilds, +} from "testHelpers/entities" +import * as api from "../../api/api" +import { Workspace } from "../../api/typesGenerated" +import { renderWithAuth, waitForLoaderToBeRemoved, } from "../../testHelpers/renderHelpers" diff --git a/site/src/pages/WorkspaceSchedulePage/WorkspaceSchedulePage.test.tsx b/site/src/pages/WorkspaceSchedulePage/WorkspaceSchedulePage.test.tsx index f8fc349c25875..5e8a2fdaa3768 100644 --- a/site/src/pages/WorkspaceSchedulePage/WorkspaceSchedulePage.test.tsx +++ b/site/src/pages/WorkspaceSchedulePage/WorkspaceSchedulePage.test.tsx @@ -1,8 +1,4 @@ -import { - MockUser, - MockWorkspace, - renderWithAuth, -} from "testHelpers/renderHelpers" +import { renderWithAuth } from "testHelpers/renderHelpers" import userEvent from "@testing-library/user-event" import { screen } from "@testing-library/react" import { @@ -23,6 +19,7 @@ import { WorkspaceSchedulePage } from "./WorkspaceSchedulePage" import i18next from "i18next" import { server } from "testHelpers/server" import { rest } from "msw" +import { MockUser, MockWorkspace } from "testHelpers/entities" const { t } = i18next diff --git a/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPage.test.tsx b/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPage.test.tsx index 02838be215db2..a2ca353ec3374 100644 --- a/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPage.test.tsx +++ b/site/src/pages/WorkspaceSettingsPage/WorkspaceSettingsPage.test.tsx @@ -1,17 +1,19 @@ import userEvent from "@testing-library/user-event" import { - MockTemplateVersionParameter1, - MockTemplateVersionParameter2, - MockWorkspace, - MockWorkspaceBuild, - MockWorkspaceBuildParameter1, - MockWorkspaceBuildParameter2, renderWithAuth, waitForLoaderToBeRemoved, } from "testHelpers/renderHelpers" import WorkspaceSettingsPage from "./WorkspaceSettingsPage" import { screen, waitFor, within } from "@testing-library/react" import * as api from "api/api" +import { + MockWorkspace, + MockTemplateVersionParameter1, + MockTemplateVersionParameter2, + MockWorkspaceBuildParameter1, + MockWorkspaceBuildParameter2, + MockWorkspaceBuild, +} from "testHelpers/entities" test("Submit the workspace settings page successfully", async () => { // Mock the API calls that loads data @@ -69,12 +71,12 @@ test("Submit the workspace settings page successfully", async () => { expect(patchWorkspaceSpy).toHaveBeenCalledWith(MockWorkspace.id, { name: "new-name", }) - expect(postWorkspaceBuildSpy).toHaveBeenCalledWith(MockWorkspace.id, { - transition: "start", - rich_parameter_values: [ - { name: MockTemplateVersionParameter1.name, value: "new-value" }, - { name: MockTemplateVersionParameter2.name, value: "1" }, - ], - }) + }) + expect(postWorkspaceBuildSpy).toHaveBeenCalledWith(MockWorkspace.id, { + transition: "start", + rich_parameter_values: [ + { name: MockTemplateVersionParameter1.name, value: "new-value" }, + { name: MockTemplateVersionParameter2.name, value: "1" }, + ], }) }) diff --git a/site/src/testHelpers/renderHelpers.tsx b/site/src/testHelpers/renderHelpers.tsx index 52995e3f3cbd9..51287b0118b16 100644 --- a/site/src/testHelpers/renderHelpers.tsx +++ b/site/src/testHelpers/renderHelpers.tsx @@ -132,6 +132,9 @@ export function renderWithTemplateSettingsLayout( } export const waitForLoaderToBeRemoved = (): Promise => - waitForElementToBeRemoved(() => screen.getByTestId("loader")) - -export * from "./entities" + // Sometimes, we have pages that are doing a lot of requests to get done, so the + // default timeout of 1_000 is not enough. We should revisit this when we unify + // some of the endpoints + waitForElementToBeRemoved(() => screen.queryByTestId("loader"), { + timeout: 5_000, + }) diff --git a/site/src/xServices/updateCheck/updateCheckXService.test.ts b/site/src/xServices/updateCheck/updateCheckXService.test.ts index a0338f4deab64..a12668d83551a 100644 --- a/site/src/xServices/updateCheck/updateCheckXService.test.ts +++ b/site/src/xServices/updateCheck/updateCheckXService.test.ts @@ -132,7 +132,7 @@ describe("updateCheckMachine", () => { updateCheckService.send("DISMISS") await waitFor(() => { expect(updateCheckService.state.matches("dismissed")).toBeTruthy() - expect(getDismissedVersionOnLocal()).toEqual(MockUpdateCheck.version) }) + expect(getDismissedVersionOnLocal()).toEqual(MockUpdateCheck.version) }) }) diff --git a/site/yarn.lock b/site/yarn.lock index 852fb9d0e8f34..6e81f10bab216 100644 --- a/site/yarn.lock +++ b/site/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@adobe/css-tools@^4.0.1": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.2.0.tgz#e1a84fca468f4b337816fcb7f0964beb620ba855" + integrity sha512-E09FiIft46CmH5Qnjb0wsW54/YQd69LsxeKUOWawmws1XWvyFGURnAChH0mlr7YPFR1ofwvUQfcL0J3lMxXqPA== + "@ampproject/remapping@^2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" @@ -1208,6 +1213,13 @@ resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.15.18.tgz#128b76ecb9be48b60cf5cfc1c63a4f00691a3239" integrity sha512-L4jVKS82XVhw2nvzLg/19ClLWg0y27ulRwuP7lcyL6AbUWB5aPglXY3M21mauDQMDfRLs8cQmeT03r/+X3cZYQ== +"@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + "@eslint/eslintrc@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.0.tgz#943309d8697c52fc82c076e90c1c74fbbe69dbff" @@ -2986,10 +2998,10 @@ "@tanstack/query-core" "4.22.4" use-sync-external-store "^1.2.0" -"@testing-library/dom@^8.5.0": - version "8.20.0" - resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.20.0.tgz#914aa862cef0f5e89b98cc48e3445c4c921010f6" - integrity sha512-d9ULIT+a4EXLX3UU8FBjauG9NnsZHkHztXoIcTsOKoOw030fyjheN9svkTULjJxtYag9DZz5Jz5qkWZDPxTFwA== +"@testing-library/dom@^9.0.0": + version "9.2.0" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-9.2.0.tgz#0e1f45e956f2a16f471559c06edd8827c4832f04" + integrity sha512-xTEnpUKiV/bMyEsE5bT4oYA0x0Z/colMtxzUY8bKyPXBNLn/e0V4ZjBZkEhms0xE4pv9QsPfSRu9AWS4y5wGvA== dependencies: "@babel/code-frame" "^7.10.4" "@babel/runtime" "^7.12.5" @@ -2997,19 +3009,19 @@ aria-query "^5.0.0" chalk "^4.1.0" dom-accessibility-api "^0.5.9" - lz-string "^1.4.4" + lz-string "^1.5.0" pretty-format "^27.0.2" -"@testing-library/jest-dom@5.16.4": - version "5.16.4" - resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.4.tgz#938302d7b8b483963a3ae821f1c0808f872245cd" - integrity sha512-Gy+IoFutbMQcky0k+bqqumXZ1cTGswLsFqmNLzNdSKkU9KGV2u9oXhukCbbJ9/LRPKiqwxEE8VpV/+YZlfkPUA== +"@testing-library/jest-dom@5.16.5": + version "5.16.5" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.16.5.tgz#3912846af19a29b2dbf32a6ae9c31ef52580074e" + integrity sha512-N5ixQ2qKpi5OLYfwQmUb/5mSV9LneAcaUfp32pn4yCnpb8r/Yz0pXFPck21dIicKmi+ta5WRAknkZCfA8refMA== dependencies: + "@adobe/css-tools" "^4.0.1" "@babel/runtime" "^7.9.2" "@types/testing-library__jest-dom" "^5.9.1" aria-query "^5.0.0" chalk "^3.0.0" - css "^3.0.0" css.escape "^1.5.1" dom-accessibility-api "^0.5.6" lodash "^4.17.15" @@ -3023,13 +3035,13 @@ "@babel/runtime" "^7.12.5" react-error-boundary "^3.1.0" -"@testing-library/react@13.4.0": - version "13.4.0" - resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-13.4.0.tgz#6a31e3bf5951615593ad984e96b9e5e2d9380966" - integrity sha512-sXOGON+WNTh3MLE9rve97ftaZukN3oNf2KjDy7YTx6hcTO2uuLHuCGynMDhFwGw/jYf4OJ2Qk0i4i79qMNNkyw== +"@testing-library/react@14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-14.0.0.tgz#59030392a6792450b9ab8e67aea5f3cc18d6347c" + integrity sha512-S04gSNJbYE30TlIMLTzv6QCTzt9AqIF5y6s6SzVFILNcNvbV/jU96GeiTPillGQo+Ny64M/5PV7klNYYgv5Dfg== dependencies: "@babel/runtime" "^7.12.5" - "@testing-library/dom" "^8.5.0" + "@testing-library/dom" "^9.0.0" "@types/react-dom" "^18.0.0" "@testing-library/user-event@14.4.3": @@ -3622,6 +3634,14 @@ "@typescript-eslint/types" "5.53.0" "@typescript-eslint/visitor-keys" "5.53.0" +"@typescript-eslint/scope-manager@5.57.0": + version "5.57.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.57.0.tgz#79ccd3fa7bde0758059172d44239e871e087ea36" + integrity sha512-NANBNOQvllPlizl9LatX8+MHi7bx7WGIWYjPHDmQe5Si/0YEYfxSljJpoTyTWFTgRy3X8gLYSE4xQ2U+aCozSw== + dependencies: + "@typescript-eslint/types" "5.57.0" + "@typescript-eslint/visitor-keys" "5.57.0" + "@typescript-eslint/type-utils@5.50.0": version "5.50.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.50.0.tgz#509d5cc9728d520008f7157b116a42c5460e7341" @@ -3647,6 +3667,11 @@ resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.53.0.tgz#f79eca62b97e518ee124086a21a24f3be267026f" integrity sha512-5kcDL9ZUIP756K6+QOAfPkigJmCPHcLN7Zjdz76lQWWDdzfOhZDTj1irs6gPBKiXx5/6O3L0+AvupAut3z7D2A== +"@typescript-eslint/types@5.57.0": + version "5.57.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.57.0.tgz#727bfa2b64c73a4376264379cf1f447998eaa132" + integrity sha512-mxsod+aZRSyLT+jiqHw1KK6xrANm19/+VFALVFP5qa/aiJnlP38qpyaTd0fEKhWvQk6YeNZ5LGwI1pDpBRBhtQ== + "@typescript-eslint/typescript-estree@5.45.1": version "5.45.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.45.1.tgz#b3dc37f0c4f0fe73e09917fc735e6f96eabf9ba4" @@ -3686,6 +3711,19 @@ semver "^7.3.7" tsutils "^3.21.0" +"@typescript-eslint/typescript-estree@5.57.0": + version "5.57.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.57.0.tgz#ebcd0ee3e1d6230e888d88cddf654252d41e2e40" + integrity sha512-LTzQ23TV82KpO8HPnWuxM2V7ieXW8O142I7hQTxWIHDcCEIjtkat6H96PFkYBQqGFLW/G/eVVOB9Z8rcvdY/Vw== + dependencies: + "@typescript-eslint/types" "5.57.0" + "@typescript-eslint/visitor-keys" "5.57.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + "@typescript-eslint/utils@5.50.0": version "5.50.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.50.0.tgz#807105f5ffb860644d30d201eefad7017b020816" @@ -3714,6 +3752,20 @@ eslint-utils "^3.0.0" semver "^7.3.7" +"@typescript-eslint/utils@^5.43.0": + version "5.57.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.57.0.tgz#eab8f6563a2ac31f60f3e7024b91bf75f43ecef6" + integrity sha512-ps/4WohXV7C+LTSgAL5CApxvxbMkl9B9AUZRtnEFonpIxZDIT7wC1xfvuJONMidrkB9scs4zhtRyIwHh4+18kw== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@types/json-schema" "^7.0.9" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.57.0" + "@typescript-eslint/types" "5.57.0" + "@typescript-eslint/typescript-estree" "5.57.0" + eslint-scope "^5.1.1" + semver "^7.3.7" + "@typescript-eslint/visitor-keys@5.45.1": version "5.45.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.45.1.tgz#204428430ad6a830d24c5ac87c71366a1cfe1948" @@ -3738,6 +3790,14 @@ "@typescript-eslint/types" "5.53.0" eslint-visitor-keys "^3.3.0" +"@typescript-eslint/visitor-keys@5.57.0": + version "5.57.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.57.0.tgz#e2b2f4174aff1d15eef887ce3d019ecc2d7a8ac1" + integrity sha512-ery2g3k0hv5BLiKpPuwYt9KBkAp2ugT6VvyShXdLOkax895EC55sP0Tx5L0fZaQueiK3fBLvHVvEl3jFS5ia+g== + dependencies: + "@typescript-eslint/types" "5.57.0" + eslint-visitor-keys "^3.3.0" + "@vitejs/plugin-react@2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-2.1.0.tgz#4c99df15e71d2630601bd3018093bdc787d40e55" @@ -5956,15 +6016,6 @@ css.escape@^1.5.1: resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg== -css@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/css/-/css-3.0.0.tgz#4447a4d58fdd03367c516ca9f64ae365cee4aa5d" - integrity sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ== - dependencies: - inherits "^2.0.4" - source-map "^0.6.1" - source-map-resolve "^0.6.0" - cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" @@ -6944,6 +6995,13 @@ eslint-plugin-react@7.31.1: semver "^6.3.0" string.prototype.matchall "^4.0.7" +eslint-plugin-testing-library@^5.10.2: + version "5.10.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.10.2.tgz#12f231ad9b52b6aef45c801fd00aa129a932e0c2" + integrity sha512-f1DmDWcz5SDM+IpCkEX0lbFqrrTs8HRsEElzDEqN/EBI0hpRj8Cns5+IVANXswE8/LeybIJqPAOQIFu2j5Y5sw== + dependencies: + "@typescript-eslint/utils" "^5.43.0" + eslint-plugin-unicorn@44.0.0: version "44.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-unicorn/-/eslint-plugin-unicorn-44.0.0.tgz#ddb2d7bf3674077d6f3b227b9a0ce22dfc1e3ceb" @@ -10180,10 +10238,10 @@ luxon@^3.1.0: resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.2.1.tgz#14f1af209188ad61212578ea7e3d518d18cee45f" integrity sha512-QrwPArQCNLAKGO/C+ZIilgIuDnEnKx5QYODdDtbFaxzsbZcc/a7WFq7MhsVYgRlwawLtvOUESTlfJ+hc/USqPg== -lz-string@^1.4.4: - version "1.4.4" - resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" - integrity sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ== +lz-string@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" + integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== magic-string@^0.26.2: version "0.26.7" @@ -13413,14 +13471,6 @@ source-map-resolve@^0.5.0: source-map-url "^0.4.0" urix "^0.1.0" -source-map-resolve@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.6.0.tgz#3d9df87e236b53f16d01e58150fc7711138e5ed2" - integrity sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - source-map-support@0.5.13: version "0.5.13" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932"