@@ -99,24 +99,30 @@ async def test_clone_nonexistent_repository(repo_exists_true: AsyncMock) -> None
9999
100100@pytest .mark .asyncio
101101@pytest .mark .parametrize (
102- ("status_code " , "expected" ),
102+ ("returncode " , "expected" ),
103103 [
104- (HTTP_200_OK , True ),
105- (HTTP_401_UNAUTHORIZED , False ),
106- (HTTP_403_FORBIDDEN , False ),
107- (HTTP_404_NOT_FOUND , False ),
104+ (0 , True ), # Repository exists and is accessible
105+ (2 , False ), # Repository doesn't exist or is not accessible
106+ (128 , False ), # Git error (e.g., authentication failure)
108107 ],
109108)
110- async def test_check_repo_exists (status_code : int , * , expected : bool , mocker : MockerFixture ) -> None :
111- """Verify that ``check_repo_exists`` interprets httpx results correctly."""
112- mock_client = AsyncMock ()
113- mock_client .__aenter__ .return_value = mock_client # context-manager protocol
114- mock_client .head .return_value = httpx .Response (status_code = status_code )
115- mocker .patch ("httpx.AsyncClient" , return_value = mock_client )
109+ async def test_check_repo_exists (returncode : int , * , expected : bool , mocker : MockerFixture ) -> None :
110+ """Verify that ``check_repo_exists`` interprets git ls-remote results correctly."""
111+ mock_exec = mocker .patch ("asyncio.create_subprocess_exec" , new_callable = AsyncMock )
112+ mock_process = AsyncMock ()
113+ mock_process .communicate .return_value = (b"" , b"" )
114+ mock_process .returncode = returncode
115+ mock_exec .return_value = mock_process
116116
117117 result = await check_repo_exists (DEMO_URL )
118118
119119 assert result is expected
120+ # Verify that git ls-remote was called with the correct arguments
121+ mock_exec .assert_called_once_with (
122+ "git" , "ls-remote" , "--exit-code" , DEMO_URL , "HEAD" ,
123+ stdout = asyncio .subprocess .PIPE ,
124+ stderr = asyncio .subprocess .PIPE ,
125+ )
120126
121127
122128@pytest .mark .asyncio
@@ -188,24 +194,53 @@ async def test_clone_commit(run_command_mock: AsyncMock) -> None:
188194
189195
190196@pytest .mark .asyncio
191- async def test_check_repo_exists_with_redirect (mocker : MockerFixture ) -> None :
192- """Test ``check_repo_exists`` when a redirect (302) is returned .
197+ async def test_check_repo_exists_with_exception (mocker : MockerFixture ) -> None :
198+ """Test ``check_repo_exists`` when an exception occurs during git ls-remote .
193199
194- Given a URL that responds with "302 Found" :
200+ Given a git ls-remote command that raises an exception :
195201 When ``check_repo_exists`` is called,
196202 Then it should return ``False``, indicating the repo is inaccessible.
197203 """
198204 mock_exec = mocker .patch ("asyncio.create_subprocess_exec" , new_callable = AsyncMock )
199- mock_process = AsyncMock ()
200- mock_process .communicate .return_value = (b"302\n " , b"" )
201- mock_process .returncode = 0 # Simulate successful request
202- mock_exec .return_value = mock_process
205+ mock_exec .side_effect = Exception ("Git command failed" )
203206
204207 repo_exists = await check_repo_exists (DEMO_URL )
205208
206209 assert repo_exists is False
207210
208211
212+ @pytest .mark .asyncio
213+ async def test_check_repo_exists_with_token (mocker : MockerFixture ) -> None :
214+ """Test ``check_repo_exists`` with GitHub token authentication.
215+
216+ Given a GitHub URL and a token:
217+ When ``check_repo_exists`` is called,
218+ Then it should include the authentication header in the git ls-remote command.
219+ """
220+ mock_exec = mocker .patch ("asyncio.create_subprocess_exec" , new_callable = AsyncMock )
221+ mock_process = AsyncMock ()
222+ mock_process .communicate .return_value = (b"" , b"" )
223+ mock_process .returncode = 0
224+ mock_exec .return_value = mock_process
225+
226+ mock_auth_header = mocker .patch ("gitingest.utils.git_utils.create_git_auth_header" )
227+ mock_auth_header .return_value = "http.extraheader=Authorization: Bearer test_token"
228+
229+ github_url = "https://github.com/owner/repo"
230+ result = await check_repo_exists (github_url , token = "test_token" )
231+
232+ assert result is True
233+ # Verify that authentication header was created
234+ mock_auth_header .assert_called_once_with ("test_token" , url = github_url )
235+ # Verify that git ls-remote was called with the authentication config
236+ mock_exec .assert_called_once_with (
237+ "git" , "ls-remote" , "-c" , "http.extraheader=Authorization: Bearer test_token" ,
238+ "--exit-code" , github_url , "HEAD" ,
239+ stdout = asyncio .subprocess .PIPE ,
240+ stderr = asyncio .subprocess .PIPE ,
241+ )
242+
243+
209244@pytest .mark .asyncio
210245async def test_clone_with_timeout (run_command_mock : AsyncMock ) -> None :
211246 """Test cloning a repository when a timeout occurs.
0 commit comments