import { describe, it, expect, beforeEach, vi, afterEach } 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 advertisementRoutes from '../../src/routes/advertisements'; import { Advertisement } from '../../src/entities/advertisement.entity'; import { AdvertisementType } from '../../src/entities/advertisement-type.entity'; // 设置集成测试钩子 setupIntegrationDatabaseHooksWithEntities([UserEntity, File, Role, Advertisement, AdvertisementType]) describe('广告管理API集成测试', () => { let client: ReturnType>; let testToken: string; let testUser: UserEntity; let testAdvertisementType: AdvertisementType; beforeEach(async () => { // 创建测试客户端 client = testClient(advertisementRoutes); // 获取数据源 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); // 创建测试广告类型 const advertisementTypeRepository = dataSource.getRepository(AdvertisementType); testAdvertisementType = advertisementTypeRepository.create({ name: '首页轮播', code: 'home_banner', remark: '用于首页轮播图展示', status: 1 }); await advertisementTypeRepository.save(testAdvertisementType); // 生成测试用户的token testToken = JWTUtil.generateToken({ id: testUser.id, username: testUser.username, roles: [{name:'user'}] }); }); describe('GET /advertisements', () => { it('应该返回广告列表', async () => { const response = await client.index.$get({ query: {} }, { 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(Array.isArray(data.data)).toBe(true); } }); it('应该拒绝未认证用户的访问', async () => { const response = await client.index.$get({ query: {} }); expect(response.status).toBe(401); }); }); describe('POST /advertisements', () => { it('应该成功创建广告', async () => { const createData = { title: '测试广告', typeId: testAdvertisementType.id, code: 'test_ad', url: 'https://example.com', sort: 10, status: 1, actionType: 1 }; const response = await client.index.$post({ json: createData }, { headers: { 'Authorization': `Bearer ${testToken}` } }); console.debug('创建广告响应状态:', response.status); expect(response.status).toBe(201); if (response.status === 201) { const data = await response.json(); expect(data).toHaveProperty('id'); expect(data.title).toBe(createData.title); expect(data.code).toBe(createData.code); expect(data.status).toBe(createData.status); } }); it('应该验证创建广告的必填字段', async () => { const invalidData = { // 缺少必填字段 title: '', typeId: 0, code: '', url: 'https://example.com' }; const response = await client.index.$post({ json: invalidData }, { headers: { 'Authorization': `Bearer ${testToken}` } }); expect(response.status).toBe(400); }); }); describe('GET /advertisements/:id', () => { it('应该返回指定广告的详情', async () => { // 先创建一个广告 const dataSource = await IntegrationTestDatabase.getDataSource(); const advertisementRepository = dataSource.getRepository(Advertisement); const testAdvertisement = advertisementRepository.create({ title: '测试广告详情', typeId: testAdvertisementType.id, code: 'test_ad_detail', url: 'https://example.com', sort: 5, status: 1, actionType: 1, createdBy: testUser.id }); await advertisementRepository.save(testAdvertisement); const response = await client[':id'].$get({ param: { id: testAdvertisement.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(testAdvertisement.id); expect(data.title).toBe(testAdvertisement.title); expect(data.code).toBe(testAdvertisement.code); } }); it('应该处理不存在的广告', async () => { const response = await client[':id'].$get({ param: { id: 999999 } }, { headers: { 'Authorization': `Bearer ${testToken}` } }); expect(response.status).toBe(404); }); }); describe('PUT /advertisements/:id', () => { it('应该成功更新广告', async () => { // 先创建一个广告 const dataSource = await IntegrationTestDatabase.getDataSource(); const advertisementRepository = dataSource.getRepository(Advertisement); const testAdvertisement = advertisementRepository.create({ title: '原始广告', typeId: testAdvertisementType.id, code: 'original_ad', url: 'https://example.com', sort: 5, status: 1, actionType: 1, createdBy: testUser.id }); await advertisementRepository.save(testAdvertisement); const updateData = { title: '更新后的广告', code: 'updated_ad', sort: 15 }; const response = await client[':id'].$put({ param: { id: testAdvertisement.id }, json: updateData }, { headers: { 'Authorization': `Bearer ${testToken}` } }); console.debug('更新广告响应状态:', response.status); expect(response.status).toBe(200); if (response.status === 200) { const data = await response.json(); expect(data.title).toBe(updateData.title); expect(data.code).toBe(updateData.code); expect(data.sort).toBe(updateData.sort); } }); }); describe('DELETE /advertisements/:id', () => { it('应该成功删除广告', async () => { // 先创建一个广告 const dataSource = await IntegrationTestDatabase.getDataSource(); const advertisementRepository = dataSource.getRepository(Advertisement); const testAdvertisement = advertisementRepository.create({ title: '待删除广告', typeId: testAdvertisementType.id, code: 'delete_ad', url: 'https://example.com', sort: 5, status: 1, actionType: 1, createdBy: testUser.id }); await advertisementRepository.save(testAdvertisement); const response = await client[':id'].$delete({ param: { id: testAdvertisement.id } }, { headers: { 'Authorization': `Bearer ${testToken}` } }); console.debug('删除广告响应状态:', response.status); expect(response.status).toBe(204); // 验证广告确实被删除 const deletedAdvertisement = await advertisementRepository.findOne({ where: { id: testAdvertisement.id } }); expect(deletedAdvertisement).toBeNull(); }); }); });