hermesBridgePanel.test.ts 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. import {flushPromises,mount} from '@vue/test-utils'
  2. import {afterEach,beforeEach,expect,it,vi} from 'vitest'
  3. import HermesBridgePanel from '@/components/app/HermesBridgePanel.vue'
  4. import {getHermesBridgeStatus,installHermesBridge} from '@/api/hermesBridge'
  5. import type {HermesBridgeStatus} from '@shared/hermesBridge'
  6. vi.mock('@/api/hermesBridge',()=>({getHermesBridgeStatus:vi.fn(),installHermesBridge:vi.fn()}))
  7. const snapshot=():HermesBridgeStatus=>({endpoint:'http://127.0.0.1:9119',local:true,bundledVersion:'1.2.0',checkedAt:1,profiles:[
  8. {profile:'default',state:'outdated',message:'需要更新',canInstall:true,installedVersion:'1.1.0'},
  9. {profile:'writer',state:'disabled',message:'尚未启用',canInstall:true,installedVersion:'1.2.0'},
  10. ]})
  11. beforeEach(()=>{vi.mocked(getHermesBridgeStatus).mockResolvedValue(snapshot())})
  12. afterEach(()=>{vi.clearAllMocks()})
  13. it('shows each Profile and installs only the selected one, with visible progress and restart instructions',async()=>{
  14. let finish!:(value:any)=>void
  15. vi.mocked(installHermesBridge).mockReturnValue(new Promise(done=>{finish=done}))
  16. const wrapper=mount(HermesBridgePanel)
  17. await flushPromises()
  18. expect(wrapper.text()).toContain('default');expect(wrapper.text()).toContain('writer')
  19. await wrapper.get('button[aria-label="安装并启用:writer"]').trigger('click')
  20. expect(installHermesBridge).toHaveBeenCalledWith('writer',true)
  21. expect(wrapper.text()).toContain('安装中…')
  22. expect(wrapper.findAll('button').every(button=>button.attributes('disabled')!==undefined)).toBe(true)
  23. const state=snapshot();state.profiles[1]!.state='restart-required'
  24. finish({profile:'writer',backup:'/backups/writer',message:'安装完成,请重启 Hermes',status:state})
  25. await flushPromises()
  26. expect(wrapper.text()).toContain('待重启');expect(wrapper.get('[role="status"]').text()).toContain('重启 Hermes')
  27. expect(wrapper.text()).toContain('/backups/writer')
  28. await wrapper.findAll('button').find(b=>b.text()==='重新检查')!.trigger('click');await flushPromises()
  29. expect(getHermesBridgeStatus).toHaveBeenCalledTimes(2)
  30. wrapper.unmount()
  31. })
  32. it('provides retry feedback and keeps remote installation unavailable',async()=>{
  33. vi.mocked(getHermesBridgeStatus).mockRejectedValueOnce(new Error('连接失败'))
  34. const wrapper=mount(HermesBridgePanel);await flushPromises()
  35. expect(wrapper.get('[role="alert"]').text()).toBe('连接失败')
  36. const state=snapshot();state.local=false;state.profiles=state.profiles.map(p=>({...p,canInstall:false}));state.message='请在 Hermes 所在节点安装'
  37. vi.mocked(getHermesBridgeStatus).mockResolvedValue(state)
  38. await wrapper.get('button').trigger('click');await flushPromises()
  39. expect(wrapper.text()).toContain('所在节点安装');expect(wrapper.findAll('.install')).toHaveLength(0)
  40. wrapper.unmount()
  41. })
  42. it('shows installation failures without claiming that Hermes has loaded the plugin',async()=>{
  43. vi.mocked(installHermesBridge).mockRejectedValue(new Error('没有写入权限'))
  44. const wrapper=mount(HermesBridgePanel);await flushPromises()
  45. await wrapper.get('button[aria-label="更新工具桥:default"]').trigger('click');await flushPromises()
  46. expect(wrapper.get('[role="alert"]').text()).toBe('没有写入权限')
  47. expect(wrapper.text()).not.toContain('已就绪');expect(wrapper.text()).not.toContain('安装中…')
  48. wrapper.unmount()
  49. })