|
@@ -1,465 +0,0 @@
|
|
|
-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 { UserEntityMt, RoleMt } from '@d8d/user-module-mt';
|
|
|
|
|
-import { FileMt } from '@d8d/file-module-mt';
|
|
|
|
|
-import { SupplierMt } from '@d8d/supplier-module-mt';
|
|
|
|
|
-import { MerchantMt } from '@d8d/merchant-module-mt';
|
|
|
|
|
-import { adminGoodsRoutesMt } from '../../src/routes/index.mt';
|
|
|
|
|
-import { GoodsMt, GoodsCategoryMt } from '../../src/entities/index.mt';
|
|
|
|
|
-import { GoodsTestFactory } from '../factories/goods-test-factory';
|
|
|
|
|
-
|
|
|
|
|
-// 设置集成测试钩子
|
|
|
|
|
-setupIntegrationDatabaseHooksWithEntities([
|
|
|
|
|
- UserEntityMt, RoleMt, GoodsMt, GoodsCategoryMt, FileMt, SupplierMt, MerchantMt
|
|
|
|
|
-])
|
|
|
|
|
-
|
|
|
|
|
-describe('管理员父子商品管理API集成测试', () => {
|
|
|
|
|
- let client: ReturnType<typeof testClient<typeof adminGoodsRoutesMt>>;
|
|
|
|
|
- let testUser: UserEntityMt;
|
|
|
|
|
- let testCategory: GoodsCategoryMt;
|
|
|
|
|
- let testSupplier: SupplierMt;
|
|
|
|
|
- let testMerchant: MerchantMt;
|
|
|
|
|
- let testFactory: GoodsTestFactory;
|
|
|
|
|
- let authToken: string;
|
|
|
|
|
- let parentGoods: GoodsMt;
|
|
|
|
|
- let childGoods1: GoodsMt;
|
|
|
|
|
- let childGoods2: GoodsMt;
|
|
|
|
|
- let normalGoods: GoodsMt;
|
|
|
|
|
-
|
|
|
|
|
- beforeEach(async () => {
|
|
|
|
|
- // 创建测试客户端
|
|
|
|
|
- client = testClient(adminGoodsRoutesMt);
|
|
|
|
|
-
|
|
|
|
|
- // 获取数据源并创建测试工厂
|
|
|
|
|
- const dataSource = await IntegrationTestDatabase.getDataSource();
|
|
|
|
|
- testFactory = new GoodsTestFactory(dataSource);
|
|
|
|
|
-
|
|
|
|
|
- // 使用测试工厂创建测试数据
|
|
|
|
|
- testUser = await testFactory.createTestUser();
|
|
|
|
|
- testCategory = await testFactory.createTestCategory(testUser.id);
|
|
|
|
|
- testSupplier = await testFactory.createTestSupplier(testUser.id);
|
|
|
|
|
- testMerchant = await testFactory.createTestMerchant(testUser.id);
|
|
|
|
|
-
|
|
|
|
|
- // 生成认证token
|
|
|
|
|
- authToken = JWTUtil.generateToken({
|
|
|
|
|
- id: testUser.id,
|
|
|
|
|
- username: testUser.username,
|
|
|
|
|
- tenantId: testUser.tenantId,
|
|
|
|
|
- roles: ['admin']
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 创建父商品
|
|
|
|
|
- parentGoods = await testFactory.createTestGoods(testUser.id, {
|
|
|
|
|
- name: '父商品测试',
|
|
|
|
|
- price: 200.00,
|
|
|
|
|
- costPrice: 150.00,
|
|
|
|
|
- categoryId1: testCategory.id,
|
|
|
|
|
- categoryId2: testCategory.id,
|
|
|
|
|
- categoryId3: testCategory.id,
|
|
|
|
|
- supplierId: testSupplier.id,
|
|
|
|
|
- merchantId: testMerchant.id,
|
|
|
|
|
- state: 1,
|
|
|
|
|
- spuId: 0,
|
|
|
|
|
- spuName: null
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 创建子商品1
|
|
|
|
|
- childGoods1 = await testFactory.createTestGoods(testUser.id, {
|
|
|
|
|
- name: '子商品1 - 红色',
|
|
|
|
|
- price: 210.00,
|
|
|
|
|
- costPrice: 160.00,
|
|
|
|
|
- categoryId1: testCategory.id,
|
|
|
|
|
- categoryId2: testCategory.id,
|
|
|
|
|
- categoryId3: testCategory.id,
|
|
|
|
|
- supplierId: testSupplier.id,
|
|
|
|
|
- merchantId: testMerchant.id,
|
|
|
|
|
- state: 1,
|
|
|
|
|
- spuId: parentGoods.id,
|
|
|
|
|
- spuName: '父商品测试'
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 创建子商品2
|
|
|
|
|
- childGoods2 = await testFactory.createTestGoods(testUser.id, {
|
|
|
|
|
- name: '子商品2 - 蓝色',
|
|
|
|
|
- price: 220.00,
|
|
|
|
|
- costPrice: 170.00,
|
|
|
|
|
- categoryId1: testCategory.id,
|
|
|
|
|
- categoryId2: testCategory.id,
|
|
|
|
|
- categoryId3: testCategory.id,
|
|
|
|
|
- supplierId: testSupplier.id,
|
|
|
|
|
- merchantId: testMerchant.id,
|
|
|
|
|
- state: 1,
|
|
|
|
|
- spuId: parentGoods.id,
|
|
|
|
|
- spuName: '父商品测试'
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 创建普通商品(非父子商品)
|
|
|
|
|
- normalGoods = await testFactory.createTestGoods(testUser.id, {
|
|
|
|
|
- name: '普通商品',
|
|
|
|
|
- price: 100.00,
|
|
|
|
|
- costPrice: 80.00,
|
|
|
|
|
- categoryId1: testCategory.id,
|
|
|
|
|
- categoryId2: testCategory.id,
|
|
|
|
|
- categoryId3: testCategory.id,
|
|
|
|
|
- supplierId: testSupplier.id,
|
|
|
|
|
- merchantId: testMerchant.id,
|
|
|
|
|
- state: 1,
|
|
|
|
|
- spuId: 0,
|
|
|
|
|
- spuName: null
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- describe('GET /api/v1/goods/:id/children', () => {
|
|
|
|
|
- it('应该成功获取父商品的子商品列表', async () => {
|
|
|
|
|
- const response = await client['{id}/children'].$get({
|
|
|
|
|
- param: { id: parentGoods.id },
|
|
|
|
|
- query: { page: 1, pageSize: 10 }
|
|
|
|
|
- }, {
|
|
|
|
|
- headers: {
|
|
|
|
|
- 'Authorization': `Bearer ${authToken}`
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- console.debug('响应状态码:', response.status);
|
|
|
|
|
- const data = await response.json();
|
|
|
|
|
- console.debug('响应数据:', data);
|
|
|
|
|
- expect(response.status).toBe(200);
|
|
|
|
|
- expect(data.data).toHaveLength(2);
|
|
|
|
|
- expect(data.total).toBe(2);
|
|
|
|
|
- expect(data.page).toBe(1);
|
|
|
|
|
- expect(data.pageSize).toBe(10);
|
|
|
|
|
- expect(data.totalPages).toBe(1);
|
|
|
|
|
-
|
|
|
|
|
- // 验证子商品数据
|
|
|
|
|
- const childIds = data.data.map((item: any) => item.id);
|
|
|
|
|
- expect(childIds).toContain(childGoods1.id);
|
|
|
|
|
- expect(childIds).toContain(childGoods2.id);
|
|
|
|
|
-
|
|
|
|
|
- // 验证子商品包含正确的关联关系
|
|
|
|
|
- const firstChild = data.data[0];
|
|
|
|
|
- expect(firstChild).toHaveProperty('category1');
|
|
|
|
|
- expect(firstChild).toHaveProperty('supplier');
|
|
|
|
|
- expect(firstChild).toHaveProperty('merchant');
|
|
|
|
|
- expect(firstChild.spuId).toBe(parentGoods.id);
|
|
|
|
|
- expect(firstChild.spuName).toBe('父商品测试');
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('应该验证父商品是否存在', async () => {
|
|
|
|
|
- const response = await client['{id}/children'].$get({
|
|
|
|
|
- param: { id: 99999 }, // 不存在的商品ID
|
|
|
|
|
- query: { page: 1, pageSize: 10 },
|
|
|
|
|
- headers: { authorization: `Bearer ${authToken}` }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- expect(response.status).toBe(404);
|
|
|
|
|
- const data = await response.json();
|
|
|
|
|
- expect(data.code).toBe(404);
|
|
|
|
|
- expect(data.message).toContain('父商品不存在');
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('应该支持搜索关键词过滤', async () => {
|
|
|
|
|
- const response = await client['{id}/children'].$get({
|
|
|
|
|
- param: { id: parentGoods.id },
|
|
|
|
|
- query: { page: 1, pageSize: 10, keyword: '红色' },
|
|
|
|
|
- headers: { authorization: `Bearer ${authToken}` }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- expect(response.status).toBe(200);
|
|
|
|
|
- const data = await response.json();
|
|
|
|
|
- expect(data.data).toHaveLength(1);
|
|
|
|
|
- expect(data.data[0].name).toBe('子商品1 - 红色');
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('应该支持排序', async () => {
|
|
|
|
|
- // 修改子商品的排序字段
|
|
|
|
|
- const dataSource = await IntegrationTestDatabase.getDataSource();
|
|
|
|
|
- const goodsRepo = dataSource.getRepository(GoodsMt);
|
|
|
|
|
-
|
|
|
|
|
- await goodsRepo.update(childGoods1.id, { sort: 2 });
|
|
|
|
|
- await goodsRepo.update(childGoods2.id, { sort: 1 });
|
|
|
|
|
-
|
|
|
|
|
- const response = await client['{id}/children'].$get({
|
|
|
|
|
- param: { id: parentGoods.id },
|
|
|
|
|
- query: { page: 1, pageSize: 10, sortBy: 'sort', sortOrder: 'ASC' },
|
|
|
|
|
- headers: { authorization: `Bearer ${authToken}` }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- expect(response.status).toBe(200);
|
|
|
|
|
- const data = await response.json();
|
|
|
|
|
- expect(data.data[0].id).toBe(childGoods2.id); // sort=1 应该在前
|
|
|
|
|
- expect(data.data[1].id).toBe(childGoods1.id); // sort=2 应该在后
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- describe('POST /api/v1/goods/:id/set-as-parent', () => {
|
|
|
|
|
- it('应该成功将普通商品设为父商品', async () => {
|
|
|
|
|
- const response = await client['{id}/set-as-parent'].$post({
|
|
|
|
|
- param: { id: normalGoods.id },
|
|
|
|
|
- headers: { authorization: `Bearer ${authToken}` }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- expect(response.status).toBe(200);
|
|
|
|
|
- const data = await response.json();
|
|
|
|
|
- expect(data.id).toBe(normalGoods.id);
|
|
|
|
|
- expect(data.spuId).toBe(0);
|
|
|
|
|
- expect(data.spuName).toBeNull();
|
|
|
|
|
-
|
|
|
|
|
- // 验证数据库中的更新
|
|
|
|
|
- const dataSource = await IntegrationTestDatabase.getDataSource();
|
|
|
|
|
- const updatedGoods = await dataSource.getRepository(GoodsMt).findOne({
|
|
|
|
|
- where: { id: normalGoods.id } as any
|
|
|
|
|
- });
|
|
|
|
|
- expect(updatedGoods?.spuId).toBe(0);
|
|
|
|
|
- expect(updatedGoods?.spuName).toBeNull();
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('应该拒绝将子商品设为父商品', async () => {
|
|
|
|
|
- const response = await client['{id}/set-as-parent'].$post({
|
|
|
|
|
- param: { id: childGoods1.id },
|
|
|
|
|
- headers: { authorization: `Bearer ${authToken}` }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- expect(response.status).toBe(400);
|
|
|
|
|
- const data = await response.json();
|
|
|
|
|
- expect(data.code).toBe(400);
|
|
|
|
|
- expect(data.message).toContain('子商品不能设为父商品');
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('应该验证商品是否存在', async () => {
|
|
|
|
|
- const response = await client['{id}/set-as-parent'].$post({
|
|
|
|
|
- param: { id: 99999 }, // 不存在的商品ID
|
|
|
|
|
- headers: { authorization: `Bearer ${authToken}` }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- expect(response.status).toBe(404);
|
|
|
|
|
- const data = await response.json();
|
|
|
|
|
- expect(data.code).toBe(404);
|
|
|
|
|
- expect(data.message).toContain('商品不存在');
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- describe('DELETE /api/v1/goods/:id/parent', () => {
|
|
|
|
|
- it('应该成功解除子商品的父子关系', async () => {
|
|
|
|
|
- const response = await client['{id}/parent'].$delete({
|
|
|
|
|
- param: { id: childGoods1.id },
|
|
|
|
|
- headers: { authorization: `Bearer ${authToken}` }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- expect(response.status).toBe(200);
|
|
|
|
|
- const data = await response.json();
|
|
|
|
|
- expect(data.id).toBe(childGoods1.id);
|
|
|
|
|
- expect(data.spuId).toBe(0);
|
|
|
|
|
- expect(data.spuName).toBeNull();
|
|
|
|
|
-
|
|
|
|
|
- // 验证数据库中的更新
|
|
|
|
|
- const dataSource = await IntegrationTestDatabase.getDataSource();
|
|
|
|
|
- const updatedGoods = await dataSource.getRepository(GoodsMt).findOne({
|
|
|
|
|
- where: { id: childGoods1.id } as any
|
|
|
|
|
- });
|
|
|
|
|
- expect(updatedGoods?.spuId).toBe(0);
|
|
|
|
|
- expect(updatedGoods?.spuName).toBeNull();
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('应该拒绝解除非子商品的父子关系', async () => {
|
|
|
|
|
- const response = await client['{id}/parent'].$delete({
|
|
|
|
|
- param: { id: normalGoods.id },
|
|
|
|
|
- headers: { authorization: `Bearer ${authToken}` }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- expect(response.status).toBe(400);
|
|
|
|
|
- const data = await response.json();
|
|
|
|
|
- expect(data.code).toBe(400);
|
|
|
|
|
- expect(data.message).toContain('该商品不是子商品');
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('应该验证商品是否存在', async () => {
|
|
|
|
|
- const response = await client['{id}/parent'].$delete({
|
|
|
|
|
- param: { id: 99999 }, // 不存在的商品ID
|
|
|
|
|
- headers: { authorization: `Bearer ${authToken}` }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- expect(response.status).toBe(404);
|
|
|
|
|
- const data = await response.json();
|
|
|
|
|
- expect(data.code).toBe(404);
|
|
|
|
|
- expect(data.message).toContain('商品不存在');
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- describe('POST /api/v1/goods/batch-create-children', () => {
|
|
|
|
|
- it('应该成功批量创建子商品', async () => {
|
|
|
|
|
- const specs = [
|
|
|
|
|
- { name: '规格1 - 黑色', price: 230.00, costPrice: 180.00, stock: 50, sort: 1 },
|
|
|
|
|
- { name: '规格2 - 白色', price: 240.00, costPrice: 190.00, stock: 60, sort: 2 },
|
|
|
|
|
- { name: '规格3 - 金色', price: 250.00, costPrice: 200.00, stock: 70, sort: 3 }
|
|
|
|
|
- ];
|
|
|
|
|
-
|
|
|
|
|
- const response = await client.batchCreateChildren.$post({
|
|
|
|
|
- json: {
|
|
|
|
|
- parentGoodsId: parentGoods.id,
|
|
|
|
|
- specs
|
|
|
|
|
- },
|
|
|
|
|
- headers: { authorization: `Bearer ${authToken}` }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- expect(response.status).toBe(200);
|
|
|
|
|
- const data = await response.json();
|
|
|
|
|
- expect(data.success).toBe(true);
|
|
|
|
|
- expect(data.count).toBe(3);
|
|
|
|
|
- expect(data.children).toHaveLength(3);
|
|
|
|
|
-
|
|
|
|
|
- // 验证子商品数据
|
|
|
|
|
- data.children.forEach((child: any, index: number) => {
|
|
|
|
|
- expect(child.name).toBe(specs[index].name);
|
|
|
|
|
- expect(child.price).toBe(specs[index].price);
|
|
|
|
|
- expect(child.costPrice).toBe(specs[index].costPrice);
|
|
|
|
|
- expect(child.stock).toBe(specs[index].stock);
|
|
|
|
|
- expect(child.sort).toBe(specs[index].sort);
|
|
|
|
|
- expect(child.spuId).toBe(parentGoods.id);
|
|
|
|
|
- expect(child.spuName).toBe('父商品测试');
|
|
|
|
|
- expect(child.state).toBe(1);
|
|
|
|
|
- expect(child.tenantId).toBe(testUser.tenantId);
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 验证数据库中的记录
|
|
|
|
|
- const dataSource = await IntegrationTestDatabase.getDataSource();
|
|
|
|
|
- const children = await dataSource.getRepository(GoodsMt).find({
|
|
|
|
|
- where: { spuId: parentGoods.id } as any,
|
|
|
|
|
- order: { sort: 'ASC' }
|
|
|
|
|
- });
|
|
|
|
|
- expect(children).toHaveLength(5); // 原有2个 + 新增3个
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('应该验证父商品是否存在', async () => {
|
|
|
|
|
- const response = await client.batchCreateChildren.$post({
|
|
|
|
|
- json: {
|
|
|
|
|
- parentGoodsId: 99999, // 不存在的父商品ID
|
|
|
|
|
- specs: [{ name: '测试规格', price: 100, costPrice: 80, stock: 10, sort: 1 }]
|
|
|
|
|
- },
|
|
|
|
|
- headers: { authorization: `Bearer ${authToken}` }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- expect(response.status).toBe(404);
|
|
|
|
|
- const data = await response.json();
|
|
|
|
|
- expect(data.code).toBe(404);
|
|
|
|
|
- expect(data.message).toContain('父商品不存在');
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('应该验证父商品必须是父商品', async () => {
|
|
|
|
|
- const response = await client.batchCreateChildren.$post({
|
|
|
|
|
- json: {
|
|
|
|
|
- parentGoodsId: childGoods1.id, // 子商品ID
|
|
|
|
|
- specs: [{ name: '测试规格', price: 100, costPrice: 80, stock: 10, sort: 1 }]
|
|
|
|
|
- },
|
|
|
|
|
- headers: { authorization: `Bearer ${authToken}` }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- expect(response.status).toBe(400);
|
|
|
|
|
- const data = await response.json();
|
|
|
|
|
- expect(data.code).toBe(400);
|
|
|
|
|
- expect(data.message).toContain('只能为父商品创建子商品');
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('应该验证规格数据有效性', async () => {
|
|
|
|
|
- const response = await client.batchCreateChildren.$post({
|
|
|
|
|
- json: {
|
|
|
|
|
- parentGoodsId: parentGoods.id,
|
|
|
|
|
- specs: [] // 空规格列表
|
|
|
|
|
- },
|
|
|
|
|
- headers: { authorization: `Bearer ${authToken}` }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- expect(response.status).toBe(400);
|
|
|
|
|
- const data = await response.json();
|
|
|
|
|
- expect(data.code).toBe(400);
|
|
|
|
|
- expect(data.message).toContain('至少需要一个规格');
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('应该继承父商品的分类和其他信息', async () => {
|
|
|
|
|
- const specs = [{ name: '继承测试规格', price: 100, costPrice: 80, stock: 10, sort: 1 }];
|
|
|
|
|
-
|
|
|
|
|
- const response = await client.batchCreateChildren.$post({
|
|
|
|
|
- json: {
|
|
|
|
|
- parentGoodsId: parentGoods.id,
|
|
|
|
|
- specs
|
|
|
|
|
- },
|
|
|
|
|
- headers: { authorization: `Bearer ${authToken}` }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- expect(response.status).toBe(200);
|
|
|
|
|
- const data = await response.json();
|
|
|
|
|
- const child = data.children[0];
|
|
|
|
|
-
|
|
|
|
|
- // 验证继承的字段
|
|
|
|
|
- expect(child.categoryId1).toBe(parentGoods.categoryId1);
|
|
|
|
|
- expect(child.categoryId2).toBe(parentGoods.categoryId2);
|
|
|
|
|
- expect(child.categoryId3).toBe(parentGoods.categoryId3);
|
|
|
|
|
- expect(child.goodsType).toBe(parentGoods.goodsType);
|
|
|
|
|
- expect(child.supplierId).toBe(parentGoods.supplierId);
|
|
|
|
|
- expect(child.merchantId).toBe(parentGoods.merchantId);
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('应该支持事务,全部成功或全部失败', async () => {
|
|
|
|
|
- const specs = [
|
|
|
|
|
- { name: '有效规格1', price: 100, costPrice: 80, stock: 10, sort: 1 },
|
|
|
|
|
- { name: '', price: 100, costPrice: 80, stock: 10, sort: 2 }, // 无效:名称为空
|
|
|
|
|
- { name: '有效规格3', price: 100, costPrice: 80, stock: 10, sort: 3 }
|
|
|
|
|
- ];
|
|
|
|
|
-
|
|
|
|
|
- const response = await client.batchCreateChildren.$post({
|
|
|
|
|
- json: {
|
|
|
|
|
- parentGoodsId: parentGoods.id,
|
|
|
|
|
- specs
|
|
|
|
|
- },
|
|
|
|
|
- headers: { authorization: `Bearer ${authToken}` }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 由于数据库约束,这个测试可能会失败
|
|
|
|
|
- // 但重要的是验证事务机制
|
|
|
|
|
- expect(response.status).toBe(500);
|
|
|
|
|
-
|
|
|
|
|
- // 验证没有创建任何子商品(事务回滚)
|
|
|
|
|
- const dataSource = await IntegrationTestDatabase.getDataSource();
|
|
|
|
|
- const children = await dataSource.getRepository(GoodsMt).find({
|
|
|
|
|
- where: { spuId: parentGoods.id } as any
|
|
|
|
|
- });
|
|
|
|
|
- expect(children).toHaveLength(2); // 只有原有的2个子商品
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- describe('认证和授权', () => {
|
|
|
|
|
- it('应该要求认证', async () => {
|
|
|
|
|
- const response = await client['{id}/children'].$get({
|
|
|
|
|
- param: { id: parentGoods.id },
|
|
|
|
|
- query: { page: 1, pageSize: 10 }
|
|
|
|
|
- // 不提供认证头
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- expect(response.status).toBe(401);
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- it('应该验证租户隔离', async () => {
|
|
|
|
|
- // 创建另一个租户的用户和商品
|
|
|
|
|
- const otherUser = await testFactory.createTestUser('other-tenant');
|
|
|
|
|
- const otherAuthToken = JWTUtil.generateToken({
|
|
|
|
|
- id: otherUser.id,
|
|
|
|
|
- username: otherUser.username,
|
|
|
|
|
- tenantId: otherUser.tenantId,
|
|
|
|
|
- roles: ['admin']
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- // 尝试访问第一个租户的商品
|
|
|
|
|
- const response = await client['{id}/children'].$get({
|
|
|
|
|
- param: { id: parentGoods.id },
|
|
|
|
|
- query: { page: 1, pageSize: 10 },
|
|
|
|
|
- header: { authorization: `Bearer ${otherAuthToken}` }
|
|
|
|
|
- });
|
|
|
|
|
-
|
|
|
|
|
- expect(response.status).toBe(404);
|
|
|
|
|
- const data = await response.json();
|
|
|
|
|
- expect(data.code).toBe(404);
|
|
|
|
|
- expect(data.message).toContain('父商品不存在');
|
|
|
|
|
- });
|
|
|
|
|
- });
|
|
|
|
|
-});
|
|
|