Files

88 lines
2.5 KiB
JavaScript

// @ts-check
import { describe, expect, it, vi } from "vitest";
import { retryer } from "../src/common/retryer.js";
vi.mock(import("../src/common/log.js"), async () => {
const { createLoggerMock } = await import("./utils.js");
return createLoggerMock();
});
const fetcher = vi.fn().mockResolvedValue({ data: "ok" });
const fetcherFail = vi.fn().mockResolvedValue({
data: { errors: [{ type: "RATE_LIMITED" }] },
});
const fetcherFailOnSecondTry = vi.fn((_vars, _token, retries) => {
if (retries < 1) {
return Promise.resolve({ data: { errors: [{ type: "RATE_LIMITED" }] } });
}
return Promise.resolve({ data: "ok" });
});
const fetcherFailWithMessageBasedRateLimitErr = vi.fn(
(_vars, _token, retries) => {
if (retries < 1) {
return Promise.resolve({
data: {
errors: [
{
type: "ASDF",
message: "API rate limit already exceeded for user ID 11111111",
},
],
},
});
}
return Promise.resolve({ data: "ok" });
},
);
const customFetcher = vi.fn((variables, token) => {
return Promise.resolve({ data: { token } });
});
describe("Test Retryer", () => {
it("retryer should return value and have zero retries on first try", async () => {
let res = await retryer(fetcher, {});
expect(fetcher).toHaveBeenCalledTimes(1);
expect(res).toStrictEqual({ data: "ok" });
});
it("retryer should return value and have 2 retries", async () => {
let res = await retryer(fetcherFailOnSecondTry, {});
expect(fetcherFailOnSecondTry).toHaveBeenCalledTimes(2);
expect(res).toStrictEqual({ data: "ok" });
});
it("retryer should return value and have 2 retries with message based rate limit error", async () => {
let res = await retryer(fetcherFailWithMessageBasedRateLimitErr, {});
expect(fetcherFailWithMessageBasedRateLimitErr).toHaveBeenCalledTimes(2);
expect(res).toStrictEqual({ data: "ok" });
});
it("retryer should throw specific error if maximum retries reached", async () => {
await expect(retryer(fetcherFail, {})).rejects.toThrow(
"Downtime due to GitHub API rate limiting",
);
expect(fetcherFail).toHaveBeenCalledTimes(2);
});
it("retryer should use injected PATs when provided", async () => {
const res = await retryer(customFetcher, {}, "user-pat-token");
expect(customFetcher).toHaveBeenCalledExactlyOnceWith(
{},
"user-pat-token",
0,
);
expect(res).toStrictEqual({ data: { token: "user-pat-token" } });
});
});