78 lines
3.5 KiB
TypeScript
78 lines
3.5 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
import { mkdirSync, writeFileSync } from "node:fs";
|
|
import { resolve } from "node:path";
|
|
|
|
import { exportResultCopy, runExportFlow } from "../../apps/web/src/export-flow.js";
|
|
|
|
function writeEvidence(file: string, value: unknown) {
|
|
const root = process.env.DADA_EVIDENCE_DIR_LATEST_EXPORTS;
|
|
if (!root) return;
|
|
const directory = resolve(root, "TDD-WP2-EXP-001-result-matrix");
|
|
mkdirSync(directory, { recursive: true });
|
|
writeFileSync(resolve(directory, file), `${JSON.stringify(value, null, 2)}\n`);
|
|
}
|
|
|
|
describe("TDD-WP2-EXP-001-result-matrix", () => {
|
|
it("uses the exact same Blob for download and latest persistence", async () => {
|
|
const blob = new Blob(["same-export"], { type: "image/png" });
|
|
const download = vi.fn(async (_value: Blob) => undefined);
|
|
const persist = vi.fn(async (_value: Blob) => undefined);
|
|
const result = await runExportFlow({ compose: async () => blob, download, persist });
|
|
|
|
expect(result.status).toBe("downloaded_and_saved");
|
|
expect(download).toHaveBeenCalledWith(blob);
|
|
expect(persist).toHaveBeenCalledWith(blob);
|
|
expect(download.mock.calls[0][0]).toBe(persist.mock.calls[0][0]);
|
|
expect(exportResultCopy[result.status]).toBe("已下载并保存为最新成品");
|
|
});
|
|
|
|
it("preserves the composed Blob for retry when browser download fails", async () => {
|
|
const blob = new Blob(["retry-export"], { type: "image/jpeg" });
|
|
const persist = vi.fn();
|
|
const result = await runExportFlow({
|
|
compose: async () => blob,
|
|
download: async () => { throw new Error("download_failed"); },
|
|
persist,
|
|
});
|
|
|
|
expect(result.status).toBe("download_failed");
|
|
expect(result.blob).toBe(blob);
|
|
expect(persist).not.toHaveBeenCalled();
|
|
expect(exportResultCopy[result.status]).toBe("浏览器下载失败,可重新下载同一次合成结果");
|
|
});
|
|
|
|
it("does not turn a successful local download into a false double success", async () => {
|
|
const result = await runExportFlow({
|
|
compose: async () => new Blob(["local-only"], { type: "image/png" }),
|
|
download: async () => undefined,
|
|
persist: async () => { throw new Error("latest_failed"); },
|
|
});
|
|
|
|
expect(result.status).toBe("downloaded_not_saved");
|
|
expect(exportResultCopy[result.status]).toBe("文件已下载,但未保存为最新成品");
|
|
});
|
|
|
|
it("does not download or persist after composition failure", async () => {
|
|
const download = vi.fn();
|
|
const persist = vi.fn();
|
|
const result = await runExportFlow({
|
|
compose: async () => { throw new Error("composition_failed"); },
|
|
download,
|
|
persist,
|
|
});
|
|
|
|
expect(result).toEqual({ blob: null, status: "composition_failed" });
|
|
expect(download).not.toHaveBeenCalled();
|
|
expect(persist).not.toHaveBeenCalled();
|
|
expect(exportResultCopy[result.status]).toBe("合成失败,请返回编辑器检查");
|
|
writeEvidence("network-timeline.json", {
|
|
composition_failed: ["compose:failed", "download:not_started", "persist:not_started"],
|
|
download_failed: ["compose:succeeded", "download:failed", "persist:not_started"],
|
|
downloaded_and_saved: ["compose:succeeded", "download:succeeded", "persist:succeeded"],
|
|
downloaded_not_saved: ["compose:succeeded", "download:succeeded", "persist:failed"],
|
|
});
|
|
writeEvidence("response.json", { copy: exportResultCopy, statuses: Object.keys(exportResultCopy) });
|
|
writeEvidence("db-diff.json", { browser_persistent_blob_writes: 0, latest_updates_after_backend_failure: 0 });
|
|
});
|
|
});
|