Files
YschcmsFront/src/__tests__/siteRouter.spec.ts
T
chenxing 6f1f666479
build / build (push) Successful in 4m47s
周末修订
2026-09-15 23:41:11 +08:00

99 lines
4.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// @vitest-environment jsdom
/**
* docs/13 方案 C 复检:真实 vue-router 集成(docs/15 §3 T1/T4)。
* siteLayer.spec.ts 全程 router 桩(vi.mock vue-router),覆盖不到镜像层真实匹配与守卫重定向,
* 本文件装载 routes.ts 全量路由 + router/index.ts 守卫补位:
* ① 路由结构:/site/{code} 无 component 镜像层存在、镜像去 name、meta.modId 保留、空段 redirect 兜底;
* ② 镜像层真实 resolve 命中(渲染层由 router-view 对无 component 记录跳过推进,此处验匹配链);
* ③ 守卫:子站编码当学校段 → 定向主站前缀且余部原样保留(含站点段),并恢复学校上下文;
* ④ legacyRedirect 旧链带 id 重定向。
*/
import { beforeEach, describe, expect, it } from "vitest";
import { createPinia, setActivePinia } from "pinia";
import { useCmsStore } from "@/store";
import router from "@/router";
import { routes } from "@/router/routes";
const SITES = [
{ id: 1, code: "demo", name: "云海大学门户", parentSiteId: 0, schId: 1001, schName: "云海大学" },
{ id: 2, code: "jdxy", name: "机电学院", parentSiteId: 1, schId: 1001, schName: "云海大学" },
];
let store: ReturnType<typeof useCmsStore>;
beforeEach(() => {
localStorage.clear();
const pinia = createPinia();
setActivePinia(pinia);
store = useCmsStore(pinia);
store.user = { superAdmin: true, sites: SITES } as any;
});
describe("docs/13 路由结构(真实 routes 数组,docs/15 T1)", () => {
it("① /site/{code} 无 component 镜像层存在;镜像去 name、meta.modId 保留、空段 redirect 到 article", () => {
const sch = routes.find(r => r.path === "/sch/:schCode")!;
const siteLayer = sch.children!.find(r => r.path === "site/:siteCode") as any;
expect(siteLayer).toBeTruthy();
expect(siteLayer.component).toBeUndefined();
expect(siteLayer.children![0].path).toBe("");
expect(siteLayer.children![0].redirect).toBeTruthy();
const mirror = siteLayer.children!.find((c: any) => c.path === "category");
expect(mirror!.name).toBeUndefined();
expect((mirror!.meta as any).modId).toBe(2);
});
it("①b 主站清单与镜像层不重名(防重复注册告警)", () => {
expect(router.getRoutes().filter(r => r.name === "CategoryManage")).toHaveLength(1);
expect(router.getRoutes().filter(r => r.name === "ArticleList")).toHaveLength(1);
});
it("② 子站 URL 真实 resolve 命中镜像记录;主站 URL 命中主记录", () => {
const sub = router.resolve("/sch/demo/site/jdxy/category");
expect(sub.matched).toHaveLength(3);
expect(sub.name).toBeUndefined();
expect(sub.meta.modId).toBe(2);
const main = router.resolve("/sch/demo/category");
expect(main.matched).toHaveLength(2);
expect(main.name).toBe("CategoryManage");
});
it("②c 事项库路由已随 V2.0 拆分移除(svc/item、svc/dict 不再注册,直达落入 404 重定向)", () => {
// 事项管理能力已迁独立办事大厅(svc-hall 应用);CMS 前端仅保留展示壳,
// 旧菜单路径由 UserBase 停用 + 通配重定向兜底。
const item = router.resolve("/sch/demo/svc/item");
expect(item.name).toBeUndefined();
});
});
describe("docs/13 守卫与旧链兼容(真实 router.push,docs/15 T4)", () => {
it("③ 子站编码当学校段 → 重定向主站前缀(余部保留)并恢复学校上下文", async () => {
await router.push("/sch/jdxy/article");
expect(router.currentRoute.value.path).toBe("/sch/demo/article");
expect(store.currentSchool?.mainSiteCode).toBe("demo");
});
it("③b 子站编码当学校段且 URL 已带站点段 → 站点段原样保留", async () => {
await router.push("/sch/jdxy/site/jdxy/category");
expect(router.currentRoute.value.path).toBe("/sch/demo/site/jdxy/category");
expect(router.currentRoute.value.params.siteCode).toBe("jdxy");
});
it("③c 学校编码不在用户可管理站点内 → 回工作台", async () => {
await router.push("/sch/other-school/article");
expect(router.currentRoute.value.path).toBe("/workbench");
});
it("④ 旧链 /article/edit/:id → 当前学校上下文主站形态(id 后缀保留)", async () => {
store.currentSchool = {
schId: 1001,
schName: "云海大学",
mainSiteId: 1,
mainSiteCode: "demo",
mainSiteName: "云海大学门户",
} as any;
await router.push("/article/edit/9");
expect(router.currentRoute.value.path).toBe("/sch/demo/article/edit/9");
});
});