forked from baron/baron-sso
164 lines
4.3 KiB
TypeScript
164 lines
4.3 KiB
TypeScript
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
|
|
import { describe, expect, it, vi } from "vitest";
|
|
import type { TenantSummary } from "../../../lib/adminApi";
|
|
import { ParentTenantSelector } from "./ParentTenantSelector";
|
|
|
|
const tenants: TenantSummary[] = [
|
|
{
|
|
id: "company-1",
|
|
type: "COMPANY",
|
|
name: "Saman Engineering",
|
|
slug: "saman",
|
|
description: "",
|
|
status: "active",
|
|
memberCount: 0,
|
|
createdAt: "",
|
|
updatedAt: "",
|
|
},
|
|
{
|
|
id: "group-1",
|
|
type: "COMPANY_GROUP",
|
|
name: "Hanmac Family",
|
|
slug: "hanmac-family",
|
|
description: "",
|
|
status: "active",
|
|
memberCount: 0,
|
|
createdAt: "",
|
|
updatedAt: "",
|
|
},
|
|
];
|
|
|
|
describe("ParentTenantSelector picker", () => {
|
|
it("opens an org-chart picker modal and applies tenant selection messages", async () => {
|
|
const onChange = vi.fn();
|
|
|
|
render(
|
|
<ParentTenantSelector
|
|
id="parentId"
|
|
label="상위 테넌트"
|
|
value=""
|
|
onChange={onChange}
|
|
tenants={tenants}
|
|
noneLabel="없음"
|
|
/>,
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: /테넌트 선택/ }));
|
|
|
|
expect(screen.getByRole("dialog")).toBeInTheDocument();
|
|
const pickerSrc = screen
|
|
.getByTestId("parent-tenant-picker-frame")
|
|
.getAttribute("src");
|
|
expect(pickerSrc).toContain("http://localhost:5175/login");
|
|
expect(decodeURIComponent(pickerSrc ?? "")).toContain("/embed/picker");
|
|
|
|
fireEvent(
|
|
window,
|
|
new MessageEvent("message", {
|
|
data: {
|
|
type: "orgfront:picker:confirm",
|
|
payload: {
|
|
selections: [
|
|
{
|
|
type: "tenant",
|
|
id: "company-1",
|
|
name: "Saman Engineering",
|
|
},
|
|
],
|
|
},
|
|
},
|
|
}),
|
|
);
|
|
|
|
await waitFor(() => expect(onChange).toHaveBeenCalledWith("company-1"));
|
|
});
|
|
|
|
it("scopes the org-chart picker to the requested tenant root", () => {
|
|
const onChange = vi.fn();
|
|
|
|
render(
|
|
<ParentTenantSelector
|
|
id="parentId"
|
|
label="상위 테넌트"
|
|
value=""
|
|
onChange={onChange}
|
|
tenants={tenants}
|
|
noneLabel="없음"
|
|
orgChartTenantId="group-1"
|
|
orgChartPickerLabel="한맥가족에서 선택"
|
|
/>,
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: "한맥가족에서 선택" }));
|
|
|
|
const pickerSrc = screen
|
|
.getByTestId("parent-tenant-picker-frame")
|
|
.getAttribute("src");
|
|
expect(decodeURIComponent(pickerSrc ?? "")).toContain("tenantId=group-1");
|
|
});
|
|
|
|
it("keeps the current tenant out of picker message selections", async () => {
|
|
const onChange = vi.fn();
|
|
|
|
render(
|
|
<ParentTenantSelector
|
|
id="parentId"
|
|
label="상위 테넌트"
|
|
value=""
|
|
onChange={onChange}
|
|
tenants={tenants}
|
|
noneLabel="없음"
|
|
excludeTenantId="company-1"
|
|
/>,
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: /테넌트 선택/ }));
|
|
fireEvent(
|
|
window,
|
|
new MessageEvent("message", {
|
|
data: {
|
|
type: "orgfront:picker:confirm",
|
|
payload: {
|
|
selections: [
|
|
{
|
|
type: "tenant",
|
|
id: "company-1",
|
|
name: "Saman Engineering",
|
|
},
|
|
],
|
|
},
|
|
},
|
|
}),
|
|
);
|
|
|
|
await waitFor(() => expect(onChange).not.toHaveBeenCalled());
|
|
});
|
|
|
|
it("selects a non-hanmac parent from the local tenant picker", async () => {
|
|
const onChange = vi.fn();
|
|
|
|
render(
|
|
<ParentTenantSelector
|
|
id="parentId"
|
|
label="상위 테넌트"
|
|
value=""
|
|
onChange={onChange}
|
|
tenants={tenants}
|
|
noneLabel="없음"
|
|
orgChartPickerLabel="한맥가족에서 선택"
|
|
localPickerLabel="다른 테넌트 선택"
|
|
localTenantFilter={(tenant) => tenant.slug !== "hanmac-family"}
|
|
/>,
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: "다른 테넌트 선택" }));
|
|
fireEvent.change(
|
|
screen.getByPlaceholderText("테넌트 이름 또는 슬러그 검색"),
|
|
{ target: { value: "saman" } },
|
|
);
|
|
fireEvent.click(screen.getByRole("button", { name: /Saman Engineering/ }));
|
|
|
|
expect(onChange).toHaveBeenCalledWith("company-1");
|
|
});
|
|
});
|