1<script module lang="ts">
  2	import { defineMeta } from '@storybook/addon-svelte-csf';
  3	import ChatForm from '$lib/components/app/chat/ChatForm/ChatForm.svelte';
  4	import { expect } from 'storybook/test';
  5	import { mockServerProps, mockConfigs } from './fixtures/storybook-mocks';
  6	import jpgAsset from './fixtures/assets/1.jpg?url';
  7	import svgAsset from './fixtures/assets/hf-logo.svg?url';
  8	import pdfAsset from './fixtures/assets/example.pdf?raw';
  9
 10	const { Story } = defineMeta({
 11		title: 'Components/ChatScreen/ChatForm',
 12		component: ChatForm,
 13		parameters: {
 14			layout: 'centered'
 15		}
 16	});
 17
 18	let fileAttachments = $state([
 19		{
 20			id: '1',
 21			name: '1.jpg',
 22			type: 'image/jpeg',
 23			size: 44891,
 24			preview: jpgAsset,
 25			file: new File([''], '1.jpg', { type: 'image/jpeg' })
 26		},
 27		{
 28			id: '2',
 29			name: 'hf-logo.svg',
 30			type: 'image/svg+xml',
 31			size: 1234,
 32			preview: svgAsset,
 33			file: new File([''], 'hf-logo.svg', { type: 'image/svg+xml' })
 34		},
 35		{
 36			id: '3',
 37			name: 'example.pdf',
 38			type: 'application/pdf',
 39			size: 351048,
 40			file: new File([pdfAsset], 'example.pdf', { type: 'application/pdf' })
 41		}
 42	]);
 43</script>
 44
 45<Story
 46	name="Default"
 47	args={{ class: 'max-w-[56rem] w-[calc(100vw-2rem)]' }}
 48	play={async ({ canvas, userEvent }) => {
 49		mockServerProps(mockConfigs.noModalities);
 50
 51		const textarea = await canvas.findByRole('textbox');
 52		const submitButton = await canvas.findByRole('button', { name: 'Send' });
 53
 54		// Expect the input to be focused after the component is mounted
 55		await expect(textarea).toHaveFocus();
 56
 57		// Expect the submit button to be disabled
 58		await expect(submitButton).toBeDisabled();
 59
 60		const text = 'What is the meaning of life?';
 61
 62		await userEvent.clear(textarea);
 63		await userEvent.type(textarea, text);
 64
 65		await expect(textarea).toHaveValue(text);
 66
 67		const fileInput = document.querySelector('input[type="file"]');
 68		await expect(fileInput).not.toHaveAttribute('accept');
 69
 70		// Open file attachments dropdown
 71		const fileUploadButton = canvas.getByText('Attach files');
 72		await userEvent.click(fileUploadButton);
 73
 74		// Check dropdown menu items are disabled (no modalities)
 75		const imagesButton = document.querySelector('.images-button');
 76		const audioButton = document.querySelector('.audio-button');
 77
 78		await expect(imagesButton).toHaveAttribute('data-disabled');
 79		await expect(audioButton).toHaveAttribute('data-disabled');
 80
 81		// Close dropdown by pressing Escape
 82		await userEvent.keyboard('{Escape}');
 83	}}
 84/>
 85
 86<Story name="Loading" args={{ class: 'max-w-[56rem] w-[calc(100vw-2rem)]', isLoading: true }} />
 87
 88<Story
 89	name="VisionModality"
 90	args={{ class: 'max-w-[56rem] w-[calc(100vw-2rem)]' }}
 91	play={async ({ canvas, userEvent }) => {
 92		mockServerProps(mockConfigs.visionOnly);
 93
 94		// Open file attachments dropdown and verify it works
 95		const fileUploadButton = canvas.getByText('Attach files');
 96		await userEvent.click(fileUploadButton);
 97
 98		// Verify dropdown menu items exist
 99		const imagesButton = document.querySelector('.images-button');
100		const audioButton = document.querySelector('.audio-button');
101
102		await expect(imagesButton).toBeInTheDocument();
103		await expect(audioButton).toBeInTheDocument();
104
105		// Close dropdown by pressing Escape
106		await userEvent.keyboard('{Escape}');
107
108		console.log(' Vision modality: Dropdown menu verified');
109	}}
110/>
111
112<Story
113	name="AudioModality"
114	args={{ class: 'max-w-[56rem] w-[calc(100vw-2rem)]' }}
115	play={async ({ canvas, userEvent }) => {
116		mockServerProps(mockConfigs.audioOnly);
117
118		// Open file attachments dropdown and verify it works
119		const fileUploadButton = canvas.getByText('Attach files');
120		await userEvent.click(fileUploadButton);
121
122		// Verify dropdown menu items exist
123		const imagesButton = document.querySelector('.images-button');
124		const audioButton = document.querySelector('.audio-button');
125
126		await expect(imagesButton).toBeInTheDocument();
127		await expect(audioButton).toBeInTheDocument();
128
129		// Close dropdown by pressing Escape
130		await userEvent.keyboard('{Escape}');
131
132		console.log(' Audio modality: Dropdown menu verified');
133	}}
134/>
135
136<Story
137	name="FileAttachments"
138	args={{
139		class: 'max-w-[56rem] w-[calc(100vw-2rem)]',
140		uploadedFiles: fileAttachments
141	}}
142	play={async ({ canvas }) => {
143		mockServerProps(mockConfigs.bothModalities);
144
145		const jpgAttachment = canvas.getByAltText('1.jpg');
146		const svgAttachment = canvas.getByAltText('hf-logo.svg');
147		const pdfFileExtension = canvas.getByText('PDF');
148		const pdfAttachment = canvas.getByText('example.pdf');
149		const pdfSize = canvas.getByText('342.82 KB');
150
151		await expect(jpgAttachment).toBeInTheDocument();
152		await expect(jpgAttachment).toHaveAttribute('src', jpgAsset);
153
154		await expect(svgAttachment).toBeInTheDocument();
155		await expect(svgAttachment).toHaveAttribute('src', svgAsset);
156
157		await expect(pdfFileExtension).toBeInTheDocument();
158		await expect(pdfAttachment).toBeInTheDocument();
159		await expect(pdfSize).toBeInTheDocument();
160	}}
161/>