Files
govoplan-core/webui/conformance/tests/campaign-attachments.spec.ts
T

85 lines
5.5 KiB
TypeScript

import { expect, test, type Page } from "@playwright/test";
async function install(page: Page) {
const errors: string[] = [];
page.on("pageerror", error => { errors.push(error.message); console.error("Attachment fixture:", error.message); });
let revision = 1;
const zip = { enabled: true, archives: [{ id: "zip-1", name: "recipient.zip", method: "zip_standard", password_enabled: true }] };
let raw = { campaign: { name: "Fixture" }, template: { subject: "Fixture", text: "" }, server: {},
attachments: { base_paths: [{ id: "source-1", name: "Source", path: ".", source: "managed:user:user-1", allow_individual: true }],
global: [], zip } };
const writes: Record<string, any>[] = [];
const version = () => ({ id: "version-attachments", campaign_id: "campaign-attachments", version_number: 1,
edit_revision: revision, strong_etag: `"version-attachments:${revision}"`, editor_state: {},
current_flow: "manual", current_step: "files", workflow_state: "editing", is_complete: false,
updated_at: "2026-09-07T10:00:00Z", raw_json: raw });
await page.route((url) => url.pathname.startsWith("/api/"), async route => {
const request = route.request(); const url = new URL(request.url());
if (request.method() === "GET") {
if (url.pathname.endsWith("/workspace/delta")) return route.fulfill({ json: {
campaign: { id: "campaign-attachments", name: "Fixture", current_version_id: "version-attachments", status: "draft" },
versions: [version()], current_version: version(), summary: null, deleted: [], full: true, has_more: false, watermark: `w${revision}`
} });
if (url.pathname === "/api/v1/files/spaces") return route.fulfill({ json: { spaces: [{ id: "space-1", label: "My files", space_type: "managed", owner_type: "user", owner_id: "user-1" }] } });
if (url.pathname === "/api/v1/files/folders") return route.fulfill({ json: { folders: [], next_cursor: null } });
if (url.pathname === "/api/v1/files") return route.fulfill({ json: { files: [], next_cursor: null } });
if (url.pathname === "/api/v1/files/delta") return route.fulfill({ json: { files: [], folders: [{ id: "folder-1", owner_type: "user", owner_id: "user-1", path: "letters", name: "letters" }], deleted: [], full: true, has_more: false, watermark: "files-w1" } });
if (url.pathname.endsWith("/versions/version-attachments")) return route.fulfill({ json: version() });
if (url.pathname.endsWith("/archive-encryption-policy")) return route.fulfill({ json: {
available: true, allowed_password_encryption_methods: ["aes"], allowed_password_delivery_channels: ["separate_mail"],
policy_hash: "fixture", source_path: [], diagnostics: [], reason: "Legacy ZipCrypto is blocked by policy.", legacy_label: "Legacy ZipCrypto"
} });
return route.fulfill({ json: {} });
}
if (request.method() === "POST" && url.pathname.endsWith("/autosave")) {
const body = request.postDataJSON(); writes.push(body);
raw = body.campaign_json; revision++;
return route.fulfill({ json: version() });
}
return route.abort();
});
await page.goto("/?campaign-attachments");
await expect(page.locator("#campaign-attachment-sources .chooser-display-input")).toBeEnabled();
return { writes, errors, zip };
}
test("actual Files chooser opens repeatedly from attachment path by click and keyboard", async ({ page }) => {
const fixture = await install(page);
const input = page.locator("#campaign-attachment-sources .chooser-display-input");
for (const action of ["click", "Enter", "Space", "click"]) {
if (action === "click") await input.click();
else { await input.focus(); await page.keyboard.press(action); }
await expect(page.getByRole("dialog")).toBeVisible();
await expect(page.getByRole("dialog").getByRole("button", { name: /Use.*folder|Select.*folder/i })).toBeEnabled();
await page.keyboard.press("Escape");
await expect(page.getByRole("dialog")).toHaveCount(0);
}
expect(fixture.writes).toHaveLength(0);
expect(fixture.errors).toEqual([]);
});
test("temporarily unavailable Files capability does not silently turn managed paths into text edits", async ({ page }) => {
const fixture = await install(page);
await page.getByRole("button", { name: "Toggle Files capability" }).click();
await expect(page.locator("#campaign-attachment-sources .chooser-display-input")).toBeDisabled();
await expect(page.getByText(/The Files browser is currently unavailable/).first()).toBeVisible();
await page.getByRole("button", { name: "Toggle Files capability" }).click();
await page.locator("#campaign-attachment-sources .chooser-display-input").click();
await expect(page.getByRole("dialog")).toBeVisible();
await page.keyboard.press("Escape");
expect(fixture.writes).toHaveLength(0);
expect(fixture.errors).toEqual([]);
});
test("attachment source corrections save without changing or reauthorizing legacy ZIP configuration", async ({ page }) => {
const fixture = await install(page);
await page.locator('#campaign-attachment-sources input[placeholder="Campaign files"]').fill("Updated source name");
await page.getByRole("button", { name: "Save", exact: true }).click();
await expect.poll(() => fixture.writes.length).toBe(1);
expect(fixture.writes[0].campaign_json.attachments.zip).toEqual(fixture.zip);
expect(fixture.writes[0].campaign_json.attachments.base_paths[0].name).toBe("Updated source name");
await page.reload();
await expect(page.locator('#campaign-attachment-sources input[placeholder="Campaign files"]')).toHaveValue("Updated source name");
expect(fixture.errors).toEqual([]);
});