diff --git a/frontend/src/lib/components/EnrichmentBlock.svelte b/frontend/src/lib/components/EnrichmentBlock.svelte new file mode 100644 index 00000000..2743329f --- /dev/null +++ b/frontend/src/lib/components/EnrichmentBlock.svelte @@ -0,0 +1,39 @@ + + +{#if showBlock} +
+ {#if bannerCount > 0} + + {/if} + {#if topDocs.length > 0} + + {:else if showSkeleton} + + {/if} +
+{/if} diff --git a/frontend/src/lib/components/EnrichmentBlock.svelte.spec.ts b/frontend/src/lib/components/EnrichmentBlock.svelte.spec.ts new file mode 100644 index 00000000..be187cf5 --- /dev/null +++ b/frontend/src/lib/components/EnrichmentBlock.svelte.spec.ts @@ -0,0 +1,61 @@ +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'; + +vi.mock('$app/stores', async () => { + const { writable } = await import('svelte/store'); + return { navigating: writable(null) }; +}); + +afterEach(cleanup); + +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(); + }); +});