import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { IntegrationTestDatabase, setupIntegrationDatabaseHooksWithEntities } from '@d8d/shared-test-util'; import { PaymentMtService } from '../../src/services/payment.mt.service'; import { SystemConfigServiceMt } from '@d8d/core-module-mt/system-config-module-mt'; import { SystemConfigMt } from '@d8d/core-module-mt/system-config-module-mt'; import { UserEntityMt, RoleMt } from '@d8d/core-module-mt/user-module-mt'; import { FileMt } from '@d8d/core-module-mt/file-module-mt'; // 设置集成测试钩子 setupIntegrationDatabaseHooksWithEntities([SystemConfigMt, UserEntityMt, RoleMt, FileMt]) /** * 支付模块系统配置集成测试 * 验证PaymentMtService与SystemConfigServiceMt的集成 */ describe('支付模块系统配置集成测试', () => { let paymentMtService: PaymentMtService; let systemConfigService: SystemConfigServiceMt; const testTenantId = 1; beforeEach(async () => { // 获取数据源 const dataSource = await IntegrationTestDatabase.getDataSource(); if (!dataSource) throw new Error('Database not initialized'); paymentMtService = new PaymentMtService(dataSource); systemConfigService = new SystemConfigServiceMt(dataSource); // 清理测试配置 await cleanupTestConfigs(testTenantId); }); afterEach(async () => { // 清理测试配置 await cleanupTestConfigs(testTenantId); }); async function cleanupTestConfigs(tenantId: number) { if (!systemConfigService) return; const configKeys = [ 'wx.payment.merchant.id', 'wx.mini.app.id', 'wx.payment.v3.key', 'wx.payment.notify.url', 'wx.payment.cert.serial.no', 'wx.payment.public.key', 'wx.payment.private.key' ]; for (const key of configKeys) { try { await systemConfigService.deleteConfig(key, tenantId); } catch (error) { // 忽略删除失败的情况 } } } async function setupCompletePaymentConfig(tenantId: number, tenantPrefix: string) { await systemConfigService.setConfig('wx.payment.merchant.id', `${tenantPrefix}-merchant-id`, tenantId, `${tenantPrefix}商户ID`); await systemConfigService.setConfig('wx.mini.app.id', `${tenantPrefix}-app-id`, tenantId, `${tenantPrefix}小程序AppID`); await systemConfigService.setConfig('wx.payment.v3.key', `${tenantPrefix}-v3-key`, tenantId, `${tenantPrefix}V3密钥`); await systemConfigService.setConfig('wx.payment.notify.url', `${tenantPrefix}-notify-url`, tenantId, `${tenantPrefix}回调URL`); await systemConfigService.setConfig('wx.payment.cert.serial.no', `${tenantPrefix}-cert-serial`, tenantId, `${tenantPrefix}证书序列号`); await systemConfigService.setConfig('wx.payment.public.key', `${tenantPrefix}-public-key`, tenantId, `${tenantPrefix}公钥`); await systemConfigService.setConfig('wx.payment.private.key', `${tenantPrefix}-private-key`, tenantId, `${tenantPrefix}私钥`); } describe('系统配置读取功能', () => { it('应该从系统配置获取支付配置', async () => { // 设置测试支付配置 await systemConfigService.setConfig('wx.payment.merchant.id', 'test-merchant-id', testTenantId, '测试商户ID'); await systemConfigService.setConfig('wx.mini.app.id', 'test-app-id', testTenantId, '测试小程序AppID'); await systemConfigService.setConfig('wx.payment.v3.key', 'test-v3-key', testTenantId, '测试V3密钥'); await systemConfigService.setConfig('wx.payment.notify.url', 'https://test.com/notify', testTenantId, '测试回调URL'); await systemConfigService.setConfig('wx.payment.cert.serial.no', 'test-serial-no', testTenantId, '测试证书序列号'); await systemConfigService.setConfig('wx.payment.public.key', 'test-public-key', testTenantId, '测试公钥'); await systemConfigService.setConfig('wx.payment.private.key', 'test-private-key', testTenantId, '测试私钥'); // 验证配置读取 const config = await paymentMtService['getPaymentConfig'](testTenantId); expect(config.merchantId).toBe('test-merchant-id'); expect(config.appId).toBe('test-app-id'); expect(config.v3Key).toBe('test-v3-key'); expect(config.notifyUrl).toBe('https://test.com/notify'); expect(config.certSerialNo).toBe('test-serial-no'); expect(config.publicKey).toBe('test-public-key'); expect(config.privateKey).toBe('test-private-key'); }); it('应该支持批量获取支付配置', async () => { // 设置测试配置 await systemConfigService.setConfig('wx.payment.merchant.id', 'test-merchant-id', testTenantId, '测试商户ID'); await systemConfigService.setConfig('wx.mini.app.id', 'test-app-id', testTenantId, '测试小程序AppID'); // 批量获取配置 const configs = await systemConfigService.getConfigsByKeys( ['wx.payment.merchant.id', 'wx.mini.app.id'], testTenantId ); expect(configs['wx.payment.merchant.id']).toBe('test-merchant-id'); expect(configs['wx.mini.app.id']).toBe('test-app-id'); }); }); describe('租户配置隔离', () => { const tenant1Id = 1; const tenant2Id = 2; it('应该支持不同租户的独立支付配置', async () => { // 为租户1设置完整的支付配置 await setupCompletePaymentConfig(tenant1Id, 'tenant1'); // 为租户2设置不同的完整支付配置 await setupCompletePaymentConfig(tenant2Id, 'tenant2'); // 验证租户1的配置 const tenant1Config = await paymentMtService['getPaymentConfig'](tenant1Id); // 验证租户2的配置 const tenant2Config = await paymentMtService['getPaymentConfig'](tenant2Id); expect(tenant1Config.merchantId).toBe('tenant1-merchant-id'); expect(tenant1Config.appId).toBe('tenant1-app-id'); expect(tenant2Config.merchantId).toBe('tenant2-merchant-id'); expect(tenant2Config.appId).toBe('tenant2-app-id'); // 验证配置隔离 expect(tenant1Config.merchantId).not.toBe(tenant2Config.merchantId); expect(tenant1Config.appId).not.toBe(tenant2Config.appId); }); }); describe('配置回退机制', () => { it('应该在系统配置不存在时回退到环境变量', async () => { // 不设置系统配置,依赖环境变量 // 注意:这里假设环境变量已设置,实际测试时需要确保环境变量存在 try { const config = await paymentMtService['getPaymentConfig'](testTenantId); // 如果环境变量存在,应该能获取到配置 expect(config).toBeDefined(); } catch (error) { // 如果环境变量不存在,应该抛出配置不完整的错误 expect(error).toBeInstanceOf(Error); expect((error as Error).message).toContain('微信支付配置不完整'); } }); it('应该优先使用系统配置', async () => { // 设置完整的系统配置 await setupCompletePaymentConfig(testTenantId, 'system'); // 获取配置,应该优先使用系统配置 const config = await paymentMtService['getPaymentConfig'](testTenantId); // 验证所有配置都来自系统配置 expect(config.merchantId).toBe('system-merchant-id'); expect(config.appId).toBe('system-app-id'); expect(config.v3Key).toBe('system-v3-key'); }); }); describe('PaymentMtService集成', () => { it('应该正确注入SystemConfigServiceMt依赖', () => { // 验证服务实例化 expect(paymentMtService).toBeDefined(); expect(paymentMtService).toBeInstanceOf(PaymentMtService); }); it('应该支持动态配置初始化', async () => { // 验证initializeWxPay方法存在 const initializeMethod = paymentMtService['initializeWxPay']; expect(typeof initializeMethod).toBe('function'); // 验证getPaymentConfig方法存在 const getConfigMethod = paymentMtService['getPaymentConfig']; expect(typeof getConfigMethod).toBe('function'); }); it('应该支持租户ID参数', async () => { // 验证createPayment方法支持tenantId参数 const method = paymentMtService.createPayment; expect(typeof method).toBe('function'); // 验证方法签名包含tenantId参数 expect(method.length).toBeGreaterThanOrEqual(6); }); }); describe('配置验证', () => { it('应该验证配置完整性', async () => { // 不设置任何配置,应该抛出配置不完整的错误 await expect(paymentMtService['getPaymentConfig'](testTenantId)) .rejects .toThrow('微信支付配置不完整'); }); it('应该处理证书字符串格式', async () => { // 设置完整的支付配置,包含包含转义字符的证书 await setupCompletePaymentConfig(testTenantId, 'cert-test'); // 覆盖证书配置为包含转义字符的格式 await systemConfigService.setConfig('wx.payment.public.key', 'test\\npublic\\nkey', testTenantId, '测试公钥'); await systemConfigService.setConfig('wx.payment.private.key', 'test\\nprivate\\nkey', testTenantId, '测试私钥'); // 获取配置并验证格式处理 const config = await paymentMtService['getPaymentConfig'](testTenantId); // 验证转义字符被正确处理 expect(config.publicKey).toBe('test\npublic\nkey'); expect(config.privateKey).toBe('test\nprivate\nkey'); }); }); });