forked from baron/baron-sso
chore: snapshot local state before dev merge
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import { expect, test } from "@playwright/test";
|
||||
import { captureEvidence } from "./helpers/evidence";
|
||||
|
||||
function tenant(
|
||||
id: string,
|
||||
@@ -31,6 +32,12 @@ function user(id: string, name: string, companyCode: string) {
|
||||
role: "user",
|
||||
status: "active",
|
||||
companyCode,
|
||||
tenant: {
|
||||
id: companyCode,
|
||||
slug: companyCode,
|
||||
type: "USER_GROUP",
|
||||
name: companyCode,
|
||||
},
|
||||
grade: "사원",
|
||||
createdAt: "2026-04-01T00:00:00.000Z",
|
||||
updatedAt: "2026-04-01T00:00:00.000Z",
|
||||
@@ -333,6 +340,139 @@ test("org chart orders managers before top executive members by rank priority",
|
||||
]);
|
||||
});
|
||||
|
||||
test("org chart renders an IS3 super admin when an org appointment exists", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.route("**/api/v1/public/orgchart**", async (route) => {
|
||||
await route.fulfill({
|
||||
contentType: "application/json",
|
||||
body: JSON.stringify({
|
||||
sharedWith: "Playwright",
|
||||
tenants: [
|
||||
tenant("hanmac-family", "한맥가족", "hanmac-family"),
|
||||
tenant(
|
||||
"gpdtdc",
|
||||
"총괄기획&기술개발센터",
|
||||
"gpdtdc",
|
||||
"hanmac-family",
|
||||
"COMPANY",
|
||||
),
|
||||
tenant("gpd", "총괄기획실", "gpd", "gpdtdc", "ORGANIZATION"),
|
||||
tenant(
|
||||
"intigrated-system",
|
||||
"통합시스템",
|
||||
"intigrated-system",
|
||||
"gpd",
|
||||
"ORGANIZATION",
|
||||
{ visibility: "public", orgUnitType: "디비전" },
|
||||
),
|
||||
tenant("is-3", "IS3", "is-3", "intigrated-system", "ORGANIZATION", {
|
||||
visibility: "public",
|
||||
orgUnitType: "팀",
|
||||
}),
|
||||
],
|
||||
users: [
|
||||
{
|
||||
id: "675a3d46-45ad-4e8c-8c22-959a38302826",
|
||||
email: "cyhan@samaneng.com",
|
||||
name: "한치영",
|
||||
role: "super_admin",
|
||||
status: "active",
|
||||
tenantSlug: "is-3",
|
||||
companyCode: "is-3",
|
||||
tenant: undefined,
|
||||
grade: "",
|
||||
metadata: {
|
||||
additionalAppointments: [
|
||||
{
|
||||
grade: "책임",
|
||||
isManager: true,
|
||||
isPrimary: true,
|
||||
tenantId: "is-3",
|
||||
tenantName: "IS3",
|
||||
tenantSlug: "is-3",
|
||||
},
|
||||
],
|
||||
},
|
||||
createdAt: "2026-06-16T00:00:00.000Z",
|
||||
updatedAt: "2026-06-16T00:00:00.000Z",
|
||||
},
|
||||
{
|
||||
...user("is3-executive", "상위직급", "is-3"),
|
||||
grade: "전무이사",
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
await page.goto("/chart?token=is3-manager");
|
||||
|
||||
const is3Node = page.locator('[data-testid="orgchart-node-is-3"]');
|
||||
await expect(is3Node).toBeVisible();
|
||||
await expect(
|
||||
is3Node.locator(
|
||||
'[data-testid="orgchart-member-675a3d46-45ad-4e8c-8c22-959a38302826"]',
|
||||
),
|
||||
).toContainText("한치영 책임");
|
||||
await expect(
|
||||
is3Node.locator('[data-testid="orgchart-member-is3-executive"]'),
|
||||
).toContainText("상위직급 전무");
|
||||
|
||||
const orderedMemberIds = await is3Node
|
||||
.locator('[data-testid^="orgchart-member-"]')
|
||||
.evaluateAll((elements) =>
|
||||
elements.map((element) => element.getAttribute("data-testid")),
|
||||
);
|
||||
|
||||
expect(orderedMemberIds).toEqual([
|
||||
"orgchart-member-675a3d46-45ad-4e8c-8c22-959a38302826",
|
||||
"orgchart-member-is3-executive",
|
||||
]);
|
||||
});
|
||||
|
||||
test("org chart ignores stale scalar org fields without a membership source", async ({
|
||||
page,
|
||||
}) => {
|
||||
await page.route("**/api/v1/public/orgchart**", async (route) => {
|
||||
await route.fulfill({
|
||||
contentType: "application/json",
|
||||
body: JSON.stringify({
|
||||
sharedWith: "Playwright",
|
||||
tenants: [
|
||||
tenant("hanmac-family", "한맥가족", "hanmac-family"),
|
||||
tenant("is-1", "IS1", "is-1", "hanmac-family", "ORGANIZATION"),
|
||||
tenant("is-2", "IS2", "is-2", "hanmac-family", "ORGANIZATION"),
|
||||
tenant("is-3", "IS3", "is-3", "hanmac-family", "ORGANIZATION"),
|
||||
],
|
||||
users: [
|
||||
{
|
||||
id: "stale-system-admin",
|
||||
email: "stale-system-admin@example.com",
|
||||
name: "Stale System Admin",
|
||||
role: "system_admin",
|
||||
status: "active",
|
||||
tenantSlug: "is-2",
|
||||
companyCode: "is-1",
|
||||
tenant: undefined,
|
||||
joinedTenants: undefined,
|
||||
metadata: { additionalAppointments: [] },
|
||||
grade: "사원",
|
||||
createdAt: "2026-06-16T00:00:00.000Z",
|
||||
updatedAt: "2026-06-16T00:00:00.000Z",
|
||||
},
|
||||
],
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
await page.goto("/chart?token=stale-scalar");
|
||||
|
||||
await expect(
|
||||
page.locator('[data-testid="orgchart-member-stale-system-admin"]'),
|
||||
).toHaveCount(0);
|
||||
});
|
||||
|
||||
test("org chart expands organization node width so long names are not clipped", async ({
|
||||
page,
|
||||
}) => {
|
||||
@@ -551,17 +691,31 @@ test("org chart places multi-tenant users only on leaf memberships without dupli
|
||||
|
||||
test("org chart allows a user in a hanmac-family descendant tenant", async ({
|
||||
page,
|
||||
}) => {
|
||||
}, testInfo) => {
|
||||
await page.setViewportSize({ width: 1600, height: 900 });
|
||||
let snapshotRequests = 0;
|
||||
await page.addInitScript(() => {
|
||||
window.localStorage.setItem("playwright_auth_bypass", "1");
|
||||
window.localStorage.setItem("dev_tenant_id", "saman-id");
|
||||
});
|
||||
|
||||
await page.route("**/api/v1/admin/orgchart/snapshot**", async (route) => {
|
||||
snapshotRequests += 1;
|
||||
const url = new URL(route.request().url());
|
||||
expect(route.request().headers()["x-tenant-id"]).toBe("saman-id");
|
||||
expect(url.searchParams.get("cache")).toBe("redis");
|
||||
if (snapshotRequests === 1) {
|
||||
expect(url.searchParams.get("refresh")).toBeNull();
|
||||
} else {
|
||||
expect(url.searchParams.get("refresh")).toBe("true");
|
||||
}
|
||||
await route.fulfill({
|
||||
contentType: "application/json",
|
||||
body: JSON.stringify({
|
||||
generatedAt:
|
||||
snapshotRequests === 1
|
||||
? "2026-06-17T07:10:11Z"
|
||||
: "2026-06-17T08:20:21Z",
|
||||
tenants: [
|
||||
tenant(
|
||||
"hanmac-family-id",
|
||||
@@ -607,10 +761,63 @@ test("org chart allows a user in a hanmac-family descendant tenant", async ({
|
||||
await expect(
|
||||
page.getByRole("button", { name: "조직: 한맥가족" }),
|
||||
).toBeVisible();
|
||||
await expect(page.getByTestId("orgchart-selection-status-panel")).toHaveCount(
|
||||
0,
|
||||
);
|
||||
await expect(page.getByTestId("orgchart-render-status-panel")).toHaveText(
|
||||
"2026-06-17 16:10:11 KST",
|
||||
);
|
||||
await expect(
|
||||
page.getByTestId("orgchart-render-status-panel"),
|
||||
).not.toContainText("데이터 기준");
|
||||
const headerBox = await page.getByTestId("orgfront-topbar").boundingBox();
|
||||
const viewportWidth = page.viewportSize()?.width ?? 1600;
|
||||
const statusPanelBox = await page
|
||||
.getByTestId("orgchart-render-status-panel")
|
||||
.boundingBox();
|
||||
expect(headerBox).not.toBeNull();
|
||||
expect(statusPanelBox).not.toBeNull();
|
||||
expect(
|
||||
viewportWidth - ((statusPanelBox?.x ?? 0) + (statusPanelBox?.width ?? 0)),
|
||||
).toBeLessThanOrEqual(20);
|
||||
expect(
|
||||
(headerBox?.y ?? 0) +
|
||||
(headerBox?.height ?? 0) -
|
||||
((statusPanelBox?.y ?? 0) + (statusPanelBox?.height ?? 0)),
|
||||
).toBeLessThanOrEqual(6);
|
||||
await expect(page.getByTestId("orgchart-render-status-panel")).toHaveCSS(
|
||||
"border-top-width",
|
||||
"0px",
|
||||
);
|
||||
await expect(page.getByTestId("orgchart-render-status-panel")).toHaveCSS(
|
||||
"box-shadow",
|
||||
"none",
|
||||
);
|
||||
await expect(page.getByTestId("orgchart-render-status-panel")).toHaveCSS(
|
||||
"background-color",
|
||||
"rgba(0, 0, 0, 0)",
|
||||
);
|
||||
await expect(page.getByTestId("orgchart-render-status-panel")).toHaveCSS(
|
||||
"opacity",
|
||||
"0.72",
|
||||
);
|
||||
await expect(page.getByRole("button", { name: "새로고침" })).toHaveCSS(
|
||||
"background-color",
|
||||
"rgba(0, 0, 0, 0)",
|
||||
);
|
||||
await expect(page.getByRole("button", { name: "새로고침" })).toHaveCSS(
|
||||
"border-top-width",
|
||||
"0px",
|
||||
);
|
||||
await page.getByRole("button", { name: "새로고침" }).click();
|
||||
await expect(page.getByTestId("orgchart-render-status-panel")).toHaveText(
|
||||
"2026-06-17 17:20:21 KST",
|
||||
);
|
||||
const svg = page.locator('[data-testid="orgchart-vector-svg"]');
|
||||
await expect(svg.getByText("한맥가족", { exact: true })).toBeVisible();
|
||||
await expect(svg.getByText("삼안", { exact: true })).toBeVisible();
|
||||
await expect(svg.getByText(/Saman Descendant User/)).toBeVisible();
|
||||
await captureEvidence(page, testInfo, "orgchart-topbar-data-refresh-aligned");
|
||||
});
|
||||
|
||||
test("org chart logs authenticated snapshot failures with actionable diagnostics", async ({
|
||||
|
||||
Reference in New Issue
Block a user