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 { Supplier } from '@d8d/supplier-module'; import { Merchant } from '@d8d/merchant-module'; import { publicGoodsRandomRoutes } from '../../src/routes/public-goods-random'; import { Goods, GoodsCategory } from '../../src/entities'; // 设置集成测试钩子 setupIntegrationDatabaseHooksWithEntities([ UserEntity, Role, Goods, GoodsCategory, File, Supplier, Merchant ]) describe('公开随机商品API集成测试', () => { let client: ReturnType>; let testUser: UserEntity; let testSupplier: Supplier; let testMerchant: Merchant; let testCategory1: GoodsCategory; let testCategory2: GoodsCategory; beforeEach(async () => { // 创建测试客户端 client = testClient(publicGoodsRandomRoutes); // 获取数据源 const dataSource = await IntegrationTestDatabase.getDataSource(); // 创建测试用户 const userRepository = dataSource.getRepository(UserEntity); testUser = userRepository.create({ username: `test_user_${Math.floor(Math.random() * 100000)}`, password: 'test_password', nickname: '测试用户', registrationSource: 'web' }); await userRepository.save(testUser); // 创建测试供应商 const supplierRepository = dataSource.getRepository(Supplier); testSupplier = supplierRepository.create({ name: '测试供应商', username: `test_supplier_${Math.floor(Math.random() * 100000)}`, password: 'password123', phone: '13800138000', realname: '测试供应商', state: 1, createdBy: testUser.id }); await supplierRepository.save(testSupplier); // 创建测试商户 const merchantRepository = dataSource.getRepository(Merchant); testMerchant = merchantRepository.create({ name: '测试商户', username: `test_merchant_${Math.floor(Math.random() * 100000)}`, password: 'password123', phone: '13800138001', realname: '测试商户', state: 1, createdBy: testUser.id }); await merchantRepository.save(testMerchant); // 创建测试商品分类 const categoryRepository = dataSource.getRepository(GoodsCategory); testCategory1 = categoryRepository.create({ name: '测试分类1', parentId: 0, level: 1, state: 1, createdBy: testUser.id }); await categoryRepository.save(testCategory1); testCategory2 = categoryRepository.create({ name: '测试分类2', parentId: 0, level: 1, state: 1, createdBy: testUser.id }); await categoryRepository.save(testCategory2); // 创建测试商品 const goodsRepository = dataSource.getRepository(Goods); // 创建可用状态的商品 const activeGoods1 = goodsRepository.create({ name: '可用商品1', price: 100.00, costPrice: 80.00, categoryId1: testCategory1.id, categoryId2: testCategory1.id, categoryId3: testCategory1.id, goodsType: 1, supplierId: testSupplier.id, merchantId: testMerchant.id, state: 1, stock: 100, lowestBuy: 1, createdBy: testUser.id }); await goodsRepository.save(activeGoods1); const activeGoods2 = goodsRepository.create({ name: '可用商品2', price: 200.00, costPrice: 160.00, categoryId1: testCategory2.id, categoryId2: testCategory2.id, categoryId3: testCategory2.id, goodsType: 1, supplierId: testSupplier.id, merchantId: testMerchant.id, state: 1, stock: 50, lowestBuy: 1, createdBy: testUser.id }); await goodsRepository.save(activeGoods2); const activeGoods3 = goodsRepository.create({ name: '可用商品3', price: 300.00, costPrice: 240.00, categoryId1: testCategory1.id, categoryId2: testCategory1.id, categoryId3: testCategory1.id, goodsType: 2, supplierId: testSupplier.id, merchantId: testMerchant.id, state: 1, stock: 30, lowestBuy: 1, createdBy: testUser.id }); await goodsRepository.save(activeGoods3); // 创建不可用状态的商品(不应该被随机查询返回) const inactiveGoods = goodsRepository.create({ name: '不可用商品', price: 400.00, costPrice: 320.00, categoryId1: testCategory1.id, categoryId2: testCategory1.id, categoryId3: testCategory1.id, goodsType: 1, supplierId: testSupplier.id, merchantId: testMerchant.id, state: 2, stock: 10, lowestBuy: 1, createdBy: testUser.id }); await goodsRepository.save(inactiveGoods); }); describe('GET /goods/random', () => { it('应该返回随机商品列表', async () => { const response = await client.index.$get({ query: {} }); 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); // 验证只返回可用状态的商品 data.data.forEach((goods: any) => { expect(goods.state).toBe(1); }); } }); it('应该支持按分类过滤', async () => { const response = await client.index.$get({ query: { categoryId: testCategory1.id } }); expect(response.status).toBe(200); if (response.status === 200) { const data = await response.json(); expect(Array.isArray(data.data)).toBe(true); // 验证只返回指定分类的商品 data.data.forEach((goods: any) => { expect(goods.categoryId1).toBe(testCategory1.id); expect(goods.state).toBe(1); }); } }); it('应该支持限制返回数量', async () => { const response = await client.index.$get({ query: { limit: 2 } }); expect(response.status).toBe(200); if (response.status === 200) { const data = await response.json(); expect(Array.isArray(data.data)).toBe(true); expect(data.data.length).toBeLessThanOrEqual(2); // 验证只返回可用状态的商品 data.data.forEach((goods: any) => { expect(goods.state).toBe(1); }); } }); it('应该支持包含图片选项', async () => { const response = await client.index.$get({ query: { includeImages: true } }); expect(response.status).toBe(200); if (response.status === 200) { const data = await response.json(); expect(Array.isArray(data.data)).toBe(true); // 验证返回的商品数据包含图片关联信息 data.data.forEach((goods: any) => { expect(goods.state).toBe(1); // 注意:实际图片数据需要先创建文件实体才能测试 }); } }); it('应该正确处理不存在的分类', async () => { const response = await client.index.$get({ query: { categoryId: 999999 } }); expect(response.status).toBe(200); if (response.status === 200) { const data = await response.json(); expect(Array.isArray(data.data)).toBe(true); // 不存在的分类应该返回空数组 expect(data.data.length).toBe(0); } }); }); describe('随机商品关联关系测试', () => { it('应该正确加载商品关联关系', async () => { const response = await client.index.$get({ query: {} }); expect(response.status).toBe(200); if (response.status === 200) { const data = await response.json(); expect(Array.isArray(data.data)).toBe(true); // 验证至少返回一个商品 if (data.data.length > 0) { const goods = data.data[0]; // 验证基础字段 expect(goods).toHaveProperty('id'); expect(goods).toHaveProperty('name'); expect(goods).toHaveProperty('price'); expect(goods).toHaveProperty('state', 1); // 验证关联关系字段存在 expect(goods).toHaveProperty('category1'); expect(goods).toHaveProperty('supplier'); expect(goods).toHaveProperty('merchant'); } } }); }); describe('随机商品排序测试', () => { it('应该返回随机排序的商品', async () => { // 多次请求验证排序的随机性 const responses = await Promise.all([ client.index.$get({ query: {} }), client.index.$get({ query: {} }), client.index.$get({ query: {} }) ]); // 验证所有请求都成功 responses.forEach((response: any) => { expect(response.status).toBe(200); }); // 提取所有商品ID const allGoodsIds: number[] = []; for (const response of responses) { if (response.status === 200) { const data = await response.json(); data.data.forEach((goods: any) => { allGoodsIds.push(goods.id); }); } } // 验证返回了商品(可能有重复,因为是随机) expect(allGoodsIds.length).toBeGreaterThan(0); }); }); });