forked from baron/baron-sso
136 lines
3.6 KiB
TypeScript
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");
|
|
});
|
|
});
|