person-extension.integration.test.ts 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  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 { Platform } from '@d8d/allin-platform-module/entities';
  8. import { EmploymentOrder, OrderPerson, OrderPersonAsset } from '@d8d/allin-order-module/entities';
  9. import { BankName } from '@d8d/bank-names-module';
  10. import { DisabledPerson, DisabledBankCard, DisabledPhoto, DisabledRemark, DisabledVisit } from '../../src/entities';
  11. import personExtensionRoutes from '../../src/routes/person-extension.route';
  12. import { Company } from '@d8d/allin-company-module/entities';
  13. // 设置集成测试钩子 - 需要包含所有相关实体
  14. setupIntegrationDatabaseHooksWithEntities([
  15. UserEntity, File, Role, Platform, Company,
  16. EmploymentOrder, OrderPerson, OrderPersonAsset,
  17. DisabledPerson, BankName, DisabledBankCard, DisabledPhoto, DisabledRemark, DisabledVisit
  18. ])
  19. describe('人才扩展API集成测试', () => {
  20. let client: ReturnType<typeof testClient<typeof personExtensionRoutes>>;
  21. let testToken: string;
  22. let testUser: UserEntity;
  23. let testCompany: Company;
  24. let testPlatform: Platform;
  25. let testDisabledPerson: DisabledPerson;
  26. let testOrder: EmploymentOrder;
  27. beforeEach(async () => {
  28. // 创建测试客户端
  29. client = testClient(personExtensionRoutes);
  30. // 获取数据源
  31. const dataSource = await IntegrationTestDatabase.getDataSource();
  32. // 创建测试平台
  33. const platformRepository = dataSource.getRepository(Platform);
  34. testPlatform = platformRepository.create({
  35. platformName: `测试平台_${Date.now()}`,
  36. contactPerson: '平台管理员',
  37. contactPhone: '13800138000',
  38. contactEmail: 'admin@example.com',
  39. address: '测试地址',
  40. status: 1
  41. }) as Platform;
  42. await platformRepository.save(testPlatform);
  43. // 创建测试公司
  44. const companyRepository = dataSource.getRepository(Company);
  45. testCompany = companyRepository.create({
  46. companyName: `测试公司_${Date.now()}`,
  47. contactPerson: '公司联系人',
  48. contactPhone: '13900139000',
  49. contactEmail: 'company@example.com',
  50. address: '公司地址',
  51. platformId: testPlatform.id,
  52. status: 1
  53. });
  54. await companyRepository.save(testCompany);
  55. // 创建测试企业用户
  56. const userRepository = dataSource.getRepository(UserEntity);
  57. testUser = userRepository.create({
  58. username: `enterprise_user_${Date.now()}`,
  59. password: 'test_password',
  60. nickname: '企业测试用户',
  61. registrationSource: 'web',
  62. companyId: testCompany.id
  63. });
  64. await userRepository.save(testUser);
  65. // 生成测试用户的token
  66. testToken = JWTUtil.generateToken({
  67. id: testUser.id,
  68. username: testUser.username,
  69. roles: [{ name: 'enterprise_user' }],
  70. companyId: testCompany.id
  71. } as any);
  72. // 创建测试残疾人
  73. const disabledPersonRepo = dataSource.getRepository(DisabledPerson);
  74. testDisabledPerson = disabledPersonRepo.create({
  75. name: '测试残疾人',
  76. idCard: `110101${Date.now() % 100000000}`,
  77. gender: '男',
  78. birthDate: new Date('1990-01-01'),
  79. disabilityType: '视力残疾',
  80. disabilityLevel: '一级',
  81. disabilityId: `DIS${Date.now() % 100000000}`,
  82. idAddress: '身份证地址',
  83. phone: '13800138000',
  84. province: '北京市',
  85. city: '北京市',
  86. address: '测试地址'
  87. } as any);
  88. await disabledPersonRepo.save(testDisabledPerson);
  89. // 创建测试订单
  90. const orderRepo = dataSource.getRepository(EmploymentOrder);
  91. testOrder = orderRepo.create({
  92. orderName: '测试订单',
  93. platformId: testPlatform.id,
  94. companyId: testCompany.id,
  95. orderStatus: 'confirmed',
  96. workStatus: 'working'
  97. } as any);
  98. await orderRepo.save(testOrder);
  99. // 创建订单人员关联,使人员属于该企业
  100. const orderPersonRepo = dataSource.getRepository(OrderPerson);
  101. const orderPerson = orderPersonRepo.create({
  102. orderId: testOrder.id,
  103. personId: testDisabledPerson.id,
  104. joinDate: new Date('2024-01-01'),
  105. workStatus: 'working',
  106. salaryDetail: 5000.00
  107. } as any);
  108. await orderPersonRepo.save(orderPerson);
  109. });
  110. describe('GET /api/v1/yongren/disability-person/{id}/work-history', () => {
  111. it('应该返回人员工作历史', async () => {
  112. // 准备测试数据:多个订单关联
  113. const dataSource = await IntegrationTestDatabase.getDataSource();
  114. const orderPersonRepo = dataSource.getRepository(OrderPerson);
  115. // 创建另一个订单关联
  116. const orderRepo = dataSource.getRepository(EmploymentOrder);
  117. const anotherOrder = orderRepo.create({
  118. orderName: '另一个测试订单',
  119. platformId: testPlatform.id,
  120. companyId: testCompany.id,
  121. orderStatus: 'completed',
  122. workStatus: 'working'
  123. } as any);
  124. await orderRepo.save(anotherOrder);
  125. const anotherOrderPerson = orderPersonRepo.create({
  126. orderId: anotherOrder.id,
  127. personId: testDisabledPerson.id,
  128. joinDate: new Date('2024-06-01'),
  129. actualStartDate: new Date('2024-06-02'),
  130. leaveDate: new Date('2024-12-31'),
  131. workStatus: 'resigned',
  132. salaryDetail: 6000.00
  133. } as any);
  134. await orderPersonRepo.save(anotherOrderPerson);
  135. // 调用API
  136. const response = await client[':id']['work-history'].$get({
  137. param: { id: testDisabledPerson.id },
  138. headers: {
  139. Authorization: `Bearer ${testToken}`
  140. }
  141. });
  142. console.debug('响应状态:', response.status);
  143. // 类型保护:如果状态不是200,抛出错误
  144. if (response.status !== 200) {
  145. try {
  146. const errorData = await response.json();
  147. console.debug('错误响应:', errorData);
  148. throw new Error(`API returned ${response.status}: ${errorData.message}`);
  149. } catch (e) {
  150. console.debug('无法解析错误响应:', e);
  151. throw new Error(`API returned ${response.status} and response could not be parsed`);
  152. }
  153. }
  154. const data = await response.json();
  155. // 验证响应结构
  156. expect(data).toHaveProperty('工作历史');
  157. expect(Array.isArray(data.工作历史)).toBe(true);
  158. // 验证数据
  159. expect(data.工作历史.length).toBeGreaterThanOrEqual(1);
  160. const workHistory = data.工作历史[0];
  161. expect(workHistory).toHaveProperty('订单ID');
  162. expect(workHistory).toHaveProperty('订单名称');
  163. expect(workHistory).toHaveProperty('入职日期');
  164. expect(workHistory).toHaveProperty('工作状态');
  165. expect(workHistory).toHaveProperty('个人薪资');
  166. });
  167. it('访问其他企业人员应该返回403', async () => {
  168. // 创建另一个公司的残疾人
  169. const dataSource = await IntegrationTestDatabase.getDataSource();
  170. // 创建另一个公司
  171. const companyRepository = dataSource.getRepository(Company);
  172. const otherCompany = companyRepository.create({
  173. companyName: `其他公司_${Date.now()}`,
  174. contactPerson: '其他联系人',
  175. contactPhone: '13900139001',
  176. contactEmail: 'other@example.com',
  177. address: '其他地址',
  178. platformId: testPlatform.id,
  179. status: 1
  180. });
  181. await companyRepository.save(otherCompany);
  182. // 创建另一个公司的残疾人
  183. const disabledPersonRepo = dataSource.getRepository(DisabledPerson);
  184. const otherDisabledPerson = disabledPersonRepo.create({
  185. name: '其他公司残疾人',
  186. idCard: `110101${Date.now() % 100000000 + 1000}`,
  187. gender: '女',
  188. birthDate: new Date('1995-01-01'),
  189. disabilityType: '听力残疾',
  190. disabilityLevel: '二级',
  191. disabilityId: `DIS${Date.now() % 100000000 + 1000}`,
  192. idAddress: '其他地址',
  193. phone: '13900139000',
  194. province: '上海市',
  195. city: '上海市',
  196. address: '其他地址'
  197. } as any);
  198. await disabledPersonRepo.save(otherDisabledPerson);
  199. // 尝试访问其他公司人员数据
  200. const response = await client[':id']['work-history'].$get({
  201. param: { id: otherDisabledPerson.id },
  202. headers: {
  203. Authorization: `Bearer ${testToken}`
  204. }
  205. });
  206. expect(response.status).toBe(403);
  207. });
  208. });
  209. describe('GET /api/v1/yongren/disability-person/{id}/salary-history', () => {
  210. it('应该返回人员薪资历史', async () => {
  211. // 注意:薪资历史可能需要从薪资模块获取,这里暂时返回空数组
  212. const response = await client[':id']['salary-history'].$get({
  213. param: { id: testDisabledPerson.id },
  214. headers: {
  215. Authorization: `Bearer ${testToken}`
  216. }
  217. });
  218. expect(response.status).toBe(200);
  219. const data = await response.json();
  220. // 验证响应结构
  221. expect(data).toHaveProperty('薪资历史');
  222. expect(Array.isArray(data.薪资历史)).toBe(true);
  223. });
  224. });
  225. describe('GET /api/v1/yongren/disability-person/{id}/credit-info', () => {
  226. it('应该返回人员征信信息', async () => {
  227. // 准备测试数据:银行卡信息
  228. const dataSource = await IntegrationTestDatabase.getDataSource();
  229. // 创建文件
  230. const fileRepository = dataSource.getRepository(File);
  231. const testFile = fileRepository.create({
  232. name: '银行卡照片.jpg',
  233. type: 'image/jpeg',
  234. size: 1024,
  235. path: 'uploads/bank-card.jpg',
  236. description: '银行卡照片',
  237. uploadUserId: testUser.id,
  238. uploadTime: new Date()
  239. });
  240. await fileRepository.save(testFile);
  241. // 创建银行名称记录
  242. const bankNameRepo = dataSource.getRepository(BankName);
  243. const bankName = bankNameRepo.create({
  244. bankName: '测试银行',
  245. bankCode: 'TESTBANK',
  246. status: 1
  247. } as any);
  248. await bankNameRepo.save(bankName);
  249. // 创建银行卡记录
  250. const bankCardRepo = dataSource.getRepository(DisabledBankCard);
  251. const bankCard = bankCardRepo.create({
  252. personId: testDisabledPerson.id,
  253. subBankName: '测试支行',
  254. bankNameId: bankName.id, // 使用实际创建的银行ID
  255. cardNumber: '6228481234567890123',
  256. cardholderName: '测试持卡人',
  257. cardType: '一类卡',
  258. fileId: testFile.id,
  259. isDefault: 1
  260. });
  261. await bankCardRepo.save(bankCard);
  262. // 调用API
  263. const response = await client[':id']['credit-info'].$get({
  264. param: { id: testDisabledPerson.id },
  265. headers: {
  266. Authorization: `Bearer ${testToken}`
  267. }
  268. });
  269. expect(response.status).toBe(200);
  270. const data = await response.json();
  271. // 验证响应结构
  272. expect(data).toHaveProperty('征信信息');
  273. expect(Array.isArray(data.征信信息)).toBe(true);
  274. if (data.征信信息.length > 0) {
  275. const creditInfo = data.征信信息[0];
  276. expect(creditInfo).toHaveProperty('文件ID');
  277. expect(creditInfo).toHaveProperty('银行卡号');
  278. expect(creditInfo).toHaveProperty('持卡人姓名');
  279. }
  280. });
  281. });
  282. describe('GET /api/v1/yongren/disability-person/{id}/videos', () => {
  283. it('应该返回人员视频关联', async () => {
  284. // 准备测试数据:订单人员资产(视频)
  285. const dataSource = await IntegrationTestDatabase.getDataSource();
  286. // 创建文件
  287. const fileRepository = dataSource.getRepository(File);
  288. const testFile = fileRepository.create({
  289. name: '工作视频.mp4',
  290. type: 'video/mp4',
  291. size: 1024000,
  292. path: 'uploads/work-video.mp4',
  293. description: '工作视频',
  294. uploadUserId: testUser.id,
  295. uploadTime: new Date()
  296. });
  297. await fileRepository.save(testFile);
  298. // 创建订单人员资产记录
  299. const assetRepo = dataSource.getRepository(OrderPersonAsset);
  300. const asset = assetRepo.create({
  301. orderId: testOrder.id,
  302. personId: testDisabledPerson.id,
  303. assetType: 'work_video',
  304. assetFileType: 'video',
  305. fileId: testFile.id,
  306. relatedTime: new Date()
  307. } as any);
  308. await assetRepo.save(asset);
  309. // 调用API
  310. const response = await client[':id'].videos.$get({
  311. param: { id: testDisabledPerson.id },
  312. headers: {
  313. Authorization: `Bearer ${testToken}`
  314. }
  315. });
  316. expect(response.status).toBe(200);
  317. const data = await response.json();
  318. // 验证响应结构
  319. expect(data).toHaveProperty('视频列表');
  320. expect(Array.isArray(data.视频列表)).toBe(true);
  321. if (data.视频列表.length > 0) {
  322. const video = data.视频列表[0];
  323. expect(video).toHaveProperty('视频类型');
  324. expect(video).toHaveProperty('文件ID');
  325. expect(video).toHaveProperty('关联订单ID');
  326. }
  327. });
  328. });
  329. });