import { expect, test } from "@playwright/test"; import { type Consent, installDevApiMock, makeClient, seedAuth, } from "./helpers/devfront-fixtures"; import { captureEvidence } from "./helpers/evidence"; test.describe("DevFront consents", () => { test.afterEach(async ({ page }, testInfo) => { if (testInfo.status === "passed") { await captureEvidence(page, testInfo, testInfo.title); } }); test.beforeEach(async ({ page }) => { page.on("dialog", async (dialog) => { await dialog.accept(); }); await seedAuth(page); }); test("consent list and revoke flow", async ({ page }) => { const state = { clients: [ makeClient("client-consent", { name: "Consent app", metadata: { id_token_claims: [ { namespace: "rp_claims", key: "contract_date", valueType: "date", value: "2026-06-09", }, { namespace: "rp_claims", key: "approved_at", valueType: "datetime", value: "2026-06-09T09:30", }, ], }, }), ], consents: [ { subject: "user-1", userName: "Alice", clientId: "client-consent", clientName: "Consent app", grantedScopes: ["openid", "profile"], authenticatedAt: "2026-03-03T08:00:00.000Z", createdAt: "2026-03-02T08:00:00.000Z", status: "active", tenantId: "tenant-a", tenantName: "Tenant A", rpMetadata: { approvalLevel: "A", approvalLevel_permissions: { readPermission: "admin_only", writePermission: "admin_only", }, }, }, ] as Consent[], auditLogsByCursor: undefined, }; await installDevApiMock(page, state); await page.goto("/clients/client-consent/consents"); await expect(page.getByText("Alice")).toBeVisible(); await expect(page.getByText("Tenant A")).toBeVisible(); await expect(page.getByText(/approvalLevel:\s*A/)).toBeVisible(); await page.getByRole("button", { name: /Claims|Claim/i }).click(); await expect(page.getByText("RP Custom Claims")).toBeVisible(); await expect(page.getByText("contract_date")).toBeVisible(); await expect(page.getByText("approved_at")).toBeVisible(); await expect(page.locator('input[type="date"]')).toHaveValue("2026-06-09"); await page.locator('input[type="date"]').fill("2026-06-10"); await page.locator('input[type="datetime-local"]').fill("2026-06-09T10:30"); await page .getByLabel(/쓰기 권한|Write permission/i) .first() .selectOption("user_and_admin"); await page.getByRole("button", { name: /Claim 저장|Save Claim/i }).click(); await expect .poll(() => state.consents[0]?.rpMetadata?.contract_date) .toBe("2026-06-10"); await expect .poll(() => state.consents[0]?.rpMetadata?.approved_at) .toBe("2026-06-09T10:30"); await expect .poll( () => ( state.consents[0]?.rpMetadata?.contract_date_permissions as | Record | undefined )?.writePermission, ) .toBe("user_and_admin"); await page.getByRole("button", { name: /권한 철회|철회|Revoke/i }).click(); await expect(page.getByText(/Revoked|철회/i).first()).toBeVisible(); }); });