disability.integration.test.ts 48 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571
  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. bankNameId: bankName1.id,
  834. cardNumber: '6222001234567890123',
  835. cardholderName: '工商银行用户',
  836. cardType: '储蓄卡',
  837. fileId: testFile.id,
  838. isDefault: 1
  839. });
  840. await bankCardRepository.save(bankCard1);
  841. // 创建人员2 - 有建设银行卡
  842. const person2 = disabledPersonRepository.create({
  843. name: '建设银行用户',
  844. gender: '女',
  845. idCard: '110101199001011392',
  846. disabilityId: 'D123456892',
  847. disabilityType: '肢体残疾',
  848. disabilityLevel: '二级',
  849. idAddress: '北京市测试区',
  850. phone: '1380013892',
  851. province: '北京市',
  852. city: '北京市'
  853. });
  854. await disabledPersonRepository.save(person2);
  855. // 为人员2创建建设银行卡
  856. const bankCard2 = bankCardRepository.create({
  857. personId: person2.id,
  858. subBankName: '北京分行',
  859. bankNameId: bankName2.id,
  860. cardNumber: '6227001234567890123',
  861. cardholderName: '建设银行用户',
  862. cardType: '信用卡',
  863. fileId: testFile.id,
  864. isDefault: 1
  865. });
  866. await bankCardRepository.save(bankCard2);
  867. // 测试工商银行筛选
  868. const response = await client.getAllDisabledPersons.$get({
  869. query: {
  870. bankNameId: bankName1.id,
  871. skip: 0,
  872. take: 10
  873. }
  874. }, {
  875. headers: {
  876. 'Authorization': `Bearer ${testToken}`
  877. }
  878. });
  879. expect(response.status).toBe(200);
  880. if (response.status === 200) {
  881. const data = await response.json();
  882. expect(data.data).toHaveLength(1);
  883. expect(data.data[0].name).toBe('工商银行用户');
  884. }
  885. });
  886. it('应该支持银行卡类型筛选', async () => {
  887. // 创建测试数据
  888. const dataSource = await IntegrationTestDatabase.getDataSource();
  889. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  890. const bankNameRepository = dataSource.getRepository(BankName);
  891. const bankCardRepository = dataSource.getRepository(DisabledBankCard);
  892. // 创建银行名称
  893. const bankName1 = bankNameRepository.create({
  894. name: '中国工商银行',
  895. code: 'ICBC',
  896. status: 1
  897. });
  898. await bankNameRepository.save(bankName1);
  899. const bankName2 = bankNameRepository.create({
  900. name: '中国建设银行',
  901. code: 'CCB',
  902. status: 1
  903. });
  904. await bankNameRepository.save(bankName2);
  905. // 创建人员1 - 有储蓄卡
  906. const person1 = disabledPersonRepository.create({
  907. name: '储蓄卡用户',
  908. gender: '男',
  909. idCard: '110101199001011393',
  910. disabilityId: 'D123456893',
  911. disabilityType: '视力残疾',
  912. disabilityLevel: '一级',
  913. idAddress: '北京市测试区',
  914. phone: '1380013893',
  915. province: '北京市',
  916. city: '北京市'
  917. });
  918. await disabledPersonRepository.save(person1);
  919. // 为人员1创建储蓄卡
  920. const bankCard1 = bankCardRepository.create({
  921. personId: person1.id,
  922. subBankName: '北京分行',
  923. bankNameId: bankName1.id,
  924. cardNumber: '6222001234567890124',
  925. cardholderName: '储蓄卡用户',
  926. cardType: '储蓄卡',
  927. fileId: testFile.id,
  928. isDefault: 1
  929. });
  930. await bankCardRepository.save(bankCard1);
  931. // 创建人员2 - 有信用卡
  932. const person2 = disabledPersonRepository.create({
  933. name: '信用卡用户',
  934. gender: '女',
  935. idCard: '110101199001011394',
  936. disabilityId: 'D123456894',
  937. disabilityType: '肢体残疾',
  938. disabilityLevel: '二级',
  939. idAddress: '北京市测试区',
  940. phone: '1380013894',
  941. province: '北京市',
  942. city: '北京市'
  943. });
  944. await disabledPersonRepository.save(person2);
  945. // 为人员2创建信用卡
  946. const bankCard2 = bankCardRepository.create({
  947. personId: person2.id,
  948. subBankName: '北京分行',
  949. bankNameId: bankName2.id,
  950. cardNumber: '6227001234567890124',
  951. cardholderName: '信用卡用户',
  952. cardType: '信用卡',
  953. fileId: testFile.id,
  954. isDefault: 1
  955. });
  956. await bankCardRepository.save(bankCard2);
  957. // 测试储蓄卡筛选
  958. const response = await client.getAllDisabledPersons.$get({
  959. query: {
  960. cardType: '储蓄卡',
  961. skip: 0,
  962. take: 10
  963. }
  964. }, {
  965. headers: {
  966. 'Authorization': `Bearer ${testToken}`
  967. }
  968. });
  969. expect(response.status).toBe(200);
  970. if (response.status === 200) {
  971. const data = await response.json();
  972. expect(data.data).toHaveLength(1);
  973. expect(data.data[0].name).toBe('储蓄卡用户');
  974. }
  975. });
  976. });
  977. describe('GET /searchDisabledPersons', () => {
  978. it('应该成功按姓名搜索残疾人', async () => {
  979. // 创建测试数据
  980. const dataSource = await IntegrationTestDatabase.getDataSource();
  981. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  982. const person1 = disabledPersonRepository.create({
  983. name: '张三',
  984. gender: '男',
  985. idCard: '110101199001011241',
  986. disabilityId: 'D123456771',
  987. disabilityType: '肢体残疾',
  988. disabilityLevel: '一级',
  989. idAddress: '北京市昌平区',
  990. phone: '13000130001',
  991. province: '北京市',
  992. city: '北京市'
  993. });
  994. await disabledPersonRepository.save(person1);
  995. const person2 = disabledPersonRepository.create({
  996. name: '李四',
  997. gender: '女',
  998. idCard: '110101199001011242',
  999. disabilityId: 'D123456770',
  1000. disabilityType: '视力残疾',
  1001. disabilityLevel: '二级',
  1002. idAddress: '北京市平谷区',
  1003. phone: '13000130002',
  1004. province: '北京市',
  1005. city: '北京市'
  1006. });
  1007. await disabledPersonRepository.save(person2);
  1008. const response = await client.searchDisabledPersons.$get({
  1009. query: {
  1010. keyword: '张三',
  1011. skip: 0,
  1012. take: 10
  1013. }
  1014. }, {
  1015. headers: {
  1016. 'Authorization': `Bearer ${testToken}`
  1017. }
  1018. });
  1019. expect(response.status).toBe(200);
  1020. if (response.status === 200) {
  1021. const data = await response.json();
  1022. expect(data.data).toHaveLength(1);
  1023. expect(data.data[0].name).toBe('张三');
  1024. }
  1025. });
  1026. it('应该验证搜索关键词不能为空', async () => {
  1027. const response = await client.searchDisabledPersons.$get({
  1028. query: {
  1029. keyword: '', // 空关键词
  1030. skip: 0,
  1031. take: 10
  1032. }
  1033. }, {
  1034. headers: {
  1035. 'Authorization': `Bearer ${testToken}`
  1036. }
  1037. });
  1038. expect(response.status).toBe(400);
  1039. });
  1040. });
  1041. describe('GET /getDisabledPerson/{id}', () => {
  1042. it('应该成功获取单个残疾人详情', async () => {
  1043. // 先创建一个残疾人
  1044. const dataSource = await IntegrationTestDatabase.getDataSource();
  1045. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  1046. const person = disabledPersonRepository.create({
  1047. name: '测试人员详情',
  1048. gender: '男',
  1049. idCard: '110101199001011243',
  1050. disabilityId: 'D123456769',
  1051. disabilityType: '肢体残疾',
  1052. disabilityLevel: '一级',
  1053. idAddress: '北京市怀柔区',
  1054. phone: '13000130003',
  1055. province: '北京市',
  1056. city: '北京市',
  1057. canDirectContact: 1,
  1058. isMarried: 1
  1059. });
  1060. await disabledPersonRepository.save(person);
  1061. const response = await client.getDisabledPerson[':id'].$get({
  1062. param: {
  1063. id: person.id
  1064. }
  1065. }, {
  1066. headers: {
  1067. 'Authorization': `Bearer ${testToken}`
  1068. }
  1069. });
  1070. expect(response.status).toBe(200);
  1071. if (response.status === 200) {
  1072. const data = await response.json();
  1073. expect(data?.name).toBe('测试人员详情');
  1074. expect(data?.canDirectContact).toBe(1);
  1075. }
  1076. });
  1077. it('应该处理不存在的残疾人ID', async () => {
  1078. const response = await client.getDisabledPerson[':id'].$get({
  1079. param: {
  1080. id: 99999 // 不存在的ID
  1081. }
  1082. }, {
  1083. headers: {
  1084. 'Authorization': `Bearer ${testToken}`
  1085. }
  1086. });
  1087. expect(response.status).toBe(200); // 返回200,但数据为null
  1088. if (response.status === 200) {
  1089. const data = await response.json();
  1090. expect(data).toBeNull();
  1091. }
  1092. });
  1093. });
  1094. describe('GET /getDisabledPersonByIdCard', () => {
  1095. it('应该成功根据身份证号查询残疾人', async () => {
  1096. // 先创建一个残疾人
  1097. const dataSource = await IntegrationTestDatabase.getDataSource();
  1098. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  1099. const person = disabledPersonRepository.create({
  1100. name: '身份证查询测试',
  1101. gender: '女',
  1102. idCard: '110101199001011244',
  1103. disabilityId: 'D123456768',
  1104. disabilityType: '听力残疾',
  1105. disabilityLevel: '三级',
  1106. idAddress: '北京市密云区',
  1107. phone: '13000130004',
  1108. province: '北京市',
  1109. city: '北京市'
  1110. });
  1111. await disabledPersonRepository.save(person);
  1112. const response = await client.findByIdCard[':idCard'].$get({
  1113. param: {
  1114. idCard: '110101199001011244'
  1115. }
  1116. }, {
  1117. headers: {
  1118. 'Authorization': `Bearer ${testToken}`
  1119. }
  1120. });
  1121. expect(response.status).toBe(200);
  1122. if (response.status === 200) {
  1123. const data = await response.json();
  1124. expect(data?.name).toBe('身份证查询测试');
  1125. expect(data?.idCard).toBe('110101199001011244');
  1126. }
  1127. });
  1128. it('应该处理不存在的身份证号', async () => {
  1129. const response = await client.findByIdCard[':idCard'].$get({
  1130. param: {
  1131. idCard: '999999999999999999' // 不存在的身份证号
  1132. }
  1133. }, {
  1134. headers: {
  1135. 'Authorization': `Bearer ${testToken}`
  1136. }
  1137. });
  1138. expect(response.status).toBe(200); // 返回200,但数据为null
  1139. if (response.status === 200) {
  1140. const data = await response.json();
  1141. expect(data).toBeNull();
  1142. }
  1143. });
  1144. });
  1145. describe('POST /createAggregatedDisabledPerson', () => {
  1146. it('应该成功创建聚合残疾人信息(包含所有关联数据)', async () => {
  1147. const createData = {
  1148. personInfo: {
  1149. name: '聚合创建测试',
  1150. gender: '男',
  1151. idCard: '110101199001011245',
  1152. disabilityId: 'D123456767',
  1153. disabilityType: '肢体残疾',
  1154. disabilityLevel: '一级',
  1155. idAddress: '北京市延庆区',
  1156. phone: '13000130005',
  1157. province: '北京市',
  1158. city: '北京市',
  1159. // 新增字段
  1160. canDirectContact: 1,
  1161. isInBlackList: 0,
  1162. jobStatus: 1,
  1163. specificDisability: '左腿截肢,右腿行动不便,需要轮椅',
  1164. // 日期字段
  1165. idValidDate: new Date('2045-11-30'),
  1166. disabilityValidDate: new Date('2045-11-30')
  1167. },
  1168. bankCards: [
  1169. {
  1170. subBankName: '北京分行',
  1171. bankNameId: 1, // 假设银行名称ID为1
  1172. cardNumber: '6222021234567890123',
  1173. cardholderName: '聚合创建测试',
  1174. cardType: '储蓄卡',
  1175. fileId: testFile.id,
  1176. isDefault: 0
  1177. }
  1178. ],
  1179. photos: [
  1180. {
  1181. photoType: '身份证照片',
  1182. fileId: testFile.id // 使用测试文件ID
  1183. }
  1184. ],
  1185. remarks: [
  1186. {
  1187. remarkContent: '家庭经济困难,需要帮助',
  1188. operatorId: 1
  1189. }
  1190. ],
  1191. visits: [
  1192. {
  1193. visitDate: '2025-12-02T10:00:00Z',
  1194. visitType: '电话回访',
  1195. visitContent: '初次回访,了解基本情况',
  1196. visitorId: 1
  1197. }
  1198. ]
  1199. };
  1200. const response = await client.createAggregatedDisabledPerson.$post({
  1201. json: createData
  1202. }, {
  1203. headers: {
  1204. 'Authorization': `Bearer ${testToken}`
  1205. }
  1206. });
  1207. expect(response.status).toBe(200);
  1208. if (response.status === 200) {
  1209. const data = await response.json();
  1210. expect(data.personInfo.name).toBe('聚合创建测试');
  1211. // 验证新增字段
  1212. expect(data.personInfo.canDirectContact).toBe(1);
  1213. expect(data.personInfo.isInBlackList).toBe(0);
  1214. expect(data.personInfo.jobStatus).toBe(1);
  1215. expect(data.personInfo.specificDisability).toBe('左腿截肢,右腿行动不便,需要轮椅');
  1216. // 验证日期字段
  1217. expect(data.personInfo.idValidDate).toBeDefined();
  1218. expect(data.personInfo.disabilityValidDate).toBeDefined();
  1219. if (data.personInfo.idValidDate) {
  1220. expect(new Date(data.personInfo.idValidDate).toISOString().split('T')[0]).toBe('2045-11-30');
  1221. }
  1222. if (data.personInfo.disabilityValidDate) {
  1223. expect(new Date(data.personInfo.disabilityValidDate).toISOString().split('T')[0]).toBe('2045-11-30');
  1224. }
  1225. expect(data.bankCards).toHaveLength(1);
  1226. expect(data.photos).toHaveLength(1);
  1227. expect(data.remarks).toHaveLength(1);
  1228. expect(data.visits).toHaveLength(1);
  1229. // 验证文件集成
  1230. expect(data.photos[0].fileId).toBe(testFile.id);
  1231. }
  1232. });
  1233. it('应该验证文件ID的有效性', async () => {
  1234. const createData = {
  1235. personInfo: {
  1236. name: '文件验证测试',
  1237. gender: '女',
  1238. idCard: '110101199001011246',
  1239. disabilityId: 'D123456766',
  1240. disabilityType: '视力残疾',
  1241. disabilityLevel: '二级',
  1242. idAddress: '北京市房山区',
  1243. phone: '13000130006',
  1244. province: '北京市',
  1245. city: '北京市',
  1246. // 新增字段
  1247. canDirectContact: 0,
  1248. isInBlackList: 1,
  1249. jobStatus: 2,
  1250. // 日期字段
  1251. idValidDate: new Date('2036-07-25'),
  1252. disabilityValidDate: new Date('2036-07-25')
  1253. },
  1254. photos: [
  1255. {
  1256. photoType: '身份证照片',
  1257. fileId: 99999 // 不存在的文件ID
  1258. }
  1259. ]
  1260. };
  1261. const response = await client.createAggregatedDisabledPerson.$post({
  1262. json: createData
  1263. }, {
  1264. headers: {
  1265. 'Authorization': `Bearer ${testToken}`
  1266. }
  1267. });
  1268. expect(response.status).toBe(400); // 应该返回400,因为文件ID无效
  1269. });
  1270. });
  1271. describe('GET /getAggregatedDisabledPerson/{personId}', () => {
  1272. it('应该成功获取聚合残疾人信息', async () => {
  1273. // 先创建一个完整的残疾人数据(包含所有关联数据)
  1274. const dataSource = await IntegrationTestDatabase.getDataSource();
  1275. // 创建残疾人
  1276. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  1277. const person = disabledPersonRepository.create({
  1278. name: '聚合查询测试',
  1279. gender: '男',
  1280. idCard: '110101199001011247',
  1281. disabilityId: 'D123456765',
  1282. disabilityType: '肢体残疾',
  1283. disabilityLevel: '一级',
  1284. idAddress: '北京市门头沟区',
  1285. phone: '13000130007',
  1286. province: '北京市',
  1287. city: '北京市'
  1288. });
  1289. await disabledPersonRepository.save(person);
  1290. // 创建银行卡
  1291. const bankCardRepository = dataSource.getRepository(DisabledBankCard);
  1292. const bankCard = bankCardRepository.create({
  1293. personId: person.id,
  1294. subBankName: '北京分行',
  1295. bankNameId: 1, // 假设银行名称ID为1
  1296. cardNumber: '6227001234567890123',
  1297. cardholderName: '聚合查询测试',
  1298. cardType: '储蓄卡',
  1299. fileId: testFile.id,
  1300. isDefault: 0
  1301. });
  1302. await bankCardRepository.save(bankCard);
  1303. // 创建照片(使用测试文件)
  1304. const photoRepository = dataSource.getRepository(DisabledPhoto);
  1305. const photo = photoRepository.create({
  1306. personId: person.id,
  1307. photoType: '身份证照片',
  1308. fileId: testFile.id
  1309. });
  1310. await photoRepository.save(photo);
  1311. // 创建备注
  1312. const remarkRepository = dataSource.getRepository(DisabledRemark);
  1313. const remark = remarkRepository.create({
  1314. personId: person.id,
  1315. remarkContent: '目前无工作,需要就业帮助',
  1316. operatorId: 1
  1317. });
  1318. await remarkRepository.save(remark);
  1319. // 创建回访记录
  1320. const visitRepository = dataSource.getRepository(DisabledVisit);
  1321. const visit = visitRepository.create({
  1322. personId: person.id,
  1323. visitDate: new Date('2025-12-01T14:30:00Z'),
  1324. visitType: '上门回访',
  1325. visitContent: '了解就业需求',
  1326. visitorId: 2
  1327. });
  1328. await visitRepository.save(visit);
  1329. const response = await client.getAggregatedDisabledPerson[':id'].$get({
  1330. param: {
  1331. id: person.id
  1332. }
  1333. }, {
  1334. headers: {
  1335. 'Authorization': `Bearer ${testToken}`
  1336. }
  1337. });
  1338. // 调试:打印响应状态和错误信息
  1339. console.debug('响应状态:', response.status);
  1340. if (response.status !== 200) {
  1341. const errorText = await response.text();
  1342. console.debug('错误响应:', errorText);
  1343. }
  1344. expect(response.status).toBe(200);
  1345. if (response.status === 200) {
  1346. const data = await response.json();
  1347. expect(data).not.toBeNull();
  1348. expect(data!.personInfo.name).toBe('聚合查询测试');
  1349. expect(data!.bankCards).toHaveLength(1);
  1350. expect(data!.photos).toHaveLength(1);
  1351. expect(data!.remarks).toHaveLength(1);
  1352. expect(data!.visits).toHaveLength(1);
  1353. // 验证文件数据完整性
  1354. expect(data!.photos[0].fileId).toBe(testFile.id);
  1355. }
  1356. });
  1357. it('应该处理不存在的残疾人ID', async () => {
  1358. const response = await client.getAggregatedDisabledPerson[':id'].$get({
  1359. param: {
  1360. id: 99999 // 不存在的ID
  1361. }
  1362. }, {
  1363. headers: {
  1364. 'Authorization': `Bearer ${testToken}`
  1365. }
  1366. });
  1367. expect(response.status).toBe(404);
  1368. });
  1369. });
  1370. describe('认证测试', () => {
  1371. it('应该验证所有端点需要认证', async () => {
  1372. // 测试没有token的情况
  1373. const response = await client.createDisabledPerson.$post({
  1374. json: {
  1375. name: '测试人员',
  1376. gender: '男',
  1377. idCard: '110101199001011235',
  1378. disabilityId: 'D123456789',
  1379. disabilityType: '视力残疾',
  1380. disabilityLevel: '一级',
  1381. idAddress: '北京市东城区',
  1382. phone: '13800138000',
  1383. province: '北京市',
  1384. city: '北京市'
  1385. }
  1386. });
  1387. expect(response.status).toBe(401);
  1388. });
  1389. it('应该验证无效token', async () => {
  1390. const response = await client.createDisabledPerson.$post({
  1391. json: {
  1392. name: '测试人员',
  1393. gender: '男',
  1394. idCard: '110101199001011236',
  1395. disabilityId: 'D123456790',
  1396. disabilityType: '视力残疾',
  1397. disabilityLevel: '一级',
  1398. idAddress: '北京市东城区',
  1399. phone: '13800138001',
  1400. province: '北京市',
  1401. city: '北京市'
  1402. }
  1403. }, {
  1404. headers: {
  1405. 'Authorization': 'Bearer invalid_token'
  1406. }
  1407. });
  1408. expect(response.status).toBe(401);
  1409. });
  1410. });
  1411. });