coder/site/src/pages/TemplateSettingsPage/TemplateGeneralSettingsPage/TemplateSettingsPage.test.tsx

130 lines
4.0 KiB
TypeScript

import { screen, waitFor } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import * as API from "api/api";
import { UpdateTemplateMeta } from "api/typesGenerated";
import { Language as FooterFormLanguage } from "components/FormFooter/FormFooter";
import { MockTemplate } from "testHelpers/entities";
import {
renderWithTemplateSettingsLayout,
waitForLoaderToBeRemoved,
} from "testHelpers/renderHelpers";
import { getValidationSchema } from "./TemplateSettingsForm";
import { TemplateSettingsPage } from "./TemplateSettingsPage";
type FormValues = Required<
Omit<
UpdateTemplateMeta,
"default_ttl_ms" | "activity_bump_ms" | "max_ttl_ms" | "deprecation_message"
>
>;
const validFormValues: FormValues = {
name: "Name",
display_name: "A display name",
description: "A description",
icon: "vscode.png",
allow_user_cancel_workspace_jobs: false,
allow_user_autostart: false,
allow_user_autostop: false,
autostop_requirement: {
days_of_week: [],
weeks: 1,
},
autostart_requirement: {
days_of_week: [
"monday",
"tuesday",
"wednesday",
"thursday",
"friday",
"saturday",
"sunday",
],
},
failure_ttl_ms: 0,
time_til_dormant_ms: 0,
time_til_dormant_autodelete_ms: 0,
update_workspace_last_used_at: false,
update_workspace_dormant_at: false,
require_active_version: false,
disable_everyone_group_access: false,
max_port_share_level: "owner",
};
const renderTemplateSettingsPage = async () => {
renderWithTemplateSettingsLayout(<TemplateSettingsPage />, {
route: `/templates/${MockTemplate.name}/settings`,
path: `/templates/:template/settings`,
});
await waitForLoaderToBeRemoved();
};
const fillAndSubmitForm = async ({
name,
display_name,
description,
icon,
allow_user_cancel_workspace_jobs,
}: FormValues) => {
const nameField = await screen.findByLabelText("Name");
await userEvent.clear(nameField);
await userEvent.type(nameField, name);
const displayNameField = await screen.findByLabelText("Display name");
await userEvent.clear(displayNameField);
await userEvent.type(displayNameField, display_name);
const descriptionField = await screen.findByLabelText("Description");
await userEvent.clear(descriptionField);
await userEvent.type(descriptionField, description);
const iconField = await screen.findByLabelText("Icon");
await userEvent.clear(iconField);
await userEvent.type(iconField, icon);
const allowCancelJobsField = screen.getByRole("checkbox", {
name: /allow users to cancel in-progress workspace jobs/i,
});
// checkbox is checked by default, so it must be clicked to get unchecked
if (!allow_user_cancel_workspace_jobs) {
await userEvent.click(allowCancelJobsField);
}
const submitButton = await screen.findByText(
FooterFormLanguage.defaultSubmitLabel,
);
await userEvent.click(submitButton);
};
describe("TemplateSettingsPage", () => {
it("succeeds", async () => {
await renderTemplateSettingsPage();
jest.spyOn(API, "updateTemplateMeta").mockResolvedValueOnce({
...MockTemplate,
...validFormValues,
});
await fillAndSubmitForm(validFormValues);
await waitFor(() => expect(API.updateTemplateMeta).toBeCalledTimes(1));
});
it("allows a description of 128 chars", () => {
const values: UpdateTemplateMeta = {
...validFormValues,
description:
"Nam quis nulla. Integer malesuada. In in enim a arcu imperdiet malesuada. Sed vel lectus. Donec odio urna, tempus molestie, port",
};
const validate = () => getValidationSchema().validateSync(values);
expect(validate).not.toThrowError();
});
it("disallows a description of 128 + 1 chars", () => {
const values: UpdateTemplateMeta = {
...validFormValues,
description:
"Nam quis nulla. Integer malesuada. In in enim a arcu imperdiet malesuada. Sed vel lectus. Donec odio urna, tempus molestie, port a",
};
const validate = () => getValidationSchema().validateSync(values);
expect(validate).toThrowError();
});
});