Skip to content

Commit b66a3bf

Browse files
feat: add tests for github_update_external_repositories
1 parent 7c69f95 commit b66a3bf

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
from unittest import mock
2+
3+
import pytest
4+
5+
from apps.github.management.commands.github_update_external_repositories import (
6+
GITHUB_ITEMS_PER_PAGE,
7+
Command,
8+
Organization,
9+
Project
10+
)
11+
12+
@pytest.fixture
13+
def command():
14+
return Command()
15+
16+
@pytest.fixture
17+
def mock_gh_repository():
18+
repo = mock.Mock()
19+
repo.name = "test-repo"
20+
repo.html_url = "https://github.com/TestOrg/test-repo"
21+
return repo
22+
23+
@pytest.mark.parametrize(
24+
"num_orgs, num_repos_per_org, expected_sync_calls, expected_bulk_save_calls",
25+
[
26+
(1, [2], 2, 1), # 1 org with 2 repos
27+
(2, [1, 3], 4, 2), # 2 orgs with 1 and 3 repos
28+
(2, [0, 2], 2, 1), # 1 org with repos, 1 without
29+
]
30+
)
31+
@mock.patch.dict("os.environ", {"GITHUB_TOKEN": "valid-token"})
32+
@mock.patch("apps.github.management.commands.github_update_external_repositories.github.Github")
33+
@mock.patch("apps.github.management.commands.github_update_external_repositories.sync_repository")
34+
@mock.patch("apps.github.management.commands.github_update_external_repositories.Project.bulk_save")
35+
@mock.patch("apps.github.management.commands.github_update_external_repositories.Organization.objects.filter")
36+
def test_handle_success(
37+
mock_org_filter,
38+
mock_bulk_save,
39+
mock_sync_repository,
40+
mock_github,
41+
command,
42+
mock_gh_repository,
43+
num_orgs,
44+
num_repos_per_org,
45+
expected_sync_calls,
46+
expected_bulk_save_calls
47+
):
48+
"""Test command execution with varying organizations and repositories."""
49+
mock_gh = mock_github.return_value
50+
51+
orgs = []
52+
gh_orgs = []
53+
for i in range(num_orgs):
54+
org = mock.Mock(spec=Organization)
55+
org.login = f"TestOrg{i+1}"
56+
org.is_owasp_related_organization = True
57+
orgs.append(org)
58+
59+
gh_org = mock.Mock()
60+
gh_repos = mock.MagicMock()
61+
gh_repos.totalCount = num_repos_per_org[i]
62+
gh_repos.__iter__.return_value = [mock_gh_repository] * num_repos_per_org[i]
63+
gh_org.get_repos.return_value = gh_repos
64+
gh_orgs.append(gh_org)
65+
66+
qs_mock = mock.MagicMock()
67+
qs_mock.count.return_value = num_orgs
68+
qs_mock.__iter__.return_value = orgs
69+
mock_org_filter.return_value.exclude.return_value = qs_mock
70+
71+
mock_gh.get_organization.side_effect = gh_orgs
72+
73+
mock_project = mock.Mock(spec=Project)
74+
mock_sync_repository.side_effect = lambda gh_repo: (orgs[0], mock.Mock(project=mock_project))
75+
76+
with mock.patch("builtins.print"):
77+
command.handle()
78+
79+
mock_github.assert_called_once_with("valid-token", per_page=GITHUB_ITEMS_PER_PAGE)
80+
81+
assert mock_gh.get_organization.call_count == num_orgs
82+
for i, org in enumerate(orgs):
83+
mock_gh.get_organization.assert_any_call(org.login)
84+
85+
assert mock_sync_repository.call_count == expected_sync_calls
86+
87+
assert mock_bulk_save.call_count == expected_bulk_save_calls
88+
89+
@pytest.mark.parametrize(
90+
"num_repos, expected_project_count",
91+
[
92+
(1, 1), # 1 repo with 1 project
93+
(3, 3), # 3 repos with 3 projects
94+
(2, 0), # 2 repos without 0 projects
95+
]
96+
)
97+
@mock.patch("apps.github.management.commands.github_update_external_repositories.sync_repository")
98+
def test_sync_organization_repositories(
99+
mock_sync_repository,
100+
command,
101+
mock_gh_repository,
102+
num_repos,
103+
expected_project_count
104+
):
105+
"""Test repository synchronization with varying repository counts."""
106+
mock_organization = mock.Mock(spec=Organization)
107+
mock_organization.login = "TestOrg"
108+
109+
mock_repositories = mock.MagicMock()
110+
mock_repositories.totalCount = num_repos
111+
mock_repositories.__iter__.return_value = [mock_gh_repository] * num_repos
112+
113+
mock_project = mock.Mock(spec=Project)
114+
if expected_project_count > 0:
115+
mock_sync_repository.return_value = (mock_organization, mock.Mock(project=mock_project))
116+
else:
117+
mock_sync_repository.return_value = (mock_organization, mock.Mock(project=None))
118+
119+
projects = command.sync_organization_repositories(mock_organization, mock_repositories)
120+
121+
assert len(projects) == expected_project_count
122+
assert mock_sync_repository.call_count == num_repos

0 commit comments

Comments
 (0)