orders.integration.test.ts 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. import { describe, it, expect, beforeEach } from 'vitest';
  2. import { testClient } from 'hono/testing';
  3. import {
  4. IntegrationTestDatabase,
  5. setupIntegrationDatabaseHooks,
  6. TestDataFactory
  7. } from '~/utils/server/integration-test-db';
  8. import { adminOrdersRoutesExport } from '@d8d/server/api';
  9. import { AuthService } from '@d8d/server/modules/auth/auth.service';
  10. import { UserService } from '@d8d/server/modules/users/user.service';
  11. import { OrderStatus, PaymentStatus } from '@d8d/server/modules/orders/order.entity';
  12. // 设置集成测试钩子
  13. setupIntegrationDatabaseHooks()
  14. describe('订单管理API集成测试', () => {
  15. let client: ReturnType<typeof testClient<typeof adminOrdersRoutesExport>>['api']['v1']['admin'];
  16. let testToken: string;
  17. beforeEach(async () => {
  18. // 创建测试客户端
  19. client = testClient(adminOrdersRoutesExport).api.v1.admin;
  20. // 创建测试用户并生成token
  21. const dataSource = await IntegrationTestDatabase.getDataSource();
  22. const userService = new UserService(dataSource);
  23. const authService = new AuthService(userService);
  24. // 确保admin用户存在
  25. const user = await authService.ensureAdminExists();
  26. // 生成admin用户的token
  27. testToken = authService.generateToken(user);
  28. });
  29. describe('订单列表查询测试', () => {
  30. it('应该成功获取订单列表', async () => {
  31. const dataSource = await IntegrationTestDatabase.getDataSource();
  32. // 创建测试数据
  33. const testUser = await TestDataFactory.createTestUser(dataSource);
  34. const testRoute = await TestDataFactory.createTestRoute(dataSource);
  35. // 创建测试订单
  36. await dataSource.getRepository('Order').save({
  37. userId: testUser.id,
  38. routeId: testRoute.id,
  39. passengerCount: 2,
  40. totalAmount: 100.00,
  41. status: OrderStatus.PENDING_PAYMENT,
  42. paymentStatus: PaymentStatus.PENDING,
  43. passengerSnapshots: [
  44. { name: '乘客1', phone: '13800138001' },
  45. { name: '乘客2', phone: '13800138002' }
  46. ],
  47. routeSnapshot: {
  48. name: testRoute.name,
  49. description: testRoute.description
  50. }
  51. });
  52. const response = await client.orders.$get({
  53. query: {
  54. page: 1,
  55. pageSize: 10
  56. }
  57. }, {
  58. headers: {
  59. 'Authorization': `Bearer ${testToken}`
  60. }
  61. });
  62. if (response.status !== 200) {
  63. const error = await response.json();
  64. console.debug('Error response:', JSON.stringify(error, null, 2));
  65. }
  66. expect(response.status).toBe(200);
  67. if (response.status === 200) {
  68. const result = await response.json();
  69. expect(Array.isArray(result.data)).toBe(true);
  70. expect(result.pagination).toHaveProperty('total');
  71. expect(result.pagination).toHaveProperty('current');
  72. expect(result.pagination).toHaveProperty('pageSize');
  73. }
  74. });
  75. it('应该支持按订单状态筛选', async () => {
  76. const dataSource = await IntegrationTestDatabase.getDataSource();
  77. // 创建测试数据
  78. const testUser = await TestDataFactory.createTestUser(dataSource);
  79. const testRoute = await TestDataFactory.createTestRoute(dataSource);
  80. // 创建不同状态的测试订单
  81. await dataSource.getRepository('Order').save([
  82. {
  83. userId: testUser.id,
  84. routeId: testRoute.id,
  85. passengerCount: 1,
  86. totalAmount: 50.00,
  87. status: OrderStatus.PENDING_PAYMENT,
  88. paymentStatus: PaymentStatus.PENDING,
  89. passengerSnapshots: [{ name: '乘客A', phone: '13800138003' }],
  90. routeSnapshot: { name: testRoute.name }
  91. },
  92. {
  93. userId: testUser.id,
  94. routeId: testRoute.id,
  95. passengerCount: 3,
  96. totalAmount: 150.00,
  97. status: OrderStatus.COMPLETED,
  98. paymentStatus: PaymentStatus.PAID,
  99. passengerSnapshots: [
  100. { name: '乘客B', phone: '13800138004' },
  101. { name: '乘客C', phone: '13800138005' },
  102. { name: '乘客D', phone: '13800138006' }
  103. ],
  104. routeSnapshot: { name: testRoute.name }
  105. }
  106. ]);
  107. const response = await client.orders.$get({
  108. query: {
  109. page: 1,
  110. pageSize: 10,
  111. filters: JSON.stringify({ status: OrderStatus.PENDING_PAYMENT })
  112. }
  113. }, {
  114. headers: {
  115. 'Authorization': `Bearer ${testToken}`
  116. }
  117. });
  118. expect(response.status).toBe(200);
  119. if (response.status === 200) {
  120. const result = await response.json();
  121. expect(result.data).toHaveLength(1);
  122. expect(result.data[0].status).toBe(OrderStatus.PENDING_PAYMENT);
  123. }
  124. });
  125. });
  126. describe('订单详情查询测试', () => {
  127. it('应该成功获取订单详情', async () => {
  128. const dataSource = await IntegrationTestDatabase.getDataSource();
  129. // 创建测试数据
  130. const testUser = await TestDataFactory.createTestUser(dataSource);
  131. const testRoute = await TestDataFactory.createTestRoute(dataSource);
  132. // 创建测试订单
  133. const order = await dataSource.getRepository('Order').save({
  134. userId: testUser.id,
  135. routeId: testRoute.id,
  136. passengerCount: 2,
  137. totalAmount: 100.00,
  138. status: OrderStatus.PENDING_PAYMENT,
  139. paymentStatus: PaymentStatus.PENDING,
  140. passengerSnapshots: [
  141. { name: '乘客1', phone: '13800138001' },
  142. { name: '乘客2', phone: '13800138002' }
  143. ],
  144. routeSnapshot: {
  145. name: testRoute.name,
  146. description: testRoute.description
  147. }
  148. });
  149. const response = await client.orders[':id'].$get({
  150. param: { id: order.id }
  151. }, {
  152. headers: {
  153. 'Authorization': `Bearer ${testToken}`
  154. }
  155. });
  156. expect(response.status).toBe(200);
  157. if (response.status === 200) {
  158. const result = await response.json();
  159. expect(result.id).toBe(order.id);
  160. expect(result.userId).toBe(testUser.id);
  161. expect(result.routeId).toBe(testRoute.id);
  162. expect(result.passengerCount).toBe(2);
  163. expect(result.totalAmount).toBe(100.00);
  164. expect(result.status).toBe(OrderStatus.PENDING_PAYMENT);
  165. expect(result.paymentStatus).toBe(PaymentStatus.PENDING);
  166. expect(Array.isArray(result.passengerSnapshots)).toBe(true);
  167. expect(result.passengerSnapshots).toHaveLength(2);
  168. }
  169. });
  170. it('应该返回404当订单不存在时', async () => {
  171. const response = await client.orders[':id'].$get({
  172. param: { id: 99999 }
  173. }, {
  174. headers: {
  175. 'Authorization': `Bearer ${testToken}`
  176. }
  177. });
  178. expect(response.status).toBe(404);
  179. });
  180. });
  181. describe('订单统计API测试', () => {
  182. it('应该成功获取订单统计信息', async () => {
  183. const dataSource = await IntegrationTestDatabase.getDataSource();
  184. // 创建测试数据
  185. const testUser = await TestDataFactory.createTestUser(dataSource);
  186. const testRoute = await TestDataFactory.createTestRoute(dataSource);
  187. // 创建不同状态的测试订单
  188. await dataSource.getRepository('Order').save([
  189. {
  190. userId: testUser.id,
  191. routeId: testRoute.id,
  192. passengerCount: 1,
  193. totalAmount: 50.00,
  194. status: OrderStatus.PENDING_PAYMENT,
  195. paymentStatus: PaymentStatus.PENDING,
  196. passengerSnapshots: [{ name: '乘客A', phone: '13800138003' }],
  197. routeSnapshot: { name: testRoute.name }
  198. },
  199. {
  200. userId: testUser.id,
  201. routeId: testRoute.id,
  202. passengerCount: 2,
  203. totalAmount: 100.00,
  204. status: OrderStatus.COMPLETED,
  205. paymentStatus: PaymentStatus.PAID,
  206. passengerSnapshots: [
  207. { name: '乘客B', phone: '13800138004' },
  208. { name: '乘客C', phone: '13800138005' }
  209. ],
  210. routeSnapshot: { name: testRoute.name }
  211. }
  212. ]);
  213. const response = await client.orders.stats.$get({}, {
  214. headers: {
  215. 'Authorization': `Bearer ${testToken}`
  216. }
  217. });
  218. expect(response.status).toBe(200);
  219. if (response.status === 200) {
  220. const result = await response.json();
  221. expect(result).toHaveProperty('total');
  222. expect(result).toHaveProperty('pendingPayment');
  223. expect(result).toHaveProperty('waitingDeparture');
  224. expect(result).toHaveProperty('inProgress');
  225. expect(result).toHaveProperty('completed');
  226. expect(result).toHaveProperty('cancelled');
  227. expect(result.total).toBeGreaterThanOrEqual(2);
  228. expect(result.pendingPayment).toBeGreaterThanOrEqual(1);
  229. expect(result.completed).toBeGreaterThanOrEqual(1);
  230. }
  231. });
  232. });
  233. describe('权限控制测试', () => {
  234. it('应该拒绝未授权访问', async () => {
  235. const response = await client.orders.$get({
  236. query: {
  237. page: 1,
  238. pageSize: 10
  239. }
  240. });
  241. expect(response.status).toBe(401);
  242. });
  243. it('应该拒绝非管理员访问', async () => {
  244. const dataSource = await IntegrationTestDatabase.getDataSource();
  245. const userService = new UserService(dataSource);
  246. const authService = new AuthService(userService);
  247. // 创建普通用户
  248. const regularUser = await TestDataFactory.createTestUser(dataSource);
  249. const regularToken = authService.generateToken(regularUser);
  250. const response = await client.orders.$get({
  251. query: {
  252. page: 1,
  253. pageSize: 10
  254. }
  255. }, {
  256. headers: {
  257. 'Authorization': `Bearer ${regularToken}`
  258. }
  259. });
  260. expect(response.status).toBe(403);
  261. });
  262. });
  263. });