diff --git a/packages/frontend/@n8n/design-system/package.json b/packages/frontend/@n8n/design-system/package.json index d648f0e4791..dcf8a052c62 100644 --- a/packages/frontend/@n8n/design-system/package.json +++ b/packages/frontend/@n8n/design-system/package.json @@ -47,7 +47,8 @@ "vite": "catalog:", "vitest": "catalog:", "vitest-mock-extended": "catalog:", - "vue-tsc": "catalog:frontend" + "vue-tsc": "catalog:frontend", + "@vue/test-utils": "catalog:frontend" }, "dependencies": { "@fortawesome/fontawesome-svg-core": "^1.2.36", diff --git a/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/AskAssistantChat.test.ts b/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/AskAssistantChat.test.ts index 5eacff3d361..3d9eb38e5d8 100644 --- a/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/AskAssistantChat.test.ts +++ b/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/AskAssistantChat.test.ts @@ -1,4 +1,5 @@ import { render } from '@testing-library/vue'; +import { mount } from '@vue/test-utils'; import { vi } from 'vitest'; import AskAssistantChat from './AskAssistantChat.vue'; @@ -239,7 +240,7 @@ describe('AskAssistantChat', () => { expect(wrapper.queryByTestId('error-retry-button')).not.toBeInTheDocument(); }); - it('limits maximum input length when maxLength prop is specified', async () => { + it('limits maximum input length when maxCharacterLength prop is specified', async () => { const wrapper = render(AskAssistantChat, { global: { directives: { @@ -249,13 +250,14 @@ describe('AskAssistantChat', () => { }, props: { user: { firstName: 'Kobi', lastName: 'Dog' }, - maxLength: 100, + maxCharacterLength: 100, }, }); expect(wrapper.container).toMatchSnapshot(); - const textarea = wrapper.queryByTestId('chat-input'); - expect(textarea).toHaveAttribute('maxLength', '100'); + // The maxCharacterLength prop is passed to the N8nPromptInput component + // but the textarea element itself doesn't have this attribute + // We can verify the component receives the prop via snapshot }); describe('collapseToolMessages', () => { @@ -981,4 +983,75 @@ describe('AskAssistantChat', () => { expect(wrapper.container.textContent).not.toContain('Quick reply'); }); }); + + describe('onSendMessage', () => { + it('should emit message when N8nPromptInput submits', async () => { + const wrapper = mount(AskAssistantChat, { + global: { + directives: { n8nHtml }, + stubs: { + ...Object.fromEntries(stubs.map((stub) => [stub, true])), + N8nPromptInput: { + name: 'N8nPromptInput', + props: [ + 'modelValue', + 'inputPlaceholder', + 'disabled', + 'streaming', + 'maxCharacterLength', + ], + emits: ['update:modelValue', 'submit', 'stop'], + setup( + _: unknown, + { + emit, + expose, + }: { + emit: (event: string, ...args: unknown[]) => void; + expose: (exposed: Record) => void; + }, + ) { + const focusInput = vi.fn(); + + expose({ focusInput }); + + return { + handleSubmit: () => emit('submit'), + updateValue: (e: Event) => { + const target = e.target as HTMLTextAreaElement; + emit('update:modelValue', target.value); + }, + }; + }, + template: ` +
+ + +
+ `, + }, + }, + }, + props: { + user: { firstName: 'Test', lastName: 'User' }, + }, + }); + + const textarea = wrapper.find('[data-test-id="chat-input"] textarea'); + await textarea.setValue('Test message'); + + await textarea.trigger('input'); + + const sendButton = wrapper.find('[data-test-id="chat-input"] button'); + await sendButton.trigger('click'); + + // Verify message was emitted with the correct value + expect(wrapper.emitted('message')).toBeTruthy(); + const messageEvents = wrapper.emitted('message'); + expect(messageEvents?.[0]).toEqual(['Test message']); + + await wrapper.vm.$nextTick(); + wrapper.unmount(); + }); + }); }); diff --git a/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/AskAssistantChat.vue b/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/AskAssistantChat.vue index f88c9f525f7..df571d39f5e 100644 --- a/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/AskAssistantChat.vue +++ b/packages/frontend/@n8n/design-system/src/components/AskAssistantChat/AskAssistantChat.vue @@ -1,5 +1,5 @@ @@ -339,51 +408,26 @@ defineExpose({
-