import "@testing-library/jest-dom"; import axios from "axios"; import MockAdapter from "axios-mock-adapter"; import { calculateRank } from "../src/calculateRank.js"; import { fetchStats } from "../src/fetchers/stats-fetcher.js"; // Test parameters. const data_stats = { data: { user: { name: "Anurag Hazra", repositoriesContributedTo: { totalCount: 61 }, contributionsCollection: { totalCommitContributions: 100, }, pullRequests: { totalCount: 300 }, openIssues: { totalCount: 100 }, closedIssues: { totalCount: 100 }, followers: { totalCount: 100 }, repositories: { totalCount: 5, nodes: [ { name: "test-repo-1", stargazers: { totalCount: 100 } }, { name: "test-repo-2", stargazers: { totalCount: 100 } }, { name: "test-repo-3", stargazers: { totalCount: 100 } }, ], pageInfo: { hasNextPage: true, endCursor: "cursor", }, }, }, }, }; const data_repo = { data: { user: { repositories: { nodes: [ { name: "test-repo-4", stargazers: { totalCount: 50 } }, { name: "test-repo-5", stargazers: { totalCount: 50 } }, ], pageInfo: { hasNextPage: false, endCursor: "cursor", }, }, }, }, }; const data_repo_zero_stars = { data: { user: { repositories: { nodes: [ { name: "test-repo-1", stargazers: { totalCount: 100 } }, { name: "test-repo-2", stargazers: { totalCount: 100 } }, { name: "test-repo-3", stargazers: { totalCount: 100 } }, { name: "test-repo-4", stargazers: { totalCount: 0 } }, { name: "test-repo-5", stargazers: { totalCount: 0 } }, ], pageInfo: { hasNextPage: true, endCursor: "cursor", }, }, }, }, }; const error = { errors: [ { type: "NOT_FOUND", path: ["user"], locations: [], message: "Could not resolve to a User with the login of 'noname'.", }, ], }; const mock = new MockAdapter(axios); beforeEach(() => { process.env.FETCH_MULTI_PAGE_STARS = "false"; // Set to `false` to fetch only one page of stars. mock.onPost("https://api.github.com/graphql").reply((cfg) => { return [ 200, cfg.data.includes("contributionsCollection") ? data_stats : data_repo, ]; }); }); afterEach(() => { mock.reset(); }); describe("Test fetchStats", () => { it("should fetch correct stats", async () => { let stats = await fetchStats("anuraghazra"); const rank = calculateRank({ all_commits: false, commits: 100, prs: 300, issues: 200, repos: 5, stars: 300, followers: 100, }); expect(stats).toStrictEqual({ contributedTo: 61, name: "Anurag Hazra", totalCommits: 100, totalIssues: 200, totalPRs: 300, totalStars: 300, rank, }); }); it("should stop fetching when there are repos with zero stars", async () => { mock.reset(); mock .onPost("https://api.github.com/graphql") .replyOnce(200, data_stats) .onPost("https://api.github.com/graphql") .replyOnce(200, data_repo_zero_stars); let stats = await fetchStats("anuraghazra"); const rank = calculateRank({ all_commits: false, commits: 100, prs: 300, issues: 200, repos: 5, stars: 300, followers: 100, }); expect(stats).toStrictEqual({ contributedTo: 61, name: "Anurag Hazra", totalCommits: 100, totalIssues: 200, totalPRs: 300, totalStars: 300, rank, }); }); it("should throw error", async () => { mock.reset(); mock.onPost("https://api.github.com/graphql").reply(200, error); await expect(fetchStats("anuraghazra")).rejects.toThrow( "Could not resolve to a User with the login of 'noname'.", ); }); it("should fetch total commits", async () => { mock .onGet("https://api.github.com/search/commits?q=author:anuraghazra") .reply(200, { total_count: 1000 }); let stats = await fetchStats("anuraghazra", true); const rank = calculateRank({ all_commits: true, commits: 1000, prs: 300, issues: 200, repos: 5, stars: 300, followers: 100, }); expect(stats).toStrictEqual({ contributedTo: 61, name: "Anurag Hazra", totalCommits: 1000, totalIssues: 200, totalPRs: 300, totalStars: 300, rank, }); }); it("should exclude stars of the `test-repo-1` repository", async () => { mock .onGet("https://api.github.com/search/commits?q=author:anuraghazra") .reply(200, { total_count: 1000 }); let stats = await fetchStats("anuraghazra", true, ["test-repo-1"]); const rank = calculateRank({ all_commits: true, commits: 1000, prs: 300, issues: 200, repos: 5, stars: 200, followers: 100, }); expect(stats).toStrictEqual({ contributedTo: 61, name: "Anurag Hazra", totalCommits: 1000, totalIssues: 200, totalPRs: 300, totalStars: 200, rank, }); }); it("should fetch two pages of stars if 'FETCH_MULTI_PAGE_STARS' env variable is set to `true`", async () => { process.env.FETCH_MULTI_PAGE_STARS = true; let stats = await fetchStats("anuraghazra"); const rank = calculateRank({ all_commits: false, commits: 100, prs: 300, issues: 200, repos: 5, stars: 400, followers: 100, }); expect(stats).toStrictEqual({ contributedTo: 61, name: "Anurag Hazra", totalCommits: 100, totalIssues: 200, totalPRs: 300, totalStars: 400, rank, }); }); it("should fetch one page of stars if 'FETCH_MULTI_PAGE_STARS' env variable is set to `false`", async () => { process.env.FETCH_MULTI_PAGE_STARS = "false"; let stats = await fetchStats("anuraghazra"); const rank = calculateRank({ all_commits: false, commits: 100, prs: 300, issues: 200, repos: 5, stars: 300, followers: 100, }); expect(stats).toStrictEqual({ contributedTo: 61, name: "Anurag Hazra", totalCommits: 100, totalIssues: 200, totalPRs: 300, totalStars: 300, rank, }); }); it("should fetch one page of stars if 'FETCH_MULTI_PAGE_STARS' env variable is not set", async () => { process.env.FETCH_MULTI_PAGE_STARS = undefined; let stats = await fetchStats("anuraghazra"); const rank = calculateRank({ all_commits: false, commits: 100, prs: 300, issues: 200, repos: 5, stars: 300, followers: 100, }); expect(stats).toStrictEqual({ contributedTo: 61, name: "Anurag Hazra", totalCommits: 100, totalIssues: 200, totalPRs: 300, totalStars: 300, rank, }); }); });