diff --git a/e2e/tests/support-legal.spec.ts b/e2e/tests/support-legal.spec.ts index 9f9bc1c..832ef23 100644 --- a/e2e/tests/support-legal.spec.ts +++ b/e2e/tests/support-legal.spec.ts @@ -1,4 +1,4 @@ -import { APIRequestContext, expect, test } from "@playwright/test"; +import { APIRequestContext, expect, Page, test } from "@playwright/test"; import { captureBrowserFailures, gotoLiveView, @@ -43,6 +43,29 @@ async function waitForNewEmail( ); } +async function submitAuthenticatedSupportRequest( + page: Page, + requesterEmail: string, + kind: "privacy_request" | "data_export", + subject: string, + details: string, +): Promise { + await page.goto("/support"); + await page.getByLabel("What do you need help with?").selectOption(kind); + await expect(page.getByLabel("Contact email")).toHaveValue(requesterEmail); + await expect(page.getByLabel("Contact email")).toHaveAttribute( + "readonly", + "", + ); + await page.getByLabel("Subject").fill(subject); + await page.getByLabel("Describe the problem").fill(details); + await page.getByRole("button", { name: "Send support request" }).click(); + await expect(page).toHaveURL(/\/support\/received\?reference=SUP-/); + await expect( + page.getByRole("heading", { name: "Support request created" }), + ).toBeVisible(); +} + test("authenticated support and legal notices reach the scoped staff queues", async ({ browser, request, @@ -56,6 +79,9 @@ test("authenticated support and legal notices reach the scoped staff queues", as "Browser E2E verifies the authenticated private case without a duplicate receipt email."; const supportReply = `E2E support reply [${projectName}]`; const supportFollowUp = `E2E support inbox follow-up [${projectName}]`; + const privacySubject = `E2E privacy request [${projectName}]`; + const dataExportSubject = `E2E data export [${projectName}]`; + const accountDeletionSubject = "Delete my Who Need Help account"; const generalExplanation = "Browser E2E verifies that a signed-in general removal notice reaches the legal queue."; const urgentExplanation = @@ -154,6 +180,70 @@ test("authenticated support and legal notices reach the scoped staff queues", as requester.page.getByText(supportFollowUp, { exact: true }), ).toBeVisible(); + await submitAuthenticatedSupportRequest( + requester.page, + requesterEmail, + "privacy_request", + privacySubject, + "Browser E2E verifies that an authenticated privacy request remains private and reaches the scoped support queue.", + ); + await submitAuthenticatedSupportRequest( + requester.page, + requesterEmail, + "data_export", + dataExportSubject, + "Browser E2E verifies that an authenticated data-export request reaches the scoped support queue.", + ); + + await requester.page.goto("/account/delete"); + await expect(requester.page.getByLabel("Account email")).toHaveValue( + requesterEmail, + ); + await expect(requester.page.getByLabel("Account email")).toHaveAttribute( + "readonly", + "", + ); + await requester.page + .getByLabel("Additional information") + .fill( + "Browser E2E verifies that account deletion enters the dedicated support workflow without deleting the fixture account immediately.", + ); + await requester.page + .getByRole("button", { name: "Request account deletion" }) + .click(); + await expect(requester.page).toHaveURL(/\/support\/received\?reference=SUP-/); + await expect( + requester.page.getByRole("heading", { name: "Support request created" }), + ).toBeVisible(); + + await gotoLiveView(admin.page, "/support/operations?queue=support"); + await admin.page + .locator("#support-case-filters") + .getByLabel("Search") + .fill(requesterEmail); + const requesterSupportRows = admin.page.locator("main tbody tr"); + await expect(requesterSupportRows).toHaveCount(4); + await expect( + requesterSupportRows.filter({ hasText: privacySubject }), + ).toHaveCount(1); + await expect( + requesterSupportRows.filter({ hasText: dataExportSubject }), + ).toHaveCount(1); + await expect( + requesterSupportRows.filter({ hasText: accountDeletionSubject }), + ).toHaveCount(1); + + await requester.page.goto("/support/requests"); + await expect( + requester.page.getByRole("link").filter({ hasText: privacySubject }), + ).toHaveCount(1); + await expect( + requester.page.getByRole("link").filter({ hasText: dataExportSubject }), + ).toHaveCount(1); + await expect( + requester.page.getByRole("link").filter({ hasText: accountDeletionSubject }), + ).toHaveCount(1); + const generalEmailBefore = await latestMessageID(request, requesterEmail); await requester.page.goto("/legal/content-removal"); await requester.page.getByLabel("Reason").selectOption("privacy_violation");