import { afterEach, expect, it, vi } from 'vitest'
import { flushPromises, mount } from '@vue/test-utils'
import { createPinia } from 'pinia'
import WorkspaceTimeline from '@/components/workspace/WorkspaceMessageTimeline.vue'
import MessageTimeline from '@/components/messages/MessageTimeline.vue'
import { workspaceMessagesToUi } from '@/components/workspace/viewModels'
import { WorkspaceTranscriptStore } from '@/components/workspace/transcriptStore'
import { buildMessageTimelineRows } from '@/utils/turnTrace'
import type { WorkspaceMessage } from '@shared/workspace'
const warning={code:'plugin_unavailable',service:'天气服务',message:'连接暂不可用,本次任务继续使用其他能力。'}
const message:WorkspaceMessage={id:'warning-message',conversationId:'chat',agentId:'bot',agentName:'竹儿',role:'assistant',content:'',reasoning:'',status:'complete',seq:1,createdAt:1,tools:[{id:'tool',name:'天气服务',status:'tool.complete'}],attachments:[],serviceWarnings:[warning]}
afterEach(()=>{vi.restoreAllMocks();vi.unstubAllGlobals()})
it('keeps warning-only messages visible independently of tool trace aggregation and model text',()=>{
const [ui]=workspaceMessagesToUi([JSON.parse(JSON.stringify(message))])
expect(ui?.serviceWarnings).toEqual([warning])
expect(ui?.status).toBe('settled')
expect(ui?.error).toBeUndefined()
const rows=buildMessageTimelineRows([ui!])
expect(rows.map(row=>row.kind)).toEqual(['trace','message'])
expect(rows[1]?.kind==='message'&&rows[1].message.serviceWarnings).toEqual([warning])
const [textOnly]=workspaceMessagesToUi([{...message,serviceWarnings:undefined,content:JSON.stringify({serviceWarnings:[warning]})}])
expect(textOnly?.serviceWarnings).toBeUndefined()
})
it.each(['workspace','session'])('shows non-blocking, escaped service notices with tools hidden in the %s timeline',async(timeline)=>{
vi.stubGlobal('ResizeObserver',class {observe(){}disconnect(){}})
const scrollTo=HTMLElement.prototype.scrollTo
HTMLElement.prototype.scrollTo=vi.fn()
const unsafe={code:'plugin_unavailable',service:'',message:' [修复](javascript:alert(3))'}
const messages=workspaceMessagesToUi([{...message,serviceWarnings:[warning,unsafe]}])
const wrapper=mount(timeline==='workspace'?WorkspaceTimeline:MessageTimeline,{props:{identity:'chat',messages,showTools:false},global:{plugins:[createPinia()],stubs:{AppIcon:true,AgentAvatar:true,MarkdownContent:{props:['content'],template:'