executionSettingsPanel.test.ts 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. import {flushPromises,mount} from '@vue/test-utils'
  2. import {beforeEach,expect,it,vi} from 'vitest'
  3. import ExecutionSettingsPanel from '@/components/app/ExecutionSettingsPanel.vue'
  4. import {apiRequest} from '@/api/client'
  5. vi.mock('@/api/client',()=>({apiRequest:vi.fn()}))
  6. const request=vi.mocked(apiRequest)
  7. const initial=()=>({execution:{mode:'none',revision:1,credentialSource:'yaoyao'},proxy:{enabled:true,protocol:'http',host:'proxy.test',port:8080,username:'',revision:2,hasPassword:true},resources:[],agents:[{id:'fixture-bot',name:'夭夭',owner:'admin'}],nodes:[],activeTurns:[]})
  8. beforeEach(()=>{request.mockReset();request.mockImplementation(async()=>initial() as never)})
  9. it('saves an explicit system environment without changing model settings',async()=>{
  10. const wrapper=mount(ExecutionSettingsPanel);await flushPromises()
  11. await wrapper.findAll('select')[0]!.setValue('virtual');await wrapper.findAll('form')[0]!.trigger('submit');await flushPromises()
  12. expect(request).toHaveBeenCalledWith('/api/app/admin/execution/environment',{method:'PUT',body:{mode:'virtual',revision:1}})
  13. expect(wrapper.text()).toContain('下一轮任务生效');wrapper.unmount()
  14. })
  15. it('keeps proxy credentials write-only and allows explicitly clearing the saved password',async()=>{
  16. const wrapper=mount(ExecutionSettingsPanel);await flushPromises()
  17. const clear=wrapper.findAll('label').find(l=>l.text().includes('清除已保存的代理密码'))!.get('input')
  18. await clear.setValue(true);await wrapper.findAll('form').at(-1)!.trigger('submit');await flushPromises()
  19. expect(request).toHaveBeenCalledWith('/api/app/admin/execution/proxy',expect.objectContaining({method:'PUT',body:expect.objectContaining({password:'',revision:2})}))
  20. expect(JSON.stringify(request.mock.calls)).not.toContain('hasPassword');wrapper.unmount()
  21. })
  22. it('does not grant new resources to every Bot and reports invalid variable JSON without sending it',async()=>{
  23. const wrapper=mount(ExecutionSettingsPanel,{global:{stubs:{StandaloneDialog:{template:'<div role="dialog"><slot /></div>'}}}});await flushPromises()
  24. await wrapper.findAll('button').find(b=>b.text()==='添加授权或变量')!.trigger('click')
  25. await wrapper.get('[role=dialog] select').setValue('variables')
  26. expect(wrapper.findAll('fieldset input').every(i=>!(i.element as HTMLInputElement).checked)).toBe(true)
  27. await wrapper.get('textarea').setValue('{broken')
  28. const count=request.mock.calls.length;await wrapper.findAll('form')[1]!.trigger('submit');await flushPromises()
  29. expect(request.mock.calls.length).toBe(count);expect(wrapper.get('[role=alert]').text()).not.toBe('');wrapper.unmount()
  30. })
  31. it('shows the node readiness failure instead of blaming proxy credentials',async()=>{
  32. const wrapper=mount(ExecutionSettingsPanel);await flushPromises()
  33. request.mockResolvedValueOnce({nodes:[{name:'本机虚拟机',ok:false,error:'缺少虚拟机网络网关,请重新准备网络镜像'}]})
  34. await wrapper.findAll('button').find(b=>b.text()==='测试已保存的代理')!.trigger('click');await flushPromises()
  35. expect(wrapper.get('[role=alert]').text()).toBe('本机虚拟机:缺少虚拟机网络网关,请重新准备网络镜像')
  36. expect(wrapper.find('[role=status]').exists()).toBe(false);wrapper.unmount()
  37. })