forked from baron/baron-sso
테넌트 목록 조회 cursor기반으로 재구성. 사용자 metadata 미사용 필드 제거
This commit is contained in:
@@ -105,6 +105,197 @@ test.describe("Tenants Management", () => {
|
||||
expect(headerWhiteSpace.every((value) => value === "nowrap")).toBe(true);
|
||||
});
|
||||
|
||||
test("should virtualize large tenant lists and load next pages automatically", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.setViewportSize({ width: 900, height: 700 });
|
||||
let requestCount = 0;
|
||||
|
||||
await page.route("**/api/v1/admin/tenants**", async (route) => {
|
||||
if (route.request().method() !== "GET") {
|
||||
return route.continue();
|
||||
}
|
||||
const url = new URL(route.request().url());
|
||||
const cursor = url.searchParams.get("cursor");
|
||||
requestCount += 1;
|
||||
|
||||
if (!cursor) {
|
||||
return route.fulfill({
|
||||
json: {
|
||||
items: Array.from({ length: 500 }, (_, index) => ({
|
||||
id: `tenant-${String(index + 1).padStart(3, "0")}`,
|
||||
name: `Tenant ${String(index + 1).padStart(3, "0")}`,
|
||||
slug: `tenant-${String(index + 1).padStart(3, "0")}`,
|
||||
status: "active",
|
||||
type: "COMPANY",
|
||||
memberCount: 0,
|
||||
updatedAt: new Date().toISOString(),
|
||||
})),
|
||||
total: 501,
|
||||
limit: 500,
|
||||
offset: 0,
|
||||
nextCursor: "next-page",
|
||||
},
|
||||
headers: { "Access-Control-Allow-Origin": "*" },
|
||||
});
|
||||
}
|
||||
|
||||
return route.fulfill({
|
||||
json: {
|
||||
items: [
|
||||
{
|
||||
id: "tenant-501",
|
||||
name: "Tenant 501",
|
||||
slug: "tenant-501",
|
||||
status: "active",
|
||||
type: "COMPANY",
|
||||
memberCount: 0,
|
||||
updatedAt: new Date().toISOString(),
|
||||
},
|
||||
],
|
||||
total: 501,
|
||||
limit: 500,
|
||||
offset: 0,
|
||||
},
|
||||
headers: { "Access-Control-Allow-Origin": "*" },
|
||||
});
|
||||
});
|
||||
|
||||
await page.goto("/tenants");
|
||||
|
||||
await expect(page.getByText("총 501개 테넌트")).toBeVisible();
|
||||
await expect(page.getByRole("button", { name: "더 불러오기" })).toHaveCount(
|
||||
0,
|
||||
);
|
||||
|
||||
await expect
|
||||
.poll(async () => page.locator("tbody tr").count())
|
||||
.toBeLessThan(80);
|
||||
|
||||
const tableScroller = page.getByTestId("tenant-table-scroll");
|
||||
await tableScroller.evaluate((element) => {
|
||||
element.scrollTop = element.scrollHeight;
|
||||
element.dispatchEvent(new Event("scroll", { bubbles: true }));
|
||||
});
|
||||
|
||||
await expect.poll(() => requestCount).toBe(2);
|
||||
await tableScroller.evaluate((element) => {
|
||||
element.scrollTop = element.scrollHeight;
|
||||
element.dispatchEvent(new Event("scroll", { bubbles: true }));
|
||||
});
|
||||
await expect(page.getByText("Tenant 501")).toBeVisible();
|
||||
expect(requestCount).toBe(2);
|
||||
});
|
||||
|
||||
test("should hide Hanmac family subtree from external tenant admins", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.route(/.*\/api\/v1\/user\/me$/, async (route) => {
|
||||
return route.fulfill({
|
||||
json: {
|
||||
id: "external-admin",
|
||||
name: "External Admin",
|
||||
role: "tenant_admin",
|
||||
tenantId: "external-tenant-id",
|
||||
tenantSlug: "external-tenant",
|
||||
tenant: {
|
||||
id: "external-tenant-id",
|
||||
slug: "external-tenant",
|
||||
name: "External Tenant",
|
||||
type: "COMPANY",
|
||||
},
|
||||
manageableTenants: [
|
||||
{
|
||||
id: "external-tenant-id",
|
||||
slug: "external-tenant",
|
||||
name: "External Tenant",
|
||||
type: "COMPANY",
|
||||
},
|
||||
{
|
||||
id: "external-team-id",
|
||||
slug: "external-team",
|
||||
name: "External Team",
|
||||
type: "USER_GROUP",
|
||||
parentId: "external-tenant-id",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
await page.route("**/api/v1/admin/tenants**", async (route) => {
|
||||
if (route.request().method() !== "GET") {
|
||||
await route.continue();
|
||||
return;
|
||||
}
|
||||
|
||||
await route.fulfill({
|
||||
json: {
|
||||
items: [
|
||||
{
|
||||
id: "hanmac-family-id",
|
||||
slug: "hanmac-family",
|
||||
name: "한맥가족",
|
||||
status: "active",
|
||||
type: "COMPANY_GROUP",
|
||||
memberCount: 0,
|
||||
},
|
||||
{
|
||||
id: "hanmac-company-id",
|
||||
slug: "hanmac-company",
|
||||
name: "한맥기술",
|
||||
status: "active",
|
||||
type: "COMPANY",
|
||||
parentId: "hanmac-family-id",
|
||||
memberCount: 0,
|
||||
},
|
||||
{
|
||||
id: "hanmac-team-id",
|
||||
slug: "hanmac-team",
|
||||
name: "한맥팀",
|
||||
status: "active",
|
||||
type: "USER_GROUP",
|
||||
parentId: "hanmac-company-id",
|
||||
memberCount: 0,
|
||||
},
|
||||
{
|
||||
id: "external-tenant-id",
|
||||
slug: "external-tenant",
|
||||
name: "External Tenant",
|
||||
status: "active",
|
||||
type: "COMPANY",
|
||||
memberCount: 0,
|
||||
},
|
||||
{
|
||||
id: "external-team-id",
|
||||
slug: "external-team",
|
||||
name: "External Team",
|
||||
status: "active",
|
||||
type: "USER_GROUP",
|
||||
parentId: "external-tenant-id",
|
||||
memberCount: 0,
|
||||
},
|
||||
],
|
||||
total: 5,
|
||||
limit: 1000,
|
||||
offset: 0,
|
||||
},
|
||||
headers: { "Access-Control-Allow-Origin": "*" },
|
||||
});
|
||||
});
|
||||
|
||||
await page.goto("/tenants");
|
||||
await expect(page.locator("h2").last()).toContainText(
|
||||
/테넌트 목록|Tenants/i,
|
||||
{ timeout: 20000 },
|
||||
);
|
||||
await expect(page.locator("table")).toContainText("External Tenant");
|
||||
await expect(page.locator("table")).toContainText("External Team");
|
||||
await expect(page.locator("table")).not.toContainText("한맥가족");
|
||||
await expect(page.locator("table")).not.toContainText("한맥기술");
|
||||
await expect(page.locator("table")).not.toContainText("한맥팀");
|
||||
});
|
||||
|
||||
test("should create a new tenant", async ({ page }) => {
|
||||
await page.goto("/tenants/new");
|
||||
await expect(page.locator("h2").last()).toContainText(/추가|Create/i, {
|
||||
|
||||
Reference in New Issue
Block a user