import { countOwnRepos, GITHUB_STATS_REVALIDATE_SECONDS, loadGithubRepoCounts, } from "./github-stats"; const repo = ( overrides: Partial<{ private: boolean; fork: boolean; archived: boolean }>, ) => ({ private: false, fork: false, archived: false, ...overrides }); function jsonResponse(body: unknown, status = 200) { return { ok: status >= 200 && status < 300, status, json: async () => body, } as unknown as Response; } describe("countOwnRepos", () => { it("counts public and private repos and ignores forks and archived ones", () => { const counts = countOwnRepos([ repo({}), repo({}), repo({ private: true }), repo({ fork: true }), repo({ private: true, fork: true }), repo({ archived: true }), repo({ private: true, archived: true }), ]); expect(counts).toEqual({ total: 3, public: 2, private: 1 }); }); }); describe("loadGithubRepoCounts", () => { it("returns null without a token and never calls the API", async () => { const fetchImpl = jest.fn(); await expect( loadGithubRepoCounts(undefined, fetchImpl), ).resolves.toBeNull(); expect(fetchImpl).not.toHaveBeenCalled(); }); it("sends the token only to the GitHub API and revalidates daily", async () => { const fetchImpl = jest.fn().mockResolvedValue(jsonResponse([repo({})])); await loadGithubRepoCounts("secret-token", fetchImpl); const [url, init] = fetchImpl.mock.calls[0]; expect(new URL(url).origin).toBe("https://api.github.com"); expect(url).toContain("affiliation=owner"); expect(url).toContain("visibility=all"); expect(init.headers.authorization).toBe("Bearer secret-token"); expect(init.next.revalidate).toBe(GITHUB_STATS_REVALIDATE_SECONDS); expect(GITHUB_STATS_REVALIDATE_SECONDS).toBe(86_400); }); it("walks every page before counting", async () => { const firstPage = Array.from({ length: 100 }, () => repo({})); const secondPage = [repo({ private: true }), repo({ fork: true })]; const fetchImpl = jest .fn() .mockResolvedValueOnce(jsonResponse(firstPage)) .mockResolvedValueOnce(jsonResponse(secondPage)); await expect(loadGithubRepoCounts("token", fetchImpl)).resolves.toEqual({ total: 101, public: 100, private: 1, }); expect(fetchImpl).toHaveBeenCalledTimes(2); }); it("returns null when the API rejects the token", async () => { const fetchImpl = jest .fn() .mockResolvedValue(jsonResponse({ message: "Bad credentials" }, 401)); await expect(loadGithubRepoCounts("bad", fetchImpl)).resolves.toBeNull(); }); it("returns null on network failure instead of breaking the page", async () => { const fetchImpl = jest.fn().mockRejectedValue(new Error("offline")); await expect(loadGithubRepoCounts("token", fetchImpl)).resolves.toBeNull(); }); });