import { describe, it, expect, beforeEach } from 'vitest'; import { AppDataSource } from '@d8d/shared-utils'; import { IntegrationTestDatabase, setupIntegrationDatabaseHooksWithEntities } from '@d8d/shared-test-util'; import { PaymentMtEntity } from '../../src/entities/payment.mt.entity.js'; import { PaymentStatus } from '../../src/entities/payment.types.js'; // 设置集成测试钩子 setupIntegrationDatabaseHooksWithEntities([PaymentMtEntity]) // 测试数据工厂 const createTestPaymentData = (tenantId: number) => ({ externalOrderId: 1001, userId: 1, totalAmount: 1000, description: '测试支付订单', paymentStatus: PaymentStatus.PENDING, openid: 'test_openid_123', tenantId }); describe('多租户支付路由集成测试', () => { let dataSource: any; beforeEach(async () => { dataSource = await IntegrationTestDatabase.getDataSource(); if (!dataSource) throw new Error('Database not initialized'); }); describe('租户数据隔离验证', () => { it('应该只返回当前租户的支付记录', async () => { // 创建不同租户的测试数据 const tenant1Payment = createTestPaymentData(1); const tenant2Payment = createTestPaymentData(2); const paymentRepository = dataSource.getRepository(PaymentMtEntity); await paymentRepository.save([tenant1Payment, tenant2Payment]); // 模拟租户1的查询 const tenant1Payments = await paymentRepository.find({ where: { tenantId: 1 } }); // 模拟租户2的查询 const tenant2Payments = await paymentRepository.find({ where: { tenantId: 2 } }); expect(tenant1Payments).toHaveLength(1); expect(tenant1Payments[0].tenantId).toBe(1); expect(tenant2Payments).toHaveLength(1); expect(tenant2Payments[0].tenantId).toBe(2); }); it('应该防止跨租户支付记录访问', async () => { // 创建租户1的支付记录 const tenant1Payment = createTestPaymentData(1); const paymentRepository = dataSource.getRepository(PaymentMtEntity); await paymentRepository.save(tenant1Payment); // 尝试使用租户2的ID查询租户1的支付记录 const crossTenantPayment = await paymentRepository.findOne({ where: { externalOrderId: tenant1Payment.externalOrderId, tenantId: 2 // 错误的租户ID } }); expect(crossTenantPayment).toBeNull(); }); it('应该正确设置租户ID在创建支付时', async () => { const paymentRepository = dataSource.getRepository(PaymentMtEntity); const tenantId = 3; const newPayment = paymentRepository.create({ ...createTestPaymentData(tenantId), externalOrderId: 1002 }); const savedPayment = await paymentRepository.save(newPayment); expect(savedPayment.tenantId).toBe(tenantId); expect(savedPayment.externalOrderId).toBe(1002); }); }); describe('支付状态管理', () => { it('应该正确更新支付状态', async () => { const paymentRepository = dataSource.getRepository(PaymentMtEntity); const paymentData = createTestPaymentData(1); const payment = paymentRepository.create(paymentData); const savedPayment = await paymentRepository.save(payment); // 更新支付状态 savedPayment.paymentStatus = PaymentStatus.PAID; savedPayment.wechatTransactionId = 'wx_transaction_123'; const updatedPayment = await paymentRepository.save(savedPayment); expect(updatedPayment.paymentStatus).toBe(PaymentStatus.PAID); expect(updatedPayment.wechatTransactionId).toBe('wx_transaction_123'); }); it('应该支持所有支付状态枚举值', async () => { const paymentRepository = dataSource.getRepository(PaymentMtEntity); // 测试所有状态枚举值 const statuses = Object.values(PaymentStatus); for (const status of statuses) { const paymentData = createTestPaymentData(1); paymentData.paymentStatus = status; paymentData.externalOrderId = Math.floor(Math.random() * 10000); const payment = paymentRepository.create(paymentData); const savedPayment = await paymentRepository.save(payment); expect(savedPayment.paymentStatus).toBe(status); } }); }); describe('支付记录唯一性', () => { it('应该防止相同外部订单ID的重复支付记录', async () => { const paymentRepository = dataSource.getRepository(PaymentMtEntity); const paymentData = createTestPaymentData(1); // 创建第一个支付记录 const payment1 = paymentRepository.create(paymentData); await paymentRepository.save(payment1); // 尝试创建相同外部订单ID的支付记录 const payment2 = paymentRepository.create({ ...paymentData, userId: 2 // 不同用户 }); // 应该成功,因为租户隔离允许相同外部订单ID const savedPayment2 = await paymentRepository.save(payment2); expect(savedPayment2.externalOrderId).toBe(paymentData.externalOrderId); expect(savedPayment2.userId).toBe(2); }); }); describe('关联实体租户一致性', () => { it('应该确保支付与用户的租户一致性', async () => { const paymentRepository = dataSource.getRepository(PaymentMtEntity); // 创建租户1的支付记录 const paymentData1 = createTestPaymentData(1); const payment1 = paymentRepository.create(paymentData1); await paymentRepository.save(payment1); // 创建租户2的支付记录 const paymentData2 = createTestPaymentData(2); paymentData2.externalOrderId = 1003; const payment2 = paymentRepository.create(paymentData2); await paymentRepository.save(payment2); // 验证租户隔离 const tenant1Payments = await paymentRepository.find({ where: { tenantId: 1 } }); const tenant2Payments = await paymentRepository.find({ where: { tenantId: 2 } }); expect(tenant1Payments).toHaveLength(1); expect(tenant1Payments[0].tenantId).toBe(1); expect(tenant2Payments).toHaveLength(1); expect(tenant2Payments[0].tenantId).toBe(2); }); }); });