import { expect, test } from "@playwright/test"; import { type ClientRelation, type Consent, installDevApiMock, makeClient, seedAuth, } from "./helpers/devfront-fixtures"; import { captureEvidence } from "./helpers/evidence"; test.describe("DevFront relationships", () => { 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, "rp_admin"); }); test("list add and remove direct RP relationships", async ({ page }) => { const state = { clients: [makeClient("client-rel", { name: "Relations app" })], consents: [] as Consent[], users: [ { id: "user-2", name: "홍길동", email: "hong@example.com", loginId: "hong01", }, ], relations: { "client-rel": [ { relation: "admins", subject: "User:playwright-user", subjectType: "User", subjectId: "playwright-user", userName: "Playwright User", userEmail: "playwright@example.com", }, { relation: "config_editor", subject: "User:user-1", subjectType: "User", subjectId: "user-1", userName: "기존 사용자", userEmail: "existing@example.com", }, ] satisfies ClientRelation[], }, auditLogsByCursor: undefined, }; await installDevApiMock(page, state); await page.goto("/clients/client-rel/relationships"); await expect(page.getByText("클라이언트 관계")).toBeVisible(); await expect( page.getByRole("heading", { name: "관계 추가" }), ).toBeVisible(); await expect( page.getByRole("heading", { name: "부여된 관계" }), ).toBeVisible(); await expect(page.getByText("기존 사용자")).toBeVisible(); await expect(page.getByText("User:user-1")).toBeVisible(); await page.getByLabel(/^사용자$/).fill("홍길동"); await page.getByRole("button", { name: /홍길동/ }).click(); await page.getByLabel(/시크릿 재발급/).check(); await page.getByLabel(/동의 조회/).check(); await page.getByRole("button", { name: /^추가$/ }).click(); await expect( page.locator("tr").filter({ hasText: "User:user-2" }).first(), ).toBeVisible(); await expect.poll(() => state.relations["client-rel"]?.length ?? 0).toBe(4); await page .locator("tr") .filter({ hasText: "User:user-2" }) .getByRole("button", { name: /Delete|삭제/i }) .first() .click(); await expect .poll( () => state.relations["client-rel"]?.filter( (item) => item.subject === "User:user-2", ).length ?? 0, ) .toBe(1); }); test("super_admin can add RP relationships even when profile role is missing", async ({ page, }) => { await seedAuth(page); await page.addInitScript(() => { window.localStorage.setItem("dev_role", "super_admin"); }); const state = { clients: [makeClient("client-rel", { name: "Relations app" })], consents: [] as Consent[], users: [ { id: "user-2", name: "홍길동", email: "hong@example.com", loginId: "hong01", }, ], relations: { "client-rel": [ { relation: "admins", subject: "User:playwright-user", subjectType: "User", subjectId: "playwright-user", userName: "Playwright User", userEmail: "playwright@example.com", }, ] satisfies ClientRelation[], }, auditLogsByCursor: undefined, }; await installDevApiMock(page, state); await page.goto("/clients/client-rel/relationships"); await expect(page.getByText("클라이언트 관계")).toBeVisible(); await page.getByLabel(/^사용자$/).fill("홍길동"); await page.getByRole("button", { name: /홍길동/ }).click(); await page.getByLabel(/시크릿 재발급/).check(); await expect(page.getByRole("button", { name: /^추가$/ })).toBeEnabled(); }); });