disability.integration.test.ts 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606
  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 { BankName } from '@d8d/bank-names-module';
  8. import { Company } from '@d8d/allin-company-module/entities';
  9. import { Platform } from '@d8d/allin-platform-module';
  10. import disabledPersonRoutes from '../../src/routes/disabled-person.routes';
  11. import { DisabledPerson } from '../../src/entities/disabled-person.entity';
  12. import { DisabledBankCard } from '../../src/entities/disabled-bank-card.entity';
  13. import { DisabledPhoto } from '../../src/entities/disabled-photo.entity';
  14. import { DisabledRemark } from '../../src/entities/disabled-remark.entity';
  15. import { DisabledVisit } from '../../src/entities/disabled-visit.entity';
  16. // 设置集成测试钩子 - 包含所有相关实体
  17. setupIntegrationDatabaseHooksWithEntities([
  18. UserEntity,
  19. Role,
  20. File,
  21. BankName,
  22. Platform,
  23. Company,
  24. DisabledPerson,
  25. DisabledBankCard,
  26. DisabledPhoto,
  27. DisabledRemark,
  28. DisabledVisit
  29. ])
  30. describe('残疾人管理API集成测试', () => {
  31. let client: ReturnType<typeof testClient<typeof disabledPersonRoutes>>;
  32. let testToken: string;
  33. let testUser: UserEntity;
  34. let testFile: File;
  35. beforeEach(async () => {
  36. // 创建测试客户端
  37. client = testClient(disabledPersonRoutes);
  38. // 获取数据源
  39. const dataSource = await IntegrationTestDatabase.getDataSource();
  40. // 创建测试用户
  41. const userRepository = dataSource.getRepository(UserEntity);
  42. testUser = userRepository.create({
  43. username: `test_user_${Date.now()}`,
  44. password: 'test_password',
  45. nickname: '测试用户',
  46. registrationSource: 'web'
  47. });
  48. await userRepository.save(testUser);
  49. // 创建测试文件(用于照片集成测试)
  50. const fileRepository = dataSource.getRepository(File);
  51. testFile = fileRepository.create({
  52. name: 'test_photo.jpg',
  53. path: 'test_photo.jpg',
  54. type: 'image/jpeg',
  55. size: 1024,
  56. uploadUserId: testUser.id,
  57. uploadTime: new Date()
  58. });
  59. await fileRepository.save(testFile);
  60. // 生成测试用户的token
  61. testToken = JWTUtil.generateToken({
  62. id: testUser.id,
  63. username: testUser.username,
  64. roles: [{name:'user'}]
  65. });
  66. });
  67. describe('POST /createDisabledPerson', () => {
  68. it('应该成功创建残疾人基本信息', async () => {
  69. const createData = {
  70. name: '张三',
  71. gender: '男',
  72. idCard: '110101199001011234',
  73. disabilityId: 'D123456789',
  74. disabilityType: '肢体残疾',
  75. disabilityLevel: '一级',
  76. idAddress: '北京市东城区',
  77. phone: '13800138000',
  78. province: '北京市',
  79. city: '北京市',
  80. // 新增字段
  81. canDirectContact: 1,
  82. isInBlackList: 0,
  83. jobStatus: 1,
  84. specificDisability: '左眼视力0.1,右眼视力0.2,需要助听器',
  85. // 日期字段
  86. idValidDate: new Date('2030-12-31'),
  87. disabilityValidDate: new Date('2030-12-31')
  88. };
  89. const response = await client.createDisabledPerson.$post({
  90. json: createData
  91. }, {
  92. headers: {
  93. 'Authorization': `Bearer ${testToken}`
  94. }
  95. });
  96. expect(response.status).toBe(200);
  97. if (response.status === 200) {
  98. const data = await response.json();
  99. expect(data.name).toBe(createData.name);
  100. expect(data.idCard).toBe(createData.idCard);
  101. expect(data.disabilityId).toBe(createData.disabilityId);
  102. // 验证新增字段
  103. expect(data.canDirectContact).toBe(createData.canDirectContact);
  104. expect(data.isInBlackList).toBe(createData.isInBlackList);
  105. expect(data.jobStatus).toBe(createData.jobStatus);
  106. expect(data.specificDisability).toBe(createData.specificDisability);
  107. // 验证日期字段
  108. expect(data.idValidDate).toBeDefined();
  109. expect(data.disabilityValidDate).toBeDefined();
  110. if (data.idValidDate) {
  111. expect(new Date(data.idValidDate).toISOString().split('T')[0]).toBe('2030-12-31');
  112. }
  113. if (data.disabilityValidDate) {
  114. expect(new Date(data.disabilityValidDate).toISOString().split('T')[0]).toBe('2030-12-31');
  115. }
  116. }
  117. });
  118. it('应该验证身份证号唯一性', async () => {
  119. // 先创建一个残疾人
  120. const dataSource = await IntegrationTestDatabase.getDataSource();
  121. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  122. const existingPerson = disabledPersonRepository.create({
  123. name: '李四',
  124. gender: '女',
  125. idCard: '110101199001011235',
  126. disabilityId: 'D123456788',
  127. disabilityType: '视力残疾',
  128. disabilityLevel: '二级',
  129. idAddress: '北京市西城区',
  130. phone: '13900139000',
  131. province: '北京市',
  132. city: '北京市',
  133. // 新增字段
  134. canDirectContact: 0,
  135. isInBlackList: 0,
  136. jobStatus: 2,
  137. // 日期字段
  138. idValidDate: new Date('2035-05-15'),
  139. disabilityValidDate: new Date('2035-05-15')
  140. });
  141. await disabledPersonRepository.save(existingPerson);
  142. // 尝试创建相同身份证号的残疾人
  143. const createData = {
  144. name: '王五',
  145. gender: '男',
  146. idCard: '110101199001011235', // 重复的身份证号
  147. disabilityId: 'D123456777',
  148. disabilityType: '听力残疾',
  149. disabilityLevel: '三级',
  150. idAddress: '北京市朝阳区',
  151. phone: '13700137000',
  152. province: '北京市',
  153. city: '北京市',
  154. // 新增字段
  155. canDirectContact: 1,
  156. isInBlackList: 1,
  157. jobStatus: 3,
  158. // 日期字段
  159. idValidDate: new Date('2043-08-20'),
  160. disabilityValidDate: new Date('2043-08-20')
  161. };
  162. const response = await client.createDisabledPerson.$post({
  163. json: createData
  164. }, {
  165. headers: {
  166. 'Authorization': `Bearer ${testToken}`
  167. }
  168. });
  169. expect(response.status).toBe(400);
  170. });
  171. it('应该验证必填字段', async () => {
  172. const createData = {
  173. name: '', // 空字符串,应该验证失败
  174. gender: '男',
  175. idCard: '110101199001011236',
  176. disabilityId: 'D123456776',
  177. disabilityType: '肢体残疾',
  178. disabilityLevel: '一级',
  179. idAddress: '北京市海淀区',
  180. phone: '13600136000',
  181. province: '北京市',
  182. city: '北京市',
  183. // 新增字段(可选字段,不影响必填验证)
  184. canDirectContact: 1,
  185. isInBlackList: 0,
  186. jobStatus: 1,
  187. // 日期字段(可选字段,不影响必填验证)
  188. idValidDate: new Date('2028-03-10'),
  189. disabilityValidDate: new Date('2028-03-10')
  190. };
  191. const response = await client.createDisabledPerson.$post({
  192. json: createData
  193. }, {
  194. headers: {
  195. 'Authorization': `Bearer ${testToken}`
  196. }
  197. });
  198. expect(response.status).toBe(400);
  199. });
  200. it('应该验证具体残疾部位和情况字段为空值', async () => {
  201. const createData = {
  202. name: '空值测试',
  203. gender: '男',
  204. idCard: '110101199001011236',
  205. disabilityId: 'D123456776',
  206. disabilityType: '肢体残疾',
  207. disabilityLevel: '一级',
  208. idAddress: '北京市海淀区',
  209. phone: '13600136000',
  210. province: '北京市',
  211. city: '北京市',
  212. canDirectContact: 1,
  213. isInBlackList: 0,
  214. jobStatus: 1,
  215. // specificDisability 字段不提供,测试空值
  216. idValidDate: new Date('2028-03-10'),
  217. disabilityValidDate: new Date('2028-03-10')
  218. };
  219. const response = await client.createDisabledPerson.$post({
  220. json: createData
  221. }, {
  222. headers: {
  223. 'Authorization': `Bearer ${testToken}`
  224. }
  225. });
  226. expect(response.status).toBe(200);
  227. if (response.status === 200) {
  228. const data = await response.json();
  229. expect(data.name).toBe(createData.name);
  230. expect(data.specificDisability).toBeNull(); // 应该为null,因为数据库字段nullable: true
  231. }
  232. });
  233. it('应该验证具体残疾部位和情况字段为有效值', async () => {
  234. const createData = {
  235. name: '有效值测试',
  236. gender: '女',
  237. idCard: '110101199001011237',
  238. disabilityId: 'D123456775',
  239. disabilityType: '视力残疾',
  240. disabilityLevel: '二级',
  241. idAddress: '北京市朝阳区',
  242. phone: '13700137000',
  243. province: '北京市',
  244. city: '北京市',
  245. canDirectContact: 0,
  246. isInBlackList: 0,
  247. jobStatus: 0,
  248. specificDisability: '双眼视力均为0.05,需要导盲犬辅助',
  249. idValidDate: new Date('2030-06-15'),
  250. disabilityValidDate: new Date('2030-06-15')
  251. };
  252. const response = await client.createDisabledPerson.$post({
  253. json: createData
  254. }, {
  255. headers: {
  256. 'Authorization': `Bearer ${testToken}`
  257. }
  258. });
  259. expect(response.status).toBe(200);
  260. if (response.status === 200) {
  261. const data = await response.json();
  262. expect(data.name).toBe(createData.name);
  263. expect(data.specificDisability).toBe(createData.specificDisability);
  264. }
  265. });
  266. it('应该验证具体残疾部位和情况字段边界值(500字符)', async () => {
  267. // 生成500字符的字符串
  268. const maxLengthText = 'A'.repeat(500);
  269. const createData = {
  270. name: '边界值测试',
  271. gender: '男',
  272. idCard: '110101199001011238',
  273. disabilityId: 'D123456774',
  274. disabilityType: '听力残疾',
  275. disabilityLevel: '三级',
  276. idAddress: '北京市丰台区',
  277. phone: '13800138001',
  278. province: '北京市',
  279. city: '北京市',
  280. canDirectContact: 1,
  281. isInBlackList: 0,
  282. jobStatus: 1,
  283. specificDisability: maxLengthText,
  284. idValidDate: new Date('2032-08-20'),
  285. disabilityValidDate: new Date('2032-08-20')
  286. };
  287. const response = await client.createDisabledPerson.$post({
  288. json: createData
  289. }, {
  290. headers: {
  291. 'Authorization': `Bearer ${testToken}`
  292. }
  293. });
  294. expect(response.status).toBe(200);
  295. if (response.status === 200) {
  296. const data = await response.json();
  297. expect(data.name).toBe(createData.name);
  298. expect(data.specificDisability).toBe(createData.specificDisability);
  299. expect(data.specificDisability?.length).toBe(500);
  300. }
  301. });
  302. it('应该验证具体残疾部位和情况字段超过500字符限制', async () => {
  303. // 生成501字符的字符串
  304. const tooLongText = 'A'.repeat(501);
  305. const createData = {
  306. name: '超长测试',
  307. gender: '女',
  308. idCard: '110101199001011239',
  309. disabilityId: 'D123456773',
  310. disabilityType: '言语残疾',
  311. disabilityLevel: '四级',
  312. idAddress: '北京市石景山区',
  313. phone: '13900139001',
  314. province: '北京市',
  315. city: '北京市',
  316. canDirectContact: 0,
  317. isInBlackList: 0,
  318. jobStatus: 0,
  319. specificDisability: tooLongText,
  320. idValidDate: new Date('2034-12-31'),
  321. disabilityValidDate: new Date('2034-12-31')
  322. };
  323. const response = await client.createDisabledPerson.$post({
  324. json: createData
  325. }, {
  326. headers: {
  327. 'Authorization': `Bearer ${testToken}`
  328. }
  329. });
  330. expect(response.status).toBe(400); // 应该返回400,因为超过长度限制
  331. });
  332. });
  333. describe('POST /deleteDisabledPerson', () => {
  334. it('应该成功删除残疾人', async () => {
  335. // 先创建一个残疾人
  336. const dataSource = await IntegrationTestDatabase.getDataSource();
  337. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  338. const person = disabledPersonRepository.create({
  339. name: '测试删除人员',
  340. gender: '男',
  341. idCard: '110101199001011237',
  342. disabilityId: 'D123456775',
  343. disabilityType: '肢体残疾',
  344. disabilityLevel: '一级',
  345. idAddress: '北京市石景山区',
  346. phone: '13500135000',
  347. province: '北京市',
  348. city: '北京市'
  349. });
  350. await disabledPersonRepository.save(person);
  351. const deleteData = {
  352. id: person.id
  353. };
  354. const response = await client.deleteDisabledPerson.$post({
  355. json: deleteData
  356. }, {
  357. headers: {
  358. 'Authorization': `Bearer ${testToken}`
  359. }
  360. });
  361. expect(response.status).toBe(200);
  362. if (response.status === 200) {
  363. const data = await response.json();
  364. expect(data.success).toBe(true);
  365. // 验证残疾人已被删除
  366. const deletedPerson = await disabledPersonRepository.findOne({ where: { id: person.id } });
  367. expect(deletedPerson).toBeNull();
  368. }
  369. });
  370. it('应该处理不存在的残疾人ID', async () => {
  371. const deleteData = {
  372. id: 99999 // 不存在的ID
  373. };
  374. const response = await client.deleteDisabledPerson.$post({
  375. json: deleteData
  376. }, {
  377. headers: {
  378. 'Authorization': `Bearer ${testToken}`
  379. }
  380. });
  381. expect(response.status).toBe(404);
  382. });
  383. });
  384. describe('POST /updateDisabledPerson', () => {
  385. it('应该成功更新残疾人信息', async () => {
  386. // 先创建一个残疾人
  387. const dataSource = await IntegrationTestDatabase.getDataSource();
  388. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  389. const person = disabledPersonRepository.create({
  390. name: '原始姓名',
  391. gender: '男',
  392. idCard: '110101199001011238',
  393. disabilityId: 'D123456774',
  394. disabilityType: '肢体残疾',
  395. disabilityLevel: '一级',
  396. idAddress: '北京市通州区',
  397. phone: '13400134000',
  398. province: '北京市',
  399. city: '北京市',
  400. // 新增字段初始值
  401. canDirectContact: 1,
  402. isInBlackList: 0,
  403. jobStatus: 1,
  404. // 日期字段初始值
  405. idValidDate: new Date('2023-01-01'),
  406. disabilityValidDate: new Date('2023-01-01')
  407. });
  408. await disabledPersonRepository.save(person);
  409. const updateData = {
  410. id: person.id,
  411. name: '更新后的姓名',
  412. gender: '女',
  413. phone: '13300133000',
  414. // 更新新增字段
  415. canDirectContact: 0,
  416. isInBlackList: 1,
  417. jobStatus: 1,
  418. // 更新日期字段
  419. idValidDate: new Date('2033-01-01'), // 更新有效期
  420. disabilityValidDate: new Date('2033-01-01') // 更新有效期
  421. };
  422. const response = await client.updateDisabledPerson.$post({
  423. json: updateData
  424. }, {
  425. headers: {
  426. 'Authorization': `Bearer ${testToken}`
  427. }
  428. });
  429. expect(response.status).toBe(200);
  430. if (response.status === 200) {
  431. const data = await response.json();
  432. expect(data.name).toBe(updateData.name);
  433. expect(data.gender).toBe(updateData.gender);
  434. expect(data.phone).toBe(updateData.phone);
  435. // 验证新增字段已更新
  436. expect(data.canDirectContact).toBe(updateData.canDirectContact);
  437. expect(data.isInBlackList).toBe(updateData.isInBlackList);
  438. expect(data.jobStatus).toBe(updateData.jobStatus);
  439. // 验证日期字段
  440. expect(data.idValidDate).toBeDefined();
  441. expect(data.disabilityValidDate).toBeDefined();
  442. if (data.idValidDate) {
  443. expect(new Date(data.idValidDate).toISOString().split('T')[0]).toBe('2033-01-01');
  444. }
  445. if (data.disabilityValidDate) {
  446. expect(new Date(data.disabilityValidDate).toISOString().split('T')[0]).toBe('2033-01-01');
  447. }
  448. }
  449. });
  450. it('应该验证身份证号唯一性(更新时)', async () => {
  451. // 创建两个残疾人
  452. const dataSource = await IntegrationTestDatabase.getDataSource();
  453. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  454. const person1 = disabledPersonRepository.create({
  455. name: '人员A',
  456. gender: '男',
  457. idCard: '110101199001011239',
  458. disabilityId: 'D123456773',
  459. disabilityType: '肢体残疾',
  460. disabilityLevel: '一级',
  461. idAddress: '北京市顺义区',
  462. phone: '13200132000',
  463. province: '北京市',
  464. city: '北京市',
  465. // 新增字段
  466. canDirectContact: 1,
  467. isInBlackList: 0,
  468. jobStatus: 1,
  469. // 日期字段
  470. idValidDate: new Date('2028-06-15'),
  471. disabilityValidDate: new Date('2028-06-15')
  472. });
  473. await disabledPersonRepository.save(person1);
  474. const person2 = disabledPersonRepository.create({
  475. name: '人员B',
  476. gender: '女',
  477. idCard: '110101199001011240',
  478. disabilityId: 'D123456772',
  479. disabilityType: '视力残疾',
  480. disabilityLevel: '二级',
  481. idAddress: '北京市大兴区',
  482. phone: '13100131000',
  483. province: '北京市',
  484. city: '北京市',
  485. // 新增字段
  486. canDirectContact: 0,
  487. isInBlackList: 1,
  488. jobStatus: 2,
  489. // 日期字段
  490. idValidDate: new Date('2034-09-20'),
  491. disabilityValidDate: new Date('2034-09-20')
  492. });
  493. await disabledPersonRepository.save(person2);
  494. // 尝试将人员2的身份证号改为人员1的身份证号
  495. const updateData = {
  496. id: person2.id,
  497. idCard: '110101199001011239' // 重复的身份证号
  498. };
  499. const response = await client.updateDisabledPerson.$post({
  500. json: updateData
  501. }, {
  502. headers: {
  503. 'Authorization': `Bearer ${testToken}`
  504. }
  505. });
  506. expect(response.status).toBe(400);
  507. });
  508. it('应该处理不存在的残疾人', async () => {
  509. const updateData = {
  510. id: 99999, // 不存在的ID
  511. name: '新姓名'
  512. };
  513. const response = await client.updateDisabledPerson.$post({
  514. json: updateData
  515. }, {
  516. headers: {
  517. 'Authorization': `Bearer ${testToken}`
  518. }
  519. });
  520. expect(response.status).toBe(404);
  521. });
  522. });
  523. describe('GET /getAllDisabledPersons', () => {
  524. it('应该成功获取残疾人列表(分页)', async () => {
  525. // 创建一些测试数据
  526. const dataSource = await IntegrationTestDatabase.getDataSource();
  527. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  528. for (let i = 1; i <= 5; i++) {
  529. const person = disabledPersonRepository.create({
  530. name: `残疾人${i}`,
  531. gender: i % 2 === 0 ? '女' : '男',
  532. idCard: `1101011990010112${40 + i}`,
  533. disabilityId: `D1234567${70 + i}`,
  534. disabilityType: '肢体残疾',
  535. disabilityLevel: '一级',
  536. idAddress: `北京市测试区${i}`,
  537. phone: `138001380${i}`,
  538. province: '北京市',
  539. city: '北京市'
  540. });
  541. await disabledPersonRepository.save(person);
  542. }
  543. const response = await client.getAllDisabledPersons.$get({
  544. query: {
  545. skip: 0,
  546. take: 10
  547. }
  548. }, {
  549. headers: {
  550. 'Authorization': `Bearer ${testToken}`
  551. }
  552. });
  553. expect(response.status).toBe(200);
  554. if (response.status === 200) {
  555. const data = await response.json();
  556. expect(data.data).toHaveLength(5);
  557. expect(data.total).toBe(5);
  558. expect(data.data[0].name).toBe('残疾人5'); // 按ID降序排列
  559. }
  560. });
  561. it('应该处理分页参数', async () => {
  562. // 创建更多测试数据
  563. const dataSource = await IntegrationTestDatabase.getDataSource();
  564. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  565. for (let i = 1; i <= 15; i++) {
  566. const person = disabledPersonRepository.create({
  567. name: `分页人员${i}`,
  568. gender: i % 2 === 0 ? '女' : '男',
  569. idCard: `1101011990010113${i}`,
  570. disabilityId: `D1234568${i}`,
  571. disabilityType: '肢体残疾',
  572. disabilityLevel: '一级',
  573. idAddress: `北京市分页区${i}`,
  574. phone: `138001381${i}`,
  575. province: '北京市',
  576. city: '北京市'
  577. });
  578. await disabledPersonRepository.save(person);
  579. }
  580. const response = await client.getAllDisabledPersons.$get({
  581. query: {
  582. skip: 5,
  583. take: 5
  584. }
  585. }, {
  586. headers: {
  587. 'Authorization': `Bearer ${testToken}`
  588. }
  589. });
  590. expect(response.status).toBe(200);
  591. if (response.status === 200) {
  592. const data = await response.json();
  593. expect(data.data).toHaveLength(5);
  594. expect(data.total).toBe(15);
  595. }
  596. });
  597. it('应该支持残疾类型筛选', async () => {
  598. // 创建测试数据
  599. const dataSource = await IntegrationTestDatabase.getDataSource();
  600. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  601. // 创建不同残疾类型的人员
  602. const person1 = disabledPersonRepository.create({
  603. name: '视力残疾人',
  604. gender: '男',
  605. idCard: '110101199001011351',
  606. disabilityId: 'D123456851',
  607. disabilityType: '视力残疾',
  608. disabilityLevel: '一级',
  609. idAddress: '北京市测试区',
  610. phone: '1380013851',
  611. province: '北京市',
  612. city: '北京市'
  613. });
  614. await disabledPersonRepository.save(person1);
  615. const person2 = disabledPersonRepository.create({
  616. name: '肢体残疾人',
  617. gender: '女',
  618. idCard: '110101199001011352',
  619. disabilityId: 'D123456852',
  620. disabilityType: '肢体残疾',
  621. disabilityLevel: '二级',
  622. idAddress: '北京市测试区',
  623. phone: '1380013852',
  624. province: '北京市',
  625. city: '北京市'
  626. });
  627. await disabledPersonRepository.save(person2);
  628. // 测试视力残疾筛选
  629. const response = await client.getAllDisabledPersons.$get({
  630. query: {
  631. disabilityType: '视力残疾',
  632. skip: 0,
  633. take: 10
  634. }
  635. }, {
  636. headers: {
  637. 'Authorization': `Bearer ${testToken}`
  638. }
  639. });
  640. expect(response.status).toBe(200);
  641. if (response.status === 200) {
  642. const data = await response.json();
  643. expect(data.data).toHaveLength(1);
  644. expect(data.data[0].disabilityType).toBe('视力残疾');
  645. }
  646. });
  647. it('应该支持残疾级别筛选', async () => {
  648. // 创建测试数据
  649. const dataSource = await IntegrationTestDatabase.getDataSource();
  650. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  651. // 创建不同残疾级别的人员
  652. const person1 = disabledPersonRepository.create({
  653. name: '一级残疾人',
  654. gender: '男',
  655. idCard: '110101199001011361',
  656. disabilityId: 'D123456861',
  657. disabilityType: '肢体残疾',
  658. disabilityLevel: '一级',
  659. idAddress: '北京市测试区',
  660. phone: '1380013861',
  661. province: '北京市',
  662. city: '北京市'
  663. });
  664. await disabledPersonRepository.save(person1);
  665. const person2 = disabledPersonRepository.create({
  666. name: '二级残疾人',
  667. gender: '女',
  668. idCard: '110101199001011362',
  669. disabilityId: 'D123456862',
  670. disabilityType: '肢体残疾',
  671. disabilityLevel: '二级',
  672. idAddress: '北京市测试区',
  673. phone: '1380013862',
  674. province: '北京市',
  675. city: '北京市'
  676. });
  677. await disabledPersonRepository.save(person2);
  678. // 测试一级残疾筛选
  679. const response = await client.getAllDisabledPersons.$get({
  680. query: {
  681. disabilityLevel: '一级',
  682. skip: 0,
  683. take: 10
  684. }
  685. }, {
  686. headers: {
  687. 'Authorization': `Bearer ${testToken}`
  688. }
  689. });
  690. expect(response.status).toBe(200);
  691. if (response.status === 200) {
  692. const data = await response.json();
  693. expect(data.data).toHaveLength(1);
  694. expect(data.data[0].disabilityLevel).toBe('一级');
  695. }
  696. });
  697. it('应该支持省份筛选', async () => {
  698. // 创建测试数据
  699. const dataSource = await IntegrationTestDatabase.getDataSource();
  700. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  701. // 创建不同省份的人员
  702. const person1 = disabledPersonRepository.create({
  703. name: '北京人员',
  704. gender: '男',
  705. idCard: '110101199001011371',
  706. disabilityId: 'D123456871',
  707. disabilityType: '肢体残疾',
  708. disabilityLevel: '一级',
  709. idAddress: '北京市测试区',
  710. phone: '1380013871',
  711. province: '北京市',
  712. city: '北京市'
  713. });
  714. await disabledPersonRepository.save(person1);
  715. const person2 = disabledPersonRepository.create({
  716. name: '上海人员',
  717. gender: '女',
  718. idCard: '310101199001011372',
  719. disabilityId: 'D123456872',
  720. disabilityType: '肢体残疾',
  721. disabilityLevel: '二级',
  722. idAddress: '上海市测试区',
  723. phone: '1380013872',
  724. province: '上海市',
  725. city: '上海市'
  726. });
  727. await disabledPersonRepository.save(person2);
  728. // 测试北京筛选
  729. const response = await client.getAllDisabledPersons.$get({
  730. query: {
  731. province: '北京市',
  732. skip: 0,
  733. take: 10
  734. }
  735. }, {
  736. headers: {
  737. 'Authorization': `Bearer ${testToken}`
  738. }
  739. });
  740. expect(response.status).toBe(200);
  741. if (response.status === 200) {
  742. const data = await response.json();
  743. expect(data.data).toHaveLength(1);
  744. expect(data.data[0].province).toBe('北京市');
  745. }
  746. });
  747. it('应该支持多条件组合筛选', async () => {
  748. // 创建测试数据
  749. const dataSource = await IntegrationTestDatabase.getDataSource();
  750. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  751. // 创建符合多个条件的人员
  752. const person1 = disabledPersonRepository.create({
  753. name: '北京一级视力残疾人',
  754. gender: '男',
  755. idCard: '110101199001011381',
  756. disabilityId: 'D123456881',
  757. disabilityType: '视力残疾',
  758. disabilityLevel: '一级',
  759. idAddress: '北京市测试区',
  760. phone: '1380013881',
  761. province: '北京市',
  762. city: '北京市'
  763. });
  764. await disabledPersonRepository.save(person1);
  765. // 创建不符合全部条件的人员
  766. const person2 = disabledPersonRepository.create({
  767. name: '北京二级肢体残疾人',
  768. gender: '女',
  769. idCard: '110101199001011382',
  770. disabilityId: 'D123456882',
  771. disabilityType: '肢体残疾',
  772. disabilityLevel: '二级',
  773. idAddress: '北京市测试区',
  774. phone: '1380013882',
  775. province: '北京市',
  776. city: '北京市'
  777. });
  778. await disabledPersonRepository.save(person2);
  779. // 测试多条件组合筛选:北京 + 一级 + 视力残疾
  780. const response = await client.getAllDisabledPersons.$get({
  781. query: {
  782. province: '北京市',
  783. disabilityType: '视力残疾',
  784. disabilityLevel: '一级',
  785. skip: 0,
  786. take: 10
  787. }
  788. }, {
  789. headers: {
  790. 'Authorization': `Bearer ${testToken}`
  791. }
  792. });
  793. expect(response.status).toBe(200);
  794. if (response.status === 200) {
  795. const data = await response.json();
  796. expect(data.data).toHaveLength(1);
  797. expect(data.data[0].name).toBe('北京一级视力残疾人');
  798. }
  799. });
  800. it('应该支持银行卡类别筛选', async () => {
  801. // 创建测试数据
  802. const dataSource = await IntegrationTestDatabase.getDataSource();
  803. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  804. const bankNameRepository = dataSource.getRepository(BankName);
  805. const bankCardRepository = dataSource.getRepository(DisabledBankCard);
  806. // 创建银行名称
  807. const bankName1 = bankNameRepository.create({
  808. name: '中国工商银行',
  809. code: 'ICBC',
  810. status: 1
  811. });
  812. await bankNameRepository.save(bankName1);
  813. const bankName2 = bankNameRepository.create({
  814. name: '中国建设银行',
  815. code: 'CCB',
  816. status: 1
  817. });
  818. await bankNameRepository.save(bankName2);
  819. // 创建人员1 - 有工商银行卡
  820. const person1 = disabledPersonRepository.create({
  821. name: '工商银行用户',
  822. gender: '男',
  823. idCard: '110101199001011391',
  824. disabilityId: 'D123456891',
  825. disabilityType: '视力残疾',
  826. disabilityLevel: '一级',
  827. idAddress: '北京市测试区',
  828. phone: '1380013891',
  829. province: '北京市',
  830. city: '北京市'
  831. });
  832. await disabledPersonRepository.save(person1);
  833. // 为人员1创建工商银行卡
  834. const bankCard1 = bankCardRepository.create({
  835. personId: person1.id,
  836. subBankName: '北京分行',
  837. bankNameId: bankName1.id,
  838. cardNumber: '6222001234567890123',
  839. cardholderName: '工商银行用户',
  840. cardType: '储蓄卡',
  841. fileId: testFile.id,
  842. isDefault: 1
  843. });
  844. await bankCardRepository.save(bankCard1);
  845. // 创建人员2 - 有建设银行卡
  846. const person2 = disabledPersonRepository.create({
  847. name: '建设银行用户',
  848. gender: '女',
  849. idCard: '110101199001011392',
  850. disabilityId: 'D123456892',
  851. disabilityType: '肢体残疾',
  852. disabilityLevel: '二级',
  853. idAddress: '北京市测试区',
  854. phone: '1380013892',
  855. province: '北京市',
  856. city: '北京市'
  857. });
  858. await disabledPersonRepository.save(person2);
  859. // 为人员2创建建设银行卡
  860. const bankCard2 = bankCardRepository.create({
  861. personId: person2.id,
  862. subBankName: '北京分行',
  863. bankNameId: bankName2.id,
  864. cardNumber: '6227001234567890123',
  865. cardholderName: '建设银行用户',
  866. cardType: '信用卡',
  867. fileId: testFile.id,
  868. isDefault: 1
  869. });
  870. await bankCardRepository.save(bankCard2);
  871. // 测试工商银行筛选
  872. const response = await client.getAllDisabledPersons.$get({
  873. query: {
  874. bankNameId: bankName1.id,
  875. skip: 0,
  876. take: 10
  877. }
  878. }, {
  879. headers: {
  880. 'Authorization': `Bearer ${testToken}`
  881. }
  882. });
  883. expect(response.status).toBe(200);
  884. if (response.status === 200) {
  885. const data = await response.json();
  886. expect(data.data).toHaveLength(1);
  887. expect(data.data[0].name).toBe('工商银行用户');
  888. }
  889. });
  890. it('应该支持银行卡类型筛选', async () => {
  891. // 创建测试数据
  892. const dataSource = await IntegrationTestDatabase.getDataSource();
  893. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  894. const bankNameRepository = dataSource.getRepository(BankName);
  895. const bankCardRepository = dataSource.getRepository(DisabledBankCard);
  896. // 创建银行名称
  897. const bankName1 = bankNameRepository.create({
  898. name: '中国工商银行',
  899. code: 'ICBC',
  900. status: 1
  901. });
  902. await bankNameRepository.save(bankName1);
  903. const bankName2 = bankNameRepository.create({
  904. name: '中国建设银行',
  905. code: 'CCB',
  906. status: 1
  907. });
  908. await bankNameRepository.save(bankName2);
  909. // 创建人员1 - 有储蓄卡
  910. const person1 = disabledPersonRepository.create({
  911. name: '储蓄卡用户',
  912. gender: '男',
  913. idCard: '110101199001011393',
  914. disabilityId: 'D123456893',
  915. disabilityType: '视力残疾',
  916. disabilityLevel: '一级',
  917. idAddress: '北京市测试区',
  918. phone: '1380013893',
  919. province: '北京市',
  920. city: '北京市'
  921. });
  922. await disabledPersonRepository.save(person1);
  923. // 为人员1创建储蓄卡
  924. const bankCard1 = bankCardRepository.create({
  925. personId: person1.id,
  926. subBankName: '北京分行',
  927. bankNameId: bankName1.id,
  928. cardNumber: '6222001234567890124',
  929. cardholderName: '储蓄卡用户',
  930. cardType: '储蓄卡',
  931. fileId: testFile.id,
  932. isDefault: 1
  933. });
  934. await bankCardRepository.save(bankCard1);
  935. // 创建人员2 - 有信用卡
  936. const person2 = disabledPersonRepository.create({
  937. name: '信用卡用户',
  938. gender: '女',
  939. idCard: '110101199001011394',
  940. disabilityId: 'D123456894',
  941. disabilityType: '肢体残疾',
  942. disabilityLevel: '二级',
  943. idAddress: '北京市测试区',
  944. phone: '1380013894',
  945. province: '北京市',
  946. city: '北京市'
  947. });
  948. await disabledPersonRepository.save(person2);
  949. // 为人员2创建信用卡
  950. const bankCard2 = bankCardRepository.create({
  951. personId: person2.id,
  952. subBankName: '北京分行',
  953. bankNameId: bankName2.id,
  954. cardNumber: '6227001234567890124',
  955. cardholderName: '信用卡用户',
  956. cardType: '信用卡',
  957. fileId: testFile.id,
  958. isDefault: 1
  959. });
  960. await bankCardRepository.save(bankCard2);
  961. // 测试储蓄卡筛选
  962. const response = await client.getAllDisabledPersons.$get({
  963. query: {
  964. cardType: '储蓄卡',
  965. skip: 0,
  966. take: 10
  967. }
  968. }, {
  969. headers: {
  970. 'Authorization': `Bearer ${testToken}`
  971. }
  972. });
  973. expect(response.status).toBe(200);
  974. if (response.status === 200) {
  975. const data = await response.json();
  976. expect(data.data).toHaveLength(1);
  977. expect(data.data[0].name).toBe('储蓄卡用户');
  978. }
  979. });
  980. });
  981. describe('GET /searchDisabledPersons', () => {
  982. it('应该成功按姓名搜索残疾人', async () => {
  983. // 创建测试数据
  984. const dataSource = await IntegrationTestDatabase.getDataSource();
  985. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  986. const person1 = disabledPersonRepository.create({
  987. name: '张三',
  988. gender: '男',
  989. idCard: '110101199001011241',
  990. disabilityId: 'D123456771',
  991. disabilityType: '肢体残疾',
  992. disabilityLevel: '一级',
  993. idAddress: '北京市昌平区',
  994. phone: '13000130001',
  995. province: '北京市',
  996. city: '北京市'
  997. });
  998. await disabledPersonRepository.save(person1);
  999. const person2 = disabledPersonRepository.create({
  1000. name: '李四',
  1001. gender: '女',
  1002. idCard: '110101199001011242',
  1003. disabilityId: 'D123456770',
  1004. disabilityType: '视力残疾',
  1005. disabilityLevel: '二级',
  1006. idAddress: '北京市平谷区',
  1007. phone: '13000130002',
  1008. province: '北京市',
  1009. city: '北京市'
  1010. });
  1011. await disabledPersonRepository.save(person2);
  1012. const response = await client.searchDisabledPersons.$get({
  1013. query: {
  1014. keyword: '张三',
  1015. skip: 0,
  1016. take: 10
  1017. }
  1018. }, {
  1019. headers: {
  1020. 'Authorization': `Bearer ${testToken}`
  1021. }
  1022. });
  1023. expect(response.status).toBe(200);
  1024. if (response.status === 200) {
  1025. const data = await response.json();
  1026. expect(data.data).toHaveLength(1);
  1027. expect(data.data[0].name).toBe('张三');
  1028. }
  1029. });
  1030. it('应该验证搜索关键词不能为空', async () => {
  1031. const response = await client.searchDisabledPersons.$get({
  1032. query: {
  1033. keyword: '', // 空关键词
  1034. skip: 0,
  1035. take: 10
  1036. }
  1037. }, {
  1038. headers: {
  1039. 'Authorization': `Bearer ${testToken}`
  1040. }
  1041. });
  1042. expect(response.status).toBe(200); // keyword是可选的,空关键词返回所有结果
  1043. });
  1044. });
  1045. describe('GET /getDisabledPerson/{id}', () => {
  1046. it('应该成功获取单个残疾人详情', async () => {
  1047. // 先创建一个残疾人
  1048. const dataSource = await IntegrationTestDatabase.getDataSource();
  1049. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  1050. const person = disabledPersonRepository.create({
  1051. name: '测试人员详情',
  1052. gender: '男',
  1053. idCard: '110101199001011243',
  1054. disabilityId: 'D123456769',
  1055. disabilityType: '肢体残疾',
  1056. disabilityLevel: '一级',
  1057. idAddress: '北京市怀柔区',
  1058. phone: '13000130003',
  1059. province: '北京市',
  1060. city: '北京市',
  1061. canDirectContact: 1,
  1062. isMarried: 1
  1063. });
  1064. await disabledPersonRepository.save(person);
  1065. const response = await client.getDisabledPerson[':id'].$get({
  1066. param: {
  1067. id: person.id
  1068. }
  1069. }, {
  1070. headers: {
  1071. 'Authorization': `Bearer ${testToken}`
  1072. }
  1073. });
  1074. expect(response.status).toBe(200);
  1075. if (response.status === 200) {
  1076. const data = await response.json();
  1077. expect(data?.name).toBe('测试人员详情');
  1078. expect(data?.canDirectContact).toBe(1);
  1079. }
  1080. });
  1081. it('应该处理不存在的残疾人ID', async () => {
  1082. const response = await client.getDisabledPerson[':id'].$get({
  1083. param: {
  1084. id: 99999 // 不存在的ID
  1085. }
  1086. }, {
  1087. headers: {
  1088. 'Authorization': `Bearer ${testToken}`
  1089. }
  1090. });
  1091. expect(response.status).toBe(200); // 返回200,但数据为null
  1092. if (response.status === 200) {
  1093. const data = await response.json();
  1094. expect(data).toBeNull();
  1095. }
  1096. });
  1097. });
  1098. describe('GET /getDisabledPersonByIdCard', () => {
  1099. it('应该成功根据身份证号查询残疾人', async () => {
  1100. // 先创建一个残疾人
  1101. const dataSource = await IntegrationTestDatabase.getDataSource();
  1102. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  1103. const person = disabledPersonRepository.create({
  1104. name: '身份证查询测试',
  1105. gender: '女',
  1106. idCard: '110101199001011244',
  1107. disabilityId: 'D123456768',
  1108. disabilityType: '听力残疾',
  1109. disabilityLevel: '三级',
  1110. idAddress: '北京市密云区',
  1111. phone: '13000130004',
  1112. province: '北京市',
  1113. city: '北京市'
  1114. });
  1115. await disabledPersonRepository.save(person);
  1116. const response = await client.findByIdCard[':idCard'].$get({
  1117. param: {
  1118. idCard: '110101199001011244'
  1119. }
  1120. }, {
  1121. headers: {
  1122. 'Authorization': `Bearer ${testToken}`
  1123. }
  1124. });
  1125. expect(response.status).toBe(200);
  1126. if (response.status === 200) {
  1127. const data = await response.json();
  1128. expect(data?.name).toBe('身份证查询测试');
  1129. expect(data?.idCard).toBe('110101199001011244');
  1130. }
  1131. });
  1132. it('应该处理不存在的身份证号', async () => {
  1133. const response = await client.findByIdCard[':idCard'].$get({
  1134. param: {
  1135. idCard: '999999999999999999' // 不存在的身份证号
  1136. }
  1137. }, {
  1138. headers: {
  1139. 'Authorization': `Bearer ${testToken}`
  1140. }
  1141. });
  1142. expect(response.status).toBe(200); // 返回200,但数据为null
  1143. if (response.status === 200) {
  1144. const data = await response.json();
  1145. expect(data).toBeNull();
  1146. }
  1147. });
  1148. });
  1149. describe('POST /createAggregatedDisabledPerson', () => {
  1150. it('应该成功创建聚合残疾人信息(包含所有关联数据)', async () => {
  1151. // 获取数据源并创建测试银行名称
  1152. const dataSource = await IntegrationTestDatabase.getDataSource();
  1153. const bankNameRepository = dataSource.getRepository(BankName);
  1154. const testBankName = bankNameRepository.create({
  1155. name: '测试银行',
  1156. code: 'TEST',
  1157. status: 1
  1158. });
  1159. await bankNameRepository.save(testBankName);
  1160. const createData = {
  1161. personInfo: {
  1162. name: '聚合创建测试',
  1163. gender: '男',
  1164. idCard: `110101${Date.now() % 1000000}`, // 动态身份证号避免重复
  1165. disabilityId: `D${Date.now() % 100000000}`, // 动态残疾证号避免重复
  1166. disabilityType: '肢体残疾',
  1167. disabilityLevel: '一级',
  1168. birthDate: new Date('1990-01-01'), // 添加出生日期字段
  1169. idAddress: '北京市延庆区',
  1170. phone: '13000130005',
  1171. province: '北京市',
  1172. city: '北京市',
  1173. // 新增字段
  1174. canDirectContact: 1,
  1175. isInBlackList: 0,
  1176. jobStatus: 1,
  1177. specificDisability: '左腿截肢,右腿行动不便,需要轮椅',
  1178. // 日期字段
  1179. idValidDate: new Date('2045-11-30'),
  1180. disabilityValidDate: new Date('2045-11-30')
  1181. },
  1182. bankCards: [
  1183. {
  1184. subBankName: '北京分行',
  1185. bankNameId: testBankName.id, // 使用创建的测试银行名称ID
  1186. bankName: {
  1187. id: testBankName.id,
  1188. name: testBankName.name,
  1189. code: testBankName.code,
  1190. status: testBankName.status,
  1191. remark: null,
  1192. createdAt: testBankName.createdAt,
  1193. updatedAt: testBankName.updatedAt,
  1194. createdBy: null,
  1195. updatedBy: null
  1196. },
  1197. cardNumber: '6222021234567890123',
  1198. cardholderName: '聚合创建测试',
  1199. cardType: '储蓄卡',
  1200. fileId: testFile.id,
  1201. isDefault: 0
  1202. }
  1203. ],
  1204. photos: [
  1205. {
  1206. photoType: '身份证照片',
  1207. fileId: testFile.id // 使用测试文件ID
  1208. }
  1209. ],
  1210. remarks: [
  1211. {
  1212. remarkContent: '家庭经济困难,需要帮助',
  1213. operatorId: testUser.id
  1214. }
  1215. ],
  1216. visits: [
  1217. {
  1218. visitDate: '2025-12-02T10:00:00Z',
  1219. visitType: '电话回访',
  1220. visitContent: '初次回访,了解基本情况',
  1221. visitorId: testUser.id
  1222. }
  1223. ]
  1224. };
  1225. const response = await client.createAggregatedDisabledPerson.$post({
  1226. json: createData
  1227. }, {
  1228. headers: {
  1229. 'Authorization': `Bearer ${testToken}`
  1230. }
  1231. });
  1232. expect(response.status).toBe(200);
  1233. if (response.status === 200) {
  1234. const data = await response.json();
  1235. expect(data.personInfo.name).toBe('聚合创建测试');
  1236. // 验证新增字段
  1237. expect(data.personInfo.canDirectContact).toBe(1);
  1238. expect(data.personInfo.isInBlackList).toBe(0);
  1239. expect(data.personInfo.jobStatus).toBe(1);
  1240. expect(data.personInfo.specificDisability).toBe('左腿截肢,右腿行动不便,需要轮椅');
  1241. // 验证日期字段
  1242. expect(data.personInfo.idValidDate).toBeDefined();
  1243. expect(data.personInfo.disabilityValidDate).toBeDefined();
  1244. if (data.personInfo.idValidDate) {
  1245. expect(new Date(data.personInfo.idValidDate).toISOString().split('T')[0]).toBe('2045-11-30');
  1246. }
  1247. if (data.personInfo.disabilityValidDate) {
  1248. expect(new Date(data.personInfo.disabilityValidDate).toISOString().split('T')[0]).toBe('2045-11-30');
  1249. }
  1250. expect(data.bankCards).toHaveLength(1);
  1251. expect(data.photos).toHaveLength(1);
  1252. expect(data.remarks).toHaveLength(1);
  1253. expect(data.visits).toHaveLength(1);
  1254. // 验证文件集成
  1255. expect(data.photos[0].fileId).toBe(testFile.id);
  1256. }
  1257. });
  1258. it('应该验证文件ID的有效性', async () => {
  1259. const createData = {
  1260. personInfo: {
  1261. name: '文件验证测试',
  1262. gender: '女',
  1263. idCard: '110101199001011246',
  1264. disabilityId: 'D123456766',
  1265. disabilityType: '视力残疾',
  1266. disabilityLevel: '二级',
  1267. idAddress: '北京市房山区',
  1268. phone: '13000130006',
  1269. province: '北京市',
  1270. city: '北京市',
  1271. // 新增字段
  1272. canDirectContact: 0,
  1273. isInBlackList: 1,
  1274. jobStatus: 2,
  1275. // 日期字段
  1276. idValidDate: new Date('2036-07-25'),
  1277. disabilityValidDate: new Date('2036-07-25')
  1278. },
  1279. photos: [
  1280. {
  1281. photoType: '身份证照片',
  1282. fileId: 99999 // 不存在的文件ID
  1283. }
  1284. ]
  1285. };
  1286. const response = await client.createAggregatedDisabledPerson.$post({
  1287. json: createData
  1288. }, {
  1289. headers: {
  1290. 'Authorization': `Bearer ${testToken}`
  1291. }
  1292. });
  1293. expect(response.status).toBe(400); // 应该返回400,因为文件ID无效
  1294. });
  1295. });
  1296. describe('GET /getAggregatedDisabledPerson/{personId}', () => {
  1297. it('应该成功获取聚合残疾人信息', async () => {
  1298. // 先创建一个完整的残疾人数据(包含所有关联数据)
  1299. const dataSource = await IntegrationTestDatabase.getDataSource();
  1300. // 创建残疾人
  1301. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  1302. const person = disabledPersonRepository.create({
  1303. name: '聚合查询测试',
  1304. gender: '男',
  1305. idCard: '110101199001011247',
  1306. disabilityId: 'D123456765',
  1307. disabilityType: '肢体残疾',
  1308. disabilityLevel: '一级',
  1309. idAddress: '北京市门头沟区',
  1310. phone: '13000130007',
  1311. province: '北京市',
  1312. city: '北京市'
  1313. });
  1314. await disabledPersonRepository.save(person);
  1315. // 创建银行名称用于测试
  1316. const bankNameRepository = dataSource.getRepository(BankName);
  1317. const testBankName = bankNameRepository.create({
  1318. name: '测试银行',
  1319. code: 'TEST',
  1320. status: 1
  1321. });
  1322. await bankNameRepository.save(testBankName);
  1323. // 创建银行卡
  1324. const bankCardRepository = dataSource.getRepository(DisabledBankCard);
  1325. const bankCard = bankCardRepository.create({
  1326. personId: person.id,
  1327. subBankName: '北京分行',
  1328. bankNameId: testBankName.id,
  1329. cardNumber: '6227001234567890123',
  1330. cardholderName: '聚合查询测试',
  1331. cardType: '储蓄卡',
  1332. fileId: testFile.id,
  1333. isDefault: 0
  1334. });
  1335. await bankCardRepository.save(bankCard);
  1336. // 创建照片(使用测试文件)
  1337. const photoRepository = dataSource.getRepository(DisabledPhoto);
  1338. const photo = photoRepository.create({
  1339. personId: person.id,
  1340. photoType: '身份证照片',
  1341. fileId: testFile.id
  1342. });
  1343. await photoRepository.save(photo);
  1344. // 创建备注
  1345. const remarkRepository = dataSource.getRepository(DisabledRemark);
  1346. const remark = remarkRepository.create({
  1347. personId: person.id,
  1348. remarkContent: '目前无工作,需要就业帮助',
  1349. operatorId: 1
  1350. });
  1351. await remarkRepository.save(remark);
  1352. // 创建回访记录
  1353. const visitRepository = dataSource.getRepository(DisabledVisit);
  1354. const visit = visitRepository.create({
  1355. personId: person.id,
  1356. visitDate: new Date('2025-12-01T14:30:00Z'),
  1357. visitType: '上门回访',
  1358. visitContent: '了解就业需求',
  1359. visitorId: 2
  1360. });
  1361. await visitRepository.save(visit);
  1362. const response = await client.getAggregatedDisabledPerson[':id'].$get({
  1363. param: {
  1364. id: person.id
  1365. }
  1366. }, {
  1367. headers: {
  1368. 'Authorization': `Bearer ${testToken}`
  1369. }
  1370. });
  1371. // 调试:打印响应状态和错误信息
  1372. console.debug('响应状态:', response.status);
  1373. if (response.status !== 200) {
  1374. const errorText = await response.text();
  1375. console.debug('错误响应:', errorText);
  1376. }
  1377. expect(response.status).toBe(200);
  1378. if (response.status === 200) {
  1379. const data = await response.json();
  1380. expect(data).not.toBeNull();
  1381. expect(data!.personInfo.name).toBe('聚合查询测试');
  1382. expect(data!.bankCards).toHaveLength(1);
  1383. expect(data!.photos).toHaveLength(1);
  1384. expect(data!.remarks).toHaveLength(1);
  1385. expect(data!.visits).toHaveLength(1);
  1386. // 验证文件数据完整性
  1387. expect(data!.photos[0].fileId).toBe(testFile.id);
  1388. }
  1389. });
  1390. it('应该处理不存在的残疾人ID', async () => {
  1391. const response = await client.getAggregatedDisabledPerson[':id'].$get({
  1392. param: {
  1393. id: 99999 // 不存在的ID
  1394. }
  1395. }, {
  1396. headers: {
  1397. 'Authorization': `Bearer ${testToken}`
  1398. }
  1399. });
  1400. expect(response.status).toBe(404);
  1401. });
  1402. });
  1403. describe('认证测试', () => {
  1404. it('应该验证所有端点需要认证', async () => {
  1405. // 测试没有token的情况
  1406. const response = await client.createDisabledPerson.$post({
  1407. json: {
  1408. name: '测试人员',
  1409. gender: '男',
  1410. idCard: '110101199001011235',
  1411. disabilityId: 'D123456789',
  1412. disabilityType: '视力残疾',
  1413. disabilityLevel: '一级',
  1414. idAddress: '北京市东城区',
  1415. phone: '13800138000',
  1416. province: '北京市',
  1417. city: '北京市'
  1418. }
  1419. });
  1420. expect(response.status).toBe(401);
  1421. });
  1422. it('应该验证无效token', async () => {
  1423. const response = await client.createDisabledPerson.$post({
  1424. json: {
  1425. name: '测试人员',
  1426. gender: '男',
  1427. idCard: '110101199001011236',
  1428. disabilityId: 'D123456790',
  1429. disabilityType: '视力残疾',
  1430. disabilityLevel: '一级',
  1431. idAddress: '北京市东城区',
  1432. phone: '13800138001',
  1433. province: '北京市',
  1434. city: '北京市'
  1435. }
  1436. }, {
  1437. headers: {
  1438. 'Authorization': 'Bearer invalid_token'
  1439. }
  1440. });
  1441. expect(response.status).toBe(401);
  1442. });
  1443. });
  1444. });