Files
hermes-web-ui/tests/client/group-message-item-highlight.test.ts
Zhicheng Han cf3b853f1d fix: harden chat tool payload rendering
(cherry picked from commit 16daa5286cad7dd89471a9cc9c46d4a4ca8b8876)
2026-06-05 09:22:53 +08:00

107 lines
3.0 KiB
TypeScript

// @vitest-environment jsdom
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { mount } from '@vue/test-utils'
import { createPinia, setActivePinia } from 'pinia'
vi.mock('vue-i18n', () => ({
useI18n: () => ({
t: (key: string) => key,
}),
}))
vi.mock('naive-ui', () => ({
useMessage: () => ({
error: vi.fn(),
success: vi.fn(),
warning: vi.fn(),
info: vi.fn(),
}),
}))
vi.mock('@/api/hermes/download', () => ({
getDownloadUrl: (_path: string, name: string) => `/download/${name}`,
}))
import GroupMessageItem from '@/components/hermes/group-chat/GroupMessageItem.vue'
import type { ChatMessage } from '@/api/hermes/group-chat'
function mountToolMessage(message: Partial<ChatMessage>) {
return mount(GroupMessageItem, {
props: {
message: {
id: 'group-tool',
roomId: 'room-1',
senderId: 'agent-1',
senderName: 'UAT Agent',
role: 'tool',
content: '',
timestamp: new Date().toISOString(),
toolName: 'runtime_payload',
toolStatus: 'done',
...message,
} as ChatMessage,
agents: [],
members: [],
currentUserId: 'user-1',
},
global: { stubs: { MarkdownRenderer: true, ProfileAvatar: true } },
})
}
describe('GroupMessageItem tool details', () => {
beforeEach(() => {
setActivePinia(createPinia())
Object.defineProperty(window, 'isSecureContext', {
configurable: true,
value: true,
})
Object.defineProperty(navigator, 'clipboard', {
configurable: true,
value: {
writeText: vi.fn().mockResolvedValue(undefined),
},
})
Object.defineProperty(window, 'speechSynthesis', {
configurable: true,
value: {
addEventListener: vi.fn(),
removeEventListener: vi.fn(),
getVoices: vi.fn(() => []),
speak: vi.fn(),
cancel: vi.fn(),
pause: vi.fn(),
resume: vi.fn(),
},
})
})
it('normalizes non-string runtime tool payloads before rendering', async () => {
const wrapper = mountToolMessage({
toolArgs: { group: true, values: [1, 2, 3] },
toolResult: false,
} as unknown as Partial<ChatMessage>)
await wrapper.find('.tool-line').trigger('click')
const blocks = wrapper.findAll('.tool-details .hljs-code-block')
expect(blocks).toHaveLength(2)
expect(blocks[0].find('.code-lang').text()).toBe('json')
expect(blocks[0].find('code').text()).toContain('values')
expect(blocks[1].find('.code-lang').text()).toBe('json')
expect(blocks[1].find('code').text()).toBe('false')
})
it('keeps plain string false payloads as text', async () => {
const wrapper = mountToolMessage({
toolResult: 'false',
})
await wrapper.find('.tool-line').trigger('click')
const block = wrapper.find('.tool-details .hljs-code-block')
expect(block.exists()).toBe(true)
expect(block.find('.code-lang').text()).toBe('text')
expect(block.find('code').text()).toBe('false')
})
})