disability.integration.test.ts 49 KB

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