import { describe, it, expect, beforeEach } from 'vitest'; import { testClient } from 'hono/testing'; import { IntegrationTestDatabase, setupIntegrationDatabaseHooksWithEntities } from '@d8d/shared-test-util'; import { JWTUtil } from '@d8d/shared-utils'; import { UserEntity, Role } from '@d8d/user-module'; import { File } from '@d8d/file-module'; import channelRoutes from '../../src/routes/channel.routes'; import { Channel } from '../../src/entities/channel.entity'; // 设置集成测试钩子 setupIntegrationDatabaseHooksWithEntities([UserEntity, File, Role, Channel]) describe('渠道管理API集成测试', () => { let client: ReturnType>; let testToken: string; let testUser: UserEntity; beforeEach(async () => { // 创建测试客户端 client = testClient(channelRoutes); // 获取数据源 const dataSource = await IntegrationTestDatabase.getDataSource(); // 创建测试用户 const userRepository = dataSource.getRepository(UserEntity); testUser = userRepository.create({ username: `test_user_${Date.now()}`, password: 'test_password', nickname: '测试用户', registrationSource: 'web' }); await userRepository.save(testUser); // 生成测试用户的token testToken = JWTUtil.generateToken({ id: testUser.id, username: testUser.username, roles: [{name:'user'}] }); }); describe('POST /channel/createChannel', () => { it('应该成功创建渠道', async () => { const createData = { channelName: '微信小程序渠道', channelType: '小程序', contactPerson: '张三', contactPhone: '13800138000', description: '微信小程序渠道描述' }; const response = await client.createChannel.$post({ json: createData }, { headers: { 'Authorization': `Bearer ${testToken}` } }); console.debug('创建渠道响应状态:', response.status); expect(response.status).toBe(200); if (response.status === 200) { const data = await response.json(); expect(data.channelName).toBe(createData.channelName); expect(data.channelType).toBe(createData.channelType); } }); it('应该验证渠道名称重复', async () => { // 先创建一个渠道 const dataSource = await IntegrationTestDatabase.getDataSource(); const channelRepository = dataSource.getRepository(Channel); const existingChannel = channelRepository.create({ channelName: '微信小程序渠道', channelType: '小程序', contactPerson: '张三', contactPhone: '13800138000', status: 1 }); await channelRepository.save(existingChannel); // 尝试创建同名渠道 const createData = { channelName: '微信小程序渠道', // 重复的名称 channelType: '小程序', contactPerson: '李四', contactPhone: '13900139000' }; const response = await client.createChannel.$post({ json: createData }, { headers: { 'Authorization': `Bearer ${testToken}` } }); expect(response.status).toBe(400); if (response.status === 400) { const data = await response.json(); expect(data.message).toContain('渠道名称已存在'); } }); it('应该拒绝未认证用户的访问', async () => { const createData = { channelName: '测试渠道', channelType: '测试' }; const response = await client.createChannel.$post({ json: createData }); expect(response.status).toBe(401); }); }); describe('POST /channel/deleteChannel', () => { it('应该成功删除渠道', async () => { // 先创建一个渠道 const dataSource = await IntegrationTestDatabase.getDataSource(); const channelRepository = dataSource.getRepository(Channel); const testChannel = channelRepository.create({ channelName: `待删除渠道_${Date.now()}`, channelType: '测试', contactPerson: '张三', contactPhone: '13800138000', status: 1 }); await channelRepository.save(testChannel); const deleteData = { id: testChannel.id }; const response = await client.deleteChannel.$post({ json: deleteData }, { headers: { 'Authorization': `Bearer ${testToken}` } }); console.debug('删除渠道响应状态:', response.status); expect(response.status).toBe(200); if (response.status === 200) { const data = await response.json(); expect(data.success).toBe(true); } // 验证渠道状态变为0(软删除) const deletedChannel = await channelRepository.findOne({ where: { id: testChannel.id } }); expect(deletedChannel?.status).toBe(0); }); }); describe('POST /channel/updateChannel', () => { it('应该成功更新渠道', async () => { // 先创建一个渠道 const dataSource = await IntegrationTestDatabase.getDataSource(); const channelRepository = dataSource.getRepository(Channel); const testChannel = channelRepository.create({ channelName: `原始渠道_${Date.now()}`, channelType: '原始类型', contactPerson: '张三', contactPhone: '13800138000', status: 1 }); await channelRepository.save(testChannel); const updateData = { id: testChannel.id, channelName: '更新后的渠道名称', channelType: '更新类型', contactPerson: '李四', contactPhone: '13900139000' }; const response = await client.updateChannel.$post({ json: updateData }, { headers: { 'Authorization': `Bearer ${testToken}` } }); console.debug('更新渠道响应状态:', response.status); if (response.status !== 200) { const errorData = await response.json(); console.debug('更新渠道错误:', errorData); } expect(response.status).toBe(200); if (response.status === 200) { const data = await response.json(); expect(data.channelName).toBe(updateData.channelName); expect(data.channelType).toBe(updateData.channelType); } // 验证渠道已更新 const updatedChannel = await channelRepository.findOne({ where: { id: testChannel.id } }); expect(updatedChannel?.channelName).toBe(updateData.channelName); expect(updatedChannel?.channelType).toBe(updateData.channelType); }); it('应该验证更新时的渠道名称重复', async () => { // 创建两个渠道 const dataSource = await IntegrationTestDatabase.getDataSource(); const channelRepository = dataSource.getRepository(Channel); const channel1 = channelRepository.create({ channelName: '渠道A', channelType: '类型A', status: 1 }); await channelRepository.save(channel1); const channel2 = channelRepository.create({ channelName: '渠道B', channelType: '类型B', status: 1 }); await channelRepository.save(channel2); // 尝试将渠道B的名称改为渠道A的名称 const updateData = { id: channel2.id, channelName: '渠道A' // 重复的名称 }; const response = await client.updateChannel.$post({ json: updateData }, { headers: { 'Authorization': `Bearer ${testToken}` } }); expect(response.status).toBe(400); if (response.status === 400) { const data = await response.json(); expect(data.message).toContain('渠道名称已存在'); } }); }); describe('GET /channel/getAllChannels', () => { it('应该返回渠道列表', async () => { // 创建一些测试渠道 const dataSource = await IntegrationTestDatabase.getDataSource(); const channelRepository = dataSource.getRepository(Channel); for (let i = 0; i < 3; i++) { const channel = channelRepository.create({ channelName: `测试渠道${i}`, channelType: '测试', contactPerson: `联系人${i}`, contactPhone: `1380013800${i}`, status: 1 }); await channelRepository.save(channel); } const response = await client.getAllChannels.$get({ query: { skip: 0, take: 10 } }, { headers: { 'Authorization': `Bearer ${testToken}` } }); console.debug('渠道列表响应状态:', response.status); expect(response.status).toBe(200); if (response.status === 200) { const data = await response.json(); expect(data).toHaveProperty('data'); expect(data).toHaveProperty('total'); expect(Array.isArray(data.data)).toBe(true); expect(data.total).toBeGreaterThanOrEqual(3); } }); it('应该支持分页参数', async () => { const response = await client.getAllChannels.$get({ query: { skip: 0, take: 5 } }, { headers: { 'Authorization': `Bearer ${testToken}` } }); expect(response.status).toBe(200); }); it('应该过滤已删除的渠道(status=0)', async () => { // 创建测试数据:3个正常渠道,2个已删除渠道 const dataSource = await IntegrationTestDatabase.getDataSource(); const channelRepository = dataSource.getRepository(Channel); // 创建3个正常渠道 for (let i = 1; i <= 3; i++) { const channel = channelRepository.create({ channelName: `正常渠道${i}`, channelType: `类型${i}`, contactPerson: `联系人${i}`, contactPhone: `1380013800${i}`, status: 1 }); await channelRepository.save(channel); } // 创建2个已删除渠道 for (let i = 4; i <= 5; i++) { const channel = channelRepository.create({ channelName: `已删除渠道${i}`, channelType: `类型${i}`, contactPerson: `联系人${i}`, contactPhone: `1380013800${i}`, status: 0 }); await channelRepository.save(channel); } const response = await client.getAllChannels.$get({ query: { skip: 0, take: 10 } }, { headers: { 'Authorization': `Bearer ${testToken}` } }); expect(response.status).toBe(200); if (response.status === 200) { const data = await response.json(); // 应该只返回3个正常渠道,不返回已删除的渠道 expect(data.data).toHaveLength(3); expect(data.total).toBe(3); // 验证返回的都是正常渠道 data.data.forEach((channel: any) => { expect(channel.status).toBe(1); expect(channel.channelName).toMatch(/^正常渠道/); }); } }); }); describe('GET /channel/searchChannels', () => { it('应该按名称搜索渠道', async () => { // 创建测试渠道 const dataSource = await IntegrationTestDatabase.getDataSource(); const channelRepository = dataSource.getRepository(Channel); const channel = channelRepository.create({ channelName: '微信小程序搜索测试', channelType: '小程序', contactPerson: '张三', contactPhone: '13800138000', status: 1 }); await channelRepository.save(channel); const response = await client.searchChannels.$get({ query: { name: '微信', skip: 0, take: 10 } }, { headers: { 'Authorization': `Bearer ${testToken}` } }); console.debug('搜索渠道响应状态:', response.status); expect(response.status).toBe(200); if (response.status === 200) { const data = await response.json(); expect(data.data.length).toBeGreaterThan(0); expect(data.data[0].channelName).toContain('微信'); } }); it('应该过滤已删除的渠道(搜索时)', async () => { // 创建测试数据 const dataSource = await IntegrationTestDatabase.getDataSource(); const channelRepository = dataSource.getRepository(Channel); // 创建正常渠道 const normalChannel = channelRepository.create({ channelName: '测试搜索渠道正常', channelType: '正常类型', contactPerson: '张三', contactPhone: '13800138000', status: 1 }); await channelRepository.save(normalChannel); // 创建已删除的渠道(不同名称) const deletedChannel = channelRepository.create({ channelName: '测试搜索渠道已删除', channelType: '删除类型', contactPerson: '李四', contactPhone: '13900139000', status: 0 }); await channelRepository.save(deletedChannel); const response = await client.searchChannels.$get({ query: { name: '测试搜索', skip: 0, take: 10 } }, { headers: { 'Authorization': `Bearer ${testToken}` } }); expect(response.status).toBe(200); if (response.status === 200) { const data = await response.json(); // 应该只返回1个正常渠道,不返回已删除的渠道 expect(data.data).toHaveLength(1); expect(data.total).toBe(1); expect(data.data[0].channelName).toBe('测试搜索渠道正常'); expect(data.data[0].status).toBe(1); expect(data.data[0].contactPerson).toBe('张三'); // 正常渠道的联系人 } }); }); describe('GET /channel/getChannel/:id', () => { it('应该返回指定渠道的详情', async () => { // 先创建一个渠道 const dataSource = await IntegrationTestDatabase.getDataSource(); const channelRepository = dataSource.getRepository(Channel); const testChannel = channelRepository.create({ channelName: `详情测试渠道_${Date.now()}`, channelType: '测试', contactPerson: '张三', contactPhone: '13800138000', status: 1 }); await channelRepository.save(testChannel); const response = await client.getChannel[':id'].$get({ param: { id: testChannel.id } }, { headers: { 'Authorization': `Bearer ${testToken}` } }); console.debug('渠道详情响应状态:', response.status); expect(response.status).toBe(200); if (response.status === 200) { const data = await response.json(); expect(data!.id).toBe(testChannel.id); expect(data!.channelName).toBe(testChannel.channelName); } }); it('应该处理不存在的渠道', async () => { const response = await client.getChannel[':id'].$get({ param: { id: 999999 } }, { headers: { 'Authorization': `Bearer ${testToken}` } }); expect(response.status).toBe(200); const data = await response.json(); expect(data).toBeNull(); }); }); });