Back to Repositories

Testing Repository Fetch Operations in github-readme-stats

This test suite validates the repository fetching functionality in github-readme-stats, focusing on GraphQL API interactions and error handling. It ensures proper data retrieval for both user and organization repositories while handling various edge cases.

Test Coverage Overview

The test suite provides comprehensive coverage of the fetchRepo function, examining both successful and error scenarios.

  • Tests user repository fetching with star count validation
  • Verifies organization repository retrieval
  • Handles null repository cases for users and organizations
  • Tests private repository access restrictions
  • Validates error handling for non-existent repositories

Implementation Analysis

The implementation uses Jest’s modern testing patterns with async/await syntax for API testing. Mock responses are implemented using axios-mock-adapter to simulate GitHub’s GraphQL API responses.

The tests utilize Jest’s describe/it blocks for organized test structure and employ expect assertions with toStrictEqual and rejects.toThrow for precise validation.

Technical Details

  • Testing Framework: Jest
  • HTTP Client: Axios
  • Mocking Library: axios-mock-adapter
  • Testing Library: @testing-library/jest-dom
  • API Type: GraphQL
  • Test Environment: Node.js

Best Practices Demonstrated

The test suite exemplifies several testing best practices in modern JavaScript development.

  • Proper test isolation using mock resets after each test
  • Comprehensive error case coverage
  • Clear test descriptions and expectations
  • Consistent use of async/await for promise handling
  • Modular test data organization

anuraghazra/github-readme-stats

tests/fetchRepo.test.js

            
import "@testing-library/jest-dom";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";
import { fetchRepo } from "../src/fetchers/repo-fetcher.js";
import { expect, it, describe, afterEach } from "@jest/globals";

const data_repo = {
  repository: {
    name: "convoychat",
    stargazers: { totalCount: 38000 },
    description: "Help us take over the world! React + TS + GraphQL Chat App",
    primaryLanguage: {
      color: "#2b7489",
      id: "MDg6TGFuZ3VhZ2UyODc=",
      name: "TypeScript",
    },
    forkCount: 100,
  },
};

const data_user = {
  data: {
    user: { repository: data_repo.repository },
    organization: null,
  },
};

const data_org = {
  data: {
    user: null,
    organization: { repository: data_repo.repository },
  },
};

const mock = new MockAdapter(axios);

afterEach(() => {
  mock.reset();
});

describe("Test fetchRepo", () => {
  it("should fetch correct user repo", async () => {
    mock.onPost("https://api.github.com/graphql").reply(200, data_user);

    let repo = await fetchRepo("anuraghazra", "convoychat");

    expect(repo).toStrictEqual({
      ...data_repo.repository,
      starCount: data_repo.repository.stargazers.totalCount,
    });
  });

  it("should fetch correct org repo", async () => {
    mock.onPost("https://api.github.com/graphql").reply(200, data_org);

    let repo = await fetchRepo("anuraghazra", "convoychat");
    expect(repo).toStrictEqual({
      ...data_repo.repository,
      starCount: data_repo.repository.stargazers.totalCount,
    });
  });

  it("should throw error if user is found but repo is null", async () => {
    mock
      .onPost("https://api.github.com/graphql")
      .reply(200, { data: { user: { repository: null }, organization: null } });

    await expect(fetchRepo("anuraghazra", "convoychat")).rejects.toThrow(
      "User Repository Not found",
    );
  });

  it("should throw error if org is found but repo is null", async () => {
    mock
      .onPost("https://api.github.com/graphql")
      .reply(200, { data: { user: null, organization: { repository: null } } });

    await expect(fetchRepo("anuraghazra", "convoychat")).rejects.toThrow(
      "Organization Repository Not found",
    );
  });

  it("should throw error if both user & org data not found", async () => {
    mock
      .onPost("https://api.github.com/graphql")
      .reply(200, { data: { user: null, organization: null } });

    await expect(fetchRepo("anuraghazra", "convoychat")).rejects.toThrow(
      "Not found",
    );
  });

  it("should throw error if repository is private", async () => {
    mock.onPost("https://api.github.com/graphql").reply(200, {
      data: {
        user: { repository: { ...data_repo, isPrivate: true } },
        organization: null,
      },
    });

    await expect(fetchRepo("anuraghazra", "convoychat")).rejects.toThrow(
      "User Repository Not found",
    );
  });
});