disability.integration.test.ts 48 KB

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