test: Fix Storybook mocks

This commit is contained in:
Aleksander Grygier 2025-11-29 02:36:41 +01:00
parent 493ef08723
commit 2d556bb93c
3 changed files with 44 additions and 20 deletions

View File

@ -70,17 +70,19 @@
await expect(acceptAttr).not.toContain('image/'); await expect(acceptAttr).not.toContain('image/');
await expect(acceptAttr).not.toContain('audio/'); await expect(acceptAttr).not.toContain('audio/');
// Open file attachments dropdown
const fileUploadButton = canvas.getByText('Attach files'); const fileUploadButton = canvas.getByText('Attach files');
await userEvent.click(fileUploadButton); await userEvent.click(fileUploadButton);
const recordButton = canvas.getAllByRole('button', { name: 'Start recording' })[1]; // Check dropdown menu items are disabled (no modalities)
const imagesButton = document.querySelector('.images-button'); const imagesButton = document.querySelector('.images-button');
const audioButton = document.querySelector('.audio-button'); const audioButton = document.querySelector('.audio-button');
await expect(recordButton).toBeDisabled();
await expect(imagesButton).toHaveAttribute('data-disabled'); await expect(imagesButton).toHaveAttribute('data-disabled');
await expect(audioButton).toHaveAttribute('data-disabled'); await expect(audioButton).toHaveAttribute('data-disabled');
// Close dropdown by pressing Escape
await userEvent.keyboard('{Escape}');
}} }}
/> />
@ -97,13 +99,10 @@
const acceptAttr = fileInput?.getAttribute('accept'); const acceptAttr = fileInput?.getAttribute('accept');
console.log('Vision modality accept attr:', acceptAttr); console.log('Vision modality accept attr:', acceptAttr);
// Open file attachments dropdown
const fileUploadButton = canvas.getByText('Attach files'); const fileUploadButton = canvas.getByText('Attach files');
await userEvent.click(fileUploadButton); await userEvent.click(fileUploadButton);
// Test that record button is disabled (no audio support)
const recordButton = canvas.getAllByRole('button', { name: 'Start recording' })[1];
await expect(recordButton).toBeDisabled();
// Test that Images button is enabled (vision support) // Test that Images button is enabled (vision support)
const imagesButton = document.querySelector('.images-button'); const imagesButton = document.querySelector('.images-button');
await expect(imagesButton).not.toHaveAttribute('data-disabled'); await expect(imagesButton).not.toHaveAttribute('data-disabled');
@ -112,11 +111,10 @@
const audioButton = document.querySelector('.audio-button'); const audioButton = document.querySelector('.audio-button');
await expect(audioButton).toHaveAttribute('data-disabled'); await expect(audioButton).toHaveAttribute('data-disabled');
// Fix for dropdown menu side effect // Close dropdown by pressing Escape
const body = document.querySelector('body'); await userEvent.keyboard('{Escape}');
if (body) body.style.pointerEvents = 'all';
console.log('✅ Vision modality: Images enabled, Audio/Recording disabled'); console.log('✅ Vision modality: Images enabled, Audio disabled');
}} }}
/> />
@ -131,13 +129,10 @@
const acceptAttr = fileInput?.getAttribute('accept'); const acceptAttr = fileInput?.getAttribute('accept');
console.log('Audio modality accept attr:', acceptAttr); console.log('Audio modality accept attr:', acceptAttr);
// Open file attachments dropdown
const fileUploadButton = canvas.getByText('Attach files'); const fileUploadButton = canvas.getByText('Attach files');
await userEvent.click(fileUploadButton); await userEvent.click(fileUploadButton);
// Test that record button is enabled (audio support)
const recordButton = canvas.getAllByRole('button', { name: 'Start recording' })[1];
await expect(recordButton).not.toBeDisabled();
// Test that Images button is disabled (no vision support) // Test that Images button is disabled (no vision support)
const imagesButton = document.querySelector('.images-button'); const imagesButton = document.querySelector('.images-button');
await expect(imagesButton).toHaveAttribute('data-disabled'); await expect(imagesButton).toHaveAttribute('data-disabled');
@ -146,11 +141,10 @@
const audioButton = document.querySelector('.audio-button'); const audioButton = document.querySelector('.audio-button');
await expect(audioButton).not.toHaveAttribute('data-disabled'); await expect(audioButton).not.toHaveAttribute('data-disabled');
// Fix for dropdown menu side effect // Close dropdown by pressing Escape
const body = document.querySelector('body'); await userEvent.keyboard('{Escape}');
if (body) body.style.pointerEvents = 'all';
console.log('✅ Audio modality: Audio/Recording enabled, Images disabled'); console.log('✅ Audio modality: Audio enabled, Images disabled');
}} }}
/> />

View File

@ -3,7 +3,6 @@
import ChatSidebar from '$lib/components/app/chat/ChatSidebar/ChatSidebar.svelte'; import ChatSidebar from '$lib/components/app/chat/ChatSidebar/ChatSidebar.svelte';
import { waitFor } from 'storybook/test'; import { waitFor } from 'storybook/test';
import { screen } from 'storybook/test'; import { screen } from 'storybook/test';
import type { DatabaseConversation } from '$lib/types';
const { Story } = defineMeta({ const { Story } = defineMeta({
title: 'Components/ChatSidebar', title: 'Components/ChatSidebar',

View File

@ -1,10 +1,15 @@
import { serverStore } from '$lib/stores/server.svelte'; import { serverStore } from '$lib/stores/server.svelte';
import { modelsStore } from '$lib/stores/models.svelte';
/** /**
* Mock server properties for Storybook testing * Mock server properties for Storybook testing
* This utility allows setting mock server configurations without polluting production code * This utility allows setting mock server configurations without polluting production code
*/ */
export function mockServerProps(props: Partial<ApiLlamaCppServerProps>): void { export function mockServerProps(props: Partial<ApiLlamaCppServerProps>): void {
// Reset any pointer-events from previous tests (dropdown cleanup)
const body = document.querySelector('body');
if (body) body.style.pointerEvents = '';
// Directly set the props for testing purposes // Directly set the props for testing purposes
(serverStore as unknown as { props: ApiLlamaCppServerProps }).props = { (serverStore as unknown as { props: ApiLlamaCppServerProps }).props = {
model_path: props.model_path || 'test-model', model_path: props.model_path || 'test-model',
@ -14,6 +19,32 @@ export function mockServerProps(props: Partial<ApiLlamaCppServerProps>): void {
}, },
...props ...props
} as ApiLlamaCppServerProps; } as ApiLlamaCppServerProps;
// Set router mode role so activeModelId can be set
(serverStore as unknown as { props: ApiLlamaCppServerProps }).props.role = 'ROUTER';
// Also mock modelsStore methods for modality checking
const vision = props.modalities?.vision ?? false;
const audio = props.modalities?.audio ?? false;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(modelsStore as any).modelSupportsVision = () => vision;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(modelsStore as any).modelSupportsAudio = () => audio;
// Mock models list with a test model so activeModelId can be resolved
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(modelsStore as any).models = [
{
id: 'test-model',
name: 'Test Model',
model: 'test-model'
}
];
// Mock selectedModelId
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(modelsStore as any).selectedModelId = 'test-model';
} }
/** /**