Write ChatWidget.vue tests

This commit is contained in:
Nemo Godebski-Pedersen 2025-02-28 13:36:42 +00:00
parent de87e35309
commit 702c23e159
6 changed files with 83 additions and 12 deletions

View File

@ -76,6 +76,8 @@ export default {
console.log('Opey Status: ', this.opeyContext.status)
} catch (error) {
console.error('Error in chat:', error);
// on error, remove the assistant message placeholder, as it will be empty.
this.opeyContext.messages = this.opeyContext.messages.filter(m => m.id !== this.opeyContext.currentAssistantMessage.id);
this.opeyContext.status = 'ready';
}
},

View File

@ -87,12 +87,16 @@ export async function sendOpeyMessage(
if (!stream) {
throw new Error('No stream returned from API')
}
if (response.status !== 200) {
throw new Error(`Error sending Opey message: ${response.statusText}`);
}
await processOpeyStream(stream, context);
} catch (error) {
console.error('Error sending Opey message:', error);
context.status = 'ready';
throw error;
throw new Error(`Error sending Opey message: ${error}`);
}
}

View File

@ -1,9 +1,77 @@
import { mount } from '@vue/test-utils';
import { describe, it, expect } from 'vitest';
import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest';
import ChatWidget from '../components/ChatWidget.vue'
import { OpeyStreamContext } from '@/obp/opey-functions';
describe('ChatWidget', () => {
it('should append messages in correct order', async () => {
let mockContext: OpeyStreamContext;
beforeEach(() => {
mockContext = {
currentAssistantMessage: {
id: '123',
role: 'assistant',
content: '',
},
messages: [],
status: 'loading',
}
// create a mock stream
const mockStream = new ReadableStream<Uint8Array>({
start(controller) {
controller.enqueue(new TextEncoder().encode(`data: {"type":"token","content":"test"}\n`));
controller.close();
},
});
// mock the fetch function
global.fetch = vi.fn(() =>
Promise.resolve(new Response(mockStream, {
headers: { 'content-type': 'text/event-stream' },
status: 200,
}))
);
})
afterEach(() => {
vi.clearAllMocks()
})
it('should call fetch when sending a user message', async () => {
const wrapper = mount(ChatWidget, {})
await wrapper.vm.onSubmit()
expect(global.fetch).toHaveBeenCalled()
})
it('should clear the assistant message placeholder from messages list on error', async () => {
// mock the fetch function with a rejected promise
const wrapper = mount(ChatWidget, {})
global.fetch = vi.fn(() =>
Promise.reject(new Error('Test error'))
);
await wrapper.vm.onSubmit()
expect(wrapper.vm.opeyContext.messages.find(m => m.id === wrapper.vm.opeyContext.currentAssistantMessage.id)).toBeUndefined()
})
it('should trigger onSubmit when enter key is pressed in the input', async () => {
const wrapper = mount(ChatWidget, {})
// This opens the chat widget
wrapper.vm.chatOpen = true
await wrapper.vm.$nextTick()
// Get the input element and trigger the keypress enter event
// This will probably fail if the class name of the input element changes
const input = wrapper.get('.user-input-container input')
input.trigger('keypress.enter')
expect(global.fetch).toHaveBeenCalled()
})
it('displays chat when chatOpen is set to true', async () => {
const wrapper = mount(ChatWidget, {})
wrapper.vm.chatOpen = true
await wrapper.vm.$nextTick()
expect(wrapper.find('.chat-container').exists()).toBe(true)
})
})

View File

@ -135,7 +135,7 @@ describe('sendOpeyMessage', () => {
expect(global.fetch).toHaveBeenCalled()
})
it("should push the 'ready' status to the context", async () => {
it("should push the 'ready' status to the context after success", async () => {
await OpeyModule.sendOpeyMessage('test message', '123', false, mockContext)

View File

@ -45,11 +45,4 @@ export default defineConfig({
},
},
},
test: {
// enable jest-like global test APIs
globals: true,
// simulate DOM with happy-dom
// (requires installing happy-dom as a peer dependency)
environment: 'happy-dom'
},
})

View File

@ -34,6 +34,10 @@ export default defineConfig({
exclude:[
...configDefaults.exclude,
'**/backend-tests/*'
]
],
pool: "vmThreads",
deps: {
inline: ['element-plus'],
}
},
});