Skip to content

Commit 5bb3338

Browse files
authored
Merge pull request #46 from sacha-development-stuff/codex/fix-coverage-threshold-failure-1pomsh
Add coverage for OAuth discovery redirects and refresh tokens
2 parents a5138c3 + 671ddd2 commit 5bb3338

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

tests/unit/client/test_oauth2_providers.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,32 @@ async def test_client_credentials_request_token_stops_on_server_error(
539539
assert provider._metadata is None
540540

541541

542+
@pytest.mark.anyio
543+
async def test_client_credentials_request_token_stops_on_redirect(
544+
monkeypatch: pytest.MonkeyPatch,
545+
) -> None:
546+
storage = InMemoryStorage()
547+
client_metadata = OAuthClientMetadata(redirect_uris=_redirect_uris(), scope="alpha")
548+
provider = ClientCredentialsProvider("https://api.example.com/service", client_metadata, storage)
549+
550+
metadata_responses = [_make_response(302)]
551+
registration_response = _make_response(200, json_data=_registration_json())
552+
token_response = _make_response(200, json_data=_token_json("alpha"))
553+
554+
clients = [
555+
DummyAsyncClient(send_responses=metadata_responses),
556+
DummyAsyncClient(send_responses=[registration_response]),
557+
DummyAsyncClient(post_responses=[token_response]),
558+
]
559+
monkeypatch.setattr("mcp.client.auth.oauth2.httpx.AsyncClient", AsyncClientFactory(clients))
560+
561+
await provider._request_token()
562+
563+
assert storage.tokens is not None
564+
assert storage.tokens.scope == "alpha"
565+
assert provider._metadata is None
566+
567+
542568
@pytest.mark.anyio
543569
async def test_client_credentials_ensure_token_returns_when_valid() -> None:
544570
storage = InMemoryStorage()

tests/unit/server/auth/test_token_handler.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,33 @@ async def test_handle_route_refresh_token_branch() -> None:
256256
assert payload["access_token"] == "refreshed-token"
257257

258258

259+
@pytest.mark.anyio
260+
async def test_handle_route_refresh_token_without_scope() -> None:
261+
provider = RefreshTokenProvider()
262+
client_info = OAuthClientInformationFull(
263+
client_id="client",
264+
grant_types=["refresh_token"],
265+
scope="alpha",
266+
)
267+
handler = TokenHandler(
268+
provider=cast(OAuthAuthorizationServerProvider[Any, Any, Any], provider),
269+
client_authenticator=cast(ClientAuthenticator, DummyAuthenticator(client_info)),
270+
)
271+
272+
request_data = {
273+
"grant_type": "refresh_token",
274+
"refresh_token": "refresh-token",
275+
"client_id": "client",
276+
"client_secret": "secret",
277+
}
278+
279+
response = await handler.handle(cast(Request, DummyRequest(request_data)))
280+
281+
assert response.status_code == 200
282+
payload = json.loads(bytes(response.body).decode())
283+
assert payload["access_token"] == "refreshed-token"
284+
285+
259286
@pytest.mark.anyio
260287
async def test_handle_route_refresh_token_invalid_scope() -> None:
261288
provider = RefreshTokenProvider()

0 commit comments

Comments
 (0)