Files
Epicnabbo-Catalogus-Updated…/src/features/housekeeping/foundation/navigation.test.ts
T

210 lines
5.4 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import { PERMS } from "@/lib/permission-slugs";
import { HOUSEKEEPING_MANIFESTS } from "../manifests";
import { anyCapability, type HousekeepingCapabilityContext } from "./contracts";
import { buildHousekeepingNavigation } from "./navigation";
import { createHousekeepingRegistry } from "./registry";
const context = (
granted: readonly string[],
): HousekeepingCapabilityContext => ({
actor: { id: 42, username: "moderator", rank: 3 },
isSuperAdmin: false,
has: (slug) => granted.includes(slug),
hasAny: (...slugs) => slugs.some((slug) => granted.includes(slug)),
hasAll: (...slugs) => slugs.every((slug) => granted.includes(slug)),
});
describe("housekeeping navigation", () => {
it("shows People to a moderator with a mod view capability while hiding Economy", () => {
const registry = createHousekeepingRegistry([
{
id: "people",
labelKey: "pages.housekeeping.domains.people.title",
descriptionKey: "pages.housekeeping.domains.people.description",
iconId: "users",
canonicalHref: "/ase/people",
capability: anyCapability(PERMS.MOD_CFH_VIEW),
routes: [],
searchProviders: [],
inboxSources: [],
widgets: [],
},
{
id: "economy",
labelKey: "pages.housekeeping.domains.economy.title",
descriptionKey: "pages.housekeeping.domains.economy.description",
iconId: "gem",
canonicalHref: "/ase/economy",
capability: anyCapability(PERMS.CATALOG_VIEW),
routes: [],
searchProviders: [],
inboxSources: [],
widgets: [],
},
]);
const navigation = buildHousekeepingNavigation(
registry,
context([PERMS.MOD_CFH_VIEW]),
"canonical",
(key) => key,
);
expect(navigation).toEqual([
{
id: "people",
href: "/ase/people",
iconId: "users",
label: "pages.housekeeping.domains.people.title",
description: "pages.housekeeping.domains.people.description",
items: [],
},
]);
});
it("filters unauthorized domains and routes before translation", () => {
const registry = createHousekeepingRegistry([
{
id: "people",
labelKey: "people.title",
descriptionKey: "people.description",
iconId: "users",
canonicalHref: "/ase/people",
capability: anyCapability(PERMS.USERS_VIEW),
routes: [
{
id: "users",
labelKey: "people.users",
href: "/ase/people/users",
capability: anyCapability(PERMS.USERS_VIEW),
},
{
id: "bans",
labelKey: "people.bans",
href: "/ase/people/bans",
capability: anyCapability(PERMS.BANS_VIEW),
},
],
searchProviders: [],
inboxSources: [],
widgets: [],
},
{
id: "system",
labelKey: "system.title",
descriptionKey: "system.description",
iconId: "settings",
canonicalHref: "/ase/system",
capability: anyCapability(PERMS.SETTINGS_VIEW),
routes: [],
searchProviders: [],
inboxSources: [],
widgets: [],
},
]);
const translate = vi.fn((key: string) => `translated:${key}`);
const navigation = buildHousekeepingNavigation(
registry,
context([PERMS.USERS_VIEW]),
"canonical",
translate,
);
expect(navigation).toEqual([
{
id: "people",
href: "/ase/people",
iconId: "users",
label: "translated:people.title",
description: "translated:people.description",
items: [
{
id: "users",
href: "/ase/people/users",
label: "translated:people.users",
},
],
},
]);
expect(translate).not.toHaveBeenCalledWith("people.bans");
expect(translate).not.toHaveBeenCalledWith("system.title");
expect(translate).not.toHaveBeenCalledWith("system.description");
});
it("shows real domains to operators authorized by owned migration capabilities", () => {
const registry = createHousekeepingRegistry(HOUSEKEEPING_MANIFESTS);
const translate = (key: string) => key;
expect(
buildHousekeepingNavigation(
registry,
context([PERMS.MOD_CFH_VIEW]),
"preview",
translate,
).map((domain) => domain.id),
).toContain("people");
expect(
buildHousekeepingNavigation(
registry,
context([PERMS.MOD_CFH_VIEW]),
"preview",
translate,
).map((domain) => domain.id),
).not.toContain("economy");
for (const [slug, expectedDomain] of [
[PERMS.MOD_ACTIONS, "people"],
[PERMS.USERS_EDIT, "people"],
[PERMS.SETTINGS_VIEW, "people"],
[PERMS.NEWS_EDIT, "content"],
[PERMS.SHOP_EDIT, "economy"],
[PERMS.ROOMS_EDIT, "hotel"],
] as const) {
const visibleDomainIds = buildHousekeepingNavigation(
registry,
context([slug]),
"preview",
translate,
).map((domain) => domain.id);
expect(visibleDomainIds, slug).toContain(expectedDomain);
}
});
});
it("maps canonical navigation hrefs onto the requested surface", () => {
const registry = createHousekeepingRegistry([
{
id: "people",
labelKey: "people.title",
descriptionKey: "people.description",
iconId: "users",
canonicalHref: "/ase/people",
capability: anyCapability(PERMS.USERS_VIEW),
routes: [
{
id: "users",
labelKey: "people.users",
href: "/ase/people/users",
capability: anyCapability(PERMS.USERS_VIEW),
},
],
searchProviders: [],
inboxSources: [],
widgets: [],
},
]);
const navigation = buildHousekeepingNavigation(
registry,
context([PERMS.USERS_VIEW]),
"preview",
(key) => key,
);
expect(navigation[0]).toMatchObject({
href: "/ase-next/people",
items: [{ href: "/ase-next/people/users" }],
});
});