69 lines
2.8 KiB
TypeScript
69 lines
2.8 KiB
TypeScript
import React from "react";
|
|
import { activeNavItemTo, activeNavTo, type NavItem } from "./layout/AppShell";
|
|
|
|
// Route ownership under test (the real sidebar entries):
|
|
// /career -> Career Workspace
|
|
// /career/builder -> CV Builder
|
|
// A child route must activate exactly one nav item — the most specific owner.
|
|
const TOS = ["/dashboard", "/jobs", "/career", "/career/builder", "/settings"];
|
|
|
|
describe("sidebar active nav ownership", () => {
|
|
test("/career activates Career Workspace only", () => {
|
|
expect(activeNavTo("/career", TOS)).toBe("/career");
|
|
});
|
|
|
|
test("/career/builder activates CV Builder only, not Career Workspace", () => {
|
|
expect(activeNavTo("/career/builder", TOS)).toBe("/career/builder");
|
|
});
|
|
|
|
test("/career/builder/{id} activates CV Builder only (the reported bug)", () => {
|
|
// Previously /career matched via startsWith('/career/') AND /career/builder matched — both lit up.
|
|
expect(activeNavTo("/career/builder/42", TOS)).toBe("/career/builder");
|
|
});
|
|
|
|
test("a plain child of /career (not /builder) still belongs to Career Workspace", () => {
|
|
expect(activeNavTo("/career/anything-else", TOS)).toBe("/career");
|
|
});
|
|
|
|
test("unrelated routes are unaffected and exact matches win", () => {
|
|
expect(activeNavTo("/jobs", TOS)).toBe("/jobs");
|
|
expect(activeNavTo("/settings/connected-accounts", TOS)).toBe("/settings");
|
|
});
|
|
|
|
test("a path owned by no nav item activates nothing", () => {
|
|
expect(activeNavTo("/admin/system", TOS)).toBeNull();
|
|
});
|
|
|
|
test("exactly one item is ever active (no double highlight)", () => {
|
|
for (const path of ["/career", "/career/builder", "/career/builder/7", "/jobs"]) {
|
|
const active = activeNavTo(path, TOS);
|
|
const matches = TOS.filter((t) => t === active);
|
|
expect(matches).toHaveLength(1);
|
|
}
|
|
});
|
|
});
|
|
|
|
describe("grouped sidebar ownership", () => {
|
|
const items: NavItem[] = [
|
|
{ to: "/jobs", activeFor: ["/applications"], label: "Jobs", icon: React.createElement("span"), children: [
|
|
{ to: "/kanban", label: "Board", icon: React.createElement("span") },
|
|
{ to: "/trash", label: "Trash", icon: React.createElement("span") },
|
|
] },
|
|
{ to: "/career", label: "Career profile", icon: React.createElement("span") },
|
|
{ to: "/career/builder", label: "CVs", icon: React.createElement("span") },
|
|
];
|
|
|
|
test("non-nested Jobs destinations select their actual secondary owner", () => {
|
|
expect(activeNavItemTo("/kanban", items)).toBe("/kanban");
|
|
expect(activeNavItemTo("/trash", items)).toBe("/trash");
|
|
});
|
|
|
|
test("legacy application details retain Jobs ownership", () => {
|
|
expect(activeNavItemTo("/applications/42", items)).toBe("/jobs");
|
|
});
|
|
|
|
test("CV editor routes never select Career Profile", () => {
|
|
expect(activeNavItemTo("/career/builder/42", items)).toBe("/career/builder");
|
|
});
|
|
});
|