Skip to content

Commit e936893

Browse files
pcarletonclaude
andcommitted
Add tests for create_client_registration_request and mark defensive code
Add tests to cover the fallback path in create_client_registration_request when auth_server_metadata is None or lacks a registration_endpoint. Mark the exception handler in is_valid_client_metadata_url as pragma: no cover since urlparse rarely throws exceptions and this is purely defensive code. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent f32cdad commit e936893

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed

src/mcp/client/auth/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ def is_valid_client_metadata_url(url: str | None) -> bool:
259259
try:
260260
parsed = urlparse(url)
261261
return parsed.scheme == "https" and parsed.path not in ("", "/")
262-
except Exception:
262+
except Exception: # pragma: no cover
263263
return False
264264

265265

tests/client/test_auth.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
build_oauth_authorization_server_metadata_discovery_urls,
1919
build_protected_resource_metadata_discovery_urls,
2020
create_client_info_from_metadata_url,
21+
create_client_registration_request,
2122
create_oauth_metadata_request,
2223
extract_field_from_www_auth,
2324
extract_resource_metadata_from_www_auth,
@@ -948,6 +949,49 @@ def text(self):
948949
assert "Registration failed: 400" in str(exc_info.value)
949950

950951

952+
class TestCreateClientRegistrationRequest:
953+
"""Test client registration request creation."""
954+
955+
def test_uses_registration_endpoint_from_metadata(self):
956+
"""Test that registration URL comes from metadata when available."""
957+
oauth_metadata = OAuthMetadata(
958+
issuer=AnyHttpUrl("https://auth.example.com"),
959+
authorization_endpoint=AnyHttpUrl("https://auth.example.com/authorize"),
960+
token_endpoint=AnyHttpUrl("https://auth.example.com/token"),
961+
registration_endpoint=AnyHttpUrl("https://auth.example.com/register"),
962+
)
963+
client_metadata = OAuthClientMetadata(redirect_uris=[AnyHttpUrl("http://localhost:3000/callback")])
964+
965+
request = create_client_registration_request(oauth_metadata, client_metadata, "https://auth.example.com")
966+
967+
assert str(request.url) == "https://auth.example.com/register"
968+
assert request.method == "POST"
969+
970+
def test_falls_back_to_default_register_endpoint_when_no_metadata(self):
971+
"""Test that registration uses fallback URL when auth_server_metadata is None."""
972+
client_metadata = OAuthClientMetadata(redirect_uris=[AnyHttpUrl("http://localhost:3000/callback")])
973+
974+
request = create_client_registration_request(None, client_metadata, "https://auth.example.com")
975+
976+
assert str(request.url) == "https://auth.example.com/register"
977+
assert request.method == "POST"
978+
979+
def test_falls_back_when_metadata_has_no_registration_endpoint(self):
980+
"""Test fallback when metadata exists but lacks registration_endpoint."""
981+
oauth_metadata = OAuthMetadata(
982+
issuer=AnyHttpUrl("https://auth.example.com"),
983+
authorization_endpoint=AnyHttpUrl("https://auth.example.com/authorize"),
984+
token_endpoint=AnyHttpUrl("https://auth.example.com/token"),
985+
# No registration_endpoint
986+
)
987+
client_metadata = OAuthClientMetadata(redirect_uris=[AnyHttpUrl("http://localhost:3000/callback")])
988+
989+
request = create_client_registration_request(oauth_metadata, client_metadata, "https://auth.example.com")
990+
991+
assert str(request.url) == "https://auth.example.com/register"
992+
assert request.method == "POST"
993+
994+
951995
class TestAuthFlow:
952996
"""Test the auth flow in httpx."""
953997

0 commit comments

Comments
 (0)