Complete provider waits and lifecycle visibility
Release aborted Real-Debrid, AllDebrid, and BestDebrid web callers even when underlying requests ignore cancellation while retaining terminal rejection observers. Publish provider cooldown deadlines and emit a fresh idle snapshot at the earliest expiry. Abort and visibly drain post-processing before dispatching one pending restart. Surface lifecycle phase, reason, retry countdown, and remaining work in the download controls. Add focused regressions for provider abort races, cooldown expiry, post-processing drain, pending start visibility, and the updated rapid stop contract.
This commit is contained in:
@@ -138,7 +138,7 @@ describe("bestdebrid-web", () => {
|
||||
expect(mockCookiesSet).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("treats BestDebrid free-user errors as logged-out sessions when the account page is guest-only", async () => {
|
||||
it("treats BestDebrid free-user errors as logged-out sessions when the account page is guest-only", async () => {
|
||||
const filePath = createCookieFile([
|
||||
"# Netscape HTTP Cookie File",
|
||||
"bestdebrid.com\tFALSE\t/\tTRUE\t1803585385\tPHPSESSID\tsecret-session"
|
||||
@@ -162,6 +162,34 @@ describe("bestdebrid-web", () => {
|
||||
|
||||
expect(mockFetch).toHaveBeenCalledTimes(2);
|
||||
expect(mockFetch.mock.calls[0]?.[0]).toBe("https://bestdebrid.com/api/v1/generateLink");
|
||||
expect(mockFetch.mock.calls[1]?.[0]).toBe("https://bestdebrid.com/en/downloader/");
|
||||
});
|
||||
});
|
||||
expect(mockFetch.mock.calls[1]?.[0]).toBe("https://bestdebrid.com/en/downloader/");
|
||||
});
|
||||
|
||||
it("releases an aborted caller while the active web request ignores its signal", async () => {
|
||||
const filePath = createCookieFile([
|
||||
"# Netscape HTTP Cookie File",
|
||||
"bestdebrid.com\tFALSE\t/\tTRUE\t1803585385\tPHPSESSID\tsecret-session"
|
||||
].join("\n"));
|
||||
tempFiles.push(filePath);
|
||||
const fallback = new BestDebridWebFallback(() => true);
|
||||
await fallback.importCookiesFromFile(filePath);
|
||||
let rejectRequest!: (error: Error) => void;
|
||||
mockFetch.mockReturnValue(new Promise<Response>((_resolve, reject) => {
|
||||
rejectRequest = reject;
|
||||
}));
|
||||
const controller = new AbortController();
|
||||
const running = fallback.unrestrict("https://1fichier.com/?abort-race", controller.signal)
|
||||
.then(() => "resolved" as const, (error) => String(error));
|
||||
|
||||
await vi.waitFor(() => expect(mockFetch).toHaveBeenCalledTimes(1));
|
||||
controller.abort("test-stop");
|
||||
const outcome = await Promise.race([
|
||||
running,
|
||||
new Promise<"timeout">((resolve) => setTimeout(() => resolve("timeout"), 200))
|
||||
]);
|
||||
|
||||
expect(outcome).toContain("aborted:bestdebrid-web");
|
||||
rejectRequest(new Error("late bestdebrid rejection"));
|
||||
await Promise.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user