Skip to content

Commit db6dd96

Browse files
authored
test: add tests for GitHubIndexer (#187)
Add tests for GitHubIndexer class in frege/indexers/models.py
1 parent b445420 commit db6dd96

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import os
2+
import pytest
3+
from unittest import mock
4+
from frege.indexers.models import GitHubIndexer
5+
from frege.repositories.models import Repository
6+
from github import Github
7+
from github import RateLimitExceededException
8+
from github.Repository import Repository as GHRepo
9+
from github.Branch import Branch
10+
from django.db import IntegrityError
11+
12+
@pytest.fixture
13+
def github_indexer():
14+
return GitHubIndexer.objects.create(min_forks=200, min_stars=300, current_page=0)
15+
16+
def mock_repo(name="test-repo", sha="abc123"):
17+
mock_branch = mock.create_autospec(Branch)
18+
mock_branch.commit.sha = sha
19+
20+
mock_repo = mock.create_autospec(GHRepo)
21+
mock_repo.name = name
22+
mock_repo.description = "Test repo"
23+
mock_repo.clone_url = f"https://github.com/test/{name}.git"
24+
mock_repo.html_url = f"https://github.com/test/{name}"
25+
mock_repo.default_branch = "main"
26+
mock_repo.get_branch.return_value = mock_branch
27+
return mock_repo
28+
29+
@mock.patch("frege.indexers.models._is_repo_unique", return_value=True)
30+
@mock.patch("frege.indexers.models.Repository.objects.bulk_create")
31+
@mock.patch("frege.indexers.models.Github")
32+
@pytest.mark.django_db
33+
def test_iter_creates_repositories(mock_github_cls, mock_bulk_create, mock_unique, github_indexer):
34+
mock_github = mock.Mock()
35+
mock_repo_obj = mock_repo()
36+
mock_github.search_repositories.return_value = [mock_repo_obj]
37+
mock_github_cls.return_value = mock_github
38+
39+
iterator = iter(github_indexer)
40+
created_repos = next(iterator)
41+
42+
mock_github.search_repositories.assert_called_once_with(
43+
query="forks:>=200 stars:>=300 is:public",
44+
sort="stars",
45+
page=0
46+
)
47+
assert github_indexer.current_page == 1
48+
mock_bulk_create.assert_called_once()
49+
assert len(created_repos) == 1
50+
51+
@mock.patch.dict(os.environ, {}, clear=True)
52+
@mock.patch("frege.indexers.models.Github")
53+
@pytest.mark.django_db
54+
def test_iter_uses_no_token(mock_github_cls, github_indexer):
55+
iter(github_indexer)
56+
mock_github_cls.assert_not_called()
57+
58+
59+
@mock.patch("frege.indexers.models._is_repo_unique", return_value=True)
60+
@mock.patch("frege.indexers.models.Repository.objects.bulk_create")
61+
@mock.patch("frege.indexers.models.Github")
62+
@pytest.mark.django_db
63+
def test_repository_field_mapping(mock_github_cls, mock_bulk_create, mock_unique, github_indexer):
64+
mock_github = mock.Mock()
65+
mock_repo_obj = mock_repo(name="test-repo", sha="test-sha")
66+
mock_github.search_repositories.return_value = [mock_repo_obj]
67+
mock_github_cls.return_value = mock_github
68+
69+
iterator = iter(github_indexer)
70+
next(iterator)
71+
72+
created_repos = mock_bulk_create.call_args[0][0]
73+
assert len(created_repos) == 1
74+
repo = created_repos[0]
75+
assert repo.name == "test-repo"
76+
assert repo.git_url == "https://github.com/test/test-repo.git"
77+
assert repo.repo_url == "https://github.com/test/test-repo"
78+
assert repo.commit_hash == "test-sha"
79+
80+
@mock.patch("frege.indexers.models._is_repo_unique", return_value=True)
81+
@mock.patch("frege.indexers.models.Repository.objects.bulk_create")
82+
@mock.patch("frege.indexers.models.Github")
83+
@pytest.mark.django_db
84+
def test_query_construction(mock_github_cls, mock_bulk_create, mock_unique, github_indexer):
85+
mock_github = mock.Mock()
86+
mock_github.search_repositories.return_value = []
87+
mock_github_cls.return_value = mock_github
88+
89+
github_indexer.min_forks = 150
90+
github_indexer.min_stars = 250
91+
iterator = iter(github_indexer)
92+
next(iterator)
93+
94+
mock_github.search_repositories.assert_called_once_with(
95+
query="forks:>=150 stars:>=250 is:public",
96+
sort="stars",
97+
page=0
98+
)
99+
100+
@mock.patch("frege.indexers.models.Github")
101+
@pytest.mark.django_db
102+
def test_iter_handles_rate_limit(mock_github_cls, github_indexer):
103+
mock_github = mock.Mock()
104+
mock_github.search_repositories.side_effect = RateLimitExceededException(403, "Rate limited", headers={})
105+
mock_github_cls.return_value = mock_github
106+
107+
iterator = iter(github_indexer)
108+
with pytest.raises(StopIteration):
109+
next(iterator)
110+
111+
assert github_indexer.rate_limit_exceeded is True

0 commit comments

Comments
 (0)