import { describe, it, expect, afterEach, vi } from 'vitest'; import { cleanup, render } from 'vitest-browser-svelte'; import { page } from 'vitest/browser'; import EnrichmentBlock from './EnrichmentBlock.svelte'; // Hoist the mutable navigation reference so vi.mock's factory (also hoisted) // can read it via a getter. Sync factory, no dynamic import: ADR-012 invariant. const { mockNavigating } = vi.hoisted(() => ({ mockNavigating: { type: null as string | null } })); vi.mock('$app/state', () => ({ get navigating() { return mockNavigating; } })); afterEach(() => { cleanup(); mockNavigating.type = null; }); type Doc = { id: string; title: string; uploadedAt: string }; function doc(id: string, title = 'Doc'): Doc { return { id, title, uploadedAt: '2026-04-20T12:00:00' }; } describe('EnrichmentBlock', () => { it('renders nothing when topDocs is empty and banner count is 0', async () => { render(EnrichmentBlock, { topDocs: [], totalCount: 0, bannerCount: 0, onBannerClose: vi.fn() }); await expect.element(page.getByTestId('enrichment-block')).not.toBeInTheDocument(); }); it('renders the list component when topDocs is non-empty', async () => { render(EnrichmentBlock, { topDocs: [doc('d1')], totalCount: 1, bannerCount: 0, onBannerClose: vi.fn() }); await expect.element(page.getByTestId('dashboard-needs-metadata')).toBeInTheDocument(); }); it('renders the banner when bannerCount > 0', async () => { render(EnrichmentBlock, { topDocs: [], totalCount: 0, bannerCount: 3, onBannerClose: vi.fn() }); await expect.element(page.getByRole('status')).toBeInTheDocument(); }); it('composes banner + list when both are present', async () => { render(EnrichmentBlock, { topDocs: [doc('d1')], totalCount: 1, bannerCount: 2, onBannerClose: vi.fn() }); await expect.element(page.getByRole('status')).toBeInTheDocument(); await expect.element(page.getByTestId('dashboard-needs-metadata')).toBeInTheDocument(); }); it('renders the skeleton when navigation is active and topDocs is empty', async () => { mockNavigating.type = 'link'; render(EnrichmentBlock, { topDocs: [], totalCount: 0, bannerCount: 0, onBannerClose: vi.fn() }); await expect.element(page.getByTestId('enrichment-block-skeleton')).toBeInTheDocument(); }); it('does not render the skeleton when topDocs is non-empty even during navigation', async () => { mockNavigating.type = 'link'; render(EnrichmentBlock, { topDocs: [doc('d1')], totalCount: 1, bannerCount: 0, onBannerClose: vi.fn() }); await expect.element(page.getByTestId('enrichment-block-skeleton')).not.toBeInTheDocument(); }); });