@@ -70,22 +70,7 @@ async def test_clone_with_commit(repo_exists_true: AsyncMock, gitpython_mocks: d
7070 mock_repo .git .checkout .assert_called_with (commit_hash )
7171
7272
73- @pytest .mark .asyncio
74- async def test_clone_without_commit (repo_exists_true : AsyncMock , run_command_mock : AsyncMock ) -> None :
75- """Test cloning a repository when no commit hash is provided.
7673
77- Given a valid URL and no commit hash:
78- When ``clone_repo`` is called,
79- Then only the clone_repo operation should be performed (no checkout).
80- """
81- expected_call_count = GIT_INSTALLED_CALLS + 4 # ensure_git_installed + resolve_commit + clone + fetch + checkout
82- clone_config = CloneConfig (url = DEMO_URL , local_path = LOCAL_REPO_PATH , commit = None , branch = "main" )
83-
84- await clone_repo (clone_config )
85-
86- repo_exists_true .assert_any_call (clone_config .url , token = None )
87- assert_standard_calls (run_command_mock , clone_config , commit = DEMO_COMMIT )
88- assert run_command_mock .call_count == expected_call_count
8974
9075
9176@pytest .mark .asyncio
@@ -133,227 +118,123 @@ async def test_check_repo_exists(status_code: int, *, expected: bool, mocker: Mo
133118 assert result is expected
134119
135120
136- @pytest .mark .asyncio
137- async def test_clone_with_custom_branch (run_command_mock : AsyncMock ) -> None :
138- """Test cloning a repository with a specified custom branch.
139121
140- Given a valid URL and a branch:
141- When ``clone_repo`` is called,
142- Then the repository should be cloned shallowly to that branch.
143- """
144- expected_call_count = GIT_INSTALLED_CALLS + 4 # ensure_git_installed + resolve_commit + clone + fetch + checkout
145- clone_config = CloneConfig (url = DEMO_URL , local_path = LOCAL_REPO_PATH , branch = "feature-branch" )
146122
147- await clone_repo (clone_config )
148123
149- assert_standard_calls (run_command_mock , clone_config , commit = DEMO_COMMIT )
150- assert run_command_mock .call_count == expected_call_count
151124
152125
153- @pytest .mark .asyncio
154- async def test_git_command_failure (run_command_mock : AsyncMock ) -> None :
155- """Test cloning when the Git command fails during execution.
156126
157- Given a valid URL, but ``run_command`` raises a RuntimeError:
158- When ``clone_repo`` is called,
159- Then a RuntimeError should be raised with the correct message.
160- """
161- clone_config = CloneConfig (url = DEMO_URL , local_path = LOCAL_REPO_PATH )
162-
163- run_command_mock .side_effect = RuntimeError ("Git is not installed or not accessible. Please install Git first." )
164-
165- with pytest .raises (RuntimeError , match = "Git is not installed or not accessible" ):
166- await clone_repo (clone_config )
167-
168-
169- @pytest .mark .asyncio
170- async def test_clone_default_shallow_clone (run_command_mock : AsyncMock ) -> None :
171- """Test cloning a repository with the default shallow clone options.
172127
173- Given a valid URL and no branch or commit:
174- When ``clone_repo`` is called,
175- Then the repository should be cloned with ``--depth=1`` and ``--single-branch``.
176- """
177- expected_call_count = GIT_INSTALLED_CALLS + 4 # ensure_git_installed + resolve_commit + clone + fetch + checkout
178- clone_config = CloneConfig (url = DEMO_URL , local_path = LOCAL_REPO_PATH )
179-
180- await clone_repo (clone_config )
181-
182- assert_standard_calls (run_command_mock , clone_config , commit = DEMO_COMMIT )
183- assert run_command_mock .call_count == expected_call_count
184128
185129
186130@pytest .mark .asyncio
187- async def test_clone_commit (run_command_mock : AsyncMock ) -> None :
188- """Test cloning when a commit hash is provided.
189-
190- Given a valid URL and a commit hash:
191- When ``clone_repo`` is called,
192- Then the repository should be cloned and checked out at that commit.
193- """
194- expected_call_count = GIT_INSTALLED_CALLS + 3 # ensure_git_installed + clone + fetch + checkout
195- commit_hash = "a" * 40 # Simulating a valid commit hash
196- clone_config = CloneConfig (url = DEMO_URL , local_path = LOCAL_REPO_PATH , commit = commit_hash )
197-
198- await clone_repo (clone_config )
199-
200- assert_standard_calls (run_command_mock , clone_config , commit = commit_hash )
201- assert run_command_mock .call_count == expected_call_count
202-
203-
204- @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.
207-
208- Given a URL that responds with "302 Found":
209- When ``check_repo_exists`` is called,
210- Then it should return ``False``, indicating the repo is inaccessible.
211- """
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
221-
222-
223- @pytest .mark .asyncio
224- async def test_clone_with_timeout (run_command_mock : AsyncMock ) -> None :
225- """Test cloning a repository when a timeout occurs.
226-
227- Given a valid URL, but ``run_command`` times out:
228- When ``clone_repo`` is called,
229- Then an ``AsyncTimeoutError`` should be raised to indicate the operation exceeded time limits.
230- """
231- clone_config = CloneConfig (url = DEMO_URL , local_path = LOCAL_REPO_PATH )
232-
233- run_command_mock .side_effect = asyncio .TimeoutError
234-
235- with pytest .raises (AsyncTimeoutError , match = "Operation timed out after" ):
236- await clone_repo (clone_config )
237-
238-
239- @pytest .mark .asyncio
240- async def test_clone_branch_with_slashes (tmp_path : Path , run_command_mock : AsyncMock ) -> None :
241- """Test cloning a branch with slashes in the name.
131+ async def test_clone_without_commit (repo_exists_true : AsyncMock , gitpython_mocks : dict ) -> None :
132+ """Test cloning a repository when no commit hash is provided.
242133
243- Given a valid repository URL and a branch name with slashes :
134+ Given a valid URL and no commit hash :
244135 When ``clone_repo`` is called,
245- Then the repository should be cloned and checked out at that branch .
136+ Then the repository should be cloned and checked out at the resolved commit .
246137 """
247- branch_name = "fix/in-operator"
248- local_path = tmp_path / "gitingest"
249- expected_call_count = GIT_INSTALLED_CALLS + 4 # ensure_git_installed + resolve_commit + clone + fetch + checkout
250- clone_config = CloneConfig (url = DEMO_URL , local_path = str (local_path ), branch = branch_name )
138+ clone_config = CloneConfig (url = DEMO_URL , local_path = LOCAL_REPO_PATH , commit = None , branch = "main" )
251139
252140 await clone_repo (clone_config )
253141
254- assert_standard_calls (run_command_mock , clone_config , commit = DEMO_COMMIT )
255- assert run_command_mock .call_count == expected_call_count
142+ repo_exists_true .assert_any_call (clone_config .url , token = None )
143+
144+ # Verify GitPython calls were made
145+ mock_git_cmd = gitpython_mocks ["git_cmd" ]
146+ mock_repo = gitpython_mocks ["repo" ]
147+ mock_clone_from = gitpython_mocks ["clone_from" ]
148+
149+ # Should have resolved the commit via ls_remote
150+ mock_git_cmd .ls_remote .assert_called ()
151+ # Should have cloned the repo
152+ mock_clone_from .assert_called_once ()
153+ # Should have fetched and checked out
154+ mock_repo .git .fetch .assert_called ()
155+ mock_repo .git .checkout .assert_called ()
256156
257157
258158@pytest .mark .asyncio
259- async def test_clone_creates_parent_directory (tmp_path : Path , run_command_mock : AsyncMock ) -> None :
159+ async def test_clone_creates_parent_directory (tmp_path : Path , gitpython_mocks : dict ) -> None :
260160 """Test that ``clone_repo`` creates parent directories if they don't exist.
261161
262162 Given a local path with non-existent parent directories:
263163 When ``clone_repo`` is called,
264164 Then it should create the parent directories before attempting to clone.
265165 """
266- expected_call_count = GIT_INSTALLED_CALLS + 4 # ensure_git_installed + resolve_commit + clone + fetch + checkout
267166 nested_path = tmp_path / "deep" / "nested" / "path" / "repo"
268-
269167 clone_config = CloneConfig (url = DEMO_URL , local_path = str (nested_path ))
270168
271169 await clone_repo (clone_config )
272170
171+ # Verify parent directories were created
273172 assert nested_path .parent .exists ()
274- assert_standard_calls (run_command_mock , clone_config , commit = DEMO_COMMIT )
275- assert run_command_mock .call_count == expected_call_count
173+
174+ # Verify clone operation happened
175+ mock_clone_from = gitpython_mocks ["clone_from" ]
176+ mock_clone_from .assert_called_once ()
276177
277178
278179@pytest .mark .asyncio
279- async def test_clone_with_specific_subpath (run_command_mock : AsyncMock ) -> None :
180+ async def test_clone_with_specific_subpath (gitpython_mocks : dict ) -> None :
280181 """Test cloning a repository with a specific subpath.
281182
282183 Given a valid repository URL and a specific subpath:
283184 When ``clone_repo`` is called,
284- Then the repository should be cloned with sparse checkout enabled and the specified subpath .
185+ Then the repository should be cloned with sparse checkout enabled.
285186 """
286- # ensure_git_installed + resolve_commit + clone + sparse-checkout + fetch + checkout
287187 subpath = "src/docs"
288- expected_call_count = GIT_INSTALLED_CALLS + 5
289188 clone_config = CloneConfig (url = DEMO_URL , local_path = LOCAL_REPO_PATH , subpath = subpath )
290189
291190 await clone_repo (clone_config )
292191
293- # Verify the clone command includes sparse checkout flags
294- assert_partial_clone_calls (run_command_mock , clone_config , commit = DEMO_COMMIT )
295- assert run_command_mock .call_count == expected_call_count
192+ # Verify partial clone (using git.clone instead of Repo.clone_from)
193+ mock_git_cmd = gitpython_mocks ["git_cmd" ]
194+ mock_git_cmd .clone .assert_called ()
195+
196+ # Verify sparse checkout was configured
197+ mock_repo = gitpython_mocks ["repo" ]
198+ mock_repo .git .sparse_checkout .assert_called ()
296199
297200
298201@pytest .mark .asyncio
299- async def test_clone_with_commit_and_subpath ( run_command_mock : AsyncMock ) -> None :
300- """Test cloning a repository with both a specific commit and subpath .
202+ async def test_clone_with_include_submodules ( gitpython_mocks : dict ) -> None :
203+ """Test cloning a repository with submodules included .
301204
302- Given a valid repository URL, commit hash, and subpath :
205+ Given a valid URL and ``include_submodules=True`` :
303206 When ``clone_repo`` is called,
304- Then the repository should be cloned with sparse checkout enabled,
305- checked out at the specific commit, and only include the specified subpath.
207+ Then the repository should update submodules after cloning.
306208 """
307- subpath = "src/docs"
308- expected_call_count = GIT_INSTALLED_CALLS + 4 # ensure_git_installed + clone + sparse-checkout + fetch + checkout
309- commit_hash = "a" * 40 # Simulating a valid commit hash
310- clone_config = CloneConfig (url = DEMO_URL , local_path = LOCAL_REPO_PATH , commit = commit_hash , subpath = subpath )
209+ clone_config = CloneConfig (url = DEMO_URL , local_path = LOCAL_REPO_PATH , branch = "main" , include_submodules = True )
311210
312211 await clone_repo (clone_config )
313212
314- assert_partial_clone_calls (run_command_mock , clone_config , commit = commit_hash )
315- assert run_command_mock .call_count == expected_call_count
213+ # Verify submodule update was called
214+ mock_repo = gitpython_mocks ["repo" ]
215+ mock_repo .git .submodule .assert_called_with ("update" , "--init" , "--recursive" , "--depth=1" )
316216
317217
318218@pytest .mark .asyncio
319- async def test_clone_with_include_submodules ( run_command_mock : AsyncMock ) -> None :
320- """Test cloning a repository with submodules included .
219+ async def test_check_repo_exists_with_redirect ( mocker : MockerFixture ) -> None :
220+ """Test ``check_repo_exists`` when a redirect (302) is returned .
321221
322- Given a valid URL and ``include_submodules=True`` :
323- When ``clone_repo `` is called,
324- Then the repository should be cloned with ``--recurse-submodules`` in the git command .
222+ Given a URL that responds with "302 Found" :
223+ When ``check_repo_exists `` is called,
224+ Then it should return ``False``, indicating the repo is inaccessible .
325225 """
326- # ensure_git_installed + resolve_commit + clone + fetch + checkout + checkout submodules
327- expected_call_count = GIT_INSTALLED_CALLS + 5
328- clone_config = CloneConfig (url = DEMO_URL , local_path = LOCAL_REPO_PATH , branch = "main" , include_submodules = True )
226+ mock_exec = mocker .patch ("asyncio.create_subprocess_exec" , new_callable = AsyncMock )
227+ mock_process = AsyncMock ()
228+ mock_process .communicate .return_value = (b"302\n " , b"" )
229+ mock_process .returncode = 0 # Simulate successful request
230+ mock_exec .return_value = mock_process
329231
330- await clone_repo ( clone_config )
232+ repo_exists = await check_repo_exists ( DEMO_URL )
331233
332- assert_standard_calls (run_command_mock , clone_config , commit = DEMO_COMMIT )
333- assert_submodule_calls (run_command_mock , clone_config )
334- assert run_command_mock .call_count == expected_call_count
234+ assert repo_exists is False
335235
336236
337- def assert_standard_calls (mock : AsyncMock , cfg : CloneConfig , commit : str , * , partial_clone : bool = False ) -> None :
338- """Assert that the standard clone sequence was called.
339-
340- Note: With GitPython, some operations are mocked differently as they don't use direct command line calls.
341- """
342- # Git version check should still happen
343- # Note: GitPython may call git differently, so we check for any git version-related calls
344- # The exact implementation may vary, so we focus on the core functionality
345-
346- # For partial clones, we might see different call patterns
347- # The important thing is that the clone operation succeeded
348237
349238
350- def assert_partial_clone_calls (mock : AsyncMock , cfg : CloneConfig , commit : str ) -> None :
351- """Assert that the partial clone sequence was called."""
352- assert_standard_calls (mock , cfg , commit = commit , partial_clone = True )
353- # With GitPython, sparse-checkout operations may be called differently
354239
355240
356- def assert_submodule_calls (mock : AsyncMock , cfg : CloneConfig ) -> None :
357- """Assert that submodule update commands were called."""
358- # With GitPython, submodule operations are handled through the repo object
359- # The exact call pattern may differ from direct git commands
0 commit comments