Files
BaronSSO/baron-sso/orgfront/tests/devfront-tenant-switch.spec.ts

117 lines
3.4 KiB
TypeScript

import { expect, test } from "@playwright/test";
import {
installDevApiMock,
makeClient,
seedAuth,
} from "./helpers/devfront-fixtures";
test.describe("DevFront tenant switch", () => {
const MOCK_STATE = {
clients: [makeClient("client-a", { name: "Tenant A App" })],
consents: [],
auditLogs: [],
};
test.beforeEach(async ({ page }) => {
await page.route("**/api/v1/user/me", async (route) => {
if (route.request().method() === "GET") {
await route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify({
id: "playwright-user",
email: "playwright@example.com",
name: "Playwright User",
role: "tenant_admin",
tenantId: "tenant-a",
}),
});
} else {
await route.continue();
}
});
});
test("multiple tenants: user can switch tenant context", async ({ page }) => {
// Seed an admin user
await seedAuth(page, "tenant_admin");
await installDevApiMock(page, MOCK_STATE);
// Mock API to return multiple tenants
await page.route("**/api/v1/dev/my-tenants", async (route) => {
await route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify([
{ id: "tenant-a", name: "Tenant A", slug: "tenant-a" },
{ id: "tenant-b", name: "Tenant B", slug: "tenant-b" },
]),
});
});
// Navigate to profile page
await page.goto("/profile");
// Wait for the switcher to load
const switcherHeading = page.getByText("작업 테넌트 (컨텍스트)");
await expect(switcherHeading).toBeVisible();
// Verify initial state is selected (tenant-a comes from seedAuth)
const select = page.getByRole("combobox", { name: /테넌트/i });
await expect(select).toHaveValue("tenant-a");
// Change to Tenant B
await select.selectOption("tenant-b");
// Click Save
await page.getByRole("button", { name: /저장|Save/i }).click();
// Verify success toast
await expect(page.getByText("테넌트 전환 완료").first()).toBeVisible();
// Verify localStorage was updated
const savedTenantId = await page.evaluate(() =>
window.localStorage.getItem("dev_tenant_id"),
);
expect(savedTenantId).toBe("tenant-b");
});
test("single tenant: switcher is disabled with a notice", async ({
page,
}) => {
await seedAuth(page, "tenant_admin");
// Mock API to return only ONE tenant
await page.route("**/api/v1/dev/my-tenants", async (route) => {
await route.fulfill({
status: 200,
contentType: "application/json",
body: JSON.stringify([
{ id: "tenant-a", name: "Tenant A", slug: "tenant-a" },
]),
});
});
await installDevApiMock(page, MOCK_STATE);
await page.goto("/profile");
// Wait for the switcher to load
await expect(page.getByText("작업 테넌트 (컨텍스트)")).toBeVisible();
// Verify the select is disabled
const select = page.getByRole("combobox", { name: /테넌트/i });
await expect(select).toBeDisabled();
// Verify the save button is disabled
const saveButton = page.getByRole("button", { name: /저장|Save/i });
await expect(saveButton).toBeDisabled();
// Verify the notice message
await expect(
page.getByText("단일 테넌트에 소속되어 전환할 필요가 없습니다."),
).toBeVisible();
});
});