/**
 * @copyright nhcarrigan
 * @license Naomi's Public License
 * @author Naomi Carrigan
 */
import { describe, it, expect, vi, beforeEach } from "vitest";
import { getGithubData } from "../../src/lib/github";

describe("github", () => {
  beforeEach(() => {
    vi.resetAllMocks();
  });

  it("should fetch and cache activities", async() => {
    expect.assertions(1);
    const mockResponse = [
      {
        act_user: {
          active:              true,
          avatar_url:          "https://example.com/avatar.png",
          created:             "2023-01-01T00:00:00Z",
          description:         "Developer",
          email:               "naomi@example.com",
          followers_count:     100,
          following_count:     50,
          full_name:           "Naomi Carrigan",
          html_url:            "https://example.com",
          id:                  1,
          is_admin:            false,
          language:            "en",
          last_login:          "2023-01-01T00:00:00Z",
          location:            "Earth",
          login:               "naomi",
          login_name:          "naomi",
          prohibit_login:      false,
          pronouns:            "she/her",
          restricted:          false,
          source_id:           1,
          starred_repos_count: 10,
          username:            "naomi",
          visibility:          "public",
          website:             "https://example.com",
        },
        act_user_id: 1,
        comment:     {
          assets:             [],
          body:               "A comment",
          created_at:         "2023-01-01T00:00:00Z",
          html_url:           "https://example.com/comment",
          id:                 1,
          issue_url:          "https://example.com/issue",
          original_author:    "naomi",
          original_author_id: 1,
          pull_request_url:   "https://example.com/pr",
          updated_at:         "2023-01-01T00:00:00Z",
          user:               null,
        },
        comment_id: 1,
        content:    "Activity content",
        created:    "2023-01-01T00:00:00Z",
        id:         1,
        is_private: false,
        op_type:    "create",
        ref_name:   "main",
        repo:       {
          allow_fast_forward_only_merge:     false,
          allow_merge_commits:               true,
          allow_rebase:                      true,
          allow_rebase_explicit:             true,
          allow_rebase_update:               true,
          allow_squash_merge:                true,
          archived:                          false,
          archived_at:                       "2023-01-01T00:00:00Z",
          avatar_url:                        "https://example.com/avatar.png",
          clone_url:                         "https://example.com/repo.git",
          created_at:                        "2023-01-01T00:00:00Z",
          default_allow_maintainer_edit:     true,
          default_branch:                    "main",
          default_delete_branch_after_merge: true,
          default_merge_style:               "merge",
          description:                       "A repository",
          empty:                             false,
          external_tracker:                  {
            external_tracker_format:         "format",
            external_tracker_regexp_pattern: "pattern",
            external_tracker_style:          "style",
            external_tracker_url:            "https://example.com/tracker",
          },
          fork:                        false,
          forks_count:                 5,
          full_name:                   "naomi/repo",
          globally_editable_wiki:      false,
          has_actions:                 true,
          has_issues:                  true,
          has_packages:                true,
          has_projects:                true,
          has_pull_requests:           true,
          has_releases:                true,
          has_wiki:                    true,
          html_url:                    "https://example.com/repo",
          id:                          1,
          ignore_whitespace_conflicts: false,
          internal:                    false,
          language:                    "TypeScript",
          languages_url:               "https://example.com/languages",
          link:                        "https://example.com/repo",
          mirror:                      false,
          mirror_interval:             "24h",
          mirror_updated:              "2023-01-01T00:00:00Z",
          name:                        "repo",
          object_format_name:          "format",
          open_issues_count:           1,
          open_pr_counter:             0,
          original_url:                "https://example.com/repo",
          owner:                       {
            active:              true,
            avatar_url:          "https://example.com/avatar.png",
            created:             "2023-01-01T00:00:00Z",
            description:         "Developer",
            email:               "naomi@example.com",
            followers_count:     100,
            following_count:     50,
            full_name:           "Naomi Carrigan",
            html_url:            "https://example.com",
            id:                  1,
            is_admin:            false,
            language:            "en",
            last_login:          "2023-01-01T00:00:00Z",
            location:            "Earth",
            login:               "naomi",
            login_name:          "naomi",
            prohibit_login:      false,
            pronouns:            "she/her",
            restricted:          false,
            source_id:           1,
            starred_repos_count: 10,
            username:            "naomi",
            visibility:          "public",
            website:             "https://example.com",
          },
          parent:      null,
          permissions: {
            admin: true,
            pull:  true,
            push:  true,
          },
          private:         false,
          release_counter: 0,
          repo_transfer:   null,
          size:            100,
          ssh_url:         "git@example.com:repo.git",
          stars_count:     10,
          template:        false,
          topics:          [],
          updated_at:      "2023-01-01T00:00:00Z",
          url:             "https://example.com/repo",
          watchers_count:  3,
          website:         "https://example.com",
          wiki_branch:     "main",
        },
        repo_id: 1,
        user_id: 1,
      },
    ];

    vi.spyOn(global, "fetch").mockResolvedValue({
      json: () => {
        return Promise.resolve(mockResponse);
      },
    });

    const data = await getGithubData();
    expect(data, "did not have correct payload").toStrictEqual(mockResponse);
  });

  it("should return cached data if not stale", async() => {
    expect.assertions(3);
    const mockResponse = [
      {
        act_user: {
          active:              true,
          avatar_url:          "https://example.com/avatar.png",
          created:             "2023-01-01T00:00:00Z",
          description:         "Developer",
          email:               "naomi@example.com",
          followers_count:     100,
          following_count:     50,
          full_name:           "Naomi Carrigan",
          html_url:            "https://example.com",
          id:                  1,
          is_admin:            false,
          language:            "en",
          last_login:          "2023-01-01T00:00:00Z",
          location:            "Earth",
          login:               "naomi",
          login_name:          "naomi",
          prohibit_login:      false,
          pronouns:            "she/her",
          restricted:          false,
          source_id:           1,
          starred_repos_count: 10,
          username:            "naomi",
          visibility:          "public",
          website:             "https://example.com",
        },
        act_user_id: 1,
        comment:     {
          assets:             [],
          body:               "A comment",
          created_at:         "2023-01-01T00:00:00Z",
          html_url:           "https://example.com/comment",
          id:                 1,
          issue_url:          "https://example.com/issue",
          original_author:    "naomi",
          original_author_id: 1,
          pull_request_url:   "https://example.com/pr",
          updated_at:         "2023-01-01T00:00:00Z",
          user:               null,
        },
        comment_id: 1,
        content:    "Activity content",
        created:    "2023-01-01T00:00:00Z",
        id:         1,
        is_private: false,
        op_type:    "create",
        ref_name:   "main",
        repo:       {
          allow_fast_forward_only_merge:     false,
          allow_merge_commits:               true,
          allow_rebase:                      true,
          allow_rebase_explicit:             true,
          allow_rebase_update:               true,
          allow_squash_merge:                true,
          archived:                          false,
          archived_at:                       "2023-01-01T00:00:00Z",
          avatar_url:                        "https://example.com/avatar.png",
          clone_url:                         "https://example.com/repo.git",
          created_at:                        "2023-01-01T00:00:00Z",
          default_allow_maintainer_edit:     true,
          default_branch:                    "main",
          default_delete_branch_after_merge: true,
          default_merge_style:               "merge",
          description:                       "A repository",
          empty:                             false,
          external_tracker:                  {
            external_tracker_format:         "format",
            external_tracker_regexp_pattern: "pattern",
            external_tracker_style:          "style",
            external_tracker_url:            "https://example.com/tracker",
          },
          fork:                        false,
          forks_count:                 5,
          full_name:                   "naomi/repo",
          globally_editable_wiki:      false,
          has_actions:                 true,
          has_issues:                  true,
          has_packages:                true,
          has_projects:                true,
          has_pull_requests:           true,
          has_releases:                true,
          has_wiki:                    true,
          html_url:                    "https://example.com/repo",
          id:                          1,
          ignore_whitespace_conflicts: false,
          internal:                    false,
          language:                    "TypeScript",
          languages_url:               "https://example.com/languages",
          link:                        "https://example.com/repo",
          mirror:                      false,
          mirror_interval:             "24h",
          mirror_updated:              "2023-01-01T00:00:00Z",
          name:                        "repo",
          object_format_name:          "format",
          open_issues_count:           1,
          open_pr_counter:             0,
          original_url:                "https://example.com/repo",
          owner:                       {
            active:              true,
            avatar_url:          "https://example.com/avatar.png",
            created:             "2023-01-01T00:00:00Z",
            description:         "Developer",
            email:               "naomi@example.com",
            followers_count:     100,
            following_count:     50,
            full_name:           "Naomi Carrigan",
            html_url:            "https://example.com",
            id:                  1,
            is_admin:            false,
            language:            "en",
            last_login:          "2023-01-01T00:00:00Z",
            location:            "Earth",
            login:               "naomi",
            login_name:          "naomi",
            prohibit_login:      false,
            pronouns:            "she/her",
            restricted:          false,
            source_id:           1,
            starred_repos_count: 10,
            username:            "naomi",
            visibility:          "public",
            website:             "https://example.com",
          },
          parent:      null,
          permissions: {
            admin: true,
            pull:  true,
            push:  true,
          },
          private:         false,
          release_counter: 0,
          repo_transfer:   null,
          size:            100,
          ssh_url:         "git@example.com:repo.git",
          stars_count:     10,
          template:        false,
          topics:          [],
          updated_at:      "2023-01-01T00:00:00Z",
          url:             "https://example.com/repo",
          watchers_count:  3,
          website:         "https://example.com",
          wiki_branch:     "main",
        },
        repo_id: 1,
        user_id: 1,
      },
    ];

    vi.spyOn(global, "fetch").mockResolvedValue({
      json: () => {
        return Promise.resolve(mockResponse);
      },
    });

    const data = await getGithubData();
    expect(data, "did not have correct payload").toStrictEqual(mockResponse);

    // Call again to check if cached data is returned
    const cachedData = await getGithubData();
    expect(cachedData, "did not cache correct payload").
      toStrictEqual(mockResponse);
    expect(global.fetch, "did not hit cache").not.toHaveBeenCalled();
  });
});