import { act, renderHook, waitFor } from '@testing-library/react' import { afterEach, describe, expect, it, vi } from 'vitest' import { useSecondaryDisplay } from './SecondaryDisplay' import { parseSecondaryDisplayGeometry, secondaryDisplayFeatures } from './secondaryDisplayGeometry' afterEach(() => { vi.restoreAllMocks() delete document.body.dataset.theme document.body.replaceChildren() }) describe('secondary display geometry', () => { it('restores a valid remembered window position', () => { expect(parseSecondaryDisplayGeometry('{"left":1920,"top":0,"width":720,"height":1040}')).toEqual({ left: 1920, top: 0, width: 720, height: 1040, }) }) it('rejects malformed state and bounds unsafe dimensions', () => { expect(parseSecondaryDisplayGeometry('not-json')).toBeNull() expect(parseSecondaryDisplayGeometry('{"left":0,"top":0,"width":2,"height":99999}')).toEqual({ left: 0, top: 0, width: 420, height: 2160, }) }) it('builds a resizable popup feature string', () => { expect(secondaryDisplayFeatures({ left: 1920, top: 10, width: 700, height: 900 })).toContain( 'left=1920,top=10,width=700,height=900,resizable=yes,scrollbars=yes', ) }) }) describe('secondary display document', () => { it('preserves metadata, semantics, focus and the active theme', async () => { const iframe = document.createElement('iframe') document.body.append(iframe) const popup = iframe.contentWindow! let closed = false Object.defineProperty(popup, 'closed', { configurable: true, get: () => closed }) Object.defineProperty(popup, 'close', { configurable: true, value: vi.fn(() => { closed = true }) }) Object.defineProperty(popup, 'focus', { configurable: true, value: vi.fn() }) vi.spyOn(window, 'open').mockReturnValue(popup) document.body.dataset.theme = 'dark' const launcher = document.createElement('button') launcher.textContent = 'Open tweede scherm' document.body.append(launcher) launcher.focus() const view = renderHook(() => useSecondaryDisplay()) act(() => view.result.current.open()) expect(popup.document.title).toBe('GeoIntel ยท Analyseconsole') expect(popup.document.documentElement.lang).toBe(document.documentElement.lang || 'nl') expect(popup.document.querySelector('meta[charset="utf-8"]')).not.toBeNull() expect(popup.document.querySelector('base')?.href).toBe(document.baseURI) expect(popup.document.querySelector('meta[name="viewport"]')).not.toBeNull() expect(popup.document.querySelector('h1')?.textContent).toBe('Analyseconsole') expect(popup.document.querySelector('main > h2')?.textContent).toBe('Live analyse en resultaten') expect(popup.document.activeElement).toBe(popup.document.querySelector('h1')) expect(popup.document.body.dataset.theme).toBe('dark') act(() => { document.body.dataset.theme = 'light' }) await waitFor(() => expect(popup.document.body.dataset.theme).toBe('light')) act(() => view.result.current.close()) expect(document.activeElement).toBe(launcher) }) })