import { expect, test } from "@playwright/test"; test.describe("Tenant Owners Management", () => { test.beforeEach(async ({ page }) => { // Authenticate await page.addInitScript(() => { const authority = "http://localhost:5000/oidc"; const client_id = "adminfront"; const key = `oidc.user:${authority}:${client_id}`; const authData = { access_token: "fake-token", token_type: "Bearer", profile: { sub: "admin-user", name: "Admin User", email: "admin@example.com", }, expires_at: Math.floor(Date.now() / 1000) + 3600, }; window.localStorage.setItem(key, JSON.stringify(authData)); }); // Mock OIDC config to avoid redirects await page.route( "**/oidc/.well-known/openid-configuration", async (route) => { await route.fulfill({ json: { issuer: "http://localhost:5000/oidc" } }); }, ); // Mock user profile await page.route("**/api/v1/user/me", async (route) => { await route.fulfill({ json: { id: "admin-user", name: "Admin User", email: "admin@example.com", role: "super_admin", }, }); }); // Mock tenant details await page.route("**/api/v1/admin/tenants/tenant-1**", async (route) => { await route.fulfill({ json: { id: "tenant-1", name: "Test Tenant", slug: "test-tenant", status: "active", type: "COMPANY", }, }); }); }); test("should list tenant owners", async ({ page }) => { // Mock owners list await page.route( "**/api/v1/admin/tenants/tenant-1/owners**", async (route) => { await route.fulfill({ json: [ { id: "owner-1", name: "Owner One", email: "owner1@example.com" }, ], }); }, ); // Mock admins list (empty) await page.route( "**/api/v1/admin/tenants/tenant-1/admins**", async (route) => { await route.fulfill({ json: [] }); }, ); await page.goto("/tenants/tenant-1/permissions"); // Check if the page title and the owner are visible await expect(page.getByText("테넌트 소유자")).toBeVisible(); await expect(page.locator("table").first()).toContainText("Owner One"); await expect(page.locator("table").first()).toContainText( "owner1@example.com", ); }); test("should add a new owner", async ({ page }) => { // Mock owners list (initially empty) await page.route( "**/api/v1/admin/tenants/tenant-1/owners**", async (route) => { if (route.request().method() === "GET") { await route.fulfill({ json: [] }); } else if (route.request().method() === "POST") { await route.fulfill({ status: 200 }); } }, ); // Mock admins list (empty) await page.route( "**/api/v1/admin/tenants/tenant-1/admins**", async (route) => { await route.fulfill({ json: [] }); }, ); // Mock users search await page.route("**/api/v1/admin/users?**", async (route) => { await route.fulfill({ json: { items: [ { id: "user-2", name: "User Two", email: "user2@example.com" }, ], total: 1, }, }); }); await page.goto("/tenants/tenant-1/permissions"); // Click add button await page.click('button:has-text("소유자 추가")'); // Search for user await page.fill('input[placeholder*="사용자 검색"]', "User Two"); // Wait for results and add - using a more specific selector to target the button in the dialog const addButton = page .locator("role=dialog") .getByRole("button", { name: "추가" }); await addButton.click(); // Verify toast or mutation (in a real app, the list would refresh) // Here we just check if the dialog was closed or toast appears // toast is shown on success }); });