system-config-integration.test.ts 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. import { describe, it, expect, beforeEach, afterEach } from 'vitest';
  2. import {
  3. IntegrationTestDatabase,
  4. setupIntegrationDatabaseHooksWithEntities
  5. } from '@d8d/shared-test-util';
  6. import { PaymentMtService } from '../../src/services/payment.mt.service';
  7. import { SystemConfigServiceMt } from '@d8d/core-module-mt/system-config-module-mt';
  8. import { SystemConfigMt } from '@d8d/core-module-mt/system-config-module-mt';
  9. import { UserEntityMt, RoleMt } from '@d8d/core-module-mt/user-module-mt';
  10. import { FileMt } from '@d8d/core-module-mt/file-module-mt';
  11. // 设置集成测试钩子
  12. setupIntegrationDatabaseHooksWithEntities([SystemConfigMt, UserEntityMt, RoleMt, FileMt])
  13. /**
  14. * 支付模块系统配置集成测试
  15. * 验证PaymentMtService与SystemConfigServiceMt的集成
  16. */
  17. describe('支付模块系统配置集成测试', () => {
  18. let paymentMtService: PaymentMtService;
  19. let systemConfigService: SystemConfigServiceMt;
  20. const testTenantId = 1;
  21. beforeEach(async () => {
  22. // 获取数据源
  23. const dataSource = await IntegrationTestDatabase.getDataSource();
  24. if (!dataSource) throw new Error('Database not initialized');
  25. paymentMtService = new PaymentMtService(dataSource);
  26. systemConfigService = new SystemConfigServiceMt(dataSource);
  27. // 清理测试配置
  28. await cleanupTestConfigs(testTenantId);
  29. });
  30. afterEach(async () => {
  31. // 清理测试配置
  32. await cleanupTestConfigs(testTenantId);
  33. });
  34. async function cleanupTestConfigs(tenantId: number) {
  35. if (!systemConfigService) return;
  36. const configKeys = [
  37. 'wx.payment.merchant.id',
  38. 'wx.mini.app.id',
  39. 'wx.payment.v3.key',
  40. 'wx.payment.notify.url',
  41. 'wx.payment.cert.serial.no',
  42. 'wx.payment.public.key',
  43. 'wx.payment.private.key'
  44. ];
  45. for (const key of configKeys) {
  46. try {
  47. await systemConfigService.deleteConfig(key, tenantId);
  48. } catch (error) {
  49. // 忽略删除失败的情况
  50. }
  51. }
  52. }
  53. async function setupCompletePaymentConfig(tenantId: number, tenantPrefix: string) {
  54. await systemConfigService.setConfig('wx.payment.merchant.id', `${tenantPrefix}-merchant-id`, tenantId, `${tenantPrefix}商户ID`);
  55. await systemConfigService.setConfig('wx.mini.app.id', `${tenantPrefix}-app-id`, tenantId, `${tenantPrefix}小程序AppID`);
  56. await systemConfigService.setConfig('wx.payment.v3.key', `${tenantPrefix}-v3-key`, tenantId, `${tenantPrefix}V3密钥`);
  57. await systemConfigService.setConfig('wx.payment.notify.url', `${tenantPrefix}-notify-url`, tenantId, `${tenantPrefix}回调URL`);
  58. await systemConfigService.setConfig('wx.payment.cert.serial.no', `${tenantPrefix}-cert-serial`, tenantId, `${tenantPrefix}证书序列号`);
  59. await systemConfigService.setConfig('wx.payment.public.key', `${tenantPrefix}-public-key`, tenantId, `${tenantPrefix}公钥`);
  60. await systemConfigService.setConfig('wx.payment.private.key', `${tenantPrefix}-private-key`, tenantId, `${tenantPrefix}私钥`);
  61. }
  62. describe('系统配置读取功能', () => {
  63. it('应该从系统配置获取支付配置', async () => {
  64. // 设置测试支付配置
  65. await systemConfigService.setConfig('wx.payment.merchant.id', 'test-merchant-id', testTenantId, '测试商户ID');
  66. await systemConfigService.setConfig('wx.mini.app.id', 'test-app-id', testTenantId, '测试小程序AppID');
  67. await systemConfigService.setConfig('wx.payment.v3.key', 'test-v3-key', testTenantId, '测试V3密钥');
  68. await systemConfigService.setConfig('wx.payment.notify.url', 'https://test.com/notify', testTenantId, '测试回调URL');
  69. await systemConfigService.setConfig('wx.payment.cert.serial.no', 'test-serial-no', testTenantId, '测试证书序列号');
  70. await systemConfigService.setConfig('wx.payment.public.key', 'test-public-key', testTenantId, '测试公钥');
  71. await systemConfigService.setConfig('wx.payment.private.key', 'test-private-key', testTenantId, '测试私钥');
  72. // 验证配置读取
  73. const config = await paymentMtService['getPaymentConfig'](testTenantId);
  74. expect(config.merchantId).toBe('test-merchant-id');
  75. expect(config.appId).toBe('test-app-id');
  76. expect(config.v3Key).toBe('test-v3-key');
  77. expect(config.notifyUrl).toBe('https://test.com/notify');
  78. expect(config.certSerialNo).toBe('test-serial-no');
  79. expect(config.publicKey).toBe('test-public-key');
  80. expect(config.privateKey).toBe('test-private-key');
  81. });
  82. it('应该支持批量获取支付配置', async () => {
  83. // 设置测试配置
  84. await systemConfigService.setConfig('wx.payment.merchant.id', 'test-merchant-id', testTenantId, '测试商户ID');
  85. await systemConfigService.setConfig('wx.mini.app.id', 'test-app-id', testTenantId, '测试小程序AppID');
  86. // 批量获取配置
  87. const configs = await systemConfigService.getConfigsByKeys(
  88. ['wx.payment.merchant.id', 'wx.mini.app.id'],
  89. testTenantId
  90. );
  91. expect(configs['wx.payment.merchant.id']).toBe('test-merchant-id');
  92. expect(configs['wx.mini.app.id']).toBe('test-app-id');
  93. });
  94. });
  95. describe('租户配置隔离', () => {
  96. const tenant1Id = 1;
  97. const tenant2Id = 2;
  98. it('应该支持不同租户的独立支付配置', async () => {
  99. // 为租户1设置完整的支付配置
  100. await setupCompletePaymentConfig(tenant1Id, 'tenant1');
  101. // 为租户2设置不同的完整支付配置
  102. await setupCompletePaymentConfig(tenant2Id, 'tenant2');
  103. // 验证租户1的配置
  104. const tenant1Config = await paymentMtService['getPaymentConfig'](tenant1Id);
  105. // 验证租户2的配置
  106. const tenant2Config = await paymentMtService['getPaymentConfig'](tenant2Id);
  107. expect(tenant1Config.merchantId).toBe('tenant1-merchant-id');
  108. expect(tenant1Config.appId).toBe('tenant1-app-id');
  109. expect(tenant2Config.merchantId).toBe('tenant2-merchant-id');
  110. expect(tenant2Config.appId).toBe('tenant2-app-id');
  111. // 验证配置隔离
  112. expect(tenant1Config.merchantId).not.toBe(tenant2Config.merchantId);
  113. expect(tenant1Config.appId).not.toBe(tenant2Config.appId);
  114. });
  115. });
  116. describe('配置回退机制', () => {
  117. it('应该在系统配置不存在时回退到环境变量', async () => {
  118. // 不设置系统配置,依赖环境变量
  119. // 注意:这里假设环境变量已设置,实际测试时需要确保环境变量存在
  120. try {
  121. const config = await paymentMtService['getPaymentConfig'](testTenantId);
  122. // 如果环境变量存在,应该能获取到配置
  123. expect(config).toBeDefined();
  124. } catch (error) {
  125. // 如果环境变量不存在,应该抛出配置不完整的错误
  126. expect(error).toBeInstanceOf(Error);
  127. expect((error as Error).message).toContain('微信支付配置不完整');
  128. }
  129. });
  130. it('应该优先使用系统配置', async () => {
  131. // 设置完整的系统配置
  132. await setupCompletePaymentConfig(testTenantId, 'system');
  133. // 获取配置,应该优先使用系统配置
  134. const config = await paymentMtService['getPaymentConfig'](testTenantId);
  135. // 验证所有配置都来自系统配置
  136. expect(config.merchantId).toBe('system-merchant-id');
  137. expect(config.appId).toBe('system-app-id');
  138. expect(config.v3Key).toBe('system-v3-key');
  139. });
  140. });
  141. describe('PaymentMtService集成', () => {
  142. it('应该正确注入SystemConfigServiceMt依赖', () => {
  143. // 验证服务实例化
  144. expect(paymentMtService).toBeDefined();
  145. expect(paymentMtService).toBeInstanceOf(PaymentMtService);
  146. });
  147. it('应该支持动态配置初始化', async () => {
  148. // 验证initializeWxPay方法存在
  149. const initializeMethod = paymentMtService['initializeWxPay'];
  150. expect(typeof initializeMethod).toBe('function');
  151. // 验证getPaymentConfig方法存在
  152. const getConfigMethod = paymentMtService['getPaymentConfig'];
  153. expect(typeof getConfigMethod).toBe('function');
  154. });
  155. it('应该支持租户ID参数', async () => {
  156. // 验证createPayment方法支持tenantId参数
  157. const method = paymentMtService.createPayment;
  158. expect(typeof method).toBe('function');
  159. // 验证方法签名包含tenantId参数
  160. expect(method.length).toBeGreaterThanOrEqual(6);
  161. });
  162. });
  163. describe('配置验证', () => {
  164. it('应该验证配置完整性', async () => {
  165. // 不设置任何配置,应该抛出配置不完整的错误
  166. await expect(paymentMtService['getPaymentConfig'](testTenantId))
  167. .rejects
  168. .toThrow('微信支付配置不完整');
  169. });
  170. it('应该处理证书字符串格式', async () => {
  171. // 设置完整的支付配置,包含包含转义字符的证书
  172. await setupCompletePaymentConfig(testTenantId, 'cert-test');
  173. // 覆盖证书配置为包含转义字符的格式
  174. await systemConfigService.setConfig('wx.payment.public.key', 'test\\npublic\\nkey', testTenantId, '测试公钥');
  175. await systemConfigService.setConfig('wx.payment.private.key', 'test\\nprivate\\nkey', testTenantId, '测试私钥');
  176. // 获取配置并验证格式处理
  177. const config = await paymentMtService['getPaymentConfig'](testTenantId);
  178. // 验证转义字符被正确处理
  179. expect(config.publicKey).toBe('test\npublic\nkey');
  180. expect(config.privateKey).toBe('test\nprivate\nkey');
  181. });
  182. });
  183. });