import { jest } from "@jest/globals"; import "@testing-library/jest-dom"; import { retryer, RETRIES } from "../src/common/retryer.js"; import { logger } from "../src/common/utils.js"; import { expect, it, describe } from "@jest/globals"; const fetcher = jest.fn((variables, token) => { logger.log(variables, token); return new Promise((res) => res({ data: "ok" })); }); const fetcherFail = jest.fn(() => { return new Promise((res) => res({ data: { errors: [{ type: "RATE_LIMITED" }] } }), ); }); const fetcherFailOnSecondTry = jest.fn((_vars, _token, retries) => { return new Promise((res) => { // faking rate limit if (retries < 1) { return res({ data: { errors: [{ type: "RATE_LIMITED" }] } }); } return res({ data: "ok" }); }); }); const fetcherFailWithMessageBasedRateLimitErr = jest.fn( (_vars, _token, retries) => { return new Promise((res) => { // faking rate limit if (retries < 1) { return res({ data: { errors: [ { type: "ASDF", message: "API rate limit already exceeded for user ID 11111111", }, ], }, }); } return res({ data: "ok" }); }); }, ); describe("Test Retryer", () => { it("retryer should return value and have zero retries on first try", async () => { let res = await retryer(fetcher, {}); expect(fetcher).toBeCalledTimes(1); expect(res).toStrictEqual({ data: "ok" }); }); it("retryer should return value and have 2 retries", async () => { let res = await retryer(fetcherFailOnSecondTry, {}); expect(fetcherFailOnSecondTry).toBeCalledTimes(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).toBeCalledTimes(2); expect(res).toStrictEqual({ data: "ok" }); }); it("retryer should throw specific error if maximum retries reached", async () => { try { await retryer(fetcherFail, {}); } catch (err) { expect(fetcherFail).toBeCalledTimes(RETRIES + 1); expect(err.message).toBe("Downtime due to GitHub API rate limiting"); } }); });