feat(cms): recover drafts and failed imports with verified UI workflows
CI / check (push) Successful in 2m3s
CI / deploy (push) Successful in 1m31s
CI / publish-container (push) Successful in 1m41s

This commit is contained in:
Simo committed 2026-09-11 08:58:10 +02:00
1 parent 410a1e466c
commit 88790d1a0d
84 files changed
+3952 -288

No files matched your search

@@ -74,3 +74,54 @@ describe("source asset preflight", () => {
expect(fetchMock).toHaveBeenCalledTimes(1);
});
});
const item = {
id: 1,
classname: "chair",
name: "Chair",
description: "",
type: "flooritem",
revision: 123,
category: "other",
};
it("reports every missing filename and HTTP reason without credentials", async () => {
vi.stubGlobal(
"fetch",
vi.fn().mockResolvedValue(new Response(null, { status: 404 })),
);
const result = await inspectSourceAssets(item, [], {
nitroBaseUrl: "https://user:[email protected]/private?token=secret",
} as never);
expect(result.state).toBe("missing");
expect(result.attempts).toHaveLength(2);
expect(result.attempts?.[1]).toMatchObject({
file: "chair.swf",
reason: "http",
status: 404,
});
expect(JSON.stringify(result)).not.toContain("secret");
});
it("keeps network and blocked sources unknown rather than calling them missing", async () => {
vi.stubGlobal(
"fetch",
vi.fn().mockRejectedValue(new Error("https://secret.test/?token=secret")),
);
const result = await inspectSourceAssets({ ...item, revision: 124 }, []);
expect(result.state).toBe("unknown");
expect(result.attempts?.[0].reason).toBe("network");
expect(JSON.stringify(result)).not.toContain("secret");
});
it("distinguishes HTML responses from valid assets", async () => {
vi.stubGlobal(
"fetch",
vi
.fn()
.mockResolvedValue(
new Response(null, { headers: { "content-type": "text/html" } }),
),
);
const result = await inspectSourceAssets({ ...item, revision: 125 }, []);
expect(result.attempts?.[0].reason).toBe("invalidResponse");
expect(result.state).toBe("unknown");
});