disability.integration.test.ts 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987
  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 disabledPersonRoutes from '../../src/routes/disabled-person.routes';
  8. import { DisabledPerson } from '../../src/entities/disabled-person.entity';
  9. import { DisabledBankCard } from '../../src/entities/disabled-bank-card.entity';
  10. import { DisabledPhoto } from '../../src/entities/disabled-photo.entity';
  11. import { DisabledRemark } from '../../src/entities/disabled-remark.entity';
  12. import { DisabledVisit } from '../../src/entities/disabled-visit.entity';
  13. // 设置集成测试钩子 - 包含所有相关实体
  14. setupIntegrationDatabaseHooksWithEntities([
  15. UserEntity,
  16. Role,
  17. File,
  18. DisabledPerson,
  19. DisabledBankCard,
  20. DisabledPhoto,
  21. DisabledRemark,
  22. DisabledVisit
  23. ])
  24. describe('残疾人管理API集成测试', () => {
  25. let client: ReturnType<typeof testClient<typeof disabledPersonRoutes>>;
  26. let testToken: string;
  27. let testUser: UserEntity;
  28. let testFile: File;
  29. beforeEach(async () => {
  30. // 创建测试客户端
  31. client = testClient(disabledPersonRoutes);
  32. // 获取数据源
  33. const dataSource = await IntegrationTestDatabase.getDataSource();
  34. // 创建测试用户
  35. const userRepository = dataSource.getRepository(UserEntity);
  36. testUser = userRepository.create({
  37. username: `test_user_${Date.now()}`,
  38. password: 'test_password',
  39. nickname: '测试用户',
  40. registrationSource: 'web'
  41. });
  42. await userRepository.save(testUser);
  43. // 创建测试文件(用于照片集成测试)
  44. const fileRepository = dataSource.getRepository(File);
  45. testFile = fileRepository.create({
  46. name: 'test_photo.jpg',
  47. path: 'test_photo.jpg',
  48. type: 'image/jpeg',
  49. size: 1024,
  50. uploadUserId: testUser.id,
  51. uploadTime: new Date()
  52. });
  53. await fileRepository.save(testFile);
  54. // 生成测试用户的token
  55. testToken = JWTUtil.generateToken({
  56. id: testUser.id,
  57. username: testUser.username,
  58. roles: [{name:'user'}]
  59. });
  60. });
  61. describe('POST /createDisabledPerson', () => {
  62. it('应该成功创建残疾人基本信息', async () => {
  63. const createData = {
  64. name: '张三',
  65. gender: '男',
  66. idCard: '110101199001011234',
  67. disabilityId: 'D123456789',
  68. disabilityType: '肢体残疾',
  69. disabilityLevel: '一级',
  70. idAddress: '北京市东城区',
  71. phone: '13800138000',
  72. province: '北京市',
  73. city: '北京市',
  74. // 新增字段
  75. canDirectContact: 1,
  76. isInBlackList: 0,
  77. jobStatus: 1,
  78. // 日期字段
  79. idValidDate: new Date('2030-12-31'),
  80. disabilityValidDate: new Date('2030-12-31')
  81. };
  82. const response = await client.createDisabledPerson.$post({
  83. json: createData
  84. }, {
  85. headers: {
  86. 'Authorization': `Bearer ${testToken}`
  87. }
  88. });
  89. expect(response.status).toBe(200);
  90. if (response.status === 200) {
  91. const data = await response.json();
  92. expect(data.name).toBe(createData.name);
  93. expect(data.idCard).toBe(createData.idCard);
  94. expect(data.disabilityId).toBe(createData.disabilityId);
  95. // 验证新增字段
  96. expect(data.canDirectContact).toBe(createData.canDirectContact);
  97. expect(data.isInBlackList).toBe(createData.isInBlackList);
  98. expect(data.jobStatus).toBe(createData.jobStatus);
  99. // 验证日期字段
  100. expect(data.idValidDate).toBeDefined();
  101. expect(data.disabilityValidDate).toBeDefined();
  102. if (data.idValidDate) {
  103. expect(new Date(data.idValidDate).toISOString().split('T')[0]).toBe('2030-12-31');
  104. }
  105. if (data.disabilityValidDate) {
  106. expect(new Date(data.disabilityValidDate).toISOString().split('T')[0]).toBe('2030-12-31');
  107. }
  108. }
  109. });
  110. it('应该验证身份证号唯一性', async () => {
  111. // 先创建一个残疾人
  112. const dataSource = await IntegrationTestDatabase.getDataSource();
  113. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  114. const existingPerson = disabledPersonRepository.create({
  115. name: '李四',
  116. gender: '女',
  117. idCard: '110101199001011235',
  118. disabilityId: 'D123456788',
  119. disabilityType: '视力残疾',
  120. disabilityLevel: '二级',
  121. idAddress: '北京市西城区',
  122. phone: '13900139000',
  123. province: '北京市',
  124. city: '北京市',
  125. // 新增字段
  126. canDirectContact: 0,
  127. isInBlackList: 0,
  128. jobStatus: 2,
  129. // 日期字段
  130. idValidDate: new Date('2035-05-15'),
  131. disabilityValidDate: new Date('2035-05-15')
  132. });
  133. await disabledPersonRepository.save(existingPerson);
  134. // 尝试创建相同身份证号的残疾人
  135. const createData = {
  136. name: '王五',
  137. gender: '男',
  138. idCard: '110101199001011235', // 重复的身份证号
  139. disabilityId: 'D123456777',
  140. disabilityType: '听力残疾',
  141. disabilityLevel: '三级',
  142. idAddress: '北京市朝阳区',
  143. phone: '13700137000',
  144. province: '北京市',
  145. city: '北京市',
  146. // 新增字段
  147. canDirectContact: 1,
  148. isInBlackList: 1,
  149. jobStatus: 3,
  150. // 日期字段
  151. idValidDate: new Date('2043-08-20'),
  152. disabilityValidDate: new Date('2043-08-20')
  153. };
  154. const response = await client.createDisabledPerson.$post({
  155. json: createData
  156. }, {
  157. headers: {
  158. 'Authorization': `Bearer ${testToken}`
  159. }
  160. });
  161. expect(response.status).toBe(400);
  162. });
  163. it('应该验证必填字段', async () => {
  164. const createData = {
  165. name: '', // 空字符串,应该验证失败
  166. gender: '男',
  167. idCard: '110101199001011236',
  168. disabilityId: 'D123456776',
  169. disabilityType: '肢体残疾',
  170. disabilityLevel: '一级',
  171. idAddress: '北京市海淀区',
  172. phone: '13600136000',
  173. province: '北京市',
  174. city: '北京市',
  175. // 新增字段(可选字段,不影响必填验证)
  176. canDirectContact: 1,
  177. isInBlackList: 0,
  178. jobStatus: 1,
  179. // 日期字段(可选字段,不影响必填验证)
  180. idValidDate: new Date('2028-03-10'),
  181. disabilityValidDate: new Date('2028-03-10')
  182. };
  183. const response = await client.createDisabledPerson.$post({
  184. json: createData
  185. }, {
  186. headers: {
  187. 'Authorization': `Bearer ${testToken}`
  188. }
  189. });
  190. expect(response.status).toBe(400);
  191. });
  192. });
  193. describe('POST /deleteDisabledPerson', () => {
  194. it('应该成功删除残疾人', async () => {
  195. // 先创建一个残疾人
  196. const dataSource = await IntegrationTestDatabase.getDataSource();
  197. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  198. const person = disabledPersonRepository.create({
  199. name: '测试删除人员',
  200. gender: '男',
  201. idCard: '110101199001011237',
  202. disabilityId: 'D123456775',
  203. disabilityType: '肢体残疾',
  204. disabilityLevel: '一级',
  205. idAddress: '北京市石景山区',
  206. phone: '13500135000',
  207. province: '北京市',
  208. city: '北京市'
  209. });
  210. await disabledPersonRepository.save(person);
  211. const deleteData = {
  212. id: person.id
  213. };
  214. const response = await client.deleteDisabledPerson.$post({
  215. json: deleteData
  216. }, {
  217. headers: {
  218. 'Authorization': `Bearer ${testToken}`
  219. }
  220. });
  221. expect(response.status).toBe(200);
  222. if (response.status === 200) {
  223. const data = await response.json();
  224. expect(data.success).toBe(true);
  225. // 验证残疾人已被删除
  226. const deletedPerson = await disabledPersonRepository.findOne({ where: { id: person.id } });
  227. expect(deletedPerson).toBeNull();
  228. }
  229. });
  230. it('应该处理不存在的残疾人ID', async () => {
  231. const deleteData = {
  232. id: 99999 // 不存在的ID
  233. };
  234. const response = await client.deleteDisabledPerson.$post({
  235. json: deleteData
  236. }, {
  237. headers: {
  238. 'Authorization': `Bearer ${testToken}`
  239. }
  240. });
  241. expect(response.status).toBe(404);
  242. });
  243. });
  244. describe('POST /updateDisabledPerson', () => {
  245. it('应该成功更新残疾人信息', async () => {
  246. // 先创建一个残疾人
  247. const dataSource = await IntegrationTestDatabase.getDataSource();
  248. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  249. const person = disabledPersonRepository.create({
  250. name: '原始姓名',
  251. gender: '男',
  252. idCard: '110101199001011238',
  253. disabilityId: 'D123456774',
  254. disabilityType: '肢体残疾',
  255. disabilityLevel: '一级',
  256. idAddress: '北京市通州区',
  257. phone: '13400134000',
  258. province: '北京市',
  259. city: '北京市',
  260. // 新增字段初始值
  261. canDirectContact: 1,
  262. isInBlackList: 0,
  263. jobStatus: 1,
  264. // 日期字段初始值
  265. idValidDate: new Date('2023-01-01'),
  266. disabilityValidDate: new Date('2023-01-01')
  267. });
  268. await disabledPersonRepository.save(person);
  269. const updateData = {
  270. id: person.id,
  271. name: '更新后的姓名',
  272. gender: '女',
  273. phone: '13300133000',
  274. // 更新新增字段
  275. canDirectContact: 0,
  276. isInBlackList: 1,
  277. jobStatus: 1,
  278. // 更新日期字段
  279. idValidDate: new Date('2033-01-01'), // 更新有效期
  280. disabilityValidDate: new Date('2033-01-01') // 更新有效期
  281. };
  282. const response = await client.updateDisabledPerson.$post({
  283. json: updateData
  284. }, {
  285. headers: {
  286. 'Authorization': `Bearer ${testToken}`
  287. }
  288. });
  289. expect(response.status).toBe(200);
  290. if (response.status === 200) {
  291. const data = await response.json();
  292. expect(data.name).toBe(updateData.name);
  293. expect(data.gender).toBe(updateData.gender);
  294. expect(data.phone).toBe(updateData.phone);
  295. // 验证新增字段已更新
  296. expect(data.canDirectContact).toBe(updateData.canDirectContact);
  297. expect(data.isInBlackList).toBe(updateData.isInBlackList);
  298. expect(data.jobStatus).toBe(updateData.jobStatus);
  299. // 验证日期字段
  300. expect(data.idValidDate).toBeDefined();
  301. expect(data.disabilityValidDate).toBeDefined();
  302. if (data.idValidDate) {
  303. expect(new Date(data.idValidDate).toISOString().split('T')[0]).toBe('2033-01-01');
  304. }
  305. if (data.disabilityValidDate) {
  306. expect(new Date(data.disabilityValidDate).toISOString().split('T')[0]).toBe('2033-01-01');
  307. }
  308. }
  309. });
  310. it('应该验证身份证号唯一性(更新时)', async () => {
  311. // 创建两个残疾人
  312. const dataSource = await IntegrationTestDatabase.getDataSource();
  313. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  314. const person1 = disabledPersonRepository.create({
  315. name: '人员A',
  316. gender: '男',
  317. idCard: '110101199001011239',
  318. disabilityId: 'D123456773',
  319. disabilityType: '肢体残疾',
  320. disabilityLevel: '一级',
  321. idAddress: '北京市顺义区',
  322. phone: '13200132000',
  323. province: '北京市',
  324. city: '北京市',
  325. // 新增字段
  326. canDirectContact: 1,
  327. isInBlackList: 0,
  328. jobStatus: 1,
  329. // 日期字段
  330. idValidDate: new Date('2028-06-15'),
  331. disabilityValidDate: new Date('2028-06-15')
  332. });
  333. await disabledPersonRepository.save(person1);
  334. const person2 = disabledPersonRepository.create({
  335. name: '人员B',
  336. gender: '女',
  337. idCard: '110101199001011240',
  338. disabilityId: 'D123456772',
  339. disabilityType: '视力残疾',
  340. disabilityLevel: '二级',
  341. idAddress: '北京市大兴区',
  342. phone: '13100131000',
  343. province: '北京市',
  344. city: '北京市',
  345. // 新增字段
  346. canDirectContact: 0,
  347. isInBlackList: 1,
  348. jobStatus: 2,
  349. // 日期字段
  350. idValidDate: new Date('2034-09-20'),
  351. disabilityValidDate: new Date('2034-09-20')
  352. });
  353. await disabledPersonRepository.save(person2);
  354. // 尝试将人员2的身份证号改为人员1的身份证号
  355. const updateData = {
  356. id: person2.id,
  357. idCard: '110101199001011239' // 重复的身份证号
  358. };
  359. const response = await client.updateDisabledPerson.$post({
  360. json: updateData
  361. }, {
  362. headers: {
  363. 'Authorization': `Bearer ${testToken}`
  364. }
  365. });
  366. expect(response.status).toBe(400);
  367. });
  368. it('应该处理不存在的残疾人', async () => {
  369. const updateData = {
  370. id: 99999, // 不存在的ID
  371. name: '新姓名'
  372. };
  373. const response = await client.updateDisabledPerson.$post({
  374. json: updateData
  375. }, {
  376. headers: {
  377. 'Authorization': `Bearer ${testToken}`
  378. }
  379. });
  380. expect(response.status).toBe(404);
  381. });
  382. });
  383. describe('GET /getAllDisabledPersons', () => {
  384. it('应该成功获取残疾人列表(分页)', async () => {
  385. // 创建一些测试数据
  386. const dataSource = await IntegrationTestDatabase.getDataSource();
  387. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  388. for (let i = 1; i <= 5; i++) {
  389. const person = disabledPersonRepository.create({
  390. name: `残疾人${i}`,
  391. gender: i % 2 === 0 ? '女' : '男',
  392. idCard: `1101011990010112${40 + i}`,
  393. disabilityId: `D1234567${70 + i}`,
  394. disabilityType: '肢体残疾',
  395. disabilityLevel: '一级',
  396. idAddress: `北京市测试区${i}`,
  397. phone: `138001380${i}`,
  398. province: '北京市',
  399. city: '北京市'
  400. });
  401. await disabledPersonRepository.save(person);
  402. }
  403. const response = await client.getAllDisabledPersons.$get({
  404. query: {
  405. skip: 0,
  406. take: 10
  407. }
  408. }, {
  409. headers: {
  410. 'Authorization': `Bearer ${testToken}`
  411. }
  412. });
  413. expect(response.status).toBe(200);
  414. if (response.status === 200) {
  415. const data = await response.json();
  416. expect(data.data).toHaveLength(5);
  417. expect(data.total).toBe(5);
  418. expect(data.data[0].name).toBe('残疾人5'); // 按ID降序排列
  419. }
  420. });
  421. it('应该处理分页参数', async () => {
  422. // 创建更多测试数据
  423. const dataSource = await IntegrationTestDatabase.getDataSource();
  424. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  425. for (let i = 1; i <= 15; i++) {
  426. const person = disabledPersonRepository.create({
  427. name: `分页人员${i}`,
  428. gender: i % 2 === 0 ? '女' : '男',
  429. idCard: `1101011990010113${i}`,
  430. disabilityId: `D1234568${i}`,
  431. disabilityType: '肢体残疾',
  432. disabilityLevel: '一级',
  433. idAddress: `北京市分页区${i}`,
  434. phone: `138001381${i}`,
  435. province: '北京市',
  436. city: '北京市'
  437. });
  438. await disabledPersonRepository.save(person);
  439. }
  440. const response = await client.getAllDisabledPersons.$get({
  441. query: {
  442. skip: 5,
  443. take: 5
  444. }
  445. }, {
  446. headers: {
  447. 'Authorization': `Bearer ${testToken}`
  448. }
  449. });
  450. expect(response.status).toBe(200);
  451. if (response.status === 200) {
  452. const data = await response.json();
  453. expect(data.data).toHaveLength(5);
  454. expect(data.total).toBe(15);
  455. }
  456. });
  457. });
  458. describe('GET /searchDisabledPersons', () => {
  459. it('应该成功按姓名搜索残疾人', async () => {
  460. // 创建测试数据
  461. const dataSource = await IntegrationTestDatabase.getDataSource();
  462. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  463. const person1 = disabledPersonRepository.create({
  464. name: '张三',
  465. gender: '男',
  466. idCard: '110101199001011241',
  467. disabilityId: 'D123456771',
  468. disabilityType: '肢体残疾',
  469. disabilityLevel: '一级',
  470. idAddress: '北京市昌平区',
  471. phone: '13000130001',
  472. province: '北京市',
  473. city: '北京市'
  474. });
  475. await disabledPersonRepository.save(person1);
  476. const person2 = disabledPersonRepository.create({
  477. name: '李四',
  478. gender: '女',
  479. idCard: '110101199001011242',
  480. disabilityId: 'D123456770',
  481. disabilityType: '视力残疾',
  482. disabilityLevel: '二级',
  483. idAddress: '北京市平谷区',
  484. phone: '13000130002',
  485. province: '北京市',
  486. city: '北京市'
  487. });
  488. await disabledPersonRepository.save(person2);
  489. const response = await client.searchDisabledPersons.$get({
  490. query: {
  491. keyword: '张三',
  492. skip: 0,
  493. take: 10
  494. }
  495. }, {
  496. headers: {
  497. 'Authorization': `Bearer ${testToken}`
  498. }
  499. });
  500. expect(response.status).toBe(200);
  501. if (response.status === 200) {
  502. const data = await response.json();
  503. expect(data.data).toHaveLength(1);
  504. expect(data.data[0].name).toBe('张三');
  505. }
  506. });
  507. it('应该验证搜索关键词不能为空', async () => {
  508. const response = await client.searchDisabledPersons.$get({
  509. query: {
  510. keyword: '', // 空关键词
  511. skip: 0,
  512. take: 10
  513. }
  514. }, {
  515. headers: {
  516. 'Authorization': `Bearer ${testToken}`
  517. }
  518. });
  519. expect(response.status).toBe(400);
  520. });
  521. });
  522. describe('GET /getDisabledPerson/{id}', () => {
  523. it('应该成功获取单个残疾人详情', async () => {
  524. // 先创建一个残疾人
  525. const dataSource = await IntegrationTestDatabase.getDataSource();
  526. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  527. const person = disabledPersonRepository.create({
  528. name: '测试人员详情',
  529. gender: '男',
  530. idCard: '110101199001011243',
  531. disabilityId: 'D123456769',
  532. disabilityType: '肢体残疾',
  533. disabilityLevel: '一级',
  534. idAddress: '北京市怀柔区',
  535. phone: '13000130003',
  536. province: '北京市',
  537. city: '北京市',
  538. canDirectContact: 1,
  539. isMarried: 1
  540. });
  541. await disabledPersonRepository.save(person);
  542. const response = await client.getDisabledPerson[':id'].$get({
  543. param: {
  544. id: person.id
  545. }
  546. }, {
  547. headers: {
  548. 'Authorization': `Bearer ${testToken}`
  549. }
  550. });
  551. expect(response.status).toBe(200);
  552. if (response.status === 200) {
  553. const data = await response.json();
  554. expect(data?.name).toBe('测试人员详情');
  555. expect(data?.canDirectContact).toBe(1);
  556. }
  557. });
  558. it('应该处理不存在的残疾人ID', async () => {
  559. const response = await client.getDisabledPerson[':id'].$get({
  560. param: {
  561. id: 99999 // 不存在的ID
  562. }
  563. }, {
  564. headers: {
  565. 'Authorization': `Bearer ${testToken}`
  566. }
  567. });
  568. expect(response.status).toBe(200); // 返回200,但数据为null
  569. if (response.status === 200) {
  570. const data = await response.json();
  571. expect(data).toBeNull();
  572. }
  573. });
  574. });
  575. describe('GET /getDisabledPersonByIdCard', () => {
  576. it('应该成功根据身份证号查询残疾人', async () => {
  577. // 先创建一个残疾人
  578. const dataSource = await IntegrationTestDatabase.getDataSource();
  579. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  580. const person = disabledPersonRepository.create({
  581. name: '身份证查询测试',
  582. gender: '女',
  583. idCard: '110101199001011244',
  584. disabilityId: 'D123456768',
  585. disabilityType: '听力残疾',
  586. disabilityLevel: '三级',
  587. idAddress: '北京市密云区',
  588. phone: '13000130004',
  589. province: '北京市',
  590. city: '北京市'
  591. });
  592. await disabledPersonRepository.save(person);
  593. const response = await client.findByIdCard[':idCard'].$get({
  594. param: {
  595. idCard: '110101199001011244'
  596. }
  597. }, {
  598. headers: {
  599. 'Authorization': `Bearer ${testToken}`
  600. }
  601. });
  602. expect(response.status).toBe(200);
  603. if (response.status === 200) {
  604. const data = await response.json();
  605. expect(data?.name).toBe('身份证查询测试');
  606. expect(data?.idCard).toBe('110101199001011244');
  607. }
  608. });
  609. it('应该处理不存在的身份证号', async () => {
  610. const response = await client.findByIdCard[':idCard'].$get({
  611. param: {
  612. idCard: '999999999999999999' // 不存在的身份证号
  613. }
  614. }, {
  615. headers: {
  616. 'Authorization': `Bearer ${testToken}`
  617. }
  618. });
  619. expect(response.status).toBe(200); // 返回200,但数据为null
  620. if (response.status === 200) {
  621. const data = await response.json();
  622. expect(data).toBeNull();
  623. }
  624. });
  625. });
  626. describe('POST /createAggregatedDisabledPerson', () => {
  627. it('应该成功创建聚合残疾人信息(包含所有关联数据)', async () => {
  628. const createData = {
  629. personInfo: {
  630. name: '聚合创建测试',
  631. gender: '男',
  632. idCard: '110101199001011245',
  633. disabilityId: 'D123456767',
  634. disabilityType: '肢体残疾',
  635. disabilityLevel: '一级',
  636. idAddress: '北京市延庆区',
  637. phone: '13000130005',
  638. province: '北京市',
  639. city: '北京市',
  640. // 新增字段
  641. canDirectContact: 1,
  642. isInBlackList: 0,
  643. jobStatus: 1,
  644. // 日期字段
  645. idValidDate: new Date('2045-11-30'),
  646. disabilityValidDate: new Date('2045-11-30')
  647. },
  648. bankCards: [
  649. {
  650. subBankName: '北京分行',
  651. bankName: '中国工商银行',
  652. cardNumber: '6222021234567890123',
  653. cardholderName: '聚合创建测试',
  654. fileId: testFile.id,
  655. isDefault: 0
  656. }
  657. ],
  658. photos: [
  659. {
  660. photoType: '身份证照片',
  661. fileId: testFile.id // 使用测试文件ID
  662. }
  663. ],
  664. remarks: [
  665. {
  666. remarkContent: '家庭经济困难,需要帮助',
  667. operatorId: 1
  668. }
  669. ],
  670. visits: [
  671. {
  672. visitDate: '2025-12-02T10:00:00Z',
  673. visitType: '电话回访',
  674. visitContent: '初次回访,了解基本情况',
  675. visitorId: 1
  676. }
  677. ]
  678. };
  679. const response = await client.createAggregatedDisabledPerson.$post({
  680. json: createData
  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.personInfo.name).toBe('聚合创建测试');
  690. // 验证新增字段
  691. expect(data.personInfo.canDirectContact).toBe(1);
  692. expect(data.personInfo.isInBlackList).toBe(0);
  693. expect(data.personInfo.jobStatus).toBe(1);
  694. // 验证日期字段
  695. expect(data.personInfo.idValidDate).toBeDefined();
  696. expect(data.personInfo.disabilityValidDate).toBeDefined();
  697. if (data.personInfo.idValidDate) {
  698. expect(new Date(data.personInfo.idValidDate).toISOString().split('T')[0]).toBe('2045-11-30');
  699. }
  700. if (data.personInfo.disabilityValidDate) {
  701. expect(new Date(data.personInfo.disabilityValidDate).toISOString().split('T')[0]).toBe('2045-11-30');
  702. }
  703. expect(data.bankCards).toHaveLength(1);
  704. expect(data.photos).toHaveLength(1);
  705. expect(data.remarks).toHaveLength(1);
  706. expect(data.visits).toHaveLength(1);
  707. // 验证文件集成
  708. expect(data.photos[0].fileId).toBe(testFile.id);
  709. }
  710. });
  711. it('应该验证文件ID的有效性', async () => {
  712. const createData = {
  713. personInfo: {
  714. name: '文件验证测试',
  715. gender: '女',
  716. idCard: '110101199001011246',
  717. disabilityId: 'D123456766',
  718. disabilityType: '视力残疾',
  719. disabilityLevel: '二级',
  720. idAddress: '北京市房山区',
  721. phone: '13000130006',
  722. province: '北京市',
  723. city: '北京市',
  724. // 新增字段
  725. canDirectContact: 0,
  726. isInBlackList: 1,
  727. jobStatus: 2,
  728. // 日期字段
  729. idValidDate: new Date('2036-07-25'),
  730. disabilityValidDate: new Date('2036-07-25')
  731. },
  732. photos: [
  733. {
  734. photoType: '身份证照片',
  735. fileId: 99999 // 不存在的文件ID
  736. }
  737. ]
  738. };
  739. const response = await client.createAggregatedDisabledPerson.$post({
  740. json: createData
  741. }, {
  742. headers: {
  743. 'Authorization': `Bearer ${testToken}`
  744. }
  745. });
  746. expect(response.status).toBe(400); // 应该返回400,因为文件ID无效
  747. });
  748. });
  749. describe('GET /getAggregatedDisabledPerson/{personId}', () => {
  750. it('应该成功获取聚合残疾人信息', async () => {
  751. // 先创建一个完整的残疾人数据(包含所有关联数据)
  752. const dataSource = await IntegrationTestDatabase.getDataSource();
  753. // 创建残疾人
  754. const disabledPersonRepository = dataSource.getRepository(DisabledPerson);
  755. const person = disabledPersonRepository.create({
  756. name: '聚合查询测试',
  757. gender: '男',
  758. idCard: '110101199001011247',
  759. disabilityId: 'D123456765',
  760. disabilityType: '肢体残疾',
  761. disabilityLevel: '一级',
  762. idAddress: '北京市门头沟区',
  763. phone: '13000130007',
  764. province: '北京市',
  765. city: '北京市'
  766. });
  767. await disabledPersonRepository.save(person);
  768. // 创建银行卡
  769. const bankCardRepository = dataSource.getRepository(DisabledBankCard);
  770. const bankCard = bankCardRepository.create({
  771. personId: person.id,
  772. subBankName: '北京分行',
  773. bankName: '中国建设银行',
  774. cardNumber: '6227001234567890123',
  775. cardholderName: '聚合查询测试',
  776. fileId: testFile.id,
  777. isDefault: 0
  778. });
  779. await bankCardRepository.save(bankCard);
  780. // 创建照片(使用测试文件)
  781. const photoRepository = dataSource.getRepository(DisabledPhoto);
  782. const photo = photoRepository.create({
  783. personId: person.id,
  784. photoType: '身份证照片',
  785. fileId: testFile.id
  786. });
  787. await photoRepository.save(photo);
  788. // 创建备注
  789. const remarkRepository = dataSource.getRepository(DisabledRemark);
  790. const remark = remarkRepository.create({
  791. personId: person.id,
  792. remarkContent: '目前无工作,需要就业帮助',
  793. operatorId: 1
  794. });
  795. await remarkRepository.save(remark);
  796. // 创建回访记录
  797. const visitRepository = dataSource.getRepository(DisabledVisit);
  798. const visit = visitRepository.create({
  799. personId: person.id,
  800. visitDate: new Date('2025-12-01T14:30:00Z'),
  801. visitType: '上门回访',
  802. visitContent: '了解就业需求',
  803. visitorId: 2
  804. });
  805. await visitRepository.save(visit);
  806. const response = await client.getAggregatedDisabledPerson[':id'].$get({
  807. param: {
  808. id: person.id
  809. }
  810. }, {
  811. headers: {
  812. 'Authorization': `Bearer ${testToken}`
  813. }
  814. });
  815. // 调试:打印响应状态和错误信息
  816. console.debug('响应状态:', response.status);
  817. if (response.status !== 200) {
  818. const errorText = await response.text();
  819. console.debug('错误响应:', errorText);
  820. }
  821. expect(response.status).toBe(200);
  822. if (response.status === 200) {
  823. const data = await response.json();
  824. expect(data).not.toBeNull();
  825. expect(data!.personInfo.name).toBe('聚合查询测试');
  826. expect(data!.bankCards).toHaveLength(1);
  827. expect(data!.photos).toHaveLength(1);
  828. expect(data!.remarks).toHaveLength(1);
  829. expect(data!.visits).toHaveLength(1);
  830. // 验证文件数据完整性
  831. expect(data!.photos[0].fileId).toBe(testFile.id);
  832. }
  833. });
  834. it('应该处理不存在的残疾人ID', async () => {
  835. const response = await client.getAggregatedDisabledPerson[':id'].$get({
  836. param: {
  837. id: 99999 // 不存在的ID
  838. }
  839. }, {
  840. headers: {
  841. 'Authorization': `Bearer ${testToken}`
  842. }
  843. });
  844. expect(response.status).toBe(404);
  845. });
  846. });
  847. describe('认证测试', () => {
  848. it('应该验证所有端点需要认证', async () => {
  849. // 测试没有token的情况
  850. const response = await client.createDisabledPerson.$post({
  851. json: {
  852. name: '测试人员',
  853. gender: '男',
  854. idCard: '110101199001011235',
  855. disabilityId: 'D123456789',
  856. disabilityType: '视力残疾',
  857. disabilityLevel: '一级',
  858. idAddress: '北京市东城区',
  859. phone: '13800138000',
  860. province: '北京市',
  861. city: '北京市'
  862. }
  863. });
  864. expect(response.status).toBe(401);
  865. });
  866. it('应该验证无效token', async () => {
  867. const response = await client.createDisabledPerson.$post({
  868. json: {
  869. name: '测试人员',
  870. gender: '男',
  871. idCard: '110101199001011236',
  872. disabilityId: 'D123456790',
  873. disabilityType: '视力残疾',
  874. disabilityLevel: '一级',
  875. idAddress: '北京市东城区',
  876. phone: '13800138001',
  877. province: '北京市',
  878. city: '北京市'
  879. }
  880. }, {
  881. headers: {
  882. 'Authorization': 'Bearer invalid_token'
  883. }
  884. });
  885. expect(response.status).toBe(401);
  886. });
  887. });
  888. });