import { describe, it, expect, beforeEach } from 'vitest'; import { testClient } from 'hono/testing'; import { IntegrationTestDatabase, setupIntegrationDatabaseHooksWithEntities, } from '@d8d/shared-test-util'; import { Role, UserEntity, UserService } from '@d8d/core-module/user-module'; import { File } from '@d8d/core-module/file-module'; import { Company } from '@d8d/allin-company-module/entities'; import { Platform } from '@d8d/allin-platform-module/entities'; import authRoutes from '../../src/routes/index'; import { AuthService } from '../../src/services/index'; import { DisabledStatus } from '@d8d/shared-types'; import { TestDataFactory } from '../utils/test-data-factory'; // 设置集成测试钩子,包含公司实体 setupIntegrationDatabaseHooksWithEntities([UserEntity, Role, File, Company, Platform]) describe('企业用户认证API集成测试', () => { let client: ReturnType>; let authService: AuthService; let userService: UserService; let testToken: string; let testUser: any; let testCompany: any; beforeEach(async () => { // 创建测试客户端 client = testClient(authRoutes); // 获取数据源 const dataSource = await IntegrationTestDatabase.getDataSource(); // 确保数据源已初始化 if (!dataSource.isInitialized) { await dataSource.initialize(); } // 初始化服务 userService = new UserService(dataSource); authService = new AuthService(userService); // 创建测试平台 const platformRepository = dataSource.getRepository(Platform); await platformRepository.delete({ platformName: '测试平台' }); const testPlatform = platformRepository.create({ platformName: '测试平台', contactPerson: '测试联系人', contactPhone: '13800138000', contactEmail: 'platform@example.com', status: 1 }); const savedPlatform = await platformRepository.save(testPlatform); // 创建测试公司 const companyRepository = dataSource.getRepository(Company); await companyRepository.delete({ companyName: '测试企业有限公司' }); testCompany = companyRepository.create({ companyName: '测试企业有限公司', contactPerson: '张经理', contactPhone: '13800138000', contactEmail: 'contact@example.com', address: '北京市朝阳区', status: 1, platformId: savedPlatform.id }); testCompany = await companyRepository.save(testCompany); // 创建测试企业用户前先删除可能存在的重复用户 const userRepository = dataSource.getRepository(UserEntity); await userRepository.delete({ username: 'enterprise_user' }); await userRepository.delete({ phone: '13800138001' }); testUser = await TestDataFactory.createTestUser(dataSource, { username: 'enterprise_user', password: 'EnterprisePass123!', email: 'enterprise@example.com', phone: '13800138001', companyId: testCompany.id }); // 生成测试用户的token testToken = authService.generateToken(testUser); }); describe('企业用户登录端点测试 (POST /api/v1/yongren/auth/login)', () => { it('应该使用正确手机号和密码成功登录', async () => { const loginData = { phone: '13800138001', password: 'EnterprisePass123!' }; const response = await client.api.v1.yongren.auth.login.$post({ json: loginData }); expect(response.status).toBe(200); if (response.status === 200) { const responseData = await response.json(); expect(responseData).toHaveProperty('token'); expect(responseData).toHaveProperty('user'); expect(responseData.user.username).toBe('enterprise_user'); expect(responseData.user.phone).toBe('13800138001'); expect(responseData.user.companyId).toBe(testCompany.id); expect(responseData.user.company).toBeDefined(); expect(responseData.user.company.companyName).toBe('测试企业有限公司'); expect(typeof responseData.token).toBe('string'); expect(responseData.token.length).toBeGreaterThan(0); } }); it('应该拒绝错误密码的登录', async () => { const loginData = { phone: '13800138001', password: 'WrongPassword123!' }; const response = await client.api.v1.yongren.auth.login.$post({ json: loginData }); expect(response.status).toBe(401); if (response.status === 401) { const responseData = await response.json(); expect(responseData.message).toContain('手机号或密码错误'); } }); it('应该拒绝不存在的手机号登录', async () => { const loginData = { phone: '13999999999', password: 'EnterprisePass123!' }; const response = await client.api.v1.yongren.auth.login.$post({ json: loginData }); expect(response.status).toBe(401); if (response.status === 401) { const responseData = await response.json(); expect(responseData.message).toContain('手机号或密码错误'); } }); it('应该拒绝非企业用户登录(company_id为NULL)', async () => { // 创建非企业用户 const dataSource = await IntegrationTestDatabase.getDataSource(); const nonEnterpriseUser = await TestDataFactory.createTestUser(dataSource, { username: 'non_enterprise_user', password: 'Password123!', email: 'non_enterprise@example.com', phone: '13800138002', companyId: null }); const loginData = { phone: '13800138002', password: 'Password123!' }; const response = await client.api.v1.yongren.auth.login.$post({ json: loginData }); expect(response.status).toBe(401); if (response.status === 401) { const responseData = await response.json(); expect(responseData.message).toContain('用户不是企业用户'); } }); it('应该拒绝禁用账户的登录', async () => { // 禁用测试用户 const dataSource = await IntegrationTestDatabase.getDataSource(); const userRepository = dataSource.getRepository(UserEntity); await userRepository.update(testUser.id, { isDisabled: DisabledStatus.DISABLED }); const loginData = { phone: '13800138001', password: 'EnterprisePass123!' }; const response = await client.api.v1.yongren.auth.login.$post({ json: loginData }); expect(response.status).toBe(401); if (response.status === 401) { const responseData = await response.json(); expect(responseData.message).toContain('账户已禁用'); } }); }); describe('企业用户信息端点测试 (GET /api/v1/yongren/auth/me)', () => { it('应该成功获取企业用户信息,包含企业详情', async () => { const response = await client.api.v1.yongren.auth.me.$get({ header: { Authorization: `Bearer ${testToken}` } }); expect(response.status).toBe(200); if (response.status === 200) { const responseData = await response.json(); expect(responseData.username).toBe('enterprise_user'); expect(responseData.phone).toBe('13800138001'); expect(responseData.companyId).toBe(testCompany.id); expect(responseData.company).toBeDefined(); expect(responseData.company.companyName).toBe('测试企业有限公司'); expect(responseData.company.contactPerson).toBe('张经理'); expect(responseData.company.contactPhone).toBe('13800138000'); } }); it('应该拒绝非企业用户访问企业信息接口', async () => { // 创建非企业用户token const dataSource = await IntegrationTestDatabase.getDataSource(); const nonEnterpriseUser = await TestDataFactory.createTestUser(dataSource, { username: 'non_enterprise_user2', password: 'Password123!', email: 'non_enterprise2@example.com', phone: '13800138003', companyId: null }); const nonEnterpriseToken = authService.generateToken(nonEnterpriseUser); const response = await client.api.v1.yongren.auth.me.$get({ header: { Authorization: `Bearer ${nonEnterpriseToken}` } }); expect(response.status).toBe(403); if (response.status === 403) { const responseData = await response.json(); expect(responseData.message).toContain('非企业用户'); } }); it('应该拒绝无效令牌的访问', async () => { const response = await client.api.v1.yongren.auth.me.$get({ header: { Authorization: 'Bearer invalid_token' } }); expect(response.status).toBe(401); }); it('应该拒绝缺少令牌的访问', async () => { const response = await client.api.v1.yongren.auth.me.$get(); expect(response.status).toBe(401); }); }); describe('企业用户退出登录端点测试 (POST /api/v1/yongren/auth/logout)', () => { it('应该成功退出登录', async () => { const response = await client.api.v1.yongren.auth.logout.$post({ header: { Authorization: `Bearer ${testToken}` } }); expect(response.status).toBe(200); if (response.status === 200) { const responseData = await response.json(); expect(responseData.message).toBe('登出成功'); } }); it('应该拒绝无效令牌的退出登录', async () => { const response = await client.api.v1.yongren.auth.logout.$post({ header: { Authorization: 'Bearer invalid_token' } }); expect(response.status).toBe(401); }); }); describe('企业用户权限验证', () => { it('verifyEnterpriseUser方法应该正确识别企业用户', async () => { const dataSource = await IntegrationTestDatabase.getDataSource(); const userService = new UserService(dataSource); const authService = new AuthService(userService); const isEnterpriseUser = await authService.verifyEnterpriseUser(testUser.id); expect(isEnterpriseUser).toBe(true); // 创建非企业用户测试 const nonEnterpriseUser = await TestDataFactory.createTestUser(dataSource, { username: 'non_enterprise_user3', password: 'Password123!', email: 'non_enterprise3@example.com', phone: '13800138004', companyId: null }); const isNonEnterpriseUser = await authService.verifyEnterpriseUser(nonEnterpriseUser.id); expect(isNonEnterpriseUser).toBe(false); }); }); });