import { describe, it, expect, beforeEach, vi } from 'vitest'; import { testClient } from 'hono/testing'; import { IntegrationTestDatabase, setupIntegrationDatabaseHooksWithEntities } from '@d8d/shared-test-util'; import { systemConfigRoutesMt } from '../../src/routes/system-config.routes.mt'; import { SystemConfigMt } from '../../src/entities/system-config.entity.mt'; import { SystemConfigServiceMt } from '../../src/services/system-config.service.mt'; import { UserEntityMt, RoleMt } from '@d8d/core-module-mt/user-module-mt'; import { FileMt } from '@d8d/core-module-mt/file-module-mt'; import { TestDataFactory } from '../utils/integration-test-db'; import { AuthService } from '@d8d/core-module-mt/auth-module-mt'; import { UserServiceMt } from '@d8d/core-module-mt/user-module-mt'; // 设置集成测试钩子 setupIntegrationDatabaseHooksWithEntities([SystemConfigMt, UserEntityMt, RoleMt, FileMt]) describe('系统配置路由API集成测试 (使用hono/testing)', () => { let client: ReturnType>; let authService: AuthService; let userService: UserServiceMt; let testToken: string; let testUser: any; beforeEach(async () => { // 创建测试客户端 client = testClient(systemConfigRoutesMt); // 获取数据源 const dataSource = await IntegrationTestDatabase.getDataSource(); if (!dataSource) throw new Error('Database not initialized'); // 初始化服务 userService = new UserServiceMt(dataSource); authService = new AuthService(userService); // 创建测试用户并生成token testUser = await TestDataFactory.createTestUser(dataSource, { username: 'testuser_systemconfig', password: 'TestPassword123!', email: 'testuser_systemconfig@example.com' }); // 生成测试用户的token testToken = authService.generateToken(testUser); }); describe('CRUD Operations', () => { it('应该成功创建系统配置', async () => { const configData = { configKey: 'app.login.enabled', configValue: 'true', description: '控制小程序登录功能是否开启' }; const response = await client.index.$post({ json: configData }, { headers: { 'Authorization': `Bearer ${testToken}` } }); expect(response.status).toBe(201); const result = await response.json(); if ('configKey' in result) { expect(result.configKey).toBe(configData.configKey); expect(result.configValue).toBe(configData.configValue); } }); it('应该根据ID获取系统配置', async () => { // 先创建配置 const dataSource = await IntegrationTestDatabase.getDataSource(); if (!dataSource) throw new Error('Database not initialized'); const systemConfigService = new SystemConfigServiceMt(dataSource); const config = await systemConfigService.create({ configKey: 'app.payment.enabled', configValue: 'true', description: '控制支付功能是否开启', tenantId: testUser.tenantId } as SystemConfigMt); const response = await client[':id'].$get({ param: { id: config.id } }, { headers: { 'Authorization': `Bearer ${testToken}` } }); expect(response.status).toBe(200); const result = await response.json(); if ('id' in result) { expect(result.id).toBe(config.id); expect(result.configKey).toBe(config.configKey); } }); it('应该更新系统配置', async () => { // 先创建配置 const dataSource = await IntegrationTestDatabase.getDataSource(); if (!dataSource) throw new Error('Database not initialized'); const systemConfigService = new SystemConfigServiceMt(dataSource); const config = await systemConfigService.create({ configKey: 'app.notification.enabled', configValue: 'true', description: '控制通知功能是否开启', tenantId: testUser.tenantId } as SystemConfigMt); const updateData = { configValue: 'false', description: '通知功能已关闭' }; const response = await client[':id'].$put({ param: { id: config.id }, json: updateData }, { headers: { 'Authorization': `Bearer ${testToken}` } }); expect(response.status).toBe(200); const result = await response.json(); if ('configValue' in result) { expect(result.configValue).toBe(updateData.configValue); expect(result.description).toBe(updateData.description); } }); it('应该删除系统配置', async () => { // 先创建配置 const dataSource = await IntegrationTestDatabase.getDataSource(); if (!dataSource) throw new Error('Database not initialized'); const systemConfigService = new SystemConfigServiceMt(dataSource); const config = await systemConfigService.create({ configKey: 'app.analytics.enabled', configValue: 'true', description: '控制分析功能是否开启', tenantId: testUser.tenantId } as SystemConfigMt); const response = await client[':id'].$delete({ param: { id: config.id } }, { headers: { 'Authorization': `Bearer ${testToken}` } }); expect(response.status).toBe(204); // 验证配置已被删除 const deletedConfig = await systemConfigService.getById(config.id); expect(deletedConfig).toBeNull(); }); it('应该列出系统配置列表', async () => { // 创建多个配置 const dataSource = await IntegrationTestDatabase.getDataSource(); if (!dataSource) throw new Error('Database not initialized'); const systemConfigService = new SystemConfigServiceMt(dataSource); await systemConfigService.create({ configKey: 'app.feature1.enabled', configValue: 'true', tenantId: testUser.tenantId } as SystemConfigMt); await systemConfigService.create({ configKey: 'app.feature2.enabled', configValue: 'false', tenantId: testUser.tenantId } as SystemConfigMt); const response = await client.index.$get({ query: {} }, { headers: { 'Authorization': `Bearer ${testToken}` } }); expect(response.status).toBe(200); const result = await response.json(); if ('data' in result) { expect(result.data).toHaveLength(2); } }); }); describe('Multi-tenant Isolation', () => { let tenant1User: any; let tenant2User: any; let tenant1Token: string; let tenant2Token: string; beforeEach(async () => { const dataSource = await IntegrationTestDatabase.getDataSource(); if (!dataSource) throw new Error('Database not initialized'); // 创建租户1的用户 tenant1User = await TestDataFactory.createTestUser(dataSource, { username: 'tenant1_user_systemconfig', password: 'TestPassword123!', email: 'tenant1_systemconfig@example.com', tenantId: 1 }); // 创建租户2的用户 tenant2User = await TestDataFactory.createTestUser(dataSource, { username: 'tenant2_user_systemconfig', password: 'TestPassword123!', email: 'tenant2_systemconfig@example.com', tenantId: 2 }); // 生成租户用户的token tenant1Token = authService.generateToken(tenant1User); tenant2Token = authService.generateToken(tenant2User); }); it('应该按租户隔离配置', async () => { const dataSource = await IntegrationTestDatabase.getDataSource(); if (!dataSource) throw new Error('Database not initialized'); const systemConfigService = new SystemConfigServiceMt(dataSource); // 为租户1创建配置 await systemConfigService.create({ configKey: 'app.shared.config', configValue: 'tenant1-value', tenantId: 1 } as SystemConfigMt); // 为租户2创建配置 await systemConfigService.create({ configKey: 'app.shared.config', configValue: 'tenant2-value', tenantId: 2 } as SystemConfigMt); // 查询租户1的配置 const response1 = await client.index.$get({ query: {} }, { headers: { 'Authorization': `Bearer ${tenant1Token}` } }); expect(response1.status).toBe(200); const result1 = await response1.json(); if ('data' in result1) { expect(result1.data).toHaveLength(1); expect(result1.data[0].configValue).toBe('tenant1-value'); } // 查询租户2的配置 const response2 = await client.index.$get({ query: {} }, { headers: { 'Authorization': `Bearer ${tenant2Token}` } }); expect(response2.status).toBe(200); const result2 = await response2.json(); if ('data' in result2) { expect(result2.data).toHaveLength(1); expect(result2.data[0].configValue).toBe('tenant2-value'); } }); }); describe('Data Validation', () => { it('应该验证必填字段', async () => { const invalidData = { configKey: '', // 空字符串 configValue: 'true' }; const response = await client.index.$post({ json: invalidData }, { headers: { 'Authorization': `Bearer ${testToken}` } }); expect(response.status).toBe(400); }); it('应该验证字段长度', async () => { const invalidData = { configKey: 'a'.repeat(256), // 超过255字符 configValue: 'true' }; const response = await client.index.$post({ json: invalidData }, { headers: { 'Authorization': `Bearer ${testToken}` } }); expect(response.status).toBe(400); }); }); });