import { test, expect, vi, afterEach, beforeEach } from 'vitest' import { render, fireEvent, waitFor, screen, act } from '@testing-library/react' import { isSearchOpen } from '@stores/search' import Search from './Search' let portalRoot: HTMLDivElement let unsubscribe: () => void let fetchSpy: any let originalFetch: any let storeState = false beforeEach(() => { portalRoot = global.document.createElement('div') portalRoot.setAttribute('id', 'document') global.document.body.appendChild(portalRoot) // Track the store's state unsubscribe = isSearchOpen.subscribe((value) => { storeState = value }) // Mock fetch API originalFetch = globalThis.fetch globalThis.fetch = async () => { return { json: () => Promise.resolve([{ data: { title: 'Test Post' }, slug: 'test-post' }]) } as Response } fetchSpy = vi.spyOn(globalThis, 'fetch') }) afterEach(() => { portalRoot.remove() unsubscribe() globalThis.fetch = originalFetch }) test('Search component', async () => { render() act(() => { // Simulate opening the search isSearchOpen.set(true) }) // Wait for the fetch to complete await waitFor(() => { expect(fetchSpy).toHaveBeenCalled() }) // Check if the search input appears const searchInput = screen.getByPlaceholderText('Search everything') expect(searchInput).toBeInTheDocument() fireEvent.change(searchInput, { target: { value: 'Test' } }) expect(searchInput).toHaveValue('Test') expect(screen.getByText('Test Post')).toBeInTheDocument() const closeButton = screen.getByTitle('Close search') fireEvent.click(closeButton) // Check if the search is closed await waitFor(() => expect(storeState).toBe(false)) })