test(vendors): update the deactivation e2e to the confirmation flow (SH-254)

The browser smoke encoded the behaviour this ticket changes: it asserted
the Deactivate button was disabled when work orders were linked. It now
asserts the opposite — the work orders are listed as links, "Deactivate
anyway" is enabled, and confirming sends confirmOpenWorkOrders=true.

Also fixes the mock's DELETE route, whose anchored pattern stopped
matching once the request carried a query string. The raced-409 case is
unchanged and still preserves the vendor.
This commit is contained in:
Codex Review Integration 2026-08-19 14:29:01 -03:00
parent 22b03b8ac0
commit 670d03d572

View file

@ -66,6 +66,7 @@ interface MockState {
createdBody?: Record<string, unknown>;
updatedBody?: Record<string, unknown>;
deletedId?: string;
deleteConfirmedOpenWorkOrders?: boolean;
}
async function fulfillJson(route: Route, body: unknown, status = 200) {
@ -259,8 +260,9 @@ async function mockVendorApi(
},
}),
);
await page.route(/\/api\/vendors\/\d+$/, async (route) => {
const id = route.request().url().split("/").pop() ?? "";
await page.route(/\/api\/vendors\/\d+(\?.*)?$/, async (route) => {
const requestUrl = new URL(route.request().url());
const id = requestUrl.pathname.split("/").pop() ?? "";
if (route.request().method() === "PUT") {
state.updatedBody = route.request().postDataJSON();
const vendor = vendorRecords.find((item) => String(item.Id) === id);
@ -273,6 +275,8 @@ async function mockVendorApi(
return;
}
if (route.request().method() === "DELETE") {
state.deleteConfirmedOpenWorkOrders =
requestUrl.searchParams.get("confirmOpenWorkOrders") === "true";
if (options.deleteConflict) {
await fulfillJson(
route,
@ -517,20 +521,28 @@ test.describe("Vendor directory prototype parity", () => {
await expect(page.getByRole("button", { name: "Close drawer" })).toHaveCount(0);
});
test("blocks deactivation for linked work orders and preserves the vendor on a raced 409", async ({
test("confirms deactivation past linked work orders and preserves the vendor on a raced 409", async ({
page,
}) => {
const blockedState = await mockVendorApi(page, { deactivationBlocked: true });
const confirmState = await mockVendorApi(page, { deactivationBlocked: true });
await page.goto("/vendors");
await page.getByRole("button", { name: "Edit vendor Gateway Plumbing" }).click();
await page.getByRole("switch", { name: "Active status" }).click();
const blockedDialog = page.getByRole("dialog", { name: "Deactivate Vendor" });
await expect(blockedDialog).toContainText("WO-501 — Emergency boiler repair");
await expect(blockedDialog.getByRole("button", { name: /^Deactivate$/ })).toBeDisabled();
expect(blockedState.deletedId).toBeUndefined();
const dialog = page.getByRole("dialog", { name: "Deactivate this vendor?" });
await expect(dialog).toContainText("It still has 1 open work order");
await expect(
dialog.getByRole("link", { name: /WO-501 — Emergency boiler repair/ }),
).toHaveAttribute("href", "/workorders/501");
// SH-254: the open work orders inform the decision, they no longer block it.
const confirm = dialog.getByRole("button", { name: "Deactivate anyway" });
await expect(confirm).toBeEnabled();
await confirm.click();
await expect.poll(() => confirmState.deletedId).toBe("1");
expect(confirmState.deleteConfirmedOpenWorkOrders).toBe(true);
await blockedDialog.getByRole("button", { name: "Cancel" }).click();
await page.unrouteAll({ behavior: "wait" });
const racedState = await mockVendorApi(page, { deleteConflict: true });
@ -538,13 +550,13 @@ test.describe("Vendor directory prototype parity", () => {
await page.getByRole("button", { name: "Edit vendor Gateway Plumbing" }).click();
await page.getByRole("switch", { name: "Active status" }).click();
await page
.getByRole("dialog", { name: "Deactivate Vendor" })
.getByRole("dialog", { name: "Deactivate this vendor?" })
.getByRole("button", {
name: /^Deactivate$/,
})
.click();
await expect(page.getByRole("dialog", { name: "Deactivate Vendor" })).toContainText(
await expect(page.getByRole("dialog", { name: "Deactivate this vendor?" })).toContainText(
/open work orders|conflict/i,
);
expect(racedState.deletedId).toBeUndefined();