fix(clip): a clip is held to its owner's storage cap, and its limits and failures say the server's truth
- The cut file is measured against what its owner has left, for a YouTube range (whose fetch never reads yt-dlp's size ceiling) and for a Plex clip (which fetches nothing), before the fetch and again before it is placed; a refusal leaves the asset pending for a Retry. - A silent Plex file is cut silent; a file the probe cannot read says so. - A second job on a failed or renamed clip gets the same YouTube diagnosis and the fetched title. - The "too long" refusal names the server's cap; a contract test holds the client's copies of the clip limits to clip.py; the shipped player clients are pinned against the installed yt-dlp. - One HDR transfer set and one rating_key lookup; job status words from JobStatus; the display-name guard sees subscript writes and the clip route; stale comments and types follow the clip job.
This commit is contained in:
@@ -261,6 +261,24 @@ describe("req — a structured refusal reads in the user's language", () => {
|
||||
).rejects.toMatchObject({ detail: localized });
|
||||
});
|
||||
|
||||
it("states the clip cap the server refused with, not a copy of it", async () => {
|
||||
// The cap is the server's (downloads/clip.py MAX_CLIP_S): a message with "10 minutes" baked in
|
||||
// goes stale the day it moves.
|
||||
const i18n = (await import("../../i18n")).default;
|
||||
const t = vi.spyOn(i18n, "t");
|
||||
vi.spyOn(globalThis, "fetch").mockResolvedValue(
|
||||
new Response(JSON.stringify({ detail: { code: "clip", reason: "too_long", limit_s: 300 } }), {
|
||||
status: 422,
|
||||
headers: { "content-type": "application/json" },
|
||||
}),
|
||||
);
|
||||
await req("/api/downloads/clip", { method: "POST" }, { quiet: true }).catch(() => undefined);
|
||||
expect(t).toHaveBeenCalledWith(
|
||||
"clip.errors.too_long",
|
||||
expect.objectContaining({ minutes: "5" }),
|
||||
);
|
||||
});
|
||||
|
||||
it.each(["quota", "reconnect", "unavailable"])(
|
||||
"says what to do about an action YouTube refused (%s)",
|
||||
async (reason) => {
|
||||
|
||||
Reference in New Issue
Block a user