88 lines
4.6 KiB
TypeScript
88 lines
4.6 KiB
TypeScript
import { expect, test } from "./helpers";
|
|
import { actor, api, closeAll } from "./shophelpers";
|
|
import { call } from "./adminhelpers";
|
|
import type { Json } from "./whhelpers";
|
|
|
|
// Change C8 on the CI stack: checklists per department. multi.mia (Clerical and 06 Code Bldg 2 supervisor) opens
|
|
// Checklists from the top bar, sees only her own department, adds an item and saves. sup.wes (03 supervisor) can
|
|
// read 06 but not change it, and Q.C. and a lead cannot change any. At the end mia sets 06 back to the default list
|
|
// so the other scenarios keep the lists they expect.
|
|
|
|
const RUN = Date.now().toString(36).toLowerCase().slice(-5);
|
|
const KEY = `e2e_${RUN}`;
|
|
const TEXT = `Nameplate checked ${RUN}`;
|
|
|
|
async function resetTo06Default(a: Parameters<typeof api>[0]): Promise<void> {
|
|
const cur = await api(a, "get", "/api/checklists/06");
|
|
if (cur.custom) await api(a, "put", "/api/checklists/06", { items: null, base: cur.version });
|
|
}
|
|
|
|
test.describe.serial("department checklists", () => {
|
|
test.setTimeout(120_000);
|
|
|
|
test("C8: a supervisor edits their own department's checklist; others cannot", async ({ browser }) => {
|
|
const mia = await actor(browser, "multi.mia");
|
|
await resetTo06Default(mia);
|
|
const list = (await api(mia, "get", "/api/checklists")) as unknown as Json[];
|
|
const editable = list.filter((d) => d.editable).map((d) => String(d.dept_code));
|
|
expect(editable).toEqual(["06"]);
|
|
|
|
// the top-bar link; one department, so no picker
|
|
const page = mia.page;
|
|
await page.goto("/clerical");
|
|
await page.getByRole("banner").getByRole("link", { name: "Checklists", exact: true }).click();
|
|
await expect(page).toHaveURL(/\/checklists$/);
|
|
await expect(page.getByRole("heading", { level: 1, name: "Checklists" })).toBeVisible();
|
|
await expect(page.getByLabel("Department", { exact: true })).toHaveCount(0);
|
|
const editor = page.locator("section").filter({ has: page.getByRole("heading", { name: /^06 / }) });
|
|
await expect(editor).toBeVisible();
|
|
await expect(editor).toContainText(/Uses the default/);
|
|
const keys = editor.getByLabel(/^Item \d+ key$/);
|
|
const n = await keys.count();
|
|
expect(n).toBeGreaterThan(0);
|
|
|
|
// add an item at the end and save
|
|
await editor.getByRole("button", { name: "Add item", exact: true }).click();
|
|
await expect(keys).toHaveCount(n + 1);
|
|
await editor.getByLabel(`Item ${n + 1} group`, { exact: true }).fill("Final");
|
|
await editor.getByLabel(`Item ${n + 1} key`, { exact: true }).fill(KEY);
|
|
await editor.getByLabel(`Item ${n + 1} text`, { exact: true }).fill(TEXT);
|
|
await editor.getByRole("button", { name: "Save checklist", exact: true }).click();
|
|
await expect(editor.getByText(/^Checklist saved\./)).toBeVisible();
|
|
await expect(editor).toContainText("Own list");
|
|
const saved = await api(mia, "get", "/api/checklists/06");
|
|
expect(saved.custom).toBe(true);
|
|
expect(saved.editable).toBe(true);
|
|
expect((saved.items as Json[]).map((i) => i.key)).toContain(KEY);
|
|
expect((saved.items as Json[]).length).toBe(n + 1);
|
|
|
|
// sup.wes reads 06 but may not change it; his own list is 03
|
|
const wes = await actor(browser, "sup.wes");
|
|
const as03 = await api(wes, "get", "/api/checklists/06");
|
|
expect(as03.editable).toBe(false);
|
|
expect((as03.items as Json[]).map((i) => i.key)).toContain(KEY);
|
|
const refused = await call(wes, "put", "/api/checklists/06", { items: [], base: saved.version });
|
|
expect(refused.status).toBe(403);
|
|
await wes.page.goto("/checklists");
|
|
await expect(wes.page.locator("section").filter({ has: wes.page.getByRole("heading", { name: /^03 / }) })).toBeVisible();
|
|
await expect(wes.page.getByRole("heading", { name: /^06 / })).toHaveCount(0);
|
|
|
|
// Q.C. and a lead: no edit, no screen
|
|
const quinn = await actor(browser, "qc.quinn");
|
|
expect((await call(quinn, "put", "/api/checklists/03", { items: [], base: 0 })).status).toBe(403);
|
|
const lou = await actor(browser, "lead.lou");
|
|
expect((await api(lou, "get", "/api/checklists/03")).editable).toBe(false);
|
|
await lou.page.goto("/checklists");
|
|
await expect(lou.page.getByTestId("not-for-role")).toContainText("The Checklists screen is not for your role.");
|
|
|
|
// a stale save is refused with the current list
|
|
const stale = await call(mia, "put", "/api/checklists/06", { items: saved.items, base: Number(saved.version) - 1 });
|
|
expect(stale.status).toBe(409);
|
|
|
|
// back to the default so the other scenarios keep their lists
|
|
await resetTo06Default(mia);
|
|
expect((await api(mia, "get", "/api/checklists/06")).custom).toBe(false);
|
|
await closeAll(mia, wes, quinn, lou);
|
|
});
|
|
});
|