order.integration.test.ts 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072
  1. import { describe, it, expect, beforeEach } from 'vitest';
  2. import { testClient } from 'hono/testing';
  3. import { IntegrationTestDatabase, setupIntegrationDatabaseHooksWithEntities } from '@d8d/shared-test-util';
  4. import { JWTUtil } from '@d8d/shared-utils';
  5. import { UserEntity, Role } from '@d8d/user-module';
  6. import { File } from '@d8d/file-module';
  7. import { DisabledPerson, DisabledBankCard, DisabledPhoto, DisabledRemark, DisabledVisit } from '@d8d/allin-disability-module';
  8. import { BankName } from '@d8d/bank-names-module';
  9. import { DataSource } from 'typeorm';
  10. import orderRoutes from '../../src/routes/order.routes';
  11. import { EmploymentOrder } from '../../src/entities/employment-order.entity';
  12. import { OrderPerson } from '../../src/entities/order-person.entity';
  13. import { OrderPersonAsset } from '../../src/entities/order-person-asset.entity';
  14. import { AssetType, AssetFileType } from '../../src/schemas/order.schema';
  15. import { OrderStatus, WorkStatus } from '@d8d/allin-enums';
  16. import { OrderTestDataFactory } from '../utils/test-data-factory';
  17. // 设置集成测试钩子
  18. setupIntegrationDatabaseHooksWithEntities([UserEntity, File, Role, DisabledPerson, DisabledBankCard, DisabledPhoto, DisabledRemark, DisabledVisit, BankName, EmploymentOrder, OrderPerson, OrderPersonAsset])
  19. describe('订单管理API集成测试', () => {
  20. let client: ReturnType<typeof testClient<typeof orderRoutes>>;
  21. let testToken: string;
  22. let testUser: UserEntity;
  23. let testFile: File;
  24. let testDisabledPerson: DisabledPerson;
  25. beforeEach(async () => {
  26. // 创建测试客户端
  27. client = testClient(orderRoutes);
  28. // 获取数据源
  29. const dataSource = await IntegrationTestDatabase.getDataSource();
  30. // 创建测试用户
  31. const userRepository = dataSource.getRepository(UserEntity);
  32. testUser = userRepository.create({
  33. username: `test_user_${Date.now()}`,
  34. password: 'test_password',
  35. nickname: '测试用户',
  36. registrationSource: 'web'
  37. });
  38. await userRepository.save(testUser);
  39. // 生成测试用户的token
  40. testToken = JWTUtil.generateToken({
  41. id: testUser.id,
  42. username: testUser.username,
  43. roles: [{name:'user'}]
  44. });
  45. // 创建测试文件
  46. const fileRepository = dataSource.getRepository(File);
  47. testFile = fileRepository.create({
  48. name: 'test_file.pdf',
  49. type: 'application/pdf',
  50. size: 1024,
  51. path: `test/${Date.now()}_test_file.pdf`,
  52. uploadUserId: testUser.id,
  53. uploadTime: new Date(),
  54. createdAt: new Date(),
  55. updatedAt: new Date()
  56. });
  57. await fileRepository.save(testFile);
  58. // 创建测试银行名称记录(用于DisabledBankCard外键约束)
  59. const bankNameRepository = dataSource.getRepository(BankName);
  60. const testBankName = bankNameRepository.create({
  61. name: '测试银行',
  62. code: 'TEST001',
  63. remark: '测试银行',
  64. createdBy: testUser.id,
  65. updatedBy: testUser.id,
  66. status: 1
  67. });
  68. await bankNameRepository.save(testBankName);
  69. // 创建测试残疾人记录(用于外键约束)
  70. testDisabledPerson = await OrderTestDataFactory.createTestDisabledPerson(dataSource);
  71. });
  72. describe('POST /order/create', () => {
  73. it('应该成功创建订单', async () => {
  74. const createData = {
  75. orderName: '测试订单',
  76. platformId: 1,
  77. companyId: 1,
  78. channelId: 1,
  79. expectedStartDate: new Date().toISOString(),
  80. orderStatus: OrderStatus.DRAFT,
  81. workStatus: WorkStatus.NOT_WORKING
  82. };
  83. const response = await client.create.$post({
  84. json: createData
  85. }, {
  86. headers: {
  87. 'Authorization': `Bearer ${testToken}`
  88. }
  89. });
  90. if (response.status !== 200) {
  91. const error = await response.json();
  92. console.debug('创建订单失败:', JSON.stringify(error, null, 2));
  93. }
  94. expect(response.status).toBe(200);
  95. if (response.status === 200) {
  96. const data = await response.json();
  97. expect(data.id).toBeDefined();
  98. expect(data.orderName).toBe('测试订单');
  99. expect(data.orderStatus).toBe(OrderStatus.DRAFT);
  100. expect(data.workStatus).toBe(WorkStatus.NOT_WORKING);
  101. }
  102. });
  103. it('应该验证订单状态枚举值', async () => {
  104. const createData = {
  105. orderName: '测试订单',
  106. platformId: 1,
  107. companyId: 1,
  108. channelId: 1,
  109. expectedStartDate: new Date().toISOString(),
  110. orderStatus: 'invalid_status', // 无效的状态
  111. workStatus: WorkStatus.NOT_WORKING
  112. };
  113. const response = await client.create.$post({
  114. json: createData as any // 使用any绕过类型检查,因为这里故意测试无效的枚举值
  115. }, {
  116. headers: {
  117. 'Authorization': `Bearer ${testToken}`
  118. }
  119. });
  120. expect(response.status).toBe(400);
  121. });
  122. it('应该验证工作状态枚举值', async () => {
  123. const createData = {
  124. orderName: '测试订单',
  125. platformId: 1,
  126. companyId: 1,
  127. channelId: 1,
  128. expectedStartDate: new Date().toISOString(),
  129. orderStatus: OrderStatus.DRAFT,
  130. workStatus: 'invalid_status' // 无效的状态
  131. };
  132. const response = await client.create.$post({
  133. json: createData as any // 使用any绕过类型检查,因为这里故意测试无效的枚举值
  134. }, {
  135. headers: {
  136. 'Authorization': `Bearer ${testToken}`
  137. }
  138. });
  139. expect(response.status).toBe(400);
  140. });
  141. });
  142. describe('GET /order/list', () => {
  143. let testOrder: EmploymentOrder;
  144. beforeEach(async () => {
  145. // 创建测试订单数据
  146. const dataSource = await IntegrationTestDatabase.getDataSource();
  147. const orderRepository = dataSource.getRepository(EmploymentOrder);
  148. testOrder = new EmploymentOrder({
  149. orderName: '测试订单1',
  150. platformId: 1,
  151. companyId: 1,
  152. channelId: 1,
  153. expectedStartDate: new Date(),
  154. orderStatus: OrderStatus.DRAFT,
  155. workStatus: WorkStatus.NOT_WORKING
  156. });
  157. await orderRepository.save(testOrder);
  158. const testOrder2 = new EmploymentOrder({
  159. orderName: '测试订单2',
  160. platformId: 2,
  161. companyId: 2,
  162. channelId: 2,
  163. expectedStartDate: new Date(),
  164. orderStatus: OrderStatus.CONFIRMED,
  165. workStatus: WorkStatus.PRE_WORKING
  166. });
  167. await orderRepository.save(testOrder2);
  168. });
  169. it('应该返回所有订单列表', async () => {
  170. const response = await client.list.$get({
  171. query: {}
  172. }, {
  173. headers: {
  174. 'Authorization': `Bearer ${testToken}`
  175. }
  176. });
  177. expect(response.status).toBe(200);
  178. if (response.status === 200) {
  179. const data = await response.json();
  180. expect(data).toHaveProperty('data');
  181. expect(data).toHaveProperty('total');
  182. expect(data.data).toHaveLength(2);
  183. expect(data.total).toBe(2);
  184. }
  185. });
  186. it('应该支持按订单名称搜索', async () => {
  187. const response = await client.list.$get({
  188. query: {
  189. orderName: '测试订单1'
  190. }
  191. }, {
  192. headers: {
  193. 'Authorization': `Bearer ${testToken}`
  194. }
  195. });
  196. expect(response.status).toBe(200);
  197. if (response.status === 200) {
  198. const data = await response.json();
  199. expect(data.data).toHaveLength(1);
  200. expect(data.data[0].orderName).toBe('测试订单1');
  201. }
  202. });
  203. it('应该支持按订单状态过滤', async () => {
  204. const response = await client.list.$get({
  205. query: {
  206. orderStatus: OrderStatus.CONFIRMED
  207. }
  208. }, {
  209. headers: {
  210. 'Authorization': `Bearer ${testToken}`
  211. }
  212. });
  213. expect(response.status).toBe(200);
  214. if (response.status === 200) {
  215. const data = await response.json();
  216. expect(data.data).toHaveLength(1);
  217. expect(data.data[0].orderStatus).toBe(OrderStatus.CONFIRMED);
  218. }
  219. });
  220. it('应该支持分页查询', async () => {
  221. const response = await client.list.$get({
  222. query: {
  223. page: '1',
  224. limit: '1'
  225. }
  226. }, {
  227. headers: {
  228. 'Authorization': `Bearer ${testToken}`
  229. }
  230. });
  231. expect(response.status).toBe(200);
  232. if (response.status === 200) {
  233. const data = await response.json();
  234. expect(data.data).toHaveLength(1);
  235. expect(data.total).toBe(2);
  236. }
  237. });
  238. });
  239. describe('GET /order/detail/:id', () => {
  240. let testOrder: EmploymentOrder;
  241. beforeEach(async () => {
  242. // 创建测试订单数据
  243. const dataSource = await IntegrationTestDatabase.getDataSource();
  244. const orderRepository = dataSource.getRepository(EmploymentOrder);
  245. testOrder = new EmploymentOrder({
  246. orderName: '测试订单详情',
  247. platformId: 1,
  248. companyId: 1,
  249. channelId: 1,
  250. expectedStartDate: new Date(),
  251. orderStatus: OrderStatus.DRAFT,
  252. workStatus: WorkStatus.NOT_WORKING
  253. });
  254. await orderRepository.save(testOrder);
  255. });
  256. it('应该返回指定ID的订单详情', async () => {
  257. const response = await client.detail[':id'].$get({
  258. param: { id: testOrder.id.toString() }
  259. }, {
  260. headers: {
  261. 'Authorization': `Bearer ${testToken}`
  262. }
  263. });
  264. if (response.status !== 200) {
  265. const error = await response.json();
  266. console.debug('获取订单详情失败:', JSON.stringify(error, null, 2));
  267. }
  268. expect(response.status).toBe(200);
  269. if (response.status === 200) {
  270. const data = await response.json();
  271. expect(data?.id).toBe(testOrder.id);
  272. expect(data?.orderName).toBe('测试订单详情');
  273. expect(data?.orderStatus).toBe(OrderStatus.DRAFT);
  274. }
  275. });
  276. it('应该处理不存在的订单ID', async () => {
  277. const response = await client.detail[':id'].$get({
  278. param: { id: '999999' }
  279. }, {
  280. headers: {
  281. 'Authorization': `Bearer ${testToken}`
  282. }
  283. });
  284. expect(response.status).toBe(404);
  285. });
  286. });
  287. describe('POST /order/activate/:orderId', () => {
  288. let testOrder: EmploymentOrder;
  289. beforeEach(async () => {
  290. // 创建测试订单数据
  291. const dataSource = await IntegrationTestDatabase.getDataSource();
  292. const orderRepository = dataSource.getRepository(EmploymentOrder);
  293. testOrder = new EmploymentOrder({
  294. orderName: '待激活订单',
  295. platformId: 1,
  296. companyId: 1,
  297. channelId: 1,
  298. expectedStartDate: new Date(),
  299. orderStatus: OrderStatus.DRAFT,
  300. workStatus: WorkStatus.NOT_WORKING
  301. });
  302. await orderRepository.save(testOrder);
  303. });
  304. it('应该成功激活草稿状态的订单', async () => {
  305. const response = await client.activate[':orderId'].$post({
  306. param: { orderId: testOrder.id.toString() }
  307. }, {
  308. headers: {
  309. 'Authorization': `Bearer ${testToken}`
  310. }
  311. });
  312. expect(response.status).toBe(200);
  313. if (response.status === 200) {
  314. const data = await response.json();
  315. expect(data.success).toBe(true);
  316. // 验证订单状态已更新
  317. const dataSource = await IntegrationTestDatabase.getDataSource();
  318. const orderRepository = dataSource.getRepository(EmploymentOrder);
  319. const updatedOrder = await orderRepository.findOne({
  320. where: { id: testOrder.id }
  321. });
  322. expect(updatedOrder?.orderStatus).toBe(OrderStatus.CONFIRMED);
  323. expect(updatedOrder?.actualStartDate).toBeDefined();
  324. }
  325. });
  326. it('应该处理非草稿状态的订单激活', async () => {
  327. // 更新订单状态为已确认
  328. const dataSource = await IntegrationTestDatabase.getDataSource();
  329. const orderRepository = dataSource.getRepository(EmploymentOrder);
  330. await orderRepository.update(testOrder.id, { orderStatus: OrderStatus.CONFIRMED });
  331. const response = await client.activate[':orderId'].$post({
  332. param: { orderId: testOrder.id.toString() }
  333. }, {
  334. headers: {
  335. 'Authorization': `Bearer ${testToken}`
  336. }
  337. });
  338. expect(response.status).toBe(400);
  339. });
  340. it('应该处理不存在的订单ID', async () => {
  341. const response = await client.activate[':orderId'].$post({
  342. param: { orderId: '999999' }
  343. }, {
  344. headers: {
  345. 'Authorization': `Bearer ${testToken}`
  346. }
  347. });
  348. expect(response.status).toBe(404);
  349. });
  350. });
  351. describe('POST /order/close/:orderId', () => {
  352. let testOrder: EmploymentOrder;
  353. beforeEach(async () => {
  354. // 创建测试订单数据
  355. const dataSource = await IntegrationTestDatabase.getDataSource();
  356. const orderRepository = dataSource.getRepository(EmploymentOrder);
  357. testOrder = new EmploymentOrder({
  358. orderName: '待关闭订单',
  359. platformId: 1,
  360. companyId: 1,
  361. channelId: 1,
  362. expectedStartDate: new Date(),
  363. actualStartDate: new Date(),
  364. orderStatus: OrderStatus.CONFIRMED,
  365. workStatus: WorkStatus.PRE_WORKING,
  366. });
  367. await orderRepository.save(testOrder);
  368. });
  369. it('应该成功关闭已确认状态的订单', async () => {
  370. const response = await client.close[':orderId'].$post({
  371. param: { orderId: testOrder.id.toString() }
  372. }, {
  373. headers: {
  374. 'Authorization': `Bearer ${testToken}`
  375. }
  376. });
  377. expect(response.status).toBe(200);
  378. if (response.status === 200) {
  379. const data = await response.json();
  380. expect(data.success).toBe(true);
  381. // 验证订单状态已更新
  382. const dataSource = await IntegrationTestDatabase.getDataSource();
  383. const orderRepository = dataSource.getRepository(EmploymentOrder);
  384. const updatedOrder = await orderRepository.findOne({
  385. where: { id: testOrder.id }
  386. });
  387. expect(updatedOrder?.orderStatus).toBe(OrderStatus.COMPLETED);
  388. expect(updatedOrder?.actualEndDate).toBeDefined();
  389. }
  390. });
  391. it('应该处理非已确认或进行中状态的订单关闭', async () => {
  392. // 更新订单状态为草稿
  393. const dataSource = await IntegrationTestDatabase.getDataSource();
  394. const orderRepository = dataSource.getRepository(EmploymentOrder);
  395. await orderRepository.update(testOrder.id, { orderStatus: OrderStatus.DRAFT });
  396. const response = await client.close[':orderId'].$post({
  397. param: { orderId: testOrder.id.toString() }
  398. }, {
  399. headers: {
  400. 'Authorization': `Bearer ${testToken}`
  401. }
  402. });
  403. expect(response.status).toBe(400);
  404. });
  405. it('应该处理不存在的订单ID', async () => {
  406. const response = await client.close[':orderId'].$post({
  407. param: { orderId: '999999' }
  408. }, {
  409. headers: {
  410. 'Authorization': `Bearer ${testToken}`
  411. }
  412. });
  413. expect(response.status).toBe(404);
  414. });
  415. });
  416. describe('POST /order/:orderId/persons/batch', () => {
  417. let testOrder: EmploymentOrder;
  418. beforeEach(async () => {
  419. // 创建测试订单数据
  420. const dataSource = await IntegrationTestDatabase.getDataSource();
  421. const orderRepository = dataSource.getRepository(EmploymentOrder);
  422. testOrder = new EmploymentOrder({
  423. orderName: '批量添加人员测试订单',
  424. platformId: 1,
  425. companyId: 1,
  426. channelId: 1,
  427. expectedStartDate: new Date(),
  428. orderStatus: OrderStatus.DRAFT,
  429. workStatus: WorkStatus.NOT_WORKING,
  430. });
  431. await orderRepository.save(testOrder);
  432. });
  433. it('应该成功批量添加人员到订单', async () => {
  434. // 创建两个测试残疾人记录
  435. const dataSource = await IntegrationTestDatabase.getDataSource();
  436. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  437. // 直接创建最简单的DisabledPerson记录
  438. const disabledPerson1 = disabledPersonRepository.create({
  439. name: '测试1',
  440. gender: '男',
  441. idCard: '1',
  442. disabilityId: '1',
  443. disabilityType: '肢体',
  444. disabilityLevel: '三级',
  445. idAddress: '地址',
  446. phone: '13800138000',
  447. canDirectContact: 1,
  448. province: '省',
  449. city: '市',
  450. district: '区',
  451. detailedAddress: '地址',
  452. isInBlackList: 0,
  453. jobStatus: 0,
  454. createTime: new Date(),
  455. updateTime: new Date()
  456. });
  457. await disabledPersonRepository.save(disabledPerson1);
  458. const disabledPerson2 = disabledPersonRepository.create({
  459. name: '测试2',
  460. gender: '女',
  461. idCard: '2',
  462. disabilityId: '2',
  463. disabilityType: '视力',
  464. disabilityLevel: '二级',
  465. idAddress: '地址',
  466. phone: '13800138001',
  467. canDirectContact: 1,
  468. province: '省',
  469. city: '市',
  470. district: '区',
  471. detailedAddress: '地址',
  472. isInBlackList: 0,
  473. jobStatus: 0,
  474. createTime: new Date(),
  475. updateTime: new Date()
  476. });
  477. await disabledPersonRepository.save(disabledPerson2);
  478. const batchData = {
  479. persons: [
  480. {
  481. personId: disabledPerson1.id,
  482. joinDate: new Date().toISOString(),
  483. salaryDetail: 5000.00
  484. },
  485. {
  486. personId: disabledPerson2.id,
  487. joinDate: new Date().toISOString(),
  488. salaryDetail: 6000.00
  489. }
  490. ]
  491. };
  492. const response = await client[':orderId'].persons.batch.$post({
  493. param: { orderId: testOrder.id.toString() },
  494. json: batchData
  495. }, {
  496. headers: {
  497. 'Authorization': `Bearer ${testToken}`
  498. }
  499. });
  500. expect(response.status).toBe(200);
  501. if (response.status === 200) {
  502. const data = await response.json();
  503. expect(data.success).toBe(true);
  504. expect(data.addedCount).toBe(2);
  505. // 验证人员已添加到订单
  506. const dataSource = await IntegrationTestDatabase.getDataSource();
  507. const orderPersonRepository = dataSource.getRepository(OrderPerson);
  508. const orderPersons = await orderPersonRepository.find({
  509. where: { orderId: testOrder.id }
  510. });
  511. expect(orderPersons).toHaveLength(2);
  512. }
  513. });
  514. it('应该处理重复的人员添加', async () => {
  515. // 创建两个测试残疾人记录
  516. const dataSource = await IntegrationTestDatabase.getDataSource();
  517. const [disabledPerson1, disabledPerson2] = await OrderTestDataFactory.createTestDisabledPersons(dataSource, 2);
  518. const orderPersonRepository = dataSource.getRepository(OrderPerson);
  519. // 先添加一个人员
  520. const existingPerson = orderPersonRepository.create({
  521. orderId: testOrder.id,
  522. personId: disabledPerson1.id,
  523. joinDate: new Date(),
  524. workStatus: WorkStatus.NOT_WORKING,
  525. salaryDetail: 5000.00
  526. });
  527. await orderPersonRepository.save(existingPerson);
  528. const batchData = {
  529. persons: [
  530. {
  531. personId: disabledPerson1.id, // 已存在的人员
  532. joinDate: new Date().toISOString(),
  533. salaryDetail: 5000.00
  534. },
  535. {
  536. personId: disabledPerson2.id, // 新人员
  537. joinDate: new Date().toISOString(),
  538. salaryDetail: 6000.00
  539. }
  540. ]
  541. };
  542. const response = await client[':orderId'].persons.batch.$post({
  543. param: { orderId: testOrder.id.toString() },
  544. json: batchData
  545. }, {
  546. headers: {
  547. 'Authorization': `Bearer ${testToken}`
  548. }
  549. });
  550. expect(response.status).toBe(200);
  551. if (response.status === 200) {
  552. const data = await response.json();
  553. expect(data.success).toBe(true);
  554. expect(data.addedCount).toBe(1); // 只添加了一个新人员
  555. }
  556. });
  557. it('应该处理已结束或已取消的订单', async () => {
  558. // 更新订单状态为已完成
  559. const dataSource = await IntegrationTestDatabase.getDataSource();
  560. const orderRepository = dataSource.getRepository(EmploymentOrder);
  561. await orderRepository.update(testOrder.id, { orderStatus: OrderStatus.COMPLETED });
  562. const batchData = {
  563. persons: [
  564. {
  565. personId: 1001,
  566. joinDate: new Date().toISOString(),
  567. salaryDetail: 5000.00
  568. }
  569. ]
  570. };
  571. const response = await client[':orderId'].persons.batch.$post({
  572. param: { orderId: testOrder.id.toString() },
  573. json: batchData
  574. }, {
  575. headers: {
  576. 'Authorization': `Bearer ${testToken}`
  577. }
  578. });
  579. expect(response.status).toBe(400);
  580. });
  581. it('应该处理不存在的订单ID', async () => {
  582. const batchData = {
  583. persons: [
  584. {
  585. personId: 1001,
  586. joinDate: new Date().toISOString(),
  587. salaryDetail: 5000.00
  588. }
  589. ]
  590. };
  591. const response = await client[':orderId'].persons.batch.$post({
  592. param: { orderId: '999999' },
  593. json: batchData
  594. }, {
  595. headers: {
  596. 'Authorization': `Bearer ${testToken}`
  597. }
  598. });
  599. expect(response.status).toBe(404);
  600. });
  601. });
  602. describe('POST /order/assets/create', () => {
  603. let testOrder: EmploymentOrder;
  604. let testOrderPerson: OrderPerson;
  605. beforeEach(async () => {
  606. // 创建测试订单数据
  607. const dataSource = await IntegrationTestDatabase.getDataSource();
  608. const orderRepository = dataSource.getRepository(EmploymentOrder);
  609. const orderPersonRepository = dataSource.getRepository(OrderPerson);
  610. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  611. testOrder = new EmploymentOrder({
  612. orderName: '资产测试订单',
  613. platformId: 1,
  614. companyId: 1,
  615. channelId: 1,
  616. expectedStartDate: new Date(),
  617. orderStatus: OrderStatus.DRAFT,
  618. workStatus: WorkStatus.NOT_WORKING,
  619. });
  620. await orderRepository.save(testOrder);
  621. // 先创建残疾人记录
  622. const testDisabledPerson = await OrderTestDataFactory.createTestDisabledPerson(dataSource);
  623. testOrderPerson = orderPersonRepository.create({
  624. orderId: testOrder.id,
  625. personId: testDisabledPerson.id,
  626. joinDate: new Date(),
  627. workStatus: WorkStatus.NOT_WORKING,
  628. salaryDetail: 5000.00
  629. });
  630. await orderPersonRepository.save(testOrderPerson);
  631. });
  632. it('应该成功创建订单人员资产', async () => {
  633. const assetData = {
  634. orderId: testOrder.id,
  635. personId: testOrderPerson.personId,
  636. assetType: AssetType.DISABILITY_CERT,
  637. assetFileType: AssetFileType.IMAGE,
  638. fileId: testFile.id,
  639. relatedTime: new Date().toISOString()
  640. };
  641. const response = await client.assets.create.$post({
  642. json: assetData
  643. }, {
  644. headers: {
  645. 'Authorization': `Bearer ${testToken}`
  646. }
  647. });
  648. if (response.status !== 200) {
  649. const error = await response.json();
  650. console.debug('创建订单人员资产失败:', JSON.stringify(error, null, 2));
  651. }
  652. expect(response.status).toBe(200);
  653. if (response.status === 200) {
  654. const data = await response.json();
  655. expect(data.id).toBeDefined();
  656. expect(data.orderId).toBe(testOrder.id);
  657. expect(data.personId).toBe(testOrderPerson.personId);
  658. expect(data.assetType).toBe(AssetType.DISABILITY_CERT);
  659. expect(data.fileId).toBe(testFile.id);
  660. }
  661. });
  662. it('应该处理不存在的文件ID', async () => {
  663. const assetData = {
  664. orderId: testOrder.id,
  665. personId: testOrderPerson.personId,
  666. assetType: AssetType.DISABILITY_CERT,
  667. assetFileType: AssetFileType.IMAGE,
  668. fileId: 999999, // 不存在的文件ID
  669. relatedTime: new Date().toISOString()
  670. };
  671. const response = await client.assets.create.$post({
  672. json: assetData
  673. }, {
  674. headers: {
  675. 'Authorization': `Bearer ${testToken}`
  676. }
  677. });
  678. expect(response.status).toBe(400);
  679. });
  680. it('应该处理人员不在订单中的情况', async () => {
  681. const assetData = {
  682. orderId: testOrder.id,
  683. personId: 999999, // 不在订单中的人员
  684. assetType: AssetType.DISABILITY_CERT,
  685. assetFileType: AssetFileType.IMAGE,
  686. fileId: testFile.id,
  687. relatedTime: new Date().toISOString()
  688. };
  689. const response = await client.assets.create.$post({
  690. json: assetData
  691. }, {
  692. headers: {
  693. 'Authorization': `Bearer ${testToken}`
  694. }
  695. });
  696. expect(response.status).toBe(404);
  697. });
  698. });
  699. describe('GET /order/assets/query', () => {
  700. let testOrder: EmploymentOrder;
  701. let testOrderPerson: OrderPerson;
  702. let testAsset: OrderPersonAsset;
  703. beforeEach(async () => {
  704. // 创建测试数据
  705. const dataSource = await IntegrationTestDatabase.getDataSource();
  706. const orderRepository = dataSource.getRepository(EmploymentOrder);
  707. const orderPersonRepository = dataSource.getRepository(OrderPerson);
  708. const assetRepository = dataSource.getRepository(OrderPersonAsset);
  709. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  710. testOrder = new EmploymentOrder({
  711. orderName: '资产查询测试订单',
  712. platformId: 1,
  713. companyId: 1,
  714. channelId: 1,
  715. expectedStartDate: new Date(),
  716. orderStatus: OrderStatus.DRAFT,
  717. workStatus: WorkStatus.NOT_WORKING,
  718. });
  719. await orderRepository.save(testOrder);
  720. // 先创建残疾人记录
  721. const testDisabledPerson = await OrderTestDataFactory.createTestDisabledPerson(dataSource);
  722. testOrderPerson = orderPersonRepository.create({
  723. orderId: testOrder.id,
  724. personId: testDisabledPerson.id,
  725. joinDate: new Date(),
  726. workStatus: WorkStatus.NOT_WORKING,
  727. salaryDetail: 5000.00
  728. });
  729. await orderPersonRepository.save(testOrderPerson);
  730. testAsset = new OrderPersonAsset({
  731. orderId: testOrder.id,
  732. personId: testOrderPerson.personId,
  733. assetType: AssetType.DISABILITY_CERT,
  734. assetFileType: AssetFileType.IMAGE,
  735. fileId: testFile.id,
  736. relatedTime: new Date()
  737. });
  738. await assetRepository.save(testAsset);
  739. // 创建第二个资产
  740. const testAsset2 = new OrderPersonAsset({
  741. orderId: testOrder.id,
  742. personId: testOrderPerson.personId,
  743. assetType: AssetType.OTHER,
  744. assetFileType: AssetFileType.IMAGE,
  745. fileId: testFile.id,
  746. relatedTime: new Date()
  747. });
  748. await assetRepository.save(testAsset2);
  749. });
  750. it('应该查询所有订单人员资产', async () => {
  751. const response = await client.assets.query.$get({
  752. query: {}
  753. }, {
  754. headers: {
  755. 'Authorization': `Bearer ${testToken}`
  756. }
  757. });
  758. expect(response.status).toBe(200);
  759. if (response.status === 200) {
  760. const data = await response.json();
  761. expect(data).toHaveProperty('data');
  762. expect(data).toHaveProperty('total');
  763. expect(data.data).toHaveLength(2);
  764. expect(data.total).toBe(2);
  765. }
  766. });
  767. it('应该支持按订单ID查询', async () => {
  768. const response = await client.assets.query.$get({
  769. query: {
  770. orderId: testOrder.id.toString()
  771. }
  772. }, {
  773. headers: {
  774. 'Authorization': `Bearer ${testToken}`
  775. }
  776. });
  777. expect(response.status).toBe(200);
  778. if (response.status === 200) {
  779. const data = await response.json();
  780. expect(data.data).toHaveLength(2);
  781. expect(data.data[0].orderId).toBe(testOrder.id);
  782. }
  783. });
  784. it('应该支持按人员ID查询', async () => {
  785. const response = await client.assets.query.$get({
  786. query: {
  787. personId: testOrderPerson.personId.toString()
  788. }
  789. }, {
  790. headers: {
  791. 'Authorization': `Bearer ${testToken}`
  792. }
  793. });
  794. expect(response.status).toBe(200);
  795. if (response.status === 200) {
  796. const data = await response.json();
  797. expect(data.data).toHaveLength(2);
  798. expect(data.data[0].personId).toBe(testOrderPerson.personId);
  799. }
  800. });
  801. it('应该支持按资产类型查询', async () => {
  802. const response = await client.assets.query.$get({
  803. query: {
  804. assetType: AssetType.DISABILITY_CERT
  805. }
  806. }, {
  807. headers: {
  808. 'Authorization': `Bearer ${testToken}`
  809. }
  810. });
  811. expect(response.status).toBe(200);
  812. if (response.status === 200) {
  813. const data = await response.json();
  814. expect(data.data).toHaveLength(1);
  815. expect(data.data[0].assetType).toBe(AssetType.DISABILITY_CERT);
  816. }
  817. });
  818. it('应该支持分页查询', async () => {
  819. const response = await client.assets.query.$get({
  820. query: {
  821. page: '1',
  822. limit: '1'
  823. }
  824. }, {
  825. headers: {
  826. 'Authorization': `Bearer ${testToken}`
  827. }
  828. });
  829. expect(response.status).toBe(200);
  830. if (response.status === 200) {
  831. const data = await response.json();
  832. expect(data.data).toHaveLength(1);
  833. expect(data.total).toBe(2);
  834. }
  835. });
  836. });
  837. describe('DELETE /order/assets/delete/:id', () => {
  838. let testAsset: OrderPersonAsset;
  839. beforeEach(async () => {
  840. // 创建测试数据
  841. const dataSource = await IntegrationTestDatabase.getDataSource();
  842. const orderRepository = dataSource.getRepository(EmploymentOrder);
  843. const orderPersonRepository = dataSource.getRepository(OrderPerson);
  844. const assetRepository = dataSource.getRepository(OrderPersonAsset);
  845. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  846. const testOrder = new EmploymentOrder({
  847. orderName: '资产删除测试订单',
  848. platformId: 1,
  849. companyId: 1,
  850. channelId: 1,
  851. expectedStartDate: new Date(),
  852. orderStatus: OrderStatus.DRAFT,
  853. workStatus: WorkStatus.NOT_WORKING,
  854. });
  855. await orderRepository.save(testOrder);
  856. // 先创建残疾人记录
  857. const testDisabledPerson = await OrderTestDataFactory.createTestDisabledPerson(dataSource);
  858. const testOrderPerson = orderPersonRepository.create({
  859. orderId: testOrder.id,
  860. personId: testDisabledPerson.id,
  861. joinDate: new Date(),
  862. workStatus: WorkStatus.NOT_WORKING,
  863. salaryDetail: 5000.00
  864. });
  865. await orderPersonRepository.save(testOrderPerson);
  866. testAsset = new OrderPersonAsset({
  867. orderId: testOrder.id,
  868. personId: testOrderPerson.personId,
  869. assetType: AssetType.DISABILITY_CERT,
  870. assetFileType: AssetFileType.IMAGE,
  871. fileId: testFile.id,
  872. relatedTime: new Date()
  873. });
  874. await assetRepository.save(testAsset);
  875. });
  876. it('应该成功删除订单人员资产', async () => {
  877. const response = await client.assets.delete[':id'].$delete({
  878. param: { id: testAsset.id.toString() }
  879. }, {
  880. headers: {
  881. 'Authorization': `Bearer ${testToken}`
  882. }
  883. });
  884. expect(response.status).toBe(200);
  885. if (response.status === 200) {
  886. const data = await response.json();
  887. expect(data.success).toBe(true);
  888. // 验证资产已删除
  889. const dataSource = await IntegrationTestDatabase.getDataSource();
  890. const assetRepository = dataSource.getRepository(OrderPersonAsset);
  891. const deletedAsset = await assetRepository.findOne({
  892. where: { id: testAsset.id }
  893. });
  894. expect(deletedAsset).toBeNull();
  895. }
  896. });
  897. it('应该处理不存在的资产ID', async () => {
  898. const response = await client.assets.delete[':id'].$delete({
  899. param: { id: '999999' }
  900. }, {
  901. headers: {
  902. 'Authorization': `Bearer ${testToken}`
  903. }
  904. });
  905. expect(response.status).toBe(404);
  906. });
  907. });
  908. describe('认证测试', () => {
  909. it('应该要求认证', async () => {
  910. const response = await client.list.$get({
  911. query: {}
  912. // 不提供Authorization header
  913. });
  914. expect(response.status).toBe(401);
  915. });
  916. it('应该验证无效token', async () => {
  917. const response = await client.list.$get({
  918. query: {}
  919. }, {
  920. headers: {
  921. 'Authorization': 'Bearer invalid_token'
  922. }
  923. });
  924. expect(response.status).toBe(401);
  925. });
  926. });
  927. });