import {mount, flushPromises} from '@vue/test-utils'
import {afterEach, beforeEach, expect, it, vi} from 'vitest'
import {defineComponent} from 'vue'
import BotSettingsDialog from '@/components/workspace/BotSettingsDialog.vue'
import {apiRequest} from '@/api/client'
vi.mock('@/api/client', () => ({apiRequest:vi.fn()}))
const request = vi.mocked(apiRequest)
const project={id:'project-a',name:'项目示例',description:'项目说明',memberIds:['bot-a'],groupIds:[],revision:1,archived:false}
const mountDialog=(isAdmin=false, initialPage='projects')=>mount(BotSettingsDialog,{
props:{isAdmin,initialPage} as never,
global:{stubs:{
StandaloneDialog:defineComponent({props:['title'],template:''}),
AppIcon:true,
LocalVmSettingsPanel:defineComponent({template:'
虚拟机管理
'}),
}},
})
beforeEach(()=>{
request.mockReset()
request.mockImplementation(async(path)=>{
if(path==='/api/app/capabilities')return {features:['bot-file-memory-v1']} as never
if(path==='/api/app/agents')return {agents:[{id:'bot-a',name:'测试 Bot'}]} as never
if(path==='/api/app/conversations')return {conversations:[]} as never
if(path==='/api/app/workspace/projects')return {projects:[project]} as never
if(String(path).includes('/memory-jobs'))return {jobs:[]} as never
if(String(path).includes('/memories'))return {memories:[]} as never
throw new Error(String(path))
})
})
afterEach(()=>vi.restoreAllMocks())
it('reuses project and user-memory management inline without nesting dialogs',async()=>{
const wrapper=mountDialog()
await flushPromises()
expect(wrapper.get('[aria-label="Bot 设置分类"]').text()).toContain('项目')
expect(wrapper.text()).toContain('项目示例')
expect(wrapper.find('dialog').exists()).toBe(false)
await wrapper.findAll('button').find(b=>b.text()==='查看记忆')!.trigger('click')
await flushPromises()
expect(request).toHaveBeenCalledWith(expect.stringContaining('scope=project&projectId=project-a'))
await wrapper.findAll('button').find(b=>b.text()==='返回项目')!.trigger('click')
await flushPromises()
expect(wrapper.text()).toContain('新建项目')
await wrapper.get('nav').findAll('button').find(b=>b.text()==='用户记忆')!.trigger('click')
await flushPromises()
expect(request).toHaveBeenCalledWith(expect.stringContaining('scope=user'))
expect(wrapper.text()).toContain('同一账号的 Bot 共享')
wrapper.unmount()
})
it('keeps VM management admin-only, including a requested initial VM page',async()=>{
const wrapper=mountDialog(false,'vm')
await flushPromises()
expect(wrapper.get('nav').text()).not.toContain('本地虚拟机')
expect(wrapper.find('[data-testid="vm-settings"]').exists()).toBe(false)
await wrapper.setProps({isAdmin:true})
await wrapper.get('nav').findAll('button').find(b=>b.text()==='本地虚拟机')!.trigger('click')
await flushPromises()
expect(wrapper.find('[data-testid="vm-settings"]').exists()).toBe(true)
await wrapper.setProps({isAdmin:false})
await flushPromises()
expect(wrapper.find('[data-testid="vm-settings"]').exists()).toBe(false)
expect(wrapper.text()).toContain('项目示例')
wrapper.unmount()
})