""" 认证集成测试 测试完整的认证流程,包括注册、登录、令牌刷新、登出等。 """ import pytest from fastapi.testclient import TestClient from apps.api.main import app client = TestClient(app) class TestUserRegistration: """用户注册集成测试""" def test_register_with_valid_data(self): """测试使用有效数据进行注册""" response = client.post( "/api/v1/auth/register", json={ "email": "newuser@example.com", "password": "SecurePass123", "username": "newuser", "display_name": "New User", }, ) assert response.status_code == 201 data = response.json() assert data["email"] == "newuser@example.com" assert data["username"] == "newuser" assert data["display_name"] == "New User" assert "user_id" in data def test_register_with_invalid_email(self): """测试使用无效邮箱进行注册""" response = client.post( "/api/v1/auth/register", json={ "email": "invalid-email", "password": "SecurePass123", "username": "testuser", }, ) assert response.status_code == 422 # Validation error def test_register_with_weak_password(self): """测试使用弱密码进行注册""" response = client.post( "/api/v1/auth/register", json={ "email": "weak@example.com", "password": "123", # Too short and simple "username": "weakuser", }, ) # Should fail validation or business logic assert response.status_code in [400, 422] def test_register_duplicate_email(self): """测试重复邮箱注册""" # First registration client.post( "/api/v1/auth/register", json={ "email": "duplicate@example.com", "password": "SecurePass123", "username": "user1", "display_name": "User 1", }, ) # Second registration with same email response = client.post( "/api/v1/auth/register", json={ "email": "duplicate@example.com", "password": "SecurePass123", "username": "user2", "display_name": "User 2", }, ) assert response.status_code == 400 assert "already" in response.json()["detail"].lower() or "exists" in response.json()["detail"].lower() class TestUserLogin: """用户登录集成测试""" def setup_method(self): """每个测试前的准备:注册用户""" client.post( "/api/v1/auth/register", json={ "email": "loginuser@example.com", "password": "SecurePass123", "username": "loginuser", "display_name": "Login User", }, ) def test_login_with_correct_credentials(self): """测试使用正确凭据登录""" response = client.post( "/api/v1/auth/login", json={ "email": "loginuser@example.com", "password": "SecurePass123", }, ) assert response.status_code == 200 data = response.json() assert "access_token" in data assert "refresh_token" in data assert data["token_type"] == "bearer" assert data["email"] == "loginuser@example.com" def test_login_with_wrong_password(self): """测试使用错误密码登录""" response = client.post( "/api/v1/auth/login", json={ "email": "loginuser@example.com", "password": "WrongPassword123", }, ) assert response.status_code == 401 assert "error" in response.json() or "detail" in response.json() def test_login_with_nonexistent_email(self): """测试使用不存在的邮箱登录""" response = client.post( "/api/v1/auth/login", json={ "email": "nonexistent@example.com", "password": "AnyPassword123", }, ) assert response.status_code == 401 def test_login_case_insensitive_email(self): """测试邮箱大小写不敏感登录""" response = client.post( "/api/v1/auth/login", json={ "email": "LOGINUSER@EXAMPLE.COM", # Uppercase email "password": "SecurePass123", }, ) # Should still work because email is normalized assert response.status_code == 200 class TestTokenRefresh: """令牌刷新集成测试""" def setup_method(self): """每个测试前的准备:注册并登录获取令牌""" client.post( "/api/v1/auth/register", json={ "email": "refresh@example.com", "password": "SecurePass123", "username": "refreshuser", "display_name": "Refresh User", }, ) response = client.post( "/api/v1/auth/login", json={ "email": "refresh@example.com", "password": "SecurePass123", }, ) self.refresh_token = response.json().get("refresh_token") self.access_token = response.json().get("access_token") def test_refresh_token_success(self): """测试成功刷新令牌""" if not self.refresh_token: pytest.skip("Refresh token not available") response = client.post( "/api/v1/auth/refresh", json={"refresh_token": self.refresh_token}, ) # If refresh endpoint exists if response.status_code != 404: assert response.status_code == 200 data = response.json() assert "access_token" in data class TestCurrentUser: """当前用户信息集成测试""" def setup_method(self): """每个测试前的准备:注册并登录获取令牌""" client.post( "/api/v1/auth/register", json={ "email": "me@example.com", "password": "SecurePass123", "username": "meuser", "display_name": "Me User", }, ) response = client.post( "/api/v1/auth/login", json={ "email": "me@example.com", "password": "SecurePass123", }, ) self.token = response.json()["access_token"] self.headers = {"Authorization": f"Bearer {self.token}"} def test_get_current_user_success(self): """测试获取当前用户信息成功""" response = client.get("/api/v1/auth/me", headers=self.headers) assert response.status_code == 200 data = response.json() assert data["email"] == "me@example.com" assert data["username"] == "meuser" assert "user_id" in data def test_get_current_user_without_token(self): """测试无令牌获取当前用户信息""" response = client.get("/api/v1/auth/me") assert response.status_code == 403 def test_get_current_user_with_invalid_token(self): """测试使用无效令牌获取当前用户信息""" response = client.get( "/api/v1/auth/me", headers={"Authorization": "Bearer invalid-token"}, ) assert response.status_code == 401 class TestPasswordReset: """密码重置集成测试""" def test_request_password_reset_success(self): """测试请求密码重置成功""" # Register user first client.post( "/api/v1/auth/register", json={ "email": "reset@example.com", "password": "SecurePass123", "username": "resetuser", }, ) response = client.post( "/api/v1/auth/password/forgot", json={"email": "reset@example.com"}, ) # Should return 202 Accepted (even if email not sent) assert response.status_code == 202 def test_request_password_reset_nonexistent_user(self): """测试请求不存在的用户密码重置""" response = client.post( "/api/v1/auth/password/forgot", json={"email": "nonexistent@example.com"}, ) # Should still return 202 for security (don't reveal if email exists) assert response.status_code == 202 if __name__ == "__main__": pytest.main([__file__, "-v"])