feat(realdebrid): rotate accounts during unrestrict

This commit is contained in:
Sucukdeluxe
2026-08-15 21:16:18 +02:00
parent 53cdac1ded
commit 7e65195057
13 changed files with 1159 additions and 139 deletions
+37 -5
View File
@@ -1,5 +1,5 @@
import { afterEach, describe, expect, it } from "vitest";
import { RealDebridClient } from "../src/main/realdebrid";
import { RealDebridApiError, RealDebridClient } from "../src/main/realdebrid";
const originalFetch = globalThis.fetch;
@@ -20,7 +20,7 @@ describe("realdebrid client", () => {
await expect(client.unrestrictLink("https://hoster.example/file/html")).rejects.toThrow(/html/i);
});
it("does not leak raw response body on JSON parse errors", async () => {
it("does not leak raw response body on JSON parse errors", async () => {
globalThis.fetch = (async (): Promise<Response> => {
return new Response("<html>token=secret-should-not-leak</html>", {
status: 200,
@@ -37,6 +37,38 @@ describe("realdebrid client", () => {
expect(text.toLowerCase()).toContain("json");
expect(text.toLowerCase()).not.toContain("secret-should-not-leak");
expect(text.toLowerCase()).not.toContain("<html>");
}
});
});
}
});
it("preserves the HTTP status and structured bad_token error", async () => {
globalThis.fetch = (async () => new Response(JSON.stringify({
error: "bad_token",
error_code: 8
}), {
status: 401,
headers: { "Content-Type": "application/json" }
})) as typeof fetch;
const client = new RealDebridClient("rd-token");
const error = await client.unrestrictLink("https://hoster.example/file/auth").then(() => null, (value) => value);
expect(error).toBeInstanceOf(RealDebridApiError);
expect(error).toMatchObject({ status: 401, apiError: "bad_token", apiErrorCode: 8 });
});
it("preserves too_many_requests after the client's retries", async () => {
globalThis.fetch = (async () => new Response(JSON.stringify({
error: "too_many_requests",
error_code: 34
}), {
status: 429,
headers: { "Content-Type": "application/json", "Retry-After": "0" }
})) as typeof fetch;
const client = new RealDebridClient("rd-token");
const error = await client.unrestrictLink("https://hoster.example/file/rate").then(() => null, (value) => value);
expect(error).toBeInstanceOf(RealDebridApiError);
expect(error).toMatchObject({ status: 429, apiError: "too_many_requests", apiErrorCode: 34 });
});
});