({ name: m, value: m }))}
+ flyoutMenuOptions={clientChatStore.supportedModels.map((m) => ({ name: m, value: m }))}
onClose={onClose}
parentIsOpen={isOpen}
setMenuState={setMenuState}
diff --git a/src/components/chat/input/__tests__/ChatInput.test.tsx b/src/components/chat/input/__tests__/ChatInput.test.tsx
new file mode 100644
index 0000000..ed4d0ce
--- /dev/null
+++ b/src/components/chat/input/__tests__/ChatInput.test.tsx
@@ -0,0 +1,181 @@
+import { describe, it, expect, vi, beforeEach } from 'vitest';
+import { render, screen, fireEvent } from '@testing-library/react';
+import React from 'react';
+import ChatInput from '../ChatInput';
+import userOptionsStore from '../../../../stores/UserOptionsStore';
+import chatStore from '../../../../stores/ClientChatStore';
+
+// Mock browser APIs
+class MockResizeObserver {
+ observe() {}
+ unobserve() {}
+ disconnect() {}
+}
+
+// Add ResizeObserver to the global object
+global.ResizeObserver = MockResizeObserver;
+
+// Mock window.matchMedia
+Object.defineProperty(window, 'matchMedia', {
+ writable: true,
+ value: vi.fn().mockImplementation(query => ({
+ matches: false,
+ media: query,
+ onchange: null,
+ addListener: vi.fn(),
+ removeListener: vi.fn(),
+ addEventListener: vi.fn(),
+ removeEventListener: vi.fn(),
+ dispatchEvent: vi.fn(),
+ })),
+});
+
+// Mock dependencies
+vi.mock('../../../../stores/UserOptionsStore', () => ({
+ default: {
+ followModeEnabled: false,
+ toggleFollowMode: vi.fn(),
+ setFollowModeEnabled: vi.fn(),
+ },
+}));
+
+vi.mock('../../../../stores/ClientChatStore', () => ({
+ default: {
+ isLoading: false,
+ input: '',
+ setInput: vi.fn(),
+ sendMessage: vi.fn(),
+ setModel: vi.fn(),
+ model: 'test-model',
+ supportedModels: ['test-model', 'another-model'],
+ },
+}));
+
+// Mock the hooks
+vi.mock('../../../../hooks/useMaxWidth', () => ({
+ useMaxWidth: () => '100%',
+}));
+
+// Mock Chakra UI hooks
+vi.mock('@chakra-ui/react', async () => {
+ const actual = await vi.importActual('@chakra-ui/react');
+ return {
+ ...actual,
+ useBreakpointValue: () => '50rem',
+ useBreakpoint: () => 'lg',
+ };
+});
+
+// Mock the child components
+vi.mock('../input-menu/InputMenu', () => ({
+ default: ({ selectedModel, onSelectModel, isDisabled }) => (
+
+ Model: {selectedModel}
+
+
+ ),
+}));
+
+vi.mock('./ChatInputTextArea', () => ({
+ default: ({ inputRef, value, onChange, onKeyDown, isLoading }) => (
+