botSettingsDialog.test.ts 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import {mount, flushPromises} from '@vue/test-utils'
  2. import {afterEach, beforeEach, expect, it, vi} from 'vitest'
  3. import {defineComponent} from 'vue'
  4. import BotSettingsDialog from '@/components/workspace/BotSettingsDialog.vue'
  5. import {apiRequest} from '@/api/client'
  6. vi.mock('@/api/client', () => ({apiRequest:vi.fn()}))
  7. const request = vi.mocked(apiRequest)
  8. const project={id:'project-a',name:'项目示例',description:'项目说明',memberIds:['bot-a'],groupIds:[],revision:1,archived:false}
  9. const mountDialog=(isAdmin=false, initialPage='projects')=>mount(BotSettingsDialog,{
  10. props:{isAdmin,initialPage} as never,
  11. global:{stubs:{
  12. StandaloneDialog:defineComponent({props:['title'],template:'<section role="dialog" :aria-label="title"><slot /></section>'}),
  13. AppIcon:true,
  14. LocalVmSettingsPanel:defineComponent({template:'<div data-testid="vm-settings">虚拟机管理</div>'}),
  15. }},
  16. })
  17. beforeEach(()=>{
  18. request.mockReset()
  19. request.mockImplementation(async(path)=>{
  20. if(path==='/api/app/capabilities')return {features:['bot-file-memory-v1']} as never
  21. if(path==='/api/app/agents')return {agents:[{id:'bot-a',name:'测试 Bot'}]} as never
  22. if(path==='/api/app/conversations')return {conversations:[]} as never
  23. if(path==='/api/app/workspace/projects')return {projects:[project]} as never
  24. if(String(path).includes('/memory-jobs'))return {jobs:[]} as never
  25. if(String(path).includes('/memories'))return {memories:[]} as never
  26. throw new Error(String(path))
  27. })
  28. })
  29. afterEach(()=>vi.restoreAllMocks())
  30. it('reuses project and user-memory management inline without nesting dialogs',async()=>{
  31. const wrapper=mountDialog()
  32. await flushPromises()
  33. expect(wrapper.get('[aria-label="Bot 设置分类"]').text()).toContain('项目')
  34. expect(wrapper.text()).toContain('项目示例')
  35. expect(wrapper.find('dialog').exists()).toBe(false)
  36. await wrapper.findAll('button').find(b=>b.text()==='查看记忆')!.trigger('click')
  37. await flushPromises()
  38. expect(request).toHaveBeenCalledWith(expect.stringContaining('scope=project&projectId=project-a'))
  39. await wrapper.findAll('button').find(b=>b.text()==='返回项目')!.trigger('click')
  40. await flushPromises()
  41. expect(wrapper.text()).toContain('新建项目')
  42. await wrapper.get('nav').findAll('button').find(b=>b.text()==='用户记忆')!.trigger('click')
  43. await flushPromises()
  44. expect(request).toHaveBeenCalledWith(expect.stringContaining('scope=user'))
  45. expect(wrapper.text()).toContain('同一账号的 Bot 共享')
  46. wrapper.unmount()
  47. })
  48. it('keeps VM management admin-only, including a requested initial VM page',async()=>{
  49. const wrapper=mountDialog(false,'vm')
  50. await flushPromises()
  51. expect(wrapper.get('nav').text()).not.toContain('本地虚拟机')
  52. expect(wrapper.find('[data-testid="vm-settings"]').exists()).toBe(false)
  53. await wrapper.setProps({isAdmin:true})
  54. await wrapper.get('nav').findAll('button').find(b=>b.text()==='本地虚拟机')!.trigger('click')
  55. await flushPromises()
  56. expect(wrapper.find('[data-testid="vm-settings"]').exists()).toBe(true)
  57. await wrapper.setProps({isAdmin:false})
  58. await flushPromises()
  59. expect(wrapper.find('[data-testid="vm-settings"]').exists()).toBe(false)
  60. expect(wrapper.text()).toContain('项目示例')
  61. wrapper.unmount()
  62. })