test-data-factory.ts 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  1. import { DataSource } from 'typeorm';
  2. import { UserEntity } from '@d8d/user-module';
  3. import { AreaEntity } from '@d8d/geo-areas';
  4. import { DeliveryAddress } from '@d8d/delivery-address-module';
  5. import { Merchant } from '@d8d/merchant-module';
  6. import { Supplier } from '@d8d/supplier-module';
  7. import { Order, OrderRefund } from '../../src/entities';
  8. import { JWTUtil } from '@d8d/shared-utils';
  9. /**
  10. * 订单模块测试数据工厂类
  11. */
  12. export class OrdersTestDataFactory {
  13. /**
  14. * 创建测试用户数据
  15. */
  16. static createUserData(overrides: Partial<UserEntity> = {}): Partial<UserEntity> {
  17. const timestamp = Math.floor(Math.random() * 100000);
  18. return {
  19. username: `test_user_${timestamp}`,
  20. password: 'test_password',
  21. nickname: '测试用户',
  22. registrationSource: 'web',
  23. ...overrides
  24. };
  25. }
  26. /**
  27. * 在数据库中创建测试用户
  28. */
  29. static async createTestUser(dataSource: DataSource, overrides: Partial<UserEntity> = {}): Promise<UserEntity> {
  30. const userData = this.createUserData(overrides);
  31. const userRepository = dataSource.getRepository(UserEntity);
  32. const user = userRepository.create(userData);
  33. return await userRepository.save(user);
  34. }
  35. /**
  36. * 为测试用户生成JWT token
  37. */
  38. static generateUserToken(user: UserEntity): string {
  39. return JWTUtil.generateToken({
  40. id: user.id,
  41. username: user.username,
  42. roles: [{ name: 'user' }]
  43. });
  44. }
  45. /**
  46. * 创建测试地区数据
  47. */
  48. static createAreaData(overrides: Partial<AreaEntity> = {}): Partial<AreaEntity> {
  49. const timestamp = Math.floor(Math.random() * 100000);
  50. return {
  51. name: '广东省',
  52. level: 1,
  53. code: `44${timestamp.toString().padStart(4, '0')}`,
  54. state: 1,
  55. ...overrides
  56. };
  57. }
  58. /**
  59. * 在数据库中创建测试地区
  60. */
  61. static async createTestArea(dataSource: DataSource, overrides: Partial<AreaEntity> = {}): Promise<AreaEntity> {
  62. const areaData = this.createAreaData(overrides);
  63. const areaRepository = dataSource.getRepository(AreaEntity);
  64. const area = areaRepository.create(areaData);
  65. return await areaRepository.save(area);
  66. }
  67. /**
  68. * 创建完整的地区层级(省、市、区、街道)
  69. */
  70. static async createCompleteAreaHierarchy(dataSource: DataSource): Promise<{
  71. province: AreaEntity;
  72. city: AreaEntity;
  73. district: AreaEntity;
  74. town: AreaEntity;
  75. }> {
  76. const timestamp = Math.floor(Math.random() * 100000);
  77. const province = await this.createTestArea(dataSource, {
  78. name: '广东省',
  79. level: 1,
  80. code: `44${timestamp.toString().padStart(4, '0')}`
  81. });
  82. const city = await this.createTestArea(dataSource, {
  83. name: '深圳市',
  84. level: 2,
  85. code: `44${(timestamp + 1).toString().padStart(4, '0')}`,
  86. parentId: province.id
  87. });
  88. const district = await this.createTestArea(dataSource, {
  89. name: '南山区',
  90. level: 3,
  91. code: `44${(timestamp + 2).toString().padStart(4, '0')}`,
  92. parentId: city.id
  93. });
  94. const town = await this.createTestArea(dataSource, {
  95. name: '粤海街道',
  96. level: 4,
  97. code: `44${(timestamp + 3).toString().padStart(4, '0')}`,
  98. parentId: district.id
  99. });
  100. return { province, city, district, town };
  101. }
  102. /**
  103. * 创建测试配送地址数据
  104. */
  105. static createDeliveryAddressData(
  106. userId: number,
  107. areaHierarchy: { province: AreaEntity; city: AreaEntity; district: AreaEntity; town: AreaEntity },
  108. overrides: Partial<DeliveryAddress> = {}
  109. ): Partial<DeliveryAddress> {
  110. return {
  111. userId,
  112. name: '收货人姓名',
  113. phone: '13800138000',
  114. receiverProvince: areaHierarchy.province.id,
  115. receiverCity: areaHierarchy.city.id,
  116. receiverDistrict: areaHierarchy.district.id,
  117. receiverTown: areaHierarchy.town.id,
  118. address: '测试地址',
  119. isDefault: 1,
  120. state: 1,
  121. createdBy: userId,
  122. ...overrides
  123. };
  124. }
  125. /**
  126. * 在数据库中创建测试配送地址
  127. */
  128. static async createTestDeliveryAddress(
  129. dataSource: DataSource,
  130. userId: number,
  131. areaHierarchy: { province: AreaEntity; city: AreaEntity; district: AreaEntity; town: AreaEntity },
  132. overrides: Partial<DeliveryAddress> = {}
  133. ): Promise<DeliveryAddress> {
  134. const addressData = this.createDeliveryAddressData(userId, areaHierarchy, overrides);
  135. const addressRepository = dataSource.getRepository(DeliveryAddress);
  136. const address = addressRepository.create(addressData);
  137. return await addressRepository.save(address);
  138. }
  139. /**
  140. * 创建测试商户数据
  141. */
  142. static createMerchantData(overrides: Partial<Merchant> = {}): Partial<Merchant> {
  143. const timestamp = Math.floor(Math.random() * 100000);
  144. return {
  145. name: '测试商户',
  146. username: `merchant_${timestamp}`,
  147. password: 'test_password',
  148. state: 1,
  149. createdBy: 1,
  150. ...overrides
  151. };
  152. }
  153. /**
  154. * 在数据库中创建测试商户
  155. */
  156. static async createTestMerchant(dataSource: DataSource, overrides: Partial<Merchant> = {}): Promise<Merchant> {
  157. const merchantData = this.createMerchantData(overrides);
  158. const merchantRepository = dataSource.getRepository(Merchant);
  159. const merchant = merchantRepository.create(merchantData);
  160. return await merchantRepository.save(merchant);
  161. }
  162. /**
  163. * 创建测试供应商数据
  164. */
  165. static createSupplierData(overrides: Partial<Supplier> = {}): Partial<Supplier> {
  166. const timestamp = Math.floor(Math.random() * 100000);
  167. return {
  168. name: '测试供应商',
  169. username: `supplier_${timestamp}`,
  170. password: 'test_password',
  171. state: 1,
  172. createdBy: 1,
  173. ...overrides
  174. };
  175. }
  176. /**
  177. * 在数据库中创建测试供应商
  178. */
  179. static async createTestSupplier(dataSource: DataSource, overrides: Partial<Supplier> = {}): Promise<Supplier> {
  180. const supplierData = this.createSupplierData(overrides);
  181. const supplierRepository = dataSource.getRepository(Supplier);
  182. const supplier = supplierRepository.create(supplierData);
  183. return await supplierRepository.save(supplier);
  184. }
  185. /**
  186. * 创建测试订单数据
  187. */
  188. static createOrderData(
  189. userId: number,
  190. deliveryAddressId: number,
  191. merchantId: number,
  192. supplierId: number,
  193. areaHierarchy: { province: AreaEntity; city: AreaEntity; district: AreaEntity; town: AreaEntity },
  194. overrides: Partial<Order> = {}
  195. ): Partial<Order> {
  196. const timestamp = Math.floor(Math.random() * 100000);
  197. return {
  198. orderNo: `ORDER_${timestamp}`,
  199. userId,
  200. amount: 100.00,
  201. costAmount: 80.00,
  202. payAmount: 100.00,
  203. orderType: 1,
  204. payType: 1,
  205. payState: 2,
  206. state: 0,
  207. deliveryAddressId,
  208. addressId: deliveryAddressId,
  209. merchantId,
  210. supplierId,
  211. recevierProvince: areaHierarchy.province.id,
  212. recevierCity: areaHierarchy.city.id,
  213. recevierDistrict: areaHierarchy.district.id,
  214. recevierTown: areaHierarchy.town.id,
  215. createdBy: userId,
  216. ...overrides
  217. };
  218. }
  219. /**
  220. * 在数据库中创建测试订单
  221. */
  222. static async createTestOrder(
  223. dataSource: DataSource,
  224. userId: number,
  225. deliveryAddressId: number,
  226. merchantId: number,
  227. supplierId: number,
  228. areaHierarchy: { province: AreaEntity; city: AreaEntity; district: AreaEntity; town: AreaEntity },
  229. overrides: Partial<Order> = {}
  230. ): Promise<Order> {
  231. const orderData = this.createOrderData(userId, deliveryAddressId, merchantId, supplierId, areaHierarchy, overrides);
  232. const orderRepository = dataSource.getRepository(Order);
  233. const order = orderRepository.create(orderData);
  234. return await orderRepository.save(order);
  235. }
  236. /**
  237. * 创建完整的测试订单环境(包含所有依赖实体)
  238. */
  239. static async createCompleteOrderEnvironment(dataSource: DataSource, userId?: number): Promise<{
  240. user: UserEntity;
  241. areaHierarchy: { province: AreaEntity; city: AreaEntity; district: AreaEntity; town: AreaEntity };
  242. deliveryAddress: DeliveryAddress;
  243. merchant: Merchant;
  244. supplier: Supplier;
  245. order: Order;
  246. }> {
  247. // 创建用户
  248. const user = await this.createTestUser(dataSource, userId ? { id: userId } : {});
  249. // 创建地区层级
  250. const areaHierarchy = await this.createCompleteAreaHierarchy(dataSource);
  251. // 创建商户和供应商
  252. const merchant = await this.createTestMerchant(dataSource, { createdBy: user.id });
  253. const supplier = await this.createTestSupplier(dataSource, { createdBy: user.id });
  254. // 创建配送地址
  255. const deliveryAddress = await this.createTestDeliveryAddress(dataSource, user.id, areaHierarchy);
  256. // 创建订单
  257. const order = await this.createTestOrder(dataSource, user.id, deliveryAddress.id, merchant.id, supplier.id, areaHierarchy);
  258. return { user, areaHierarchy, deliveryAddress, merchant, supplier, order };
  259. }
  260. /**
  261. * 创建测试退款数据
  262. */
  263. static createRefundData(orderNo: string, overrides: Partial<OrderRefund> = {}): Partial<OrderRefund> {
  264. const timestamp = Math.floor(Math.random() * 100000);
  265. return {
  266. orderNo,
  267. refundOrderNo: `REFUND_${timestamp}`,
  268. refundAmount: 50.00,
  269. state: 0,
  270. createdBy: 1,
  271. ...overrides
  272. };
  273. }
  274. /**
  275. * 在数据库中创建测试退款
  276. */
  277. static async createTestRefund(
  278. dataSource: DataSource,
  279. orderNo: string,
  280. overrides: Partial<OrderRefund> = {}
  281. ): Promise<OrderRefund> {
  282. const refundData = this.createRefundData(orderNo, overrides);
  283. const refundRepository = dataSource.getRepository(OrderRefund);
  284. const refund = refundRepository.create(refundData);
  285. return await refundRepository.save(refund);
  286. }
  287. }