Skip to content

Commit e3c1eef

Browse files
committed
Add test for ProtectedResourceMetadata parsing
1 parent 39e7576 commit e3c1eef

File tree

1 file changed

+82
-2
lines changed

1 file changed

+82
-2
lines changed

tests/shared/test_auth.py

Lines changed: 82 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""Tests for OAuth 2.0 shared code."""
2-
3-
from mcp.shared.auth import OAuthMetadata
2+
import pytest
3+
from mcp.shared.auth import OAuthMetadata, ProtectedResourceMetadata
44

55

66
class TestOAuthMetadata:
@@ -37,3 +37,83 @@ def test_oidc(self):
3737
"userinfo_endpoint": "https://example.com/oauth2/userInfo",
3838
}
3939
)
40+
41+
class TestProtectedResourceMetadataInvalid:
42+
"""Tests for ProtectedResourceMetadata parsing."""
43+
44+
def test_invalid_metadata(self):
45+
"""Should throw when parsing invalid metadata."""
46+
with pytest.raises(ValueError):
47+
ProtectedResourceMetadata.model_validate(
48+
{
49+
"resource": "Not a valid URL",
50+
"authorization_servers": ["https://example.com/oauth2/authorize"],
51+
"scopes_supported": ["read", "write"],
52+
"bearer_methods_supported": ["header"],
53+
}
54+
)
55+
56+
def test_valid_metadata(self):
57+
"""Should not throw when parsing protected resource metadata."""
58+
59+
ProtectedResourceMetadata.model_validate(
60+
{
61+
"resource": "https://example.com/resource",
62+
"authorization_servers": ["https://example.com/oauth2/authorize"],
63+
"scopes_supported": ["read", "write"],
64+
"bearer_methods_supported": ["header"],
65+
}
66+
)
67+
68+
def test_valid_with_resource_metadata(self):
69+
"""Should not throw when parsing metadata with resource_name and resource_documentation."""
70+
71+
ProtectedResourceMetadata.model_validate(
72+
{
73+
"resource": "https://example.com/resource",
74+
"authorization_servers": ["https://example.com/oauth2/authorize"],
75+
"scopes_supported": ["read", "write"],
76+
"bearer_methods_supported": ["header"],
77+
"resource_name": "Example Resource",
78+
"resource_documentation": "https://example.com/resource/documentation",
79+
}
80+
)
81+
82+
def test_valid_witn_invalid_resource_documentation(self):
83+
"""Should throw when parsing metadata with resource_name and resource_documentation."""
84+
with pytest.raises(ValueError):
85+
ProtectedResourceMetadata.model_validate(
86+
{
87+
"resource": "https://example.com/resource",
88+
"authorization_servers": ["https://example.com/oauth2/authorize"],
89+
"scopes_supported": ["read", "write"],
90+
"bearer_methods_supported": ["header"],
91+
"resource_name": "Example Resource",
92+
"resource_documentation": "Not a valid URL",
93+
}
94+
)
95+
96+
def test_valid_full_protected_resource_metadata(self):
97+
"""Should not throw when parsing full metadata."""
98+
99+
ProtectedResourceMetadata.model_validate(
100+
{
101+
"resource": "https://example.com/resource",
102+
"authorization_servers": ["https://example.com/oauth2/authorize"],
103+
"jwks_uri": "https://example.com/.well-known/jwks.json",
104+
"scopes_supported": ["read", "write"],
105+
"bearer_methods_supported": ["header"],
106+
"resource_signing_alg_values_supported": ["RS256"],
107+
"resource_name": "Example Resource",
108+
"resource_documentation": "https://example.com/resource/documentation",
109+
"resource_policy_uri": "https://example.com/resource/policy",
110+
"resource_tos_uri": "https://example.com/resource/tos",
111+
"tls_client_certificate_bound_access_tokens": True,
112+
# authorization_details_types_supported is a complext type
113+
# so we use an empty list for simplicity
114+
# see RFC9396
115+
"authorization_details_types_supported": [],
116+
"dpop_signing_alg_values_supported": ["RS256", "ES256"],
117+
"dpop_signing_access_tokens": True,
118+
}
119+
)

0 commit comments

Comments
 (0)