|
10 | 10 |
|
11 | 11 | import httpx
|
12 | 12 | import pytest
|
| 13 | +from inline_snapshot import snapshot |
13 | 14 | from pydantic import AnyHttpUrl
|
14 | 15 |
|
15 | 16 | from mcp.client.auth import OAuthClientProvider
|
| 17 | +from mcp.server.auth.routes import build_metadata |
| 18 | +from mcp.server.auth.settings import ClientRegistrationOptions, RevocationOptions |
16 | 19 | from mcp.shared.auth import (
|
17 | 20 | OAuthClientInformationFull,
|
18 | 21 | OAuthClientMetadata,
|
@@ -905,3 +908,76 @@ async def test_token_exchange_error_basic(self, oauth_provider, oauth_client_inf
|
905 | 908 | await oauth_provider._exchange_code_for_token(
|
906 | 909 | "invalid_auth_code", oauth_client_info
|
907 | 910 | )
|
| 911 | + |
| 912 | + |
| 913 | +@pytest.mark.parametrize( |
| 914 | + ( |
| 915 | + "issuer_url", |
| 916 | + "service_documentation_url", |
| 917 | + "authorization_endpoint", |
| 918 | + "token_endpoint", |
| 919 | + "registration_endpoint", |
| 920 | + "revocation_endpoint", |
| 921 | + ), |
| 922 | + ( |
| 923 | + pytest.param( |
| 924 | + "https://auth.example.com", |
| 925 | + "https://auth.example.com/docs", |
| 926 | + "https://auth.example.com/authorize", |
| 927 | + "https://auth.example.com/token", |
| 928 | + "https://auth.example.com/register", |
| 929 | + "https://auth.example.com/revoke", |
| 930 | + id="simple-url", |
| 931 | + ), |
| 932 | + pytest.param( |
| 933 | + "https://auth.example.com/", |
| 934 | + "https://auth.example.com/docs", |
| 935 | + "https://auth.example.com/authorize", |
| 936 | + "https://auth.example.com/token", |
| 937 | + "https://auth.example.com/register", |
| 938 | + "https://auth.example.com/revoke", |
| 939 | + id="with-trailing-slash", |
| 940 | + ), |
| 941 | + pytest.param( |
| 942 | + "https://auth.example.com/v1/mcp", |
| 943 | + "https://auth.example.com/v1/mcp/docs", |
| 944 | + "https://auth.example.com/v1/mcp/authorize", |
| 945 | + "https://auth.example.com/v1/mcp/token", |
| 946 | + "https://auth.example.com/v1/mcp/register", |
| 947 | + "https://auth.example.com/v1/mcp/revoke", |
| 948 | + id="with-path-param", |
| 949 | + ), |
| 950 | + ), |
| 951 | +) |
| 952 | +def test_build_metadata( |
| 953 | + issuer_url: str, |
| 954 | + service_documentation_url: str, |
| 955 | + authorization_endpoint: str, |
| 956 | + token_endpoint: str, |
| 957 | + registration_endpoint: str, |
| 958 | + revocation_endpoint: str, |
| 959 | +): |
| 960 | + metadata = build_metadata( |
| 961 | + issuer_url=AnyHttpUrl(issuer_url), |
| 962 | + service_documentation_url=AnyHttpUrl(service_documentation_url), |
| 963 | + client_registration_options=ClientRegistrationOptions( |
| 964 | + enabled=True, valid_scopes=["read", "write", "admin"] |
| 965 | + ), |
| 966 | + revocation_options=RevocationOptions(enabled=True), |
| 967 | + ) |
| 968 | + |
| 969 | + assert metadata == snapshot( |
| 970 | + OAuthMetadata( |
| 971 | + issuer=AnyHttpUrl(issuer_url), |
| 972 | + authorization_endpoint=AnyHttpUrl(authorization_endpoint), |
| 973 | + token_endpoint=AnyHttpUrl(token_endpoint), |
| 974 | + registration_endpoint=AnyHttpUrl(registration_endpoint), |
| 975 | + scopes_supported=["read", "write", "admin"], |
| 976 | + grant_types_supported=["authorization_code", "refresh_token"], |
| 977 | + token_endpoint_auth_methods_supported=["client_secret_post"], |
| 978 | + service_documentation=AnyHttpUrl(service_documentation_url), |
| 979 | + revocation_endpoint=AnyHttpUrl(revocation_endpoint), |
| 980 | + revocation_endpoint_auth_methods_supported=["client_secret_post"], |
| 981 | + code_challenge_methods_supported=["S256"], |
| 982 | + ) |
| 983 | + ) |
0 commit comments