import assert from "node:assert/strict"; import { describe, it } from "node:test"; import { announcementPath, entityPath, leaderboardPath, matchPrettyPath, matchStandardPath, normalizeUrlStyle, pagePath, parseEntityPath, postPath, userPath, } from "./urlStyle.ts"; describe("normalizeUrlStyle", () => { it("合法值与容错", () => { assert.equal(normalizeUrlStyle("default"), "default"); assert.equal(normalizeUrlStyle(" HTML "), "html"); assert.equal(normalizeUrlStyle("DISCUZ"), "discuz"); assert.equal(normalizeUrlStyle("pretty"), "default"); assert.equal(normalizeUrlStyle(undefined), "default"); assert.equal(normalizeUrlStyle(42), "default"); }); }); describe("路径构造器", () => { it("三风格帖子路径", () => { assert.equal(postPath("default", 123), "/post/123"); assert.equal(postPath("html", 123), "/post-123.html"); assert.equal(postPath("discuz", 123), "/thread-123.html"); }); it("三风格用户路径", () => { assert.equal(userPath("default", 5), "/u/5"); assert.equal(userPath("html", 5), "/user-5.html"); assert.equal(userPath("discuz", 5), "/space-uid-5.html"); }); it("三风格公告路径", () => { assert.equal(announcementPath("default", 1), "/announcement/1"); assert.equal(announcementPath("html", 1), "/announcement-1.html"); assert.equal(announcementPath("discuz", 1), "/notice-1.html"); }); it("非法 id 返回空串", () => { assert.equal(postPath("default", 0), ""); assert.equal(postPath("html", -1), ""); assert.equal(userPath("discuz", Number.NaN), ""); }); it("自建页三风格并编码 slug", () => { assert.equal(pagePath("default", "about"), "/p/about"); assert.equal(pagePath("html", "about"), "/p-about.html"); assert.equal(pagePath("discuz", "使用指南"), `/page-${encodeURIComponent("使用指南")}.html`); assert.equal(pagePath("html", "使用指南"), `/p-${encodeURIComponent("使用指南")}.html`); assert.equal(pagePath("default", " "), "/p/"); }); it("排行榜三风格", () => { assert.equal(leaderboardPath("default"), "/leaderboard"); assert.equal(leaderboardPath("html"), "/leaderboard.html"); assert.equal(leaderboardPath("discuz"), "/rank.html"); }); it("entityPath 与标准路径", () => { assert.equal(entityPath("discuz", "post", 9), "/thread-9.html"); assert.equal(entityPath("default", "user", 9), "/u/9"); assert.equal(entityPath("html", "announcement", 9), "/announcement-9.html"); }); }); describe("matchPrettyPath", () => { it("命中各风格模板", () => { assert.deepEqual(matchPrettyPath("/post-12.html"), { style: "html", kind: "post", id: 12 }); assert.deepEqual(matchPrettyPath("/user-3.html"), { style: "html", kind: "user", id: 3 }); assert.deepEqual(matchPrettyPath("/announcement-7.html"), { style: "html", kind: "announcement", id: 7 }); assert.deepEqual(matchPrettyPath("/thread-12.html"), { style: "discuz", kind: "post", id: 12 }); assert.deepEqual(matchPrettyPath("/space-uid-3.html"), { style: "discuz", kind: "user", id: 3 }); assert.deepEqual(matchPrettyPath("/notice-7.html"), { style: "discuz", kind: "announcement", id: 7 }); assert.deepEqual(matchPrettyPath("/p-about.html"), { style: "html", kind: "page", slug: "about" }); assert.deepEqual(matchPrettyPath("/leaderboard.html"), { style: "html", kind: "leaderboard" }); assert.deepEqual(matchPrettyPath("/rank.html"), { style: "discuz", kind: "leaderboard" }); }); it("page slug 保持 encoded 原样", () => { const enc = encodeURIComponent("使用指南"); assert.deepEqual(matchPrettyPath(`/page-${enc}.html`), { style: "discuz", kind: "page", slug: enc }); assert.deepEqual(matchPrettyPath(`/p-${enc}.html`), { style: "html", kind: "page", slug: enc }); }); it("排除子路径与伪造路径", () => { assert.equal(matchPrettyPath("/post/12"), null); assert.equal(matchPrettyPath("/post/12/edit"), null); assert.equal(matchPrettyPath("/post-abc.html"), null); assert.equal(matchPrettyPath("/thread-12.htmlx"), null); assert.equal(matchPrettyPath("/thread-12.html/edit"), null); assert.equal(matchPrettyPath("/thread--12.html"), null); assert.equal(matchPrettyPath("/post.html"), null); assert.equal(matchPrettyPath("/p-.html"), null); assert.equal(matchPrettyPath("/leaderboardx.html"), null); assert.equal(matchPrettyPath("/rank.htmlx"), null); assert.equal(matchPrettyPath("/rank"), null); }); }); describe("matchStandardPath / parseEntityPath", () => { it("标准路径精确匹配", () => { assert.deepEqual(matchStandardPath("/post/12"), { kind: "post", id: 12 }); assert.deepEqual(matchStandardPath("/u/5"), { kind: "user", id: 5 }); assert.deepEqual(matchStandardPath("/announcement/7"), { kind: "announcement", id: 7 }); assert.deepEqual(matchStandardPath("/p/about"), { kind: "page", slug: "about" }); assert.deepEqual(matchStandardPath("/leaderboard"), { kind: "leaderboard" }); assert.deepEqual(matchStandardPath("/leaderboard/"), { kind: "leaderboard" }); assert.equal(matchStandardPath("/post/12/edit"), null); assert.equal(matchStandardPath("/post/abc"), null); assert.equal(matchStandardPath("/u/5/followers"), null); assert.equal(matchStandardPath("/p/"), null); assert.equal(matchStandardPath("/p/a/b"), null); }); it("parseEntityPath 兼容标准与全部模板", () => { assert.deepEqual(parseEntityPath("/post/12"), { kind: "post", id: 12 }); assert.deepEqual(parseEntityPath("/thread-12.html"), { kind: "post", id: 12 }); assert.deepEqual(parseEntityPath("/post-12.html"), { kind: "post", id: 12 }); assert.deepEqual(parseEntityPath("/space-uid-5.html"), { kind: "user", id: 5 }); assert.deepEqual(parseEntityPath("/p/about"), { kind: "page", slug: "about" }); assert.deepEqual(parseEntityPath("/p-about.html"), { kind: "page", slug: "about" }); assert.deepEqual(parseEntityPath(`/page-${encodeURIComponent("使用指南")}.html`), { kind: "page", slug: "使用指南", }); assert.deepEqual(parseEntityPath("/rank.html"), { kind: "leaderboard" }); assert.equal(parseEntityPath("/chat/5"), null); assert.equal(parseEntityPath("/"), null); }); });