@@ -163,3 +163,71 @@ async def api_request(**kwargs):
163163 assert created .new_project ["name" ] == "My Project"
164164 # Path should be permalink-like (kebab)
165165 assert seen ["create_payload" ]["path" ] == "my-project"
166+
167+
168+ @pytest .mark .asyncio
169+ async def test_make_api_request_prefers_api_key_over_oauth (config_home , config_manager ):
170+ """API key in config should be used without needing an OAuth token on disk."""
171+ # Arrange: set an API key in config, no OAuth token on disk
172+ config = config_manager .load_config ()
173+ config .cloud_api_key = "bmc_test_key_12345"
174+ config_manager .save_config (config )
175+
176+ async def handler (request : httpx .Request ) -> httpx .Response :
177+ # Verify the API key is sent as the Bearer token
178+ assert request .headers .get ("authorization" ) == "Bearer bmc_test_key_12345"
179+ return httpx .Response (200 , json = {"ok" : True })
180+
181+ transport = httpx .MockTransport (handler )
182+
183+ @asynccontextmanager
184+ async def http_client_factory ():
185+ async with httpx .AsyncClient (transport = transport ) as client :
186+ yield client
187+
188+ # Act — no auth= parameter, no OAuth token file; should use API key from config
189+ resp = await make_api_request (
190+ method = "GET" ,
191+ url = "https://cloud.example.test/proxy/health" ,
192+ http_client_factory = http_client_factory ,
193+ )
194+
195+ # Assert
196+ assert resp .json ()["ok" ] is True
197+
198+
199+ @pytest .mark .asyncio
200+ async def test_make_api_request_falls_back_to_oauth_when_no_api_key (config_home , config_manager ):
201+ """When no API key is configured, should fall back to OAuth token."""
202+ # Arrange: no API key, but OAuth token on disk
203+ config = config_manager .load_config ()
204+ config .cloud_api_key = None
205+ config_manager .save_config (config )
206+
207+ auth = CLIAuth (client_id = "cid" , authkit_domain = "https://auth.example.test" )
208+ auth .token_file .parent .mkdir (parents = True , exist_ok = True )
209+ auth .token_file .write_text (
210+ '{"access_token":"oauth-token-456","refresh_token":null,'
211+ '"expires_at":9999999999,"token_type":"Bearer"}' ,
212+ encoding = "utf-8" ,
213+ )
214+
215+ async def handler (request : httpx .Request ) -> httpx .Response :
216+ assert request .headers .get ("authorization" ) == "Bearer oauth-token-456"
217+ return httpx .Response (200 , json = {"ok" : True })
218+
219+ transport = httpx .MockTransport (handler )
220+
221+ @asynccontextmanager
222+ async def http_client_factory ():
223+ async with httpx .AsyncClient (transport = transport ) as client :
224+ yield client
225+
226+ resp = await make_api_request (
227+ method = "GET" ,
228+ url = "https://cloud.example.test/proxy/health" ,
229+ auth = auth ,
230+ http_client_factory = http_client_factory ,
231+ )
232+
233+ assert resp .json ()["ok" ] is True
0 commit comments