59 lines
2.2 KiB
Python
59 lines
2.2 KiB
Python
|
|
"""Tests for JWTHandler token creation and decoding.
|
||
|
|
|
||
|
|
These tests do not require a running server or database.
|
||
|
|
"""
|
||
|
|
|
||
|
|
import time
|
||
|
|
import pytest
|
||
|
|
|
||
|
|
SECRET = "test-secret-key-minimum-32-characters-long"
|
||
|
|
|
||
|
|
|
||
|
|
@pytest.fixture
|
||
|
|
def handler():
|
||
|
|
"""Return a JWTHandler configured with a test secret."""
|
||
|
|
from app.infrastructure.auth.jwt_handler import JWTHandler
|
||
|
|
return JWTHandler(secret_key=SECRET, algorithm="HS256", expire_minutes=30)
|
||
|
|
|
||
|
|
|
||
|
|
def test_create_token_returns_string(handler):
|
||
|
|
"""create_access_token must return a non-empty string."""
|
||
|
|
token = handler.create_access_token(user_id="u1", username="alice", role="admin")
|
||
|
|
assert isinstance(token, str)
|
||
|
|
assert len(token) > 20
|
||
|
|
|
||
|
|
|
||
|
|
def test_decode_token_returns_correct_claims(handler):
|
||
|
|
"""decode_token must return UserClaims matching the input."""
|
||
|
|
token = handler.create_access_token(user_id="u1", username="alice", role="admin")
|
||
|
|
claims = handler.decode_token(token)
|
||
|
|
assert claims.user_id == "u1"
|
||
|
|
assert claims.username == "alice"
|
||
|
|
assert claims.role == "admin"
|
||
|
|
|
||
|
|
|
||
|
|
def test_decode_expired_token_raises(handler):
|
||
|
|
"""decode_token must raise ValueError on an expired token."""
|
||
|
|
from app.infrastructure.auth.jwt_handler import JWTHandler
|
||
|
|
short_handler = JWTHandler(secret_key=SECRET, algorithm="HS256", expire_minutes=0)
|
||
|
|
token = short_handler.create_access_token(user_id="u2", username="bob", role="readonly")
|
||
|
|
time.sleep(1)
|
||
|
|
with pytest.raises(ValueError, match="expired"):
|
||
|
|
short_handler.decode_token(token)
|
||
|
|
|
||
|
|
|
||
|
|
def test_decode_invalid_token_raises(handler):
|
||
|
|
"""decode_token must raise ValueError for a tampered token."""
|
||
|
|
with pytest.raises(ValueError):
|
||
|
|
handler.decode_token("not.a.valid.jwt.token")
|
||
|
|
|
||
|
|
|
||
|
|
def test_decode_wrong_secret_raises():
|
||
|
|
"""decode_token must raise ValueError when signed with a different secret."""
|
||
|
|
from app.infrastructure.auth.jwt_handler import JWTHandler
|
||
|
|
creator = JWTHandler(secret_key=SECRET, algorithm="HS256", expire_minutes=60)
|
||
|
|
verifier = JWTHandler(secret_key="wrong-secret-key-also-minimum-32-chars", algorithm="HS256", expire_minutes=60)
|
||
|
|
token = creator.create_access_token(user_id="u3", username="carol", role="legal")
|
||
|
|
with pytest.raises(ValueError):
|
||
|
|
verifier.decode_token(token)
|