Files
EpicNext-Cms/src/lib/services/furni-job-store.test.ts
T
Simo 2619bec165
CI / check (push) Successful in 1m30s
CI / deploy (push) Successful in 1m26s
CI / e2e (push) Successful in 25s
feat(catalog): queue furniture imports with history and matching file attachments
2026-09-05 17:02:26 +02:00

62 lines
1.9 KiB
TypeScript

import { randomUUID } from "node:crypto";
import { promises as fs } from "node:fs";
import { tmpdir } from "node:os";
import path from "node:path";
import { afterEach, expect, it } from "vitest";
import type { ImportJob } from "@/lib/furni/import-job";
import { ImportJobStore } from "./furni-job-store";
const roots: string[] = [];
afterEach(async () => {
for (const root of roots.splice(0))
await fs.rm(root, { recursive: true, force: true });
});
const job = (): ImportJob => ({
id: randomUUID(),
userId: 4,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(),
state: "queued",
translate: false,
items: [],
});
async function store() {
const root = await fs.mkdtemp(path.join(tmpdir(), "furni-jobs-test-"));
roots.push(root);
return new ImportJobStore(root);
}
it("persists history across store instances", async () => {
const s = await store(),
j = job();
await s.create(j);
expect(await new ImportJobStore(s.root).read(j.id)).toEqual(j);
});
it("deduplicates concurrent submissions of the same request", async () => {
const s = await store(),
j = job();
await Promise.all([s.create(j), s.create(j)]);
expect(await s.list()).toHaveLength(1);
});
it("does not overwrite a completed job on a repeated request", async () => {
const s = await store(),
j = job();
await s.create(j);
await s.save({ ...j, state: "completed" });
expect((await s.create(j)).state).toBe("completed");
});
it("rejects another user attempting to reuse an ID", async () => {
const s = await store(),
j = job();
await s.create(j);
await expect(s.create({ ...j, userId: 8 })).rejects.toThrow(
"Request ID already used",
);
});
it("rejects unsafe job paths", async () => {
const s = await store();
await expect(s.create({ ...job(), id: "../escape" })).rejects.toThrow(
"Invalid import ID",
);
await expect(s.read("../escape")).rejects.toThrow("Invalid import ID");
});