Back to Repositories

Testing WakaTime Stats Integration in github-readme-stats

This test suite validates the WakaTime statistics fetching functionality in github-readme-stats, ensuring proper API integration and error handling. The tests verify data retrieval, parameter validation, and edge cases for the WakaTime integration.

Test Coverage Overview

The test suite provides comprehensive coverage of the WakaTime stats fetcher functionality.

Key areas tested include:
  • Successful API data retrieval and response parsing
  • Missing username parameter validation
  • Non-existent user error handling
  • Response data structure verification
Integration points focus on the WakaTime API endpoint interaction and axios HTTP client implementation.

Implementation Analysis

The testing approach utilizes Jest’s modern async/await pattern for API testing, combined with axios-mock-adapter for HTTP request mocking. The implementation demonstrates clean separation of concerns with isolated test cases.

Technical patterns include:
  • Mock adapter setup and reset between tests
  • Async test case structure
  • Expected error message validation
  • Sample data fixtures

Technical Details

Testing tools and configuration:
  • Jest test framework
  • axios for HTTP requests
  • axios-mock-adapter for API mocking
  • @testing-library/jest-dom for DOM assertions
  • ES6 module structure
  • Async/await pattern

Best Practices Demonstrated

The test suite exemplifies several testing best practices for API integration testing.

Notable practices include:
  • Proper test isolation with mock resets
  • Comprehensive error case coverage
  • Clear test case descriptions
  • Modular test data organization
  • Consistent assertion patterns
  • Proper async/await usage

anuraghazra/github-readme-stats

tests/fetchWakatime.test.js

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

const mock = new MockAdapter(axios);

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

const wakaTimeData = {
  data: {
    categories: [
      {
        digital: "22:40",
        hours: 22,
        minutes: 40,
        name: "Coding",
        percent: 100,
        text: "22 hrs 40 mins",
        total_seconds: 81643.570077,
      },
    ],
    daily_average: 16095,
    daily_average_including_other_language: 16329,
    days_including_holidays: 7,
    days_minus_holidays: 5,
    editors: [
      {
        digital: "22:40",
        hours: 22,
        minutes: 40,
        name: "VS Code",
        percent: 100,
        text: "22 hrs 40 mins",
        total_seconds: 81643.570077,
      },
    ],
    holidays: 2,
    human_readable_daily_average: "4 hrs 28 mins",
    human_readable_daily_average_including_other_language: "4 hrs 32 mins",
    human_readable_total: "22 hrs 21 mins",
    human_readable_total_including_other_language: "22 hrs 40 mins",
    id: "random hash",
    is_already_updating: false,
    is_coding_activity_visible: true,
    is_including_today: false,
    is_other_usage_visible: true,
    is_stuck: false,
    is_up_to_date: true,
    languages: [
      {
        digital: "0:19",
        hours: 0,
        minutes: 19,
        name: "Other",
        percent: 1.43,
        text: "19 mins",
        total_seconds: 1170.434361,
      },
      {
        digital: "0:01",
        hours: 0,
        minutes: 1,
        name: "TypeScript",
        percent: 0.1,
        text: "1 min",
        total_seconds: 83.293809,
      },
      {
        digital: "0:00",
        hours: 0,
        minutes: 0,
        name: "YAML",
        percent: 0.07,
        text: "0 secs",
        total_seconds: 54.975151,
      },
    ],
    operating_systems: [
      {
        digital: "22:40",
        hours: 22,
        minutes: 40,
        name: "Mac",
        percent: 100,
        text: "22 hrs 40 mins",
        total_seconds: 81643.570077,
      },
    ],
    percent_calculated: 100,
    range: "last_7_days",
    status: "ok",
    timeout: 15,
    total_seconds: 80473.135716,
    total_seconds_including_other_language: 81643.570077,
    user_id: "random hash",
    username: "anuraghazra",
    writes_only: false,
  },
};

describe("WakaTime fetcher", () => {
  it("should fetch correct WakaTime data", async () => {
    const username = "anuraghazra";
    mock
      .onGet(
        `https://wakatime.com/api/v1/users/${username}/stats?is_including_today=true`,
      )
      .reply(200, wakaTimeData);

    const repo = await fetchWakatimeStats({ username });
    expect(repo).toStrictEqual(wakaTimeData.data);
  });

  it("should throw error if username param missing", async () => {
    mock.onGet(/\/https:\/\/wakatime\.com\/api/).reply(404, wakaTimeData);

    await expect(fetchWakatimeStats("noone")).rejects.toThrow(
      'Missing params "username" make sure you pass the parameters in URL',
    );
  });

  it("should throw error if username is not found", async () => {
    mock.onGet(/\/https:\/\/wakatime\.com\/api/).reply(404, wakaTimeData);

    await expect(fetchWakatimeStats({ username: "noone" })).rejects.toThrow(
      "Could not resolve to a User with the login of 'noone'",
    );
  });
});

export { wakaTimeData };