Simpl-Resultat/src/services/categoryTaxonomyService.test.ts
le king fu 742aa9ec3c
All checks were successful
PR Check / rust (push) Successful in 22m44s
PR Check / frontend (push) Successful in 2m17s
PR Check / rust (pull_request) Successful in 22m4s
PR Check / frontend (pull_request) Successful in 2m15s
feat(categories): add categoryTaxonomyService + useCategoryTaxonomy hook (#116)
Source of truth for the v1 IPC taxonomy on the TS side. Loads the bundled
JSON, exposes typed helpers (findById, findByPath, getLeaves, getParentById)
used by the upcoming Guide (#117) and Migration (#121) pages.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-20 20:53:15 -04:00

102 lines
2.6 KiB
TypeScript

import { describe, it, expect, beforeEach } from "vitest";
import {
getTaxonomyV1,
findById,
findByPath,
getLeaves,
getParentById,
resetTaxonomyCache,
} from "./categoryTaxonomyService";
beforeEach(() => {
resetTaxonomyCache();
});
describe("getTaxonomyV1", () => {
it("returns version v1 with non-empty roots", () => {
const tax = getTaxonomyV1();
expect(tax.version).toBe("v1");
expect(tax.roots.length).toBeGreaterThan(0);
});
it("caches the taxonomy across calls (same reference)", () => {
const a = getTaxonomyV1();
const b = getTaxonomyV1();
expect(a).toBe(b);
});
});
describe("findById", () => {
it("finds a root-level node", () => {
const node = findById(1000);
expect(node).not.toBeNull();
expect(node?.name).toBe("Revenus");
});
it("finds a nested leaf node", () => {
const node = findById(1011);
expect(node).not.toBeNull();
expect(node?.i18n_key).toBe("categoriesSeed.revenus.emploi.paie");
});
it("returns null for an unknown id", () => {
expect(findById(99999)).toBeNull();
});
});
describe("findByPath", () => {
it("returns null for an empty path", () => {
expect(findByPath([])).toBeNull();
});
it("finds a root by single-segment path", () => {
const node = findByPath(["Revenus"]);
expect(node?.id).toBe(1000);
});
it("finds a nested leaf by multi-segment path", () => {
const node = findByPath(["Revenus", "Emploi", "Paie régulière"]);
expect(node?.id).toBe(1011);
});
it("returns null when a segment does not match", () => {
expect(findByPath(["Revenus", "Emploi", "NoSuchLeaf"])).toBeNull();
expect(findByPath(["Unknown"])).toBeNull();
});
});
describe("getLeaves", () => {
it("returns only nodes with no children", () => {
const leaves = getLeaves();
expect(leaves.length).toBeGreaterThan(0);
for (const leaf of leaves) {
expect(leaf.children.length).toBe(0);
}
});
it("includes a known leaf by id", () => {
const leaves = getLeaves();
expect(leaves.some((l) => l.id === 1011)).toBe(true);
});
});
describe("getParentById", () => {
it("returns the direct parent of a leaf", () => {
const parent = getParentById(1011);
expect(parent?.id).toBe(1010);
expect(parent?.name).toBe("Emploi");
});
it("returns the root as parent of a level-2 node", () => {
const parent = getParentById(1010);
expect(parent?.id).toBe(1000);
});
it("returns null for a root-level node", () => {
expect(getParentById(1000)).toBeNull();
});
it("returns null for an unknown id", () => {
expect(getParentById(99999)).toBeNull();
});
});