"""认证服务单元测试。""" from datetime import UTC import pytest from app.core.errors import AppError from app.services.auth import ( create_access_token, create_refresh_token, decode_token, hash_password, verify_password, ) class TestPasswordHashing: def test_hash_and_verify(self): plain = "test_password_123" hashed = hash_password(plain) assert hashed != plain assert verify_password(plain, hashed) is True def test_wrong_password(self): hashed = hash_password("correct") assert verify_password("wrong", hashed) is False def test_same_password_different_hashes(self): h1 = hash_password("password") h2 = hash_password("password") assert h1 != h2 # argon2 自动盐值 class TestJWT: def test_create_and_decode_access_token(self, monkeypatch): monkeypatch.setattr("app.core.config.settings.jwt_secret", "test-secret") token = create_access_token(subject="user_test", extra={"owner_scope": "user_test"}) assert isinstance(token, str) payload = decode_token(token) assert payload["sub"] == "user_test" assert payload["type"] == "access" assert payload["owner_scope"] == "user_test" def test_create_and_decode_refresh_token(self, monkeypatch): monkeypatch.setattr("app.core.config.settings.jwt_secret", "test-secret") token = create_refresh_token(subject="user_test") payload = decode_token(token) assert payload["sub"] == "user_test" assert payload["type"] == "refresh" def test_expired_token(self, monkeypatch): from datetime import datetime, timedelta from jose import jwt secret = "test-secret" monkeypatch.setattr("app.core.config.settings.jwt_secret", secret) payload = { "sub": "user_test", "type": "access", "iat": datetime.now(UTC) - timedelta(hours=2), "exp": datetime.now(UTC) - timedelta(hours=1), } token = jwt.encode(payload, secret, algorithm="HS256") with pytest.raises(AppError): decode_token(token) def test_wrong_signature(self, monkeypatch): from datetime import datetime, timedelta from jose import jwt monkeypatch.setattr("app.core.config.settings.jwt_secret", "real-secret") wrong_token = jwt.encode( { "sub": "test", "type": "access", "exp": datetime.now(UTC) + timedelta(hours=1), }, "wrong-secret", algorithm="HS256", ) with pytest.raises(AppError): decode_token(wrong_token)