import { render, screen, waitFor } from '@testing-library/react' import userEvent from '@testing-library/user-event' import { describe, expect, it, vi, beforeEach } from 'vitest' import './i18n' import App from './App' import * as api from './api' vi.mock('./api') const statsBody = { entities: 7, sessions: 42, utterances: 133, anomalies: 1024 } const codexBody = { entities: [] } function mockFetch() { vi.stubGlobal( 'fetch', vi.fn(async (input: RequestInfo | URL) => { const url = String(input) const body = url.includes('/api/stats') ? statsBody : codexBody return new Response(JSON.stringify(body), { status: 200, headers: { 'Content-Type': 'application/json' }, }) }), ) } describe('App', () => { beforeEach(() => { mockFetch() vi.mocked(api.me).mockRejectedValue(new Error('not authenticated')) }) it('renders the landing page with the Quantumancy title', async () => { render() await waitFor(() => expect(screen.getAllByText('QUANTUMANCY').length).toBeGreaterThan(0), ) }) it('shows live veil activity from /api/stats', async () => { render() // counters animate up from 0 over ~900ms — wait for the final values await waitFor( () => { const values = Array.from(document.querySelectorAll('.stat-value')).map( (el) => el.textContent, ) expect(values).toContain('42') expect(values).toContain('7') }, { timeout: 4000 }, ) }) it('sends anonymous visitors to /enter from the séance CTA', async () => { render() await waitFor(() => expect(screen.getAllByText('QUANTUMANCY').length).toBeGreaterThan(0), ) const cta = screen.getByRole('button', { name: /begin the séance/i }) await userEvent.click(cta) await waitFor(() => expect(window.location.pathname).toBe('/enter')) }) })