mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-11-13 06:31:47 +00:00
* feat(frontend): improve file attachment recovery and artifact presentation * feat(extensions): add Office artifact previews with search and navigation * fix: preserve public viewers and HTTP Office previews * fix: address file preview and upload review findings * fix: use typed upload errors and linear bookmark allocation * fix(office-preview): isolate parsing and bound preview resources * fix(ci): install Office preview fixture dependencies for E2E * fix(ci): provision matching Playwright browsers before E2E tests * fix(ci): isolate Python libraries and include Office documentation * test(frontend): wait for download status to finish rendering
66 lines
2.6 KiB
JavaScript
66 lines
2.6 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import { WorkerXmlParser } from "../ui/worker-xml.js";
|
|
import { checkModelBudget, transferBuffers } from "../ui/document-model.js";
|
|
import { wordView } from "../ui/word-view.js";
|
|
|
|
test("worker XML preserves namespace, descendant and escaped-prefix selectors", () => {
|
|
const doc = new WorkerXmlParser().parseFromString(
|
|
'<p:root xmlns:p="urn:p" xmlns:a="urn:a"><p:spPr/><a:lstStyle><a:defRPr><a:solidFill/></a:defRPr></a:lstStyle></p:root>',
|
|
"application/xml",
|
|
);
|
|
assert.equal(doc.querySelector("p\\:spPr, spPr").namespaceURI, "urn:p");
|
|
assert.equal(doc.querySelector("*|lstStyle *|defRPr").localName, "defRPr");
|
|
assert.equal(doc.querySelectorAll("*|solidFill").length, 1);
|
|
assert.equal(doc.firstElementChild, doc.documentElement);
|
|
assert.throws(() => doc.querySelector("div > span"), /unsupported/i);
|
|
});
|
|
test("parser output budgets reject amplified arrays and strings before transfer", () => {
|
|
assert.throws(() => checkModelBudget({ nodes: new Array(100001) }), /limit/i);
|
|
assert.throws(
|
|
() => checkModelBudget({ html: "x".repeat(17 * 1024 * 1024) }),
|
|
/limit/i,
|
|
);
|
|
const bytes = new Uint8Array(10);
|
|
const model = { bytes, again: bytes.subarray(1) };
|
|
model.self = model;
|
|
assert.deepEqual(transferBuffers(model), [bytes.buffer]);
|
|
assert.doesNotThrow(() => checkModelBudget(model));
|
|
});
|
|
test("Word resource facade resolves headers and images, deduplicates URLs and revokes on disposal", async () => {
|
|
const image = new Uint8Array([0x89, 0x50]);
|
|
const rel = { id: "image", type: "image", target: "media/image.png" };
|
|
const body = { path: "word/document.xml", rels: [rel] };
|
|
const header = {
|
|
path: "word/header.xml",
|
|
rels: [rel],
|
|
rootElement: { type: "header" },
|
|
};
|
|
body.rels.push(
|
|
{ id: "header", target: "header.xml" },
|
|
{
|
|
id: "external",
|
|
target: "https://invalid.test/image.png",
|
|
targetMode: "External",
|
|
},
|
|
);
|
|
const view = wordView({
|
|
word: {
|
|
documentPart: body,
|
|
partsMap: { "word/header.xml": header },
|
|
rels: [],
|
|
},
|
|
images: { "word/media/image.png": image },
|
|
});
|
|
assert.equal(view.document.findPartByRelId("header", body), header);
|
|
const first = await view.document.loadDocumentImage("image");
|
|
assert.ok(first.startsWith("blob:"));
|
|
assert.equal(await view.document.loadDocumentImage("image", header), first);
|
|
assert.equal(await view.document.loadDocumentImage("external"), null);
|
|
assert.equal((await fetch(first)).status, 200);
|
|
view.dispose();
|
|
view.dispose();
|
|
assert.equal(await view.document.loadDocumentImage("image"), null);
|
|
await assert.rejects(fetch(first));
|
|
});
|