@@ -304,59 +304,62 @@ def test_check_connector(
304304 pytest .fail (f"API call failed: { e } " )
305305
306306
307- @pytest .mark .parametrize (
308- "bogus_api_root" ,
309- [
310- pytest .param (
311- "https://bogus.invalid.example.com/api/v1" ,
312- id = "completely_invalid_host" ,
313- ),
314- pytest .param (
315- "https://httpbin.org/status/404" ,
316- id = "httpbin_404_endpoint" ,
317- ),
318- ],
319- )
320- def test_bogus_api_root_error_includes_url_context (bogus_api_root : str ) -> None :
321- """Test that API errors include the request URL in context for debugging.
307+ def test_404_error_includes_request_url_context () -> None :
308+ """Test that 404 API errors include the full request URL in context.
322309
323- This test validates that when an API call fails due to a bogus base URL,
324- the error message includes the full request URL that was attempted. This
325- helps debug URL construction issues like those seen with custom API roots.
310+ This test validates that when an API call fails with a 404, the error
311+ includes the full request URL that was attempted. This helps debug URL
312+ construction issues like those seen with custom API roots.
326313
327- Note: This test does not require credentials since it's testing error
328- behavior with invalid URLs that will fail before authentication .
314+ Uses httpbin.org which returns 404 for /sources endpoint, allowing us
315+ to verify the error context contains the expected URL information .
329316 """
317+ from urllib .parse import parse_qs , urlparse
318+
319+ api_root = "https://httpbin.org"
320+ workspace_id = "00000000-0000-0000-0000-000000000000"
330321 fake_bearer_token = SecretString ("fake-token-for-testing" )
331- fake_workspace_id = "00000000-0000-0000-0000-000000000000"
332322
333- with pytest .raises (Exception ) as exc_info :
323+ with pytest .raises (AirbyteError ) as exc_info :
334324 api_util .list_sources (
335- workspace_id = fake_workspace_id ,
336- api_root = bogus_api_root ,
325+ workspace_id = workspace_id ,
326+ api_root = api_root ,
337327 client_id = None ,
338328 client_secret = None ,
339329 bearer_token = fake_bearer_token ,
340330 )
341331
342332 error = exc_info .value
343- error_str = str (error )
344-
345- print (f"\n Bogus API root: { bogus_api_root } " )
346- print (f"Error type: { type (error ).__name__ } " )
347- print (f"Error message: { error_str } " )
348-
349- if isinstance (error , AirbyteError ) and hasattr (error , "context" ):
350- context = error .context or {}
351- print (f"Error context: { context } " )
352- if "request_url" in context :
353- request_url = str (context ["request_url" ])
354- print (f"Request URL from context: { request_url } " )
355- host_from_bogus = bogus_api_root .split ("/" )[2 ]
356- assert host_from_bogus in request_url , (
357- f"Expected request_url to contain host '{ host_from_bogus } ' "
358- f"from bogus_api_root '{ bogus_api_root } ', but got '{ request_url } '"
359- )
333+
334+ # Assert error has context
335+ assert error .context is not None , "Error should have context dict"
336+
337+ # Assert required context keys exist
338+ assert "api_root" in error .context , "Error context should contain 'api_root'"
339+ assert "status_code" in error .context , "Error context should contain 'status_code'"
340+ assert "request_url" in error .context , "Error context should contain 'request_url'"
341+
342+ # Assert context values
343+ assert error .context ["api_root" ] == api_root
344+ assert error .context ["status_code" ] == 404
345+
346+ # Parse and validate the request URL
347+ request_url = str (error .context ["request_url" ])
348+ parsed = urlparse (request_url )
349+
350+ assert parsed .netloc == "httpbin.org" , (
351+ f"Expected host 'httpbin.org', got '{ parsed .netloc } '"
352+ )
353+ assert parsed .path .endswith ("/sources" ), (
354+ f"Expected path ending with '/sources', got '{ parsed .path } '"
355+ )
356+
357+ # Validate query params include workspace ID
358+ query_params = parse_qs (parsed .query )
359+ assert "workspaceIds" in query_params , "Expected 'workspaceIds' in query params"
360+ assert query_params ["workspaceIds" ] == [workspace_id ], (
361+ f"Expected workspaceIds=['{ workspace_id } '], got { query_params ['workspaceIds' ]} "
362+ )
360363
361364
362365def test_url_construction_with_path_prefix () -> None :
0 commit comments