1
0
forked from baron/baron-sso

feat: improve Worksmobile tenant sync handling

This commit is contained in:
2026-06-02 18:05:36 +09:00
parent d6d39ca300
commit d32ca69eee
58 changed files with 4035 additions and 1400 deletions

View File

@@ -3,179 +3,237 @@ import type { TenantSummary, UserSummary } from "../../lib/adminApi";
import { buildOrgPickerTree } from "./pickerTree";
function tenant(
id: string,
type: string,
name: string,
slug: string,
parentId?: string,
id: string,
type: string,
name: string,
slug: string,
parentId?: string,
): TenantSummary {
return {
id,
type,
name,
slug,
description: "",
status: "active",
parentId,
memberCount: 0,
createdAt: "2026-05-11T00:00:00.000Z",
updatedAt: "2026-05-11T00:00:00.000Z",
};
return {
id,
type,
name,
slug,
description: "",
status: "active",
parentId,
memberCount: 0,
createdAt: "2026-05-11T00:00:00.000Z",
updatedAt: "2026-05-11T00:00:00.000Z",
};
}
describe("buildOrgPickerTree", () => {
it("uses the hanmac-family company-group as the default picker root", () => {
const tenants = [
tenant("wrong-group", "COMPANY_GROUP", "Wrong Group", "wrong-group"),
tenant(
"wrong-company",
"COMPANY",
"Wrong Company",
"wrong-company",
"wrong-group",
),
tenant("hanmac-family-id", "COMPANY_GROUP", "한맥가족", "hanmac-family"),
tenant("saman-id", "COMPANY", "삼안", "saman", "hanmac-family-id"),
];
it("uses the hanmac-family company-group as the default picker root", () => {
const tenants = [
tenant(
"wrong-group",
"COMPANY_GROUP",
"Wrong Group",
"wrong-group",
),
tenant(
"wrong-company",
"COMPANY",
"Wrong Company",
"wrong-company",
"wrong-group",
),
tenant(
"hanmac-family-id",
"COMPANY_GROUP",
"한맥가족",
"hanmac-family",
),
tenant("saman-id", "COMPANY", "삼안", "saman", "hanmac-family-id"),
];
const tree = buildOrgPickerTree({
tenants,
users: [] satisfies UserSummary[],
const tree = buildOrgPickerTree({
tenants,
users: [] satisfies UserSummary[],
});
expect(tree.companyGroupId).toBe("hanmac-family-id");
expect(tree.roots).toHaveLength(1);
expect(tree.roots[0]?.id).toBe("hanmac-family-id");
expect(tree.roots[0]?.children.map((node) => node.id)).toEqual([
"saman-id",
]);
});
expect(tree.companyGroupId).toBe("hanmac-family-id");
expect(tree.roots).toHaveLength(1);
expect(tree.roots[0]?.id).toBe("hanmac-family-id");
expect(tree.roots[0]?.children.map((node) => node.id)).toEqual([
"saman-id",
]);
});
it("orders hanmac-family children by the shared organization policy", () => {
const tenants = [
tenant(
"hanmac-family-id",
"COMPANY_GROUP",
"한맥가족",
"hanmac-family",
),
tenant(
"baron-group-id",
"COMPANY_GROUP",
"바론그룹",
"baron-group",
"hanmac-family-id",
),
tenant(
"hanmac-id",
"COMPANY",
"한맥기술",
"hanmac",
"hanmac-family-id",
),
tenant(
"halla-id",
"COMPANY",
"한라산업개발",
"halla",
"hanmac-family-id",
),
tenant("saman-id", "COMPANY", "삼안", "saman", "hanmac-family-id"),
tenant(
"gpdtdc-id",
"ORGANIZATION",
"총괄기획&기술개발센터",
"gpdtdc",
"hanmac-family-id",
),
];
it("orders hanmac-family children by the shared organization policy", () => {
const tenants = [
tenant("hanmac-family-id", "COMPANY_GROUP", "한맥가족", "hanmac-family"),
tenant(
"baron-group-id",
"COMPANY_GROUP",
"바론그룹",
"baron-group",
"hanmac-family-id",
),
tenant("hanmac-id", "COMPANY", "한맥기술", "hanmac", "hanmac-family-id"),
tenant("saman-id", "COMPANY", "삼안", "saman", "hanmac-family-id"),
tenant(
"gpdtdc-id",
"ORGANIZATION",
"총괄기획&기술개발센터",
"gpdtdc",
"hanmac-family-id",
),
];
const tree = buildOrgPickerTree({
tenants,
users: [] satisfies UserSummary[],
});
const tree = buildOrgPickerTree({
tenants,
users: [] satisfies UserSummary[],
expect(tree.roots[0]?.children.map((node) => node.name)).toEqual([
"총괄기획&기술개발센터",
"삼안",
"한맥기술",
"바론그룹",
"한라산업개발",
]);
});
expect(tree.roots[0]?.children.map((node) => node.name)).toEqual([
"총괄기획&기술개발센터",
"삼안",
"한맥기술",
"바론그룹",
]);
});
it("scopes descendant filtering by tenant slug", () => {
const tenants = [
tenant(
"hanmac-family-id",
"COMPANY_GROUP",
"한맥가족",
"hanmac-family",
),
tenant("saman-id", "COMPANY", "삼안", "saman", "hanmac-family-id"),
tenant(
"planning-id",
"ORGANIZATION",
"기획팀",
"planning",
"saman-id",
),
tenant(
"hanmac-id",
"COMPANY",
"한맥기술",
"hanmac",
"hanmac-family-id",
),
];
it("scopes descendant filtering by tenant slug", () => {
const tenants = [
tenant("hanmac-family-id", "COMPANY_GROUP", "한맥가족", "hanmac-family"),
tenant("saman-id", "COMPANY", "삼안", "saman", "hanmac-family-id"),
tenant("planning-id", "ORGANIZATION", "기획팀", "planning", "saman-id"),
tenant("hanmac-id", "COMPANY", "한맥기술", "hanmac", "hanmac-family-id"),
];
const tree = buildOrgPickerTree({
tenants,
users: [] satisfies UserSummary[],
tenantId: "saman",
});
const tree = buildOrgPickerTree({
tenants,
users: [] satisfies UserSummary[],
tenantId: "saman",
expect(tree.roots).toHaveLength(1);
expect(tree.roots[0]?.id).toBe("saman-id");
expect(tree.roots[0]?.children.map((node) => node.id)).toEqual([
"planning-id",
]);
});
expect(tree.roots).toHaveLength(1);
expect(tree.roots[0]?.id).toBe("saman-id");
expect(tree.roots[0]?.children.map((node) => node.id)).toEqual([
"planning-id",
]);
});
it("excludes internal and private tenants from picker choices by default", () => {
const tenants = [
tenant(
"hanmac-family-id",
"COMPANY_GROUP",
"한맥가족",
"hanmac-family",
),
tenant("saman-id", "COMPANY", "삼안", "saman", "hanmac-family-id"),
{
...tenant(
"internal-id",
"ORGANIZATION",
"내부 조직",
"internal",
"saman-id",
),
config: { visibility: "internal" },
},
{
...tenant(
"secret-id",
"ORGANIZATION",
"비공개 조직",
"secret",
"saman-id",
),
config: { visibility: "private" },
},
tenant(
"secret-child-id",
"USER_GROUP",
"비공개 하위",
"secret-child",
"secret-id",
),
tenant("open-id", "ORGANIZATION", "공개 조직", "open", "saman-id"),
];
it("excludes internal and private tenants from picker choices by default", () => {
const tenants = [
tenant("hanmac-family-id", "COMPANY_GROUP", "한맥가족", "hanmac-family"),
tenant("saman-id", "COMPANY", "삼안", "saman", "hanmac-family-id"),
{
...tenant(
"internal-id",
"ORGANIZATION",
"내부 조직",
"internal",
"saman-id",
),
config: { visibility: "internal" },
},
{
...tenant(
"secret-id",
"ORGANIZATION",
"비공개 조직",
"secret",
"saman-id",
),
config: { visibility: "private" },
},
tenant(
"secret-child-id",
"USER_GROUP",
"비공개 하위",
"secret-child",
"secret-id",
),
tenant("open-id", "ORGANIZATION", "공개 조직", "open", "saman-id"),
];
const tree = buildOrgPickerTree({
tenants,
users: [] satisfies UserSummary[],
tenantId: "saman",
});
const tree = buildOrgPickerTree({
tenants,
users: [] satisfies UserSummary[],
tenantId: "saman",
expect(tree.roots[0]?.children.map((node) => node.id)).toEqual([
"open-id",
]);
});
expect(tree.roots[0]?.children.map((node) => node.id)).toEqual(["open-id"]);
});
it("includes internal tenants when explicitly requested", () => {
const tenants = [
tenant(
"hanmac-family-id",
"COMPANY_GROUP",
"한맥가족",
"hanmac-family",
),
tenant("saman-id", "COMPANY", "삼안", "saman", "hanmac-family-id"),
{
...tenant(
"internal-id",
"ORGANIZATION",
"내부 조직",
"internal",
"saman-id",
),
config: { visibility: "internal" },
},
tenant("open-id", "ORGANIZATION", "공개 조직", "open", "saman-id"),
];
it("includes internal tenants when explicitly requested", () => {
const tenants = [
tenant("hanmac-family-id", "COMPANY_GROUP", "한맥가족", "hanmac-family"),
tenant("saman-id", "COMPANY", "삼안", "saman", "hanmac-family-id"),
{
...tenant(
"internal-id",
"ORGANIZATION",
"내부 조직",
"internal",
"saman-id",
),
config: { visibility: "internal" },
},
tenant("open-id", "ORGANIZATION", "공개 조직", "open", "saman-id"),
];
const tree = buildOrgPickerTree({
includeInternal: true,
tenants,
users: [] satisfies UserSummary[],
tenantId: "saman",
});
const tree = buildOrgPickerTree({
includeInternal: true,
tenants,
users: [] satisfies UserSummary[],
tenantId: "saman",
expect(tree.roots[0]?.children.map((node) => node.id)).toEqual([
"internal-id",
"open-id",
]);
});
expect(tree.roots[0]?.children.map((node) => node.id)).toEqual([
"internal-id",
"open-id",
]);
});
});