diff --git a/devfront/tests/devfront-role-switch-report.spec.ts b/devfront/tests/devfront-role-switch-report.spec.ts index b42dbe25..c4e0a1c3 100644 --- a/devfront/tests/devfront-role-switch-report.spec.ts +++ b/devfront/tests/devfront-role-switch-report.spec.ts @@ -17,7 +17,7 @@ test.describe("DevFront role report", () => { }); }); - test("user(tenant_member) can enter and sees empty RP list", async ({ + test("user can enter and sees empty RP list", async ({ page, }, testInfo) => { await seedAuth(page, "user"); @@ -66,6 +66,40 @@ test.describe("DevFront role report", () => { await captureEvidence(page, testInfo, "role-user-overview-request-entry"); }); + test("user with approved developer request sees overview without CTA", async ({ + page, + }, testInfo) => { + await seedAuth(page, "user"); + await installDevApiMock(page, { + clients: [], + consents: [] as Consent[], + auditLogs: [] as AuditLog[], + auditLogsByCursor: undefined, + developerRequests: [ + { + id: "req-approved", + userId: "playwright-user", + userName: "Playwright User", + name: "Playwright User", + userEmail: "playwright@example.com", + organization: "Tenant A", + reason: "Need access", + status: "approved", + createdAt: "2026-05-29T00:00:00.000Z", + updatedAt: "2026-05-29T00:00:00.000Z", + approvedAt: "2026-05-29T00:10:00.000Z", + }, + ], + }); + + await page.goto("/"); + await expect(page.getByRole("heading", { name: /운영 현황/ })).toBeVisible(); + await expect( + page.getByRole("button", { name: /개발자 권한 신청/ }), + ).toHaveCount(0); + await captureEvidence(page, testInfo, "role-user-overview-approved"); + }); + test("rp_admin sees only assigned Gitea app and its logs", async ({ page, }, testInfo) => { @@ -93,8 +127,12 @@ test.describe("DevFront role report", () => { await installDevApiMock(page, state); await page.goto("/clients"); - await expect(page.getByRole("link", { name: /Gitea/ })).toBeVisible(); - await expect(page.getByText("gitea-client")).toBeVisible(); + await expect( + page.getByRole("link", { name: "Gitea", exact: true }), + ).toBeVisible(); + await expect( + page.getByRole("cell", { name: "gitea-client" }), + ).toBeVisible(); await captureEvidence(page, testInfo, "role-rp-admin-clients"); await page.goto("/audit-logs"); diff --git a/devfront/tests/devfront-security.spec.ts b/devfront/tests/devfront-security.spec.ts index b993e557..d62eac18 100644 --- a/devfront/tests/devfront-security.spec.ts +++ b/devfront/tests/devfront-security.spec.ts @@ -137,4 +137,82 @@ test.describe("DevFront security and isolation", () => { page.getByText(/테넌트 관리자 권한|Tenant administrator permissions/i), ).toBeVisible(); }); + + test("user sees audit log access CTA when access is blocked", async ({ + page, + }, testInfo) => { + await seedAuth(page, "user"); + + const state = { + clients: [] as ReturnType[], + consents: [] as Consent[], + auditLogsByCursor: undefined, + developerRequests: [], + }; + await installDevApiMock(page, state); + + await page.goto("/audit-logs"); + await expect(page.getByRole("heading", { name: /감사 로그|Audit Logs/ })).toBeVisible(); + await expect( + page.getByText(/감사 로그는 개발자 권한이 있어야 볼 수 있습니다|Audit logs are available only to users with developer access/i), + ).toBeVisible(); + const requestBtn = page.getByRole("button", { + name: /개발자 권한 신청/, + }); + await expect(requestBtn).toBeVisible(); + await requestBtn.click(); + await expect(page).toHaveURL(/\/developer-requests$/); + await captureEvidence(page, testInfo, "security-user-audit-request-entry"); + }); + + test("user with approved developer request can enter audit logs without CTA", async ({ + page, + }, testInfo) => { + await seedAuth(page, "user"); + + const state = { + clients: [] as ReturnType[], + consents: [] as Consent[], + auditLogs: [ + { + event_id: "evt-audit-1", + timestamp: "2026-05-29T00:00:00.000Z", + user_id: "playwright-user", + event_type: "CLIENT_UPDATE", + status: "success" as const, + ip_address: "127.0.0.1", + user_agent: "playwright", + details: JSON.stringify({ + action: "UPDATE_CLIENT", + target_id: "tenant-a-client", + tenant_id: "tenant-a", + }), + }, + ], + auditLogsByCursor: undefined, + developerRequests: [ + { + id: "req-approved", + userId: "playwright-user", + userName: "Playwright User", + name: "Playwright User", + userEmail: "playwright@example.com", + organization: "Tenant A", + reason: "Need access", + status: "approved", + createdAt: "2026-05-29T00:00:00.000Z", + updatedAt: "2026-05-29T00:10:00.000Z", + approvedAt: "2026-05-29T00:10:00.000Z", + }, + ], + }; + await installDevApiMock(page, state); + + await page.goto("/audit-logs"); + await expect(page.getByText("UPDATE_CLIENT")).toBeVisible(); + await expect( + page.getByRole("button", { name: /개발자 권한 신청/ }), + ).toHaveCount(0); + await captureEvidence(page, testInfo, "security-user-audit-approved"); + }); });