@@ -20,14 +20,15 @@ async def test_mount_success(self, mock_coordinator):
2020 with patch ("shutil.which" , return_value = "/usr/bin/copilot" ):
2121 with patch ("os.path.isfile" , return_value = True ):
2222 with patch ("os.path.isabs" , return_value = True ):
23- cleanup = await mount (mock_coordinator , {"model" : "claude-opus-4.5" })
23+ with patch ("amplifier_module_provider_github_copilot._ensure_executable" ):
24+ cleanup = await mount (mock_coordinator , {"model" : "claude-opus-4.5" })
2425
25- # Should return cleanup function
26- assert cleanup is not None
27- assert callable (cleanup )
26+ # Should return cleanup function
27+ assert cleanup is not None
28+ assert callable (cleanup )
2829
29- # Provider should be mounted
30- assert "github-copilot" in mock_coordinator .mounted_providers
30+ # Provider should be mounted
31+ assert "github-copilot" in mock_coordinator .mounted_providers
3132
3233 @pytest .mark .asyncio
3334 async def test_mount_missing_cli (self , mock_coordinator ):
@@ -47,60 +48,64 @@ async def test_mount_with_custom_cli_path(self, mock_coordinator):
4748 with patch ("shutil.which" ) as mock_which :
4849 with patch ("os.path.isfile" , return_value = True ):
4950 with patch ("os.path.isabs" , return_value = True ):
50- mock_which .return_value = "/custom/path/copilot"
51+ with patch ("amplifier_module_provider_github_copilot._ensure_executable" ):
52+ mock_which .return_value = "/custom/path/copilot"
5153
52- cleanup = await mount (
53- mock_coordinator ,
54- {"cli_path" : "/custom/path/copilot" },
55- )
54+ cleanup = await mount (
55+ mock_coordinator ,
56+ {"cli_path" : "/custom/path/copilot" },
57+ )
5658
57- assert cleanup is not None
59+ assert cleanup is not None
5860
5961 @pytest .mark .asyncio
6062 async def test_mount_cleanup_function (self , mock_coordinator ):
6163 """Cleanup function should close provider."""
6264 with patch ("shutil.which" , return_value = "/usr/bin/copilot" ):
6365 with patch ("os.path.isfile" , return_value = True ):
6466 with patch ("os.path.isabs" , return_value = True ):
65- cleanup = await mount (mock_coordinator , {})
67+ with patch ("amplifier_module_provider_github_copilot._ensure_executable" ):
68+ cleanup = await mount (mock_coordinator , {})
6669
67- assert cleanup is not None
70+ assert cleanup is not None
6871
69- # Get the mounted provider
70- provider = mock_coordinator .mounted_providers .get ("github-copilot" )
71- assert provider is not None
72+ # Get the mounted provider
73+ provider = mock_coordinator .mounted_providers .get ("github-copilot" )
74+ assert provider is not None
7275
73- # Mock the provider's close method
74- with patch .object (provider , "close" , new_callable = AsyncMock ) as mock_close :
75- await cleanup ()
76- mock_close .assert_called_once ()
76+ # Mock the provider's close method
77+ with patch .object (provider , "close" , new_callable = AsyncMock ) as mock_close :
78+ await cleanup ()
79+ mock_close .assert_called_once ()
7780
7881 @pytest .mark .asyncio
7982 async def test_mount_default_config (self , mock_coordinator ):
8083 """Mount should work with no config (uses defaults)."""
8184 with patch ("shutil.which" , return_value = "/usr/bin/copilot" ):
8285 with patch ("os.path.isfile" , return_value = True ):
8386 with patch ("os.path.isabs" , return_value = True ):
84- cleanup = await mount (mock_coordinator , None )
87+ with patch ("amplifier_module_provider_github_copilot._ensure_executable" ):
88+ cleanup = await mount (mock_coordinator , None )
8589
86- assert cleanup is not None
87- provider = mock_coordinator .mounted_providers .get ("github-copilot" )
88- assert provider ._model == "claude-opus-4.5" # Default model
90+ assert cleanup is not None
91+ provider = mock_coordinator .mounted_providers .get ("github-copilot" )
92+ assert provider ._model == "claude-opus-4.5" # Default model
8993
9094 @pytest .mark .asyncio
9195 async def test_mount_registers_with_coordinator (self , mock_coordinator ):
9296 """Mount should call coordinator.mount with correct arguments."""
9397 with patch ("shutil.which" , return_value = "/usr/bin/copilot" ):
9498 with patch ("os.path.isfile" , return_value = True ):
9599 with patch ("os.path.isabs" , return_value = True ):
96- await mount (mock_coordinator , {})
100+ with patch ("amplifier_module_provider_github_copilot._ensure_executable" ):
101+ await mount (mock_coordinator , {})
97102
98- # Verify mount was called
99- mock_coordinator .mount .assert_called_once ()
100- call_args = mock_coordinator .mount .call_args
103+ # Verify mount was called
104+ mock_coordinator .mount .assert_called_once ()
105+ call_args = mock_coordinator .mount .call_args
101106
102- assert call_args [0 ][0 ] == "providers" # category
103- assert call_args [1 ]["name" ] == "github-copilot"
107+ assert call_args [0 ][0 ] == "providers" # category
108+ assert call_args [1 ]["name" ] == "github-copilot"
104109
105110
106111class TestModuleMetadata :
@@ -152,15 +157,16 @@ async def test_mount_returns_none_on_provider_init_error(self, mock_coordinator)
152157 with patch ("shutil.which" , return_value = "/usr/bin/copilot" ):
153158 with patch ("os.path.isfile" , return_value = True ):
154159 with patch ("os.path.isabs" , return_value = True ):
155- # Make coordinator.mount raise during provider registration
156- mock_coordinator .mount = AsyncMock (
157- side_effect = RuntimeError ("Mount failed: config error" )
158- )
160+ with patch ("amplifier_module_provider_github_copilot._ensure_executable" ):
161+ # Make coordinator.mount raise during provider registration
162+ mock_coordinator .mount = AsyncMock (
163+ side_effect = RuntimeError ("Mount failed: config error" )
164+ )
159165
160- cleanup = await mount (mock_coordinator , {})
166+ cleanup = await mount (mock_coordinator , {})
161167
162- # Should return None (graceful degradation)
163- assert cleanup is None
168+ # Should return None (graceful degradation)
169+ assert cleanup is None
164170
165171
166172class TestFindCopilotCli :
@@ -172,9 +178,10 @@ def test_cli_from_config(self):
172178
173179 with patch ("os.path.isabs" , return_value = True ):
174180 with patch ("os.path.isfile" , return_value = True ):
175- result = _find_copilot_cli ({"cli_path" : "/custom/copilot" })
181+ with patch ("amplifier_module_provider_github_copilot._ensure_executable" ):
182+ result = _find_copilot_cli ({"cli_path" : "/custom/copilot" })
176183
177- assert result == "/custom/copilot"
184+ assert result == "/custom/copilot"
178185
179186 def test_cli_from_env_var (self ):
180187 """_find_copilot_cli should check COPILOT_CLI_PATH env var."""
@@ -183,9 +190,10 @@ def test_cli_from_env_var(self):
183190 with patch .dict ("os.environ" , {"COPILOT_CLI_PATH" : "/env/copilot" }):
184191 with patch ("os.path.isabs" , return_value = True ):
185192 with patch ("os.path.isfile" , return_value = True ):
186- result = _find_copilot_cli ({})
193+ with patch ("amplifier_module_provider_github_copilot._ensure_executable" ):
194+ result = _find_copilot_cli ({})
187195
188- assert result == "/env/copilot"
196+ assert result == "/env/copilot"
189197
190198 def test_cli_from_shutil_which (self ):
191199 """_find_copilot_cli should fall back to shutil.which()."""
@@ -195,9 +203,10 @@ def test_cli_from_shutil_which(self):
195203 with patch ("shutil.which" , return_value = "/usr/bin/copilot" ):
196204 with patch ("os.path.isabs" , return_value = True ):
197205 with patch ("os.path.isfile" , return_value = True ):
198- result = _find_copilot_cli ({})
206+ with patch ("amplifier_module_provider_github_copilot._ensure_executable" ):
207+ result = _find_copilot_cli ({})
199208
200- assert result == "/usr/bin/copilot"
209+ assert result == "/usr/bin/copilot"
201210
202211 def test_cli_not_found_returns_none (self ):
203212 """_find_copilot_cli should return None when CLI not found."""
@@ -225,9 +234,10 @@ def test_cli_relative_path_resolved_via_which(self):
225234
226235 with patch ("os.path.isabs" , return_value = False ):
227236 with patch ("shutil.which" , return_value = "/resolved/path/copilot" ):
228- result = _find_copilot_cli ({"cli_path" : "copilot" })
237+ with patch ("amplifier_module_provider_github_copilot._ensure_executable" ):
238+ result = _find_copilot_cli ({"cli_path" : "copilot" })
229239
230- assert result == "/resolved/path/copilot"
240+ assert result == "/resolved/path/copilot"
231241
232242 def test_cli_relative_path_not_found_in_path (self ):
233243 """_find_copilot_cli should return None if relative path not in PATH."""
0 commit comments