文件
hyb-oa/client/tests/e2e/management-navigation-contract.spec.ts
T
wangsli 9bc83eb6c0
ci-e2e / e2e (push) Canceled after 0s
ci-minimal / check-minimal (push) Canceled after 0s
test(management-navigation-single-company-ux): 锁定父子路由权限包含关系
2026-08-03 13:10:49 +08:00

136 行
5.1 KiB
TypeScript

import { expect, test } from "@playwright/test";
import {
getVisibleManagementItems,
getManagementRoutePermissions,
isKnownManagementPath,
isManagementPath,
MANAGEMENT_ROOT_PERMISSIONS,
MANAGEMENT_ROUTES,
resolveManagementBreadcrumbs,
resolveManagementRoute,
} from "../../src/features/navigation/managementRoutes";
import { resolvePageMeta } from "../../src/features/navigation/schema";
import {
filterRecentVisitsByPermissions,
type RecentVisit,
} from "../../src/lib/recentVisits";
import { resolveSingleCompanyState } from "../../src/features/company/singleCompany";
const REGISTERED_MANAGEMENT_PATHS = [
"/system/settings",
"/people",
"/people/stats",
"/people/:employeeId",
"/organization",
"/system/users",
"/system/departments",
"/system/approval-rules",
"/system/workflow-definitions",
"/system/expense-standards",
"/system/reimbursement-templates",
"/system/workspace",
"/audit-logs",
"/system/master-data",
"/system/payment-accounts",
"/system/notification-channels",
"/system/feature-flags",
"/system/announcements",
"/system/cutover",
"/performance",
];
test("管理路由注册表覆盖路径、父级、权限和聚合入口合同", () => {
expect(MANAGEMENT_ROUTES.map((route) => route.path)).toEqual(REGISTERED_MANAGEMENT_PATHS);
expect(new Set(MANAGEMENT_ROUTES.map((route) => route.key)).size).toBe(MANAGEMENT_ROUTES.length);
const keys = new Set(MANAGEMENT_ROUTES.map((route) => route.key));
const routesByKey = new Map(MANAGEMENT_ROUTES.map((route) => [route.key, route]));
for (const route of MANAGEMENT_ROUTES) {
expect(route.title.trim()).not.toBe("");
expect(route.anyOf.length).toBeGreaterThan(0);
if (route.parentKey) {
expect(keys.has(route.parentKey)).toBe(true);
const parent = routesByKey.get(route.parentKey)!;
expect(
route.anyOf.every((permission) => parent.anyOf.includes(permission)),
`${route.key} 的权限必须包含在父节点 ${parent.key} 的权限中`,
).toBe(true);
}
if (route.showOnLanding) {
expect(route.group).not.toBeNull();
expect(route.icon.trim()).not.toBe("");
expect(route.description.trim()).not.toBe("");
}
const ancestors = new Set<string>();
let cursor = route;
while (cursor.parentKey) {
expect(ancestors.has(cursor.key)).toBe(false);
ancestors.add(cursor.key);
cursor = routesByKey.get(cursor.parentKey)!;
}
}
const expectedRootPermissions = new Set(
MANAGEMENT_ROUTES.filter((route) => route.showOnLanding).flatMap((route) => route.anyOf),
);
expect(new Set(MANAGEMENT_ROOT_PERMISSIONS)).toEqual(expectedRootPermissions);
});
test("企业银行账户与人员档案按当前权限解析管理父链", () => {
const paymentPermissions = ["payment.account.read"];
expect(resolveManagementRoute("/system/payment-accounts", paymentPermissions)?.title).toBe("企业银行账户");
expect(isManagementPath("/system/payment-accounts", paymentPermissions)).toBe(true);
expect(resolveManagementBreadcrumbs("/system/payment-accounts", paymentPermissions)).toEqual([
{ key: "management", title: "管理", href: "/system/settings" },
{ key: "payment_accounts", title: "企业银行账户", href: null },
]);
const peoplePermissions = ["system.users"];
expect(getManagementRoutePermissions("employee_profile")).toEqual(peoplePermissions);
expect(resolveManagementBreadcrumbs("/people/synthetic-employee", peoplePermissions)).toEqual([
{ key: "management", title: "管理", href: "/system/settings" },
{ key: "people", title: "人员", href: "/people" },
{ key: "employee_profile", title: "员工档案", href: null },
]);
});
test("无权限路径不披露管理标题或面包屑", () => {
expect(isKnownManagementPath("/system/payment-accounts")).toBe(true);
expect(resolveManagementRoute("/system/payment-accounts", [])).toBeNull();
expect(resolveManagementBreadcrumbs("/system/payment-accounts", [])).toEqual([]);
expect(resolvePageMeta("/system/payment-accounts", [])).toEqual({ title: "管理", group: "管理" });
expect(getVisibleManagementItems([])).toEqual([]);
});
test("最近访问在权限撤销后移除受限管理标题和链接", () => {
const visits: RecentVisit[] = [
{
path: "/system/payment-accounts",
title: "企业银行账户",
visitedAt: "2026-08-03T00:00:00.000Z",
},
{
path: "/reimbursements",
title: "报销",
visitedAt: "2026-08-02T00:00:00.000Z",
},
];
expect(filterRecentVisitsByPermissions(visits, ["payment.account.read"])).toEqual(visits);
expect(filterRecentVisitsByPermissions(visits, [])).toEqual([visits[1]]);
});
test("单公司状态对零个、一个和多个启用公司采用明确且保守的分支", () => {
expect(resolveSingleCompanyState([])).toEqual({ kind: "empty" });
expect(resolveSingleCompanyState([{ id: "company-1" }])).toEqual({
kind: "single",
company: { id: "company-1" },
});
expect(resolveSingleCompanyState([{ id: "company-1" }, { id: "company-2" }])).toEqual({
kind: "multiple",
companies: [{ id: "company-1" }, { id: "company-2" }],
});
});