- Implemented unit tests for Object model including folder and file creation, properties, and path retrieval. - Added unit tests for Setting model covering creation, unique constraints, and type enumeration. - Created unit tests for User model focusing on user creation, uniqueness, and group relationships. - Developed unit tests for Login service to validate login functionality, including 2FA and token generation. - Added utility tests for JWT creation and verification, ensuring token integrity and expiration handling. - Implemented password utility tests for password generation, hashing, and TOTP verification.
164 lines
4.6 KiB
Python
164 lines
4.6 KiB
Python
"""
|
|
JWT 工具的单元测试
|
|
"""
|
|
import time
|
|
from datetime import timedelta, datetime, timezone
|
|
|
|
import jwt as pyjwt
|
|
import pytest
|
|
|
|
from utils.JWT.JWT import create_access_token, create_refresh_token, SECRET_KEY
|
|
|
|
|
|
# 设置测试用的密钥
|
|
@pytest.fixture(autouse=True)
|
|
def setup_secret_key():
|
|
"""为测试设置密钥"""
|
|
import utils.JWT.JWT as jwt_module
|
|
jwt_module.SECRET_KEY = "test_secret_key_for_unit_tests"
|
|
yield
|
|
# 测试后恢复(虽然在单元测试中不太重要)
|
|
|
|
|
|
def test_create_access_token():
|
|
"""测试访问令牌创建"""
|
|
data = {"sub": "testuser", "role": "user"}
|
|
|
|
token, expire_time = create_access_token(data)
|
|
|
|
assert isinstance(token, str)
|
|
assert isinstance(expire_time, datetime)
|
|
|
|
# 解码验证
|
|
decoded = pyjwt.decode(token, "test_secret_key_for_unit_tests", algorithms=["HS256"])
|
|
assert decoded["sub"] == "testuser"
|
|
assert decoded["role"] == "user"
|
|
assert "exp" in decoded
|
|
|
|
|
|
def test_create_access_token_custom_expiry():
|
|
"""测试自定义过期时间"""
|
|
data = {"sub": "testuser"}
|
|
custom_expiry = timedelta(hours=1)
|
|
|
|
token, expire_time = create_access_token(data, expires_delta=custom_expiry)
|
|
|
|
decoded = pyjwt.decode(token, "test_secret_key_for_unit_tests", algorithms=["HS256"])
|
|
|
|
# 验证过期时间大约是1小时后
|
|
exp_timestamp = decoded["exp"]
|
|
now_timestamp = datetime.now(timezone.utc).timestamp()
|
|
|
|
# 允许1秒误差
|
|
assert abs(exp_timestamp - now_timestamp - 3600) < 1
|
|
|
|
|
|
def test_create_refresh_token():
|
|
"""测试刷新令牌创建"""
|
|
data = {"sub": "testuser"}
|
|
|
|
token, expire_time = create_refresh_token(data)
|
|
|
|
assert isinstance(token, str)
|
|
assert isinstance(expire_time, datetime)
|
|
|
|
# 解码验证
|
|
decoded = pyjwt.decode(token, "test_secret_key_for_unit_tests", algorithms=["HS256"])
|
|
assert decoded["sub"] == "testuser"
|
|
assert decoded["token_type"] == "refresh"
|
|
assert "exp" in decoded
|
|
|
|
|
|
def test_create_refresh_token_default_expiry():
|
|
"""测试刷新令牌默认30天过期"""
|
|
data = {"sub": "testuser"}
|
|
|
|
token, expire_time = create_refresh_token(data)
|
|
|
|
decoded = pyjwt.decode(token, "test_secret_key_for_unit_tests", algorithms=["HS256"])
|
|
|
|
# 验证过期时间大约是30天后
|
|
exp_timestamp = decoded["exp"]
|
|
now_timestamp = datetime.now(timezone.utc).timestamp()
|
|
|
|
# 30天 = 30 * 24 * 3600 = 2592000 秒
|
|
# 允许1秒误差
|
|
assert abs(exp_timestamp - now_timestamp - 2592000) < 1
|
|
|
|
|
|
def test_token_decode():
|
|
"""测试令牌解码"""
|
|
data = {"sub": "user123", "email": "user@example.com"}
|
|
|
|
token, _ = create_access_token(data)
|
|
|
|
# 解码
|
|
decoded = pyjwt.decode(token, "test_secret_key_for_unit_tests", algorithms=["HS256"])
|
|
|
|
assert decoded["sub"] == "user123"
|
|
assert decoded["email"] == "user@example.com"
|
|
|
|
|
|
def test_token_expired():
|
|
"""测试令牌过期"""
|
|
data = {"sub": "testuser"}
|
|
|
|
# 创建一个立即过期的令牌
|
|
token, _ = create_access_token(data, expires_delta=timedelta(seconds=-1))
|
|
|
|
# 尝试解码应该抛出过期异常
|
|
with pytest.raises(pyjwt.ExpiredSignatureError):
|
|
pyjwt.decode(token, "test_secret_key_for_unit_tests", algorithms=["HS256"])
|
|
|
|
|
|
def test_token_invalid_signature():
|
|
"""测试无效签名"""
|
|
data = {"sub": "testuser"}
|
|
|
|
token, _ = create_access_token(data)
|
|
|
|
# 使用错误的密钥解码
|
|
with pytest.raises(pyjwt.InvalidSignatureError):
|
|
pyjwt.decode(token, "wrong_secret_key", algorithms=["HS256"])
|
|
|
|
|
|
def test_access_token_does_not_have_token_type():
|
|
"""测试访问令牌不包含 token_type"""
|
|
data = {"sub": "testuser"}
|
|
|
|
token, _ = create_access_token(data)
|
|
|
|
decoded = pyjwt.decode(token, "test_secret_key_for_unit_tests", algorithms=["HS256"])
|
|
|
|
assert "token_type" not in decoded
|
|
|
|
|
|
def test_refresh_token_has_token_type():
|
|
"""测试刷新令牌包含 token_type"""
|
|
data = {"sub": "testuser"}
|
|
|
|
token, _ = create_refresh_token(data)
|
|
|
|
decoded = pyjwt.decode(token, "test_secret_key_for_unit_tests", algorithms=["HS256"])
|
|
|
|
assert decoded["token_type"] == "refresh"
|
|
|
|
|
|
def test_token_payload_preserved():
|
|
"""测试自定义负载保留"""
|
|
data = {
|
|
"sub": "user123",
|
|
"name": "Test User",
|
|
"roles": ["admin", "user"],
|
|
"metadata": {"key": "value"}
|
|
}
|
|
|
|
token, _ = create_access_token(data)
|
|
|
|
decoded = pyjwt.decode(token, "test_secret_key_for_unit_tests", algorithms=["HS256"])
|
|
|
|
assert decoded["sub"] == "user123"
|
|
assert decoded["name"] == "Test User"
|
|
assert decoded["roles"] == ["admin", "user"]
|
|
assert decoded["metadata"] == {"key": "value"}
|