feat: 实现动态 DOCX 模板与样式映射
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { zipSync } from "fflate";
|
||||
import {
|
||||
readReferenceDocxPackage,
|
||||
requiredReferenceDocxParts
|
||||
} from "../src/index.js";
|
||||
|
||||
function createReferencePackage(
|
||||
overrides: Record<string, Uint8Array> = {}
|
||||
) {
|
||||
const entries = Object.fromEntries(
|
||||
requiredReferenceDocxParts.map((name) => [
|
||||
name,
|
||||
new TextEncoder().encode(`<part name="${name}"/>`)
|
||||
])
|
||||
);
|
||||
return zipSync({ ...entries, ...overrides });
|
||||
}
|
||||
|
||||
describe("reference.docx 包", () => {
|
||||
it("预检中央目录并返回稳定指纹", () => {
|
||||
const content = createReferencePackage();
|
||||
const first = readReferenceDocxPackage(content);
|
||||
const second = readReferenceDocxPackage(content);
|
||||
|
||||
expect(first.entries.size).toBe(requiredReferenceDocxParts.length);
|
||||
expect(first.entries.has("word/styles.xml")).toBe(true);
|
||||
expect(first.fingerprint).toMatch(/^[0-9a-f]{64}$/u);
|
||||
expect(second.fingerprint).toBe(first.fingerprint);
|
||||
});
|
||||
|
||||
it("拒绝路径穿越和缺少必要部件", () => {
|
||||
expect(() =>
|
||||
readReferenceDocxPackage(
|
||||
createReferencePackage({
|
||||
"../outside.xml": new Uint8Array([1])
|
||||
})
|
||||
)
|
||||
).toThrow("不安全路径");
|
||||
|
||||
const incomplete = zipSync({
|
||||
"[Content_Types].xml": new Uint8Array([1])
|
||||
});
|
||||
expect(() => readReferenceDocxPackage(incomplete)).toThrow(
|
||||
"缺少必要部件"
|
||||
);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user