1
0
forked from baron/baron-sso
Files
baron-sso/adminfront/src/lib/tenantTree.test.ts
2026-06-10 09:36:57 +09:00

136 lines
3.6 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { TenantSummary } from "./adminApi";
import { buildTenantFullTree } from "./tenantTree";
describe("tenantTree utility", () => {
const mockTenants: TenantSummary[] = [
{
id: "root-1",
name: "Root",
slug: "root",
type: "COMPANY",
memberCount: 10,
parentId: undefined,
description: "",
status: "active",
createdAt: "",
updatedAt: "",
},
{
id: "child-1",
name: "Child 1",
slug: "child-1",
type: "USER_GROUP",
memberCount: 5,
parentId: "root-1",
description: "",
status: "active",
createdAt: "",
updatedAt: "",
},
{
id: "grandchild-1",
name: "Grandchild 1",
slug: "grandchild-1",
type: "USER_GROUP",
memberCount: 2,
parentId: "child-1",
description: "",
status: "active",
createdAt: "",
updatedAt: "",
},
];
it("calculates recursive member counts correctly", () => {
const { currentBase } = buildTenantFullTree(mockTenants, "root-1");
expect(currentBase).not.toBeNull();
if (currentBase) {
// Direct: 10, Child: 5, Grandchild: 2 -> Total: 17
expect(currentBase.recursiveMemberCount).toBe(17);
expect(currentBase.children).toHaveLength(1);
const child = currentBase.children[0];
// Direct: 5, Grandchild: 2 -> Total: 7
expect(child.recursiveMemberCount).toBe(7);
expect(child.children).toHaveLength(1);
const grandchild = child.children[0];
// Direct: 2 -> Total: 2
expect(grandchild.recursiveMemberCount).toBe(2);
expect(grandchild.children).toHaveLength(0);
}
});
it("uses backend total member counts without double-counting children", () => {
const tenantsWithTotals: TenantSummary[] = [
{
...mockTenants[0],
memberCount: 10,
totalMemberCount: 17,
},
{
...mockTenants[1],
memberCount: 5,
totalMemberCount: 7,
},
{
...mockTenants[2],
memberCount: 2,
totalMemberCount: 2,
},
];
const { currentBase } = buildTenantFullTree(tenantsWithTotals, "root-1");
expect(currentBase?.recursiveMemberCount).toBe(17);
expect(currentBase?.children[0]?.recursiveMemberCount).toBe(7);
expect(currentBase?.children[0]?.children[0]?.recursiveMemberCount).toBe(2);
});
it("keeps total member counts when descendants are not loaded on the current page", () => {
const { currentBase } = buildTenantFullTree(
[
{
...mockTenants[0],
memberCount: 10,
totalMemberCount: 17,
},
],
"root-1",
);
expect(currentBase?.recursiveMemberCount).toBe(17);
expect(currentBase?.children).toHaveLength(0);
});
it("returns null currentBase if rootId is not found", () => {
const { currentBase } = buildTenantFullTree(mockTenants, "non-existent");
expect(currentBase).toBeNull();
});
it("builds correct structure with multiple roots", () => {
const multiRootTenants: TenantSummary[] = [
...mockTenants,
{
id: "root-2",
name: "Root 2",
slug: "root-2",
type: "COMPANY",
memberCount: 3,
parentId: undefined,
description: "",
status: "active",
createdAt: "",
updatedAt: "",
},
];
const { subTree } = buildTenantFullTree(multiRootTenants);
expect(subTree).toHaveLength(2);
expect(subTree.map((n) => n.id)).toContain("root-1");
expect(subTree.map((n) => n.id)).toContain("root-2");
});
});