localVmImages.test.ts 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. import {it,expect,vi,afterEach} from 'vitest'
  2. import {mount,flushPromises} from '@vue/test-utils'
  3. import Settings from '../../src/client/components/app/LocalVmSettingsPanel.vue'
  4. import Panel from '../../src/client/components/workspace/LocalVmChatPanel.vue'
  5. import {apiRequest} from '../../src/client/api/client'
  6. vi.mock('../../src/client/api/client',()=>({apiRequest:vi.fn()}))
  7. const images=[{key:'standard',name:'标准桌面',description:'XFCE',ready:true,imageId:'sha256:a'},{key:'cursor',name:'Cursor Universal',description:'Debian',ready:true,imageId:'sha256:b'}]
  8. const agent={id:'image-fixture',name:'镜像测试',computer:'vm',execution:'computer',nodeId:'local',profile:'default'} as any
  9. const vm={configured:true,runtime:'docker',daemonUp:true,image:true,mode:'per-bot',maxInstances:2,busy:false,images}
  10. afterEach(()=>{vi.clearAllMocks();vi.restoreAllMocks()})
  11. it('prepares the selected image in Settings and explains the shared image constraint',async()=>{
  12. vi.mocked(apiRequest).mockImplementation(async path=>path==='/api/app/computers'?{computers:[]}:vm as any)
  13. const wrapper=mount(Settings,{global:{stubs:{AppIcon:true,RunnerSettingsPanel:true}}})
  14. try{
  15. await flushPromises()
  16. const select=wrapper.findAll('select').find(select=>select.text().includes('Cursor Universal'))!
  17. await select.setValue('cursor')
  18. await wrapper.findAll('button').find(b=>b.text()==='重新检查所选镜像')!.trigger('click')
  19. await flushPromises()
  20. expect(apiRequest).toHaveBeenCalledWith('/api/app/admin/local-vm/prepare',expect.objectContaining({body:expect.objectContaining({imageKey:'cursor'})}))
  21. expect(wrapper.text()).toContain('同一共享桌面的所有机器人使用一个镜像')
  22. }finally{wrapper.unmount()}
  23. })
  24. it('selects a prepared desktop image and locks the selection for an existing shared instance',async()=>{
  25. vi.spyOn(document,'hidden','get').mockReturnValue(false)
  26. let detail={...vm,enabled:true,container:'missing',ready:false,inUse:false,imageKey:'standard'}
  27. vi.mocked(apiRequest).mockImplementation(async path=>{
  28. if(path.endsWith('/desktop-environment'))return {selected:null,local:{supported:false},browser:{available:false}} as any
  29. if(path.endsWith('/cloud-computer'))return {configured:false} as any
  30. return detail as any
  31. })
  32. const wrapper=mount(Panel,{props:{agents:[agent],isAdmin:true,active:true},global:{stubs:{AppIcon:true,GrokAuthPanel:true}}})
  33. try{
  34. await flushPromises()
  35. const select=wrapper.findAll('select').find(s=>s.text().includes('Cursor Universal'))!
  36. await select.setValue('cursor');await flushPromises()
  37. expect(apiRequest).toHaveBeenCalledWith('/api/app/agents/image-fixture/local-vm/image',{method:'PUT',body:{imageKey:'cursor'}})
  38. detail={...detail,mode:'shared',container:'stopped'}
  39. await wrapper.setProps({active:false});await wrapper.setProps({active:true});await flushPromises()
  40. expect(select.attributes('disabled')).toBeDefined()
  41. expect(wrapper.text()).toContain('同一共享桌面只能使用一个镜像')
  42. }finally{wrapper.unmount()}
  43. })