Files
WRNexusJS/packages/block-editor/test/download.test.ts
T

76 lines
2.1 KiB
TypeScript

import { expect, test } from "bun:test";
import { readFileSync } from "node:fs";
const source = new Bun.Transpiler({ loader: "ts" })
.transformSync(readFileSync(new URL("../src/download.ts", import.meta.url), "utf8"))
.replace("export function", "function");
test("download keeps direct link after blocked automatic click and releases replaced/detached blobs", () => {
const revoked: string[] = [],
observers: Array<{ callback(): void; disconnect(): void }> = [];
let sequence = 0,
clicks = 0,
disconnected = 0;
const links: any[] = [];
const outlet = {
replaceChildren: (link: unknown) => {
links.splice(0, links.length, link);
},
};
const host = {
isConnected: true,
querySelector: () => outlet,
ownerDocument: {
documentElement: {},
createElement: () => ({
href: "",
download: "",
textContent: "",
click() {
clicks++;
throw new Error("blocked");
},
remove() {
const index = links.indexOf(this);
if (index >= 0) links.splice(index, 1);
},
}),
},
};
const offer = new Function(
"URL",
"Blob",
"MutationObserver",
source + ";return offerBuilderDownload;",
)(
{
createObjectURL: () => `blob:${++sequence}`,
revokeObjectURL: (url: string) => revoked.push(url),
},
Blob,
class {
constructor(public callback: () => void) {
observers.push(this);
}
observe() {}
disconnect() {
disconnected++;
}
},
);
offer(host, "html", "text/html", "draft.html");
expect(links[0].href).toBe("blob:1");
expect(links[0].download).toBe("draft.html");
expect(revoked).toEqual([]);
expect(clicks).toBe(1);
offer(host, "text", "text/plain", "draft.txt");
expect(revoked).toEqual(["blob:1"]);
expect(links[0].download).toBe("draft.txt");
host.isConnected = false;
observers[1]!.callback();
observers[1]!.callback();
expect(revoked).toEqual(["blob:1", "blob:2"]);
expect(links).toEqual([]);
expect(disconnected).toBe(2);
});