@@ -464,34 +464,6 @@ async def test_client_credentials_request_token_without_metadata(monkeypatch: py
464464 assert provider ._metadata is None
465465
466466
467- @pytest .mark .anyio
468- async def test_client_credentials_request_token_omits_scope_when_unset (monkeypatch : pytest .MonkeyPatch ) -> None :
469- storage = InMemoryStorage ()
470- client_metadata = OAuthClientMetadata (redirect_uris = _redirect_uris (), scope = None )
471- provider = ClientCredentialsProvider ("https://api.example.com/service" , client_metadata , storage )
472-
473- provider ._metadata = OAuthMetadata .model_validate (_metadata_json ())
474- provider ._client_info = OAuthClientInformationFull (client_id = "client" , client_secret = "secret" )
475-
476- class RecordingAsyncClient (DummyAsyncClient ):
477- def __init__ (self ) -> None :
478- super ().__init__ (post_responses = [_make_response (200 , json_data = _token_json ())])
479- self .last_data : dict [str , str ] | None = None
480-
481- async def post (self , url : str , * , data : dict [str , str ], headers : dict [str , str ]) -> httpx .Response :
482- self .last_data = data
483- return await super ().post (url , data = data , headers = headers )
484-
485- clients : list [DummyAsyncClient ] = [RecordingAsyncClient ()]
486- monkeypatch .setattr ("mcp.client.auth.oauth2.httpx.AsyncClient" , AsyncClientFactory (clients ))
487-
488- await provider ._request_token ()
489-
490- recorded_client = cast (RecordingAsyncClient , clients [0 ])
491- assert recorded_client .last_data is not None
492- assert "scope" not in recorded_client .last_data
493-
494-
495467@pytest .mark .anyio
496468async def test_client_credentials_ensure_token_returns_when_valid () -> None :
497469 storage = InMemoryStorage ()
@@ -696,43 +668,6 @@ async def test_token_exchange_request_token_handles_invalid_metadata(monkeypatch
696668 actor_supplier .assert_awaited_once ()
697669
698670
699- @pytest .mark .anyio
700- async def test_token_exchange_request_token_skips_discovery_when_no_urls (monkeypatch : pytest .MonkeyPatch ) -> None :
701- storage = InMemoryStorage ()
702- client_metadata = OAuthClientMetadata (redirect_uris = _redirect_uris ())
703-
704- subject_supplier = AsyncMock (return_value = "subject-token" )
705-
706- provider = TokenExchangeProvider (
707- "https://api.example.com/service" ,
708- client_metadata ,
709- storage ,
710- subject_token_supplier = subject_supplier ,
711- )
712-
713- provider ._client_info = OAuthClientInformationFull (client_id = "client" , client_secret = "secret" )
714- provider ._get_discovery_urls = MethodType (lambda self , server_url = None : [], provider )
715-
716- class RecordingAsyncClient (DummyAsyncClient ):
717- def __init__ (self ) -> None :
718- super ().__init__ (post_responses = [_make_response (200 , json_data = _token_json ())])
719- self .last_data : dict [str , str ] | None = None
720-
721- async def post (self , url : str , * , data : dict [str , str ], headers : dict [str , str ]) -> httpx .Response :
722- self .last_data = data
723- return await super ().post (url , data = data , headers = headers )
724-
725- clients : list [DummyAsyncClient ] = [RecordingAsyncClient ()]
726- monkeypatch .setattr ("mcp.client.auth.oauth2.httpx.AsyncClient" , AsyncClientFactory (clients ))
727-
728- await provider ._request_token ()
729-
730- recorded_client = cast (RecordingAsyncClient , clients [0 ])
731- assert recorded_client .last_data is not None
732- assert subject_supplier .await_count == 1
733- assert provider ._metadata is None
734-
735-
736671@pytest .mark .anyio
737672async def test_token_exchange_request_token_excludes_resource_when_unset (monkeypatch : pytest .MonkeyPatch ) -> None :
738673 storage = InMemoryStorage ()
@@ -770,42 +705,6 @@ async def post(self, url: str, *, data: dict[str, str], headers: dict[str, str])
770705 assert "resource" not in recorded_client .last_data
771706
772707
773- @pytest .mark .anyio
774- async def test_token_exchange_request_token_omits_scope_when_unset (monkeypatch : pytest .MonkeyPatch ) -> None :
775- storage = InMemoryStorage ()
776- client_metadata = OAuthClientMetadata (redirect_uris = _redirect_uris (), scope = None )
777-
778- subject_supplier = AsyncMock (return_value = "subject-token" )
779-
780- provider = TokenExchangeProvider (
781- "https://api.example.com/service" ,
782- client_metadata ,
783- storage ,
784- subject_token_supplier = subject_supplier ,
785- )
786-
787- provider ._metadata = OAuthMetadata .model_validate (_metadata_json ())
788- provider ._client_info = OAuthClientInformationFull (client_id = "client" , client_secret = "secret" )
789-
790- class RecordingAsyncClient (DummyAsyncClient ):
791- def __init__ (self ) -> None :
792- super ().__init__ (post_responses = [_make_response (200 , json_data = _token_json ())])
793- self .last_data : dict [str , str ] | None = None
794-
795- async def post (self , url : str , * , data : dict [str , str ], headers : dict [str , str ]) -> httpx .Response :
796- self .last_data = data
797- return await super ().post (url , data = data , headers = headers )
798-
799- clients : list [DummyAsyncClient ] = [RecordingAsyncClient ()]
800- monkeypatch .setattr ("mcp.client.auth.oauth2.httpx.AsyncClient" , AsyncClientFactory (clients ))
801-
802- await provider ._request_token ()
803-
804- recorded_client = cast (RecordingAsyncClient , clients [0 ])
805- assert recorded_client .last_data is not None
806- assert "scope" not in recorded_client .last_data
807-
808-
809708@pytest .mark .anyio
810709async def test_token_exchange_request_token_raises_on_failure (monkeypatch : pytest .MonkeyPatch ) -> None :
811710 storage = InMemoryStorage ()
0 commit comments