85 lines
2.7 KiB
Python
85 lines
2.7 KiB
Python
"""认证服务单元测试。"""
|
|
|
|
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)
|