Files
012-kaopeilian/backend/tests/unit/test_auth.py
111 998211c483 feat: 初始化考培练系统项目
- 从服务器拉取完整代码
- 按框架规范整理项目结构
- 配置 Drone CI 测试环境部署
- 包含后端(FastAPI)、前端(Vue3)、管理端

技术栈: Vue3 + TypeScript + FastAPI + MySQL
2026-01-24 19:33:28 +08:00

209 lines
6.9 KiB
Python

"""
认证模块单元测试
"""
import pytest
from httpx import AsyncClient
from sqlalchemy.ext.asyncio import AsyncSession
from app.services.auth_service import AuthService
from app.schemas.auth import UserRegister
from app.core.security import verify_password, create_password_hash
from app.core.exceptions import InvalidCredentialsError, UsernameExistsError
@pytest.mark.asyncio
class TestAuthService:
"""认证服务测试类"""
async def test_user_registration(self, db_session: AsyncSession, test_user_data):
"""测试用户注册"""
# 创建认证服务
auth_service = AuthService(db_session)
# 准备注册数据
register_data = UserRegister(**test_user_data)
# 注册用户
user = await auth_service.create_user(register_data)
# 验证用户创建成功
assert user.id is not None
assert user.username == test_user_data["username"]
assert user.email == test_user_data["email"]
assert user.is_active is True
assert user.role == "trainee"
# 验证密码已加密
assert user.password_hash != test_user_data["password"]
assert verify_password(test_user_data["password"], user.password_hash)
async def test_duplicate_username_registration(
self,
db_session: AsyncSession,
test_user_data
):
"""测试重复用户名注册"""
auth_service = AuthService(db_session)
# 第一次注册
register_data = UserRegister(**test_user_data)
await auth_service.create_user(register_data)
# 尝试使用相同用户名再次注册
with pytest.raises(UsernameExistsError):
await auth_service.create_user(register_data)
async def test_user_login(self, db_session: AsyncSession, test_user_data):
"""测试用户登录"""
auth_service = AuthService(db_session)
# 先注册用户
register_data = UserRegister(**test_user_data)
user = await auth_service.create_user(register_data)
# 测试登录
authenticated_user = await auth_service.authenticate_user(
username=test_user_data["username"],
password=test_user_data["password"]
)
assert authenticated_user.id == user.id
assert authenticated_user.username == user.username
# 验证登录信息已更新
assert authenticated_user.login_count == "1"
assert authenticated_user.failed_login_count == "0"
assert authenticated_user.last_login is not None
async def test_login_with_email(self, db_session: AsyncSession, test_user_data):
"""测试使用邮箱登录"""
auth_service = AuthService(db_session)
# 注册用户
register_data = UserRegister(**test_user_data)
await auth_service.create_user(register_data)
# 使用邮箱登录
user = await auth_service.authenticate_user(
username=test_user_data["email"],
password=test_user_data["password"]
)
assert user.email == test_user_data["email"]
async def test_invalid_password_login(
self,
db_session: AsyncSession,
test_user_data
):
"""测试错误密码登录"""
auth_service = AuthService(db_session)
# 注册用户
register_data = UserRegister(**test_user_data)
await auth_service.create_user(register_data)
# 尝试使用错误密码登录
with pytest.raises(InvalidCredentialsError):
await auth_service.authenticate_user(
username=test_user_data["username"],
password="WrongPassword123!"
)
async def test_token_creation(self, db_session: AsyncSession, test_user_data):
"""测试Token创建"""
auth_service = AuthService(db_session)
# 注册用户
register_data = UserRegister(**test_user_data)
user = await auth_service.create_user(register_data)
# 创建tokens
tokens = await auth_service.create_tokens_for_user(user)
assert "access_token" in tokens
assert "refresh_token" in tokens
assert tokens["token_type"] == "bearer"
assert tokens["expires_in"] > 0
@pytest.mark.asyncio
class TestAuthAPI:
"""认证API测试类"""
async def test_register_endpoint(self, client: AsyncClient, test_user_data):
"""测试注册端点"""
response = await client.post(
"/api/v1/auth/register",
json=test_user_data
)
assert response.status_code == 200
data = response.json()
assert data["code"] == 200
assert data["message"] == "注册成功"
assert "access_token" in data["data"]
assert "refresh_token" in data["data"]
async def test_login_endpoint(self, client: AsyncClient, test_user_data):
"""测试登录端点"""
# 先注册
await client.post("/api/v1/auth/register", json=test_user_data)
# 测试登录
response = await client.post(
"/api/v1/auth/login",
data={
"username": test_user_data["username"],
"password": test_user_data["password"]
}
)
assert response.status_code == 200
data = response.json()
assert data["code"] == 200
assert "access_token" in data["data"]
async def test_refresh_token_endpoint(
self,
client: AsyncClient,
test_user_data
):
"""测试Token刷新端点"""
# 先注册并获取tokens
register_response = await client.post(
"/api/v1/auth/register",
json=test_user_data
)
tokens = register_response.json()["data"]
# 刷新token
response = await client.post(
"/api/v1/auth/refresh",
json={"refresh_token": tokens["refresh_token"]}
)
assert response.status_code == 200
data = response.json()
assert "access_token" in data["data"]
assert data["data"]["access_token"] != tokens["access_token"]
async def test_logout_endpoint(self, client: AsyncClient):
"""测试登出端点"""
response = await client.post("/api/v1/auth/logout")
assert response.status_code == 200
data = response.json()
assert data["message"] == "登出成功"
async def test_reset_password_request(self, client: AsyncClient):
"""测试重置密码请求"""
response = await client.post(
"/api/v1/auth/reset-password",
json={"email": "test@example.com"}
)
assert response.status_code == 200
data = response.json()
assert "如果该邮箱已注册" in data["message"]