import { describe, it, expect, beforeEach, vi } from 'vitest'; import { testClient } from 'hono/testing'; import { IntegrationTestDatabase, setupIntegrationDatabaseHooks, TestDataFactory } from '~/utils/server/integration-test-db'; import { authRoutes } from '@d8d/server/api'; import { AuthService } from '@d8d/server/modules/auth/auth.service'; import { UserService } from '@d8d/server/modules/users/user.service'; // 设置集成测试钩子 setupIntegrationDatabaseHooks() // Mock MiniAuthService 的 decryptPhoneNumber 方法 vi.mock('@d8d/server/modules/auth/mini-auth.service', () => ({ MiniAuthService: vi.fn().mockImplementation(() => ({ decryptPhoneNumber: vi.fn().mockImplementation(async (encryptedData: string, iv: string, sessionKey: string) => { // 模拟解密过程 if (!encryptedData || !iv || !sessionKey) { throw { code: 400, message: '加密数据或初始向量不能为空' }; } // 根据不同的加密数据返回不同的手机号用于测试 if (encryptedData === 'valid_encrypted_data') { return '13800138000'; } else if (encryptedData === 'another_valid_data') { return '13900139000'; } else { throw { code: 400, message: '解密失败' }; } }) })) })); describe('手机号解密API集成测试', () => { let client: ReturnType>['api']['v1']; let testToken: string; let testUser: any; beforeEach(async () => { // 创建测试客户端 client = testClient(authRoutes).api.v1; // 创建测试用户并生成token const dataSource = await IntegrationTestDatabase.getDataSource(); const userService = new UserService(dataSource); const authService = new AuthService(userService); // 创建测试用户 testUser = await TestDataFactory.createTestUser(dataSource, { phone: null // 初始手机号为null }); // 生成测试用户的token testToken = authService.generateToken(testUser); }); describe('POST /auth/phone-decrypt', () => { it('应该成功解密手机号并更新用户信息', async () => { const requestData = { encryptedData: 'valid_encrypted_data', iv: 'encryption_iv' }; const response = await client.auth['phone-decrypt'].$post({ json: requestData }, { headers: { 'Authorization': `Bearer ${testToken}` } }); expect(response.status).toBe(200); if (response.status === 200) { const data = await response.json(); // 验证响应数据格式 expect(data).toHaveProperty('phoneNumber'); expect(data).toHaveProperty('user'); expect(data.phoneNumber).toBe('13800138000'); expect(data.user.phone).toBe('13800138000'); expect(data.user.id).toBe(testUser.id); } // 验证数据库中的用户手机号已更新 const dataSource = await IntegrationTestDatabase.getDataSource(); const userRepository = dataSource.getRepository('UserEntity'); const updatedUser = await userRepository.findOne({ where: { id: testUser.id } }); expect(updatedUser?.phone).toBe('13800138000'); }); it('应该处理用户不存在的情况', async () => { // 创建另一个用户的token const dataSource = await IntegrationTestDatabase.getDataSource(); const userService = new UserService(dataSource); const authService = new AuthService(userService); // 创建一个不存在的用户实体 const nonExistentUser = await TestDataFactory.createTestUser(dataSource, { username: 'nonexistent_user', phone: null }); // 删除这个用户以确保它不存在 await dataSource.getRepository('UserEntity').delete({ id: nonExistentUser.id }); // 使用已删除用户的ID生成token const nonExistentUserToken = authService.generateToken(nonExistentUser); const requestData = { encryptedData: 'valid_encrypted_data', iv: 'encryption_iv' }; const response = await client.auth['phone-decrypt'].$post({ json: requestData }, { headers: { 'Authorization': `Bearer ${nonExistentUserToken}` } }); // 当用户不存在时,auth中间件应该返回401 expect(response.status).toBe(401); if (response.status === 401) { const data = await response.json(); expect(data.message).toBe('User not found'); } }); it('应该处理解密失败的情况', async () => { const requestData = { encryptedData: '', // 空加密数据 iv: 'encryption_iv' }; const response = await client.auth['phone-decrypt'].$post({ json: requestData }, { headers: { 'Authorization': `Bearer ${testToken}` } }); expect(response.status).toBe(400); if (response.status === 400) { const data = await response.json(); expect(data.message).toBe('加密数据或初始向量不能为空'); } }); it('应该处理无效的加密数据', async () => { const requestData = { encryptedData: 'invalid_encrypted_data', iv: 'encryption_iv' }; const response = await client.auth['phone-decrypt'].$post({ json: requestData }, { headers: { 'Authorization': `Bearer ${testToken}` } }); expect(response.status).toBe(400); if (response.status === 400) { const data = await response.json(); expect(data.message).toBe('解密失败'); } }); it('应该拒绝未认证用户的访问', async () => { const requestData = { encryptedData: 'valid_encrypted_data', iv: 'encryption_iv' }; const response = await client.auth['phone-decrypt'].$post({ json: requestData }); expect(response.status).toBe(401); }); it('应该拒绝无效token的访问', async () => { const requestData = { encryptedData: 'valid_encrypted_data', iv: 'encryption_iv' }; const response = await client.auth['phone-decrypt'].$post({ json: requestData }, { headers: { 'Authorization': 'Bearer invalid_token' } }); expect(response.status).toBe(401); }); }); });