|
8 | 8 |
|
9 | 9 | import sys |
10 | 10 | from typing import TYPE_CHECKING |
11 | | -from unittest.mock import AsyncMock |
12 | 11 |
|
13 | | -import httpx |
| 12 | +import git |
14 | 13 | import pytest |
15 | | -from starlette.status import HTTP_200_OK, HTTP_401_UNAUTHORIZED, HTTP_403_FORBIDDEN, HTTP_404_NOT_FOUND |
16 | 14 |
|
17 | 15 | from gitingest.clone import clone_repo |
18 | 16 | from gitingest.schemas import CloneConfig |
|
21 | 19 |
|
22 | 20 | if TYPE_CHECKING: |
23 | 21 | from pathlib import Path |
| 22 | + from unittest.mock import AsyncMock |
24 | 23 |
|
25 | 24 | from pytest_mock import MockerFixture |
26 | 25 |
|
@@ -93,24 +92,31 @@ async def test_clone_nonexistent_repository(repo_exists_true: AsyncMock) -> None |
93 | 92 |
|
94 | 93 | @pytest.mark.asyncio |
95 | 94 | @pytest.mark.parametrize( |
96 | | - ("status_code", "expected"), |
| 95 | + ("git_command_succeeds", "expected"), |
97 | 96 | [ |
98 | | - (HTTP_200_OK, True), |
99 | | - (HTTP_401_UNAUTHORIZED, False), |
100 | | - (HTTP_403_FORBIDDEN, False), |
101 | | - (HTTP_404_NOT_FOUND, False), |
| 97 | + (True, True), # git ls-remote succeeds -> repo exists |
| 98 | + (False, False), # git ls-remote fails -> repo doesn't exist or no access |
102 | 99 | ], |
103 | 100 | ) |
104 | | -async def test_check_repo_exists(status_code: int, *, expected: bool, mocker: MockerFixture) -> None: |
105 | | - """Verify that ``check_repo_exists`` interprets httpx results correctly.""" |
106 | | - mock_client = AsyncMock() |
107 | | - mock_client.__aenter__.return_value = mock_client # context-manager protocol |
108 | | - mock_client.head.return_value = httpx.Response(status_code=status_code) |
109 | | - mocker.patch("httpx.AsyncClient", return_value=mock_client) |
| 101 | +async def test_check_repo_exists( |
| 102 | + git_command_succeeds: bool, # noqa: FBT001 |
| 103 | + *, |
| 104 | + expected: bool, |
| 105 | + mocker: MockerFixture, |
| 106 | +) -> None: |
| 107 | + """Verify that ``check_repo_exists`` interprets git ls-remote results correctly.""" |
| 108 | + mock_git = mocker.patch("git.Git") |
| 109 | + mock_git_instance = mock_git.return_value |
| 110 | + |
| 111 | + if git_command_succeeds: |
| 112 | + mock_git_instance.ls_remote.return_value = "abc123\trefs/heads/main\n" |
| 113 | + else: |
| 114 | + mock_git_instance.ls_remote.side_effect = git.GitCommandError("ls-remote", 128) |
110 | 115 |
|
111 | 116 | result = await check_repo_exists(DEMO_URL) |
112 | 117 |
|
113 | 118 | assert result is expected |
| 119 | + mock_git_instance.ls_remote.assert_called_once_with(DEMO_URL, "--exit-code") |
114 | 120 |
|
115 | 121 |
|
116 | 122 | @pytest.mark.asyncio |
@@ -202,19 +208,27 @@ async def test_clone_with_include_submodules(gitpython_mocks: dict) -> None: |
202 | 208 |
|
203 | 209 |
|
204 | 210 | @pytest.mark.asyncio |
205 | | -async def test_check_repo_exists_with_redirect(mocker: MockerFixture) -> None: |
206 | | - """Test ``check_repo_exists`` when a redirect (302) is returned. |
| 211 | +async def test_check_repo_exists_with_auth_token(mocker: MockerFixture) -> None: |
| 212 | + """Test ``check_repo_exists`` with authentication token. |
207 | 213 |
|
208 | | - Given a URL that responds with "302 Found": |
| 214 | + Given a GitHub URL and a token: |
209 | 215 | When ``check_repo_exists`` is called, |
210 | | - Then it should return ``False``, indicating the repo is inaccessible. |
| 216 | + Then it should add the token to the URL and call git ls-remote. |
211 | 217 | """ |
212 | | - mock_exec = mocker.patch("asyncio.create_subprocess_exec", new_callable=AsyncMock) |
213 | | - mock_process = AsyncMock() |
214 | | - mock_process.communicate.return_value = (b"302\n", b"") |
215 | | - mock_process.returncode = 0 # Simulate successful request |
216 | | - mock_exec.return_value = mock_process |
217 | | - |
218 | | - repo_exists = await check_repo_exists(DEMO_URL) |
219 | | - |
220 | | - assert repo_exists is False |
| 218 | + mock_git = mocker.patch("git.Git") |
| 219 | + mock_git_instance = mock_git.return_value |
| 220 | + mock_git_instance.ls_remote.return_value = "abc123\trefs/heads/main\n" |
| 221 | + |
| 222 | + # Mock the _add_token_to_url function |
| 223 | + mock_add_token = mocker.patch("gitingest.utils.git_utils._add_token_to_url") |
| 224 | + mock_add_token.return_value = "https://x-oauth-basic:token123@github.com/test/repo" |
| 225 | + |
| 226 | + test_token = "token123" # noqa: S105 |
| 227 | + result = await check_repo_exists("https://github.com/test/repo", token=test_token) |
| 228 | + |
| 229 | + assert result is True |
| 230 | + mock_add_token.assert_called_once_with("https://github.com/test/repo", "token123") |
| 231 | + mock_git_instance.ls_remote.assert_called_once_with( |
| 232 | + "https://x-oauth-basic:token123@github.com/test/repo", |
| 233 | + "--exit-code", |
| 234 | + ) |
0 commit comments