"""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)