Files
jiang13-bbs/frontend/lib/directiveBlocks.test.ts
freefire 99c0f0319d feat: 品牌裁剪弹窗/Markdown 行内短代码与详情视频块等
新增:
- BrandCropModal 品牌图裁剪弹窗 + cropImage 工具
- Markdown 行内短代码(inlineShortcodes + remark 插件)
- MdDetails 折叠块、MdVideo 视频块组件
- directiveBlocks/inlineShortcodes 测试

其它:
- 聊天后端(handler/service chat)调整
- Markdown 渲染链路、编辑器、全局样式与品牌相关面板更新
2026-10-02 01:40:06 +08:00

118 lines
4.1 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.
import assert from "node:assert/strict";
import { describe, it } from "node:test";
import {
DETAILS_DEFAULT_TITLE,
isDetailsOpen,
parseDetailsOpen,
parseVideoInput,
parseVideoLine,
splitContentSegments,
} from "./directiveBlocks.ts";
describe("parseDetailsOpen / isDetailsOpen", () => {
it("开标记整行匹配,标题缺省「点击展开」", () => {
assert.equal(isDetailsOpen("[details]"), true);
assert.equal(parseDetailsOpen("[details]"), DETAILS_DEFAULT_TITLE);
assert.equal(parseDetailsOpen("[details 点击展开看结论]"), "点击展开看结论");
assert.equal(isDetailsOpen("[details 标题] 后缀"), false);
assert.equal(isDetailsOpen("[details]"), true);
});
});
describe("parseVideoInput", () => {
it("BV 号与 B站链接", () => {
assert.deepEqual(parseVideoInput("BV1GJ411x7h7"), {
provider: "bilibili",
id: "BV1GJ411x7h7",
});
assert.deepEqual(parseVideoInput("https://www.bilibili.com/video/BV1GJ411x7h7/?p=1"), {
provider: "bilibili",
id: "BV1GJ411x7h7",
});
});
it("YouTube ID 与链接", () => {
assert.deepEqual(parseVideoInput("dQw4w9WgXcQ"), {
provider: "youtube",
id: "dQw4w9WgXcQ",
});
assert.deepEqual(parseVideoInput("https://youtu.be/dQw4w9WgXcQ"), {
provider: "youtube",
id: "dQw4w9WgXcQ",
});
assert.deepEqual(parseVideoInput("https://www.youtube.com/watch?v=dQw4w9WgXcQ"), {
provider: "youtube",
id: "dQw4w9WgXcQ",
});
});
it("非法输入返回 null", () => {
assert.equal(parseVideoInput(""), null);
assert.equal(parseVideoInput("hello world"), null);
assert.equal(parseVideoInput("https://evil.com/<script>"), null);
});
});
describe("parseVideoLine", () => {
it("整行短代码匹配且大小写不敏感", () => {
assert.deepEqual(parseVideoLine("[bilibili]BV1GJ411x7h7[/bilibili]"), {
provider: "bilibili",
id: "BV1GJ411x7h7",
});
assert.deepEqual(parseVideoLine("[BILIBILI]https://www.bilibili.com/video/BV1GJ411x7h7[/BILIBILI]"), {
provider: "bilibili",
id: "BV1GJ411x7h7",
});
assert.deepEqual(parseVideoLine("[youtube]dQw4w9WgXcQ[/youtube]"), {
provider: "youtube",
id: "dQw4w9WgXcQ",
});
});
it("标签与平台不一致或内容非法时返回 null", () => {
assert.equal(parseVideoLine("[bilibili]dQw4w9WgXcQ[/bilibili]"), null);
assert.equal(parseVideoLine("[youtube]BV1GJ411x7h7[/youtube]"), null);
assert.equal(parseVideoLine("[bilibili]随便[/bilibili]"), null);
});
});
describe("splitContentSegments: details/video", () => {
it("[details] 块拆分,正文保留 markdown", () => {
const segs = splitContentSegments(
"前文\n\n[details 结论]\n**加粗** 内容\n[/details]\n\n后文"
);
assert.deepEqual(
segs.map((s) => s.type),
["md", "details", "md"]
);
const d = segs[1];
assert.equal(d.type === "details" ? d.title : "", "结论");
assert.equal(d.type === "details" ? d.body : "", "**加粗** 内容");
});
it("details 嵌套开标签:外层按 md,内层与闭合配对(与 timeline 语义一致)", () => {
const segs = splitContentSegments("[details A]\n[details B]\n[/details]");
assert.deepEqual(segs.map((s) => s.type), ["md", "details"]);
});
it("未闭合的 details 整段按 md", () => {
const segs = splitContentSegments("正文\n\n[details A]\n没有闭合标记");
assert.deepEqual(segs.map((s) => s.type), ["md"]);
});
it("代码围栏内伪语法不拆", () => {
const segs = splitContentSegments("```\n[details 假的]\n[/details]\n```");
assert.deepEqual(segs.map((s) => s.type), ["md"]);
});
it("视频整行拆为 video 段;行内出现不拆", () => {
const segs = splitContentSegments(
"看这个:\n\n[bilibili]BV1GJ411x7h7[/bilibili]\n\n文中 [youtube]dQw4w9WgXcQ[/youtube] 不拆"
);
assert.deepEqual(
segs.map((s) => s.type),
["md", "video", "md"]
);
const v = segs[1];
assert.equal(v.type === "video" ? v.provider : "", "bilibili");
assert.equal(v.type === "video" ? v.id : "", "BV1GJ411x7h7");
});
});