@@ -74,3 +74,98 @@ async def test_check_repo_exists() -> None:
7474 # Test failed request
7575 mock_process .returncode = 1
7676 assert await _check_repo_exists (url ) is False
77+
78+
79+ @pytest .mark .asyncio
80+ async def test_clone_repo_invalid_url () -> None :
81+ clone_config = CloneConfig (
82+ url = "" ,
83+ local_path = "/tmp/repo" ,
84+ )
85+ with pytest .raises (ValueError , match = "The 'url' parameter is required." ):
86+ await clone_repo (clone_config )
87+
88+
89+ @pytest .mark .asyncio
90+ async def test_clone_repo_invalid_local_path () -> None :
91+ clone_config = CloneConfig (
92+ url = "https://github.com/user/repo" ,
93+ local_path = "" ,
94+ )
95+ with pytest .raises (ValueError , match = "The 'local_path' parameter is required." ):
96+ await clone_repo (clone_config )
97+
98+
99+ @pytest .mark .asyncio
100+ async def test_clone_repo_with_custom_branch () -> None :
101+ clone_config = CloneConfig (
102+ url = "https://github.com/user/repo" ,
103+ local_path = "/tmp/repo" ,
104+ branch = "feature-branch" ,
105+ )
106+ with patch ("gitingest.clone._check_repo_exists" , return_value = True ):
107+ with patch ("gitingest.clone._run_git_command" , new_callable = AsyncMock ) as mock_exec :
108+ await clone_repo (clone_config )
109+ mock_exec .assert_called_once_with (
110+ "git" ,
111+ "clone" ,
112+ "--depth=1" ,
113+ "--single-branch" ,
114+ "--branch" ,
115+ "feature-branch" ,
116+ clone_config .url ,
117+ clone_config .local_path ,
118+ )
119+
120+
121+ @pytest .mark .asyncio
122+ async def test_git_command_failure () -> None :
123+ clone_config = CloneConfig (
124+ url = "https://github.com/user/repo" ,
125+ local_path = "/tmp/repo" ,
126+ )
127+ with patch ("gitingest.clone._check_repo_exists" , return_value = True ):
128+ with patch ("gitingest.clone._run_git_command" , side_effect = RuntimeError ("Git command failed" )):
129+ with pytest .raises (RuntimeError , match = "Git command failed" ):
130+ await clone_repo (clone_config )
131+
132+
133+ @pytest .mark .asyncio
134+ async def test_clone_repo_default_shallow_clone () -> None :
135+ clone_config = CloneConfig (
136+ url = "https://github.com/user/repo" ,
137+ local_path = "/tmp/repo" ,
138+ )
139+ with patch ("gitingest.clone._check_repo_exists" , return_value = True ):
140+ with patch ("gitingest.clone._run_git_command" , new_callable = AsyncMock ) as mock_exec :
141+ await clone_repo (clone_config )
142+ mock_exec .assert_called_once_with (
143+ "git" , "clone" , "--depth=1" , "--single-branch" , clone_config .url , clone_config .local_path
144+ )
145+
146+
147+ @pytest .mark .asyncio
148+ async def test_clone_repo_commit_without_branch () -> None :
149+ clone_config = CloneConfig (
150+ url = "https://github.com/user/repo" ,
151+ local_path = "/tmp/repo" ,
152+ commit = "a" * 40 , # Simulating a valid commit hash
153+ )
154+ with patch ("gitingest.clone._check_repo_exists" , return_value = True ):
155+ with patch ("gitingest.clone._run_git_command" , new_callable = AsyncMock ) as mock_exec :
156+ await clone_repo (clone_config )
157+ assert mock_exec .call_count == 2 # Clone and checkout calls
158+ mock_exec .assert_any_call ("git" , "clone" , "--single-branch" , clone_config .url , clone_config .local_path )
159+ mock_exec .assert_any_call ("git" , "-C" , clone_config .local_path , "checkout" , clone_config .commit )
160+
161+
162+ @pytest .mark .asyncio
163+ async def test_check_repo_exists_with_redirect () -> None :
164+ url = "https://github.com/user/repo"
165+ with patch ("asyncio.create_subprocess_exec" , new_callable = AsyncMock ) as mock_exec :
166+ mock_process = AsyncMock ()
167+ mock_process .communicate .return_value = (b"HTTP/1.1 302 Found\n " , b"" )
168+ mock_process .returncode = 0 # Simulate successful request
169+ mock_exec .return_value = mock_process
170+
171+ assert await _check_repo_exists (url )
0 commit comments