): MediaJobBlock {
return {
kind: "media",
jobId: "job-1",
operation: "edit_video",
status: "done",
title: "Cut the intro",
outputs: [],
...overrides,
};
}
const everything = { export: true, transcribe: true };
const noop = async () => undefined;
describe("media card", () => {
it.each([
["queued", "Queued"],
["waiting", "Waiting for GPU"],
["running", "Working…"],
["done", "Done"],
["failed", "Failed"],
["cancelled", "Cancelled"],
] as const)("labels a %s job as %s", (status, label) => {
const html = renderToString();
expect(html).toContain(`data-status="${status}"`);
expect(html).toContain(label);
expect(html).toContain("Cut the intro");
});
it("shows progress and a cancel action while the job runs, and no result actions", () => {
const html = renderToString(
,
);
expect(html).toContain('role="progressbar"');
expect(html).toContain('aria-valuenow="42"');
expect(html).toContain("width:42%");
expect(html).toContain("Cancel");
expect(html).not.toContain("Export");
expect(html).not.toContain("Transcribe");
});
it("leaves the progress value out when the backend does not report one", () => {
const html = renderToString();
expect(html).toContain('role="progressbar"');
expect(html).not.toContain("aria-valuenow");
});
it("offers download, export and transcribe for a finished video", () => {
const html = renderToString(
,
);
expect(html).toContain('data-player="video"');
expect(html).toContain('href="/artifact/video-1?download=1"');
expect(html).toContain('download="clip.mp4"');
expect(html).toContain('aria-label="Download clip.mp4"');
expect(html).toContain("Export");
expect(html).toContain("Transcribe");
expect(html).not.toContain("progressbar");
expect(html).not.toContain("Cancel");
});
it("shows a finished analysis as done, with nothing to open or act on", () => {
const html = renderToString(
,
);
expect(html).toContain('data-status="done"');
expect(html).toContain("Find the cut points");
expect(html).toContain("Done");
expect(html).toContain("lucide-scan-search");
expect(html).not.toContain("Download");
expect(html).not.toContain("Export");
expect(html).not.toContain("Transcribe");
});
it("offers only what the space can run and what fits the output", () => {
const audio = { ...video, artifactId: "audio-1", kind: "audio" as const, name: "take.m4a" };
const onlyTranscribe = renderToString(
,
);
expect(onlyTranscribe).toContain('data-player="audio"');
expect(onlyTranscribe).toContain("Transcribe");
expect(onlyTranscribe).not.toContain("Export");
const nothingAvailable = renderToString(
,
);
expect(nothingAvailable).toContain("Download clip.mp4");
expect(nothingAvailable).not.toContain("Export");
expect(nothingAvailable).not.toContain("Transcribe");
});
it("renders images as thumbnails and subtitle files as file cards", () => {
const html = renderToString(
,
);
expect(html).toContain('data-artifact="image-1"');
expect(html).toContain("clip.srt");
expect(html).toContain("clip.vtt");
expect(html).not.toContain("Transcribe");
});
it("names the platform of an export, and its first problem only when the check did not pass", () => {
const tiktok = {
...video,
artifactId: "tiktok-1",
platform: "tiktok" as const,
check: { status: "pass" as const, issues: [] },
};
const shorts = {
...video,
artifactId: "shorts-1",
platform: "youtube-shorts" as const,
check: {
status: "warn" as const,
issues: [
{ code: "loudness_off" as const, targetLufs: -14, actualLufs: -18 },
{ code: "true_peak_high" as const, maxDb: -1, actualDb: 0 },
],
},
};
const html = renderToString(
,
);
expect(html).toContain('TikTok
');
expect(html).toContain(
'Too quiet for YouTube Shorts (target -14 LUFS)
',
);
expect(html).not.toContain("Peaks too high");
expect(html.match(/text-ui-body-sm text-(muted-foreground|warning|destructive)/g)).toHaveLength(
2,
);
});
it("lists skipped platforms, which also explain a job that rendered nothing", () => {
const skipped = [
{
platform: "snapchat-spotlight" as const,
issues: [{ code: "too_long" as const, maxMs: 60_000, actualMs: 75_000 }],
},
];
const partial = renderToString(
,
);
expect(partial).toContain("Too long for Snapchat Spotlight (max 1:00)");
const failed = renderToString(
,
);
expect(failed).toContain("Too long for Snapchat Spotlight (max 1:00)");
expect(failed).not.toContain("Not exported");
});
it("shows why a job failed", () => {
const html = renderToString(
,
);
expect(html).toContain("GPU server is unreachable");
});
});
describe("exportPresetsFor", () => {
it("leaves out the shape the video already has, labelled by aspect ratio elsewhere", () => {
expect(exportPresetsFor({ width: 1920, height: 1080 })).toEqual([
"vertical",
"square",
"portrait",
"classic",
"cinema",
]);
expect(exportPresetsFor({ width: 1080, height: 1920, preset: "vertical" })).not.toContain(
"vertical",
);
expect(exportPresetsFor({})).toHaveLength(6);
});
});
describe("isActiveMediaStatus", () => {
it("treats queued, waiting and running as active", () => {
expect(["queued", "waiting", "running"].every((s) => isActiveMediaStatus(s as never))).toBe(
true,
);
expect(isActiveMediaStatus("done")).toBe(false);
});
});