// @vitest-environment jsdom import '@testing-library/jest-dom/vitest'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; import { cleanup, render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { HttpResponse, http } from 'msw'; import { setupServer } from 'msw/node'; import { afterAll, afterEach, beforeAll, describe, expect, it } from 'vitest'; import type { ReactNode } from 'react'; import { MemoryRouter, Route, Routes, useLocation } from 'react-router-dom'; import { ConversationRoute } from '../../apps/dashboard/src/features/conversations/conversation-route.js'; import { MediaRoute } from '../../apps/dashboard/src/features/media/media-route.js'; const server = setupServer(); function LocationProbe() { const location = useLocation(); return {location.pathname}{location.search}; } function renderRoute(path: string, element: ReactNode) { const client = new QueryClient({ defaultOptions: { queries: { retry: false }, mutations: { retry: false } } }); render(); } beforeAll(() => server.listen({ onUnhandledRequest: 'error' })); afterEach(() => { cleanup(); server.resetHandlers(); }); afterAll(() => server.close()); describe('route-friendly filters', () => { it('hydrates and writes conversation search and status filters', async () => { server.use(http.get('/api/conversations', () => HttpResponse.json([]))); const user = userEvent.setup(); renderRoute('/conversations?q=alice&filter=received-images&showSellers=true', ); const search = await screen.findByRole('searchbox', { name: 'Search conversations' }); expect(search).toHaveValue('alice'); expect(screen.getByRole('combobox', { name: 'Filter conversations' })).toHaveValue('received-images'); expect(screen.getByRole('checkbox', { name: 'Show sellers' })).toBeChecked(); await user.clear(search); await user.type(search, 'bob'); expect(screen.getByLabelText('Current URL')).toHaveTextContent('q=bob'); }); it('hydrates and writes media filters', async () => { server.use( http.get('/api/media', () => HttpResponse.json([{ id: 'one', chatUsername: 'alice', chatRoomId: 'room-a', sender: 'alice', timestamp: Date.now(), originalUrl: 'https://example.test/a.gif', fileName: 'a.gif', relativePath: 'a.gif', createdAt: Date.now(), urlPath: '/media/a.gif' }])), http.get('/api/media/sync', () => HttpResponse.json({ isSyncing: false, lastSyncAt: null, lastSyncDurationMs: null, lastSyncChats: null, lastError: null, nextSyncAt: null })), ); const user = userEvent.setup(); renderRoute('/media?conversation=alice&type=gif', ); expect(await screen.findByRole('combobox', { name: 'Conversation' })).toHaveValue('alice'); await user.selectOptions(screen.getByRole('combobox', { name: 'Date range' }), '7d'); expect(screen.getByLabelText('Current URL')).toHaveTextContent('range=7d'); }); });