import { expect, test } from "@playwright/test"; import { type Consent, installDevApiMock, makeClient, seedAuth, } from "./helpers/devfront-fixtures"; test.describe("DevFront security and isolation", () => { test.beforeEach(async ({ page }) => { page.on("dialog", async (dialog) => { await dialog.accept(); }); await seedAuth(page); }); test("tenant isolation: forbidden client shows blocked error", async ({ page, }) => { const state = { clients: [makeClient("tenant-a-client", { name: "Tenant A app" })], consents: [] as Consent[], auditLogsByCursor: undefined, }; await installDevApiMock(page, state); await page.goto("/clients/tenant-b-client"); await expect(page.getByText(/Error loading client|조회/i)).toBeVisible(); }); test("RBAC: non-AppManager user should not see private apps", async ({ page, }) => { const state = { clients: [ makeClient("pkce-client", { name: "PKCE only app", type: "pkce", }), ], consents: [] as Consent[], auditLogsByCursor: undefined, }; await installDevApiMock(page, state); await page.goto("/clients"); await expect(page.getByText("PKCE only app")).toBeVisible(); await expect(page.getByText("Server side App")).not.toBeVisible(); }); test("tenant_member user is blocked at AuthGuard", async ({ page }) => { await seedAuth(page, "tenant_member"); await page.goto("/clients"); await expect( page.getByText(/DevFront는 관리자 전용 화면입니다|administrator access/i), ).toBeVisible(); await expect(page).toHaveURL(/\/clients$/); }); });