payment-flow.test.ts 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /**
  2. * 支付流程集成测试
  3. * 测试下单→支付回调→会员激活完整流程
  4. */
  5. import { describe, it, expect, beforeAll } from 'vitest';
  6. import { apiPost, apiGet, setAuthToken, initHttpClient, createTestUser } from '../../integration/http-client';
  7. describe('支付流程集成测试', () => {
  8. let authToken: string;
  9. let userId: string;
  10. beforeAll(async () => {
  11. try {
  12. const user = await createTestUser();
  13. authToken = user.token;
  14. userId = user.userId;
  15. setAuthToken(authToken);
  16. } catch (e) {
  17. console.log('创建测试用户失败,跳过部分测试');
  18. }
  19. });
  20. describe('创建支付订单', () => {
  21. it('创建支付宝订单成功', async () => {
  22. if (!authToken) return;
  23. const res = await apiPost('/api/payment/create-order', {
  24. planId: 2, // 专业版
  25. paymentMethod: 'mock', // 使用 mock 支付
  26. period: 'monthly'
  27. });
  28. expect(res.code).toBe(0);
  29. expect(res.data?.orderNo).toBeDefined();
  30. expect(res.data?.amount).toBeGreaterThan(0);
  31. });
  32. it('创建年付订单成功', async () => {
  33. if (!authToken) return;
  34. const res = await apiPost('/api/payment/create-order', {
  35. planId: 2,
  36. paymentMethod: 'mock',
  37. period: 'yearly'
  38. });
  39. expect(res.code).toBe(0);
  40. // 年付价格应该是月付的 10 倍左右
  41. expect(res.data?.amount).toBeGreaterThan(500);
  42. });
  43. it('无效套餐返回错误', async () => {
  44. if (!authToken) return;
  45. const res = await apiPost('/api/payment/create-order', {
  46. planId: 9999,
  47. paymentMethod: 'mock'
  48. });
  49. expect(res.code).not.toBe(0);
  50. });
  51. });
  52. describe('模拟支付回调', () => {
  53. it('支付成功后会员等级更新', async () => {
  54. if (!authToken) return;
  55. // 获取当前会员等级
  56. const userBeforeRes = await apiGet('/api/auth/user-info');
  57. const levelBefore = userBeforeRes.data?.memberLevel || 0;
  58. // 创建订单
  59. const orderRes = await apiPost('/api/payment/create-order', {
  60. planId: 2,
  61. paymentMethod: 'mock',
  62. period: 'monthly'
  63. });
  64. const orderNo = orderRes.data?.orderNo;
  65. if (!orderNo) return;
  66. // 模拟支付成功
  67. const callbackRes = await apiPost('/api/payment/callback/mock', {
  68. orderNo,
  69. paymentId: 'MOCK_' + Date.now(),
  70. status: 'success'
  71. });
  72. expect(callbackRes.code).toBe(0);
  73. // 验证会员等级已更新
  74. const userAfterRes = await apiGet('/api/auth/user-info');
  75. const levelAfter = userAfterRes.data?.memberLevel;
  76. expect(levelAfter).toBeGreaterThanOrEqual(levelBefore);
  77. });
  78. it('支付失败时订单状态更新', async () => {
  79. if (!authToken) return;
  80. // 创建订单
  81. const orderRes = await apiPost('/api/payment/create-order', {
  82. planId: 1,
  83. paymentMethod: 'mock'
  84. });
  85. const orderNo = orderRes.data?.orderNo;
  86. if (!orderNo) return;
  87. // 模拟支付失败
  88. const callbackRes = await apiPost('/api/payment/callback/mock', {
  89. orderNo,
  90. paymentId: 'MOCK_FAIL_' + Date.now(),
  91. status: 'failed'
  92. });
  93. expect(callbackRes.code).toBe(0);
  94. });
  95. });
  96. describe('订单查询', () => {
  97. it('查询订单列表', async () => {
  98. if (!authToken) return;
  99. const res = await apiGet('/api/payment/orders');
  100. expect(res.code).toBe(0);
  101. expect(Array.isArray(res.data?.list)).toBe(true);
  102. });
  103. it('查询订单详情', async () => {
  104. if (!authToken) return;
  105. // 先创建订单
  106. const orderRes = await apiPost('/api/payment/create-order', {
  107. planId: 1,
  108. paymentMethod: 'mock'
  109. });
  110. const orderNo = orderRes.data?.orderNo;
  111. if (!orderNo) return;
  112. const res = await apiGet(`/api/payment/order/${orderNo}`);
  113. expect(res.code).toBe(0);
  114. expect(res.data?.orderNo).toBe(orderNo);
  115. });
  116. });
  117. describe('套餐查询', () => {
  118. it('获取可用套餐列表', async () => {
  119. if (!authToken) return;
  120. const res = await apiGet('/api/payment/plans');
  121. expect(res.code).toBe(0);
  122. expect(Array.isArray(res.data?.plans)).toBe(true);
  123. expect(res.data?.plans.length).toBeGreaterThan(0);
  124. });
  125. it('获取单个套餐详情', async () => {
  126. if (!authToken) return;
  127. const res = await apiGet('/api/payment/plan/2');
  128. expect(res.code).toBe(0);
  129. expect(res.data?.name).toBeDefined();
  130. });
  131. });
  132. });