Skip to content

Commit 5a00716

Browse files
committed
refactor: update tests
1 parent 1268fe1 commit 5a00716

4 files changed

Lines changed: 59 additions & 41 deletions

File tree

mcpauth/utils/_validate_server_config.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -99,22 +99,8 @@ def validate_server_config(
9999

100100
errors: List[AuthServerConfigError] = []
101101
warnings: List[AuthServerConfigWarning] = []
102-
103102
metadata = config.metadata
104103

105-
# Validate metadata
106-
try:
107-
# Validation is already done by Pydantic when the object is created
108-
# But we can add additional validation if needed
109-
pass
110-
except ValidationError as e:
111-
errors.append(
112-
_create_error(AuthServerConfigErrorCode.INVALID_SERVER_METADATA, e)
113-
)
114-
return AuthServerConfigValidationResult(
115-
is_valid=False, errors=errors, warnings=warnings
116-
)
117-
118104
# Check if 'code' is included in any of the supported response types
119105
has_code_response_type = any(
120106
"code" in response_type.split(" ")

tests/__init__test.py

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
from contextvars import ContextVar
22
import pytest
3-
from unittest.mock import patch, MagicMock
3+
from unittest.mock import AsyncMock, patch, MagicMock
44
from mcpauth import MCPAuth, MCPAuthAuthServerException, AuthServerExceptionCode
55
from mcpauth.config import AuthServerConfig, AuthServerType, AuthorizationServerMetadata
66
from mcpauth.middleware.create_bearer_auth import BearerAuthConfig
7+
from mcpauth.types import AuthInfo
78

89

910
class TestMCPAuth:
@@ -154,8 +155,8 @@ def test_bearer_auth_middleware_jwt_mode(self):
154155
"https://example.com/.well-known/jwks.json", leeway=60
155156
)
156157

157-
def test_bearer_auth_middleware_custom_verify(self):
158-
# Setup
158+
@pytest.mark.asyncio
159+
async def test_bearer_auth_middleware_custom_verify(self):
159160
server_config = AuthServerConfig(
160161
type=AuthServerType.OAUTH,
161162
metadata=AuthorizationServerMetadata(
@@ -169,24 +170,25 @@ def test_bearer_auth_middleware_custom_verify(self):
169170
)
170171
auth = MCPAuth(server=server_config)
171172

173+
auth_info = AuthInfo(
174+
token="valid_token",
175+
issuer="https://example.com",
176+
subject="1234567890",
177+
scopes=["profile"],
178+
claims={},
179+
)
172180
custom_verify = MagicMock()
181+
custom_verify.return_value = auth_info
173182

174-
# Exercise
175-
with patch(
176-
"mcpauth.middleware.create_bearer_auth.create_bearer_auth"
177-
) as mock_create_bearer_auth:
178-
middleware_class = auth.bearer_auth_middleware(
179-
custom_verify, required_scopes=["profile"]
180-
)
183+
middleware_class = auth.bearer_auth_middleware(
184+
custom_verify, required_scopes=["profile"]
185+
)
181186

182-
# Verify
183-
assert middleware_class is not None
184-
mock_create_bearer_auth.assert_called_once()
185-
args, kwargs = mock_create_bearer_auth.call_args
186-
assert args[0] == custom_verify
187-
assert isinstance(kwargs, dict)
188-
assert isinstance(kwargs.get("config"), BearerAuthConfig) # type: ignore
189-
assert isinstance(kwargs.get("context_var"), ContextVar) # type: ignore
187+
mock_request = MagicMock()
188+
mock_request.headers = {"Authorization": "Bearer valid_token"}
189+
middleware_instance = middleware_class(MagicMock())
190+
await middleware_instance.dispatch(mock_request, AsyncMock())
191+
assert auth.auth_info == auth_info
190192

191193
def test_bearer_auth_middleware_jwt_without_jwks_uri(self):
192194
# Setup

tests/middleware/create_bearer_auth_test.py

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,41 +22,51 @@
2222

2323

2424
class TestHandleBearerAuth:
25-
def test_should_return_middleware_class(self):
25+
@pytest.fixture
26+
def auth_info(self):
27+
return ContextVar("auth_info", default=None)
28+
29+
def test_should_return_middleware_class(
30+
self, auth_info: ContextVar[AuthInfo | None]
31+
):
2632
middleware = create_bearer_auth(
2733
lambda _: None, # type: ignore
2834
BearerAuthConfig(issuer="https://example.com"),
29-
ContextVar("auth_info", default=None),
35+
auth_info,
3036
)
3137
assert callable(middleware)
3238

33-
def test_should_throw_error_if_verify_access_token_is_not_a_function(self):
39+
def test_should_throw_error_if_verify_access_token_is_not_a_function(
40+
self, auth_info: ContextVar[AuthInfo | None]
41+
):
3442
with pytest.raises(
3543
TypeError, match=r"`verify_access_token` must be a function"
3644
):
3745
create_bearer_auth(
3846
"not a function", # type: ignore
3947
BearerAuthConfig(issuer="https://example.com"),
40-
ContextVar("auth_info", default=None),
48+
auth_info,
4149
)
4250

43-
def test_should_throw_error_if_issuer_is_not_a_valid_url(self):
51+
def test_should_throw_error_if_issuer_is_not_a_valid_url(
52+
self, auth_info: ContextVar[AuthInfo | None]
53+
):
4454
with pytest.raises(TypeError, match=r"`issuer` must be a valid URL."):
4555
create_bearer_auth(
4656
lambda _: None, # type: ignore
4757
BearerAuthConfig(issuer="not a valid url"),
48-
ContextVar("auth_info", default=None),
58+
auth_info,
4959
)
5060

5161

5262
@pytest.mark.asyncio
5363
class TestHandleBearerAuthMiddleware:
5464
@pytest.fixture
55-
def auth_info_context(self):
65+
def auth_info(self):
5666
return ContextVar("auth_info", default=None)
5767

5868
@pytest.fixture
59-
def auth_config(self, auth_info_context: ContextVar[AuthInfo | None]):
69+
def auth_config(self, auth_info: ContextVar[AuthInfo | None]):
6070
issuer = "https://example.com"
6171
required_scopes = ["read", "write"]
6272
audience = "test-audience"
@@ -83,7 +93,7 @@ def verify_access_token(token: str) -> AuthInfo:
8393
required_scopes=required_scopes,
8494
audience=audience,
8595
),
86-
auth_info_context,
96+
auth_info,
8797
)
8898

8999
@pytest.fixture

tests/utils/create_verify_jwt_test.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from unittest.mock import MagicMock
12
import pytest
23
import time
34
import jwt
@@ -122,6 +123,25 @@ def test_should_throw_error_if_jwt_payload_missing_sub(self):
122123
== MCPAuthTokenVerificationExceptionCode.INVALID_TOKEN
123124
)
124125

126+
def test_should_throw_error_if_unknown_exception_occurs(self):
127+
# Mock get_signing_key_from_jwt to raise an unexpected exception
128+
mock_jwk_client = MagicMock()
129+
mock_jwk_client.get_signing_key_from_jwt.side_effect = Exception(
130+
"Unexpected error"
131+
)
132+
verify_jwt = create_verify_jwt(mock_jwk_client, algorithms=[_algorithm])
133+
jwt_token = create_jwt(
134+
{"iss": "https://logto.io/", "client_id": "client12345", "sub": "user12345"}
135+
)
136+
137+
# Verify that the correct exception is raised
138+
with pytest.raises(MCPAuthTokenVerificationException) as exc_info:
139+
verify_jwt(jwt_token)
140+
assert (
141+
exc_info.value.code
142+
== MCPAuthTokenVerificationExceptionCode.TOKEN_VERIFICATION_FAILED
143+
)
144+
125145

126146
class TestCreateVerifyJwtNormalBehavior:
127147
def test_should_return_verified_jwt_payload_with_string_scope(self):

0 commit comments

Comments
 (0)