diff --git a/frontend/src/lib/components/EnrichmentBlock.svelte b/frontend/src/lib/components/EnrichmentBlock.svelte index 2743329f..a4327cf3 100644 --- a/frontend/src/lib/components/EnrichmentBlock.svelte +++ b/frontend/src/lib/components/EnrichmentBlock.svelte @@ -31,8 +31,10 @@ const showBlock = $derived(topDocs.length > 0 || bannerCount > 0 || showSkeleton {:else if showSkeleton} {/if} diff --git a/frontend/src/lib/components/EnrichmentBlock.svelte.spec.ts b/frontend/src/lib/components/EnrichmentBlock.svelte.spec.ts index be187cf5..ac5167d1 100644 --- a/frontend/src/lib/components/EnrichmentBlock.svelte.spec.ts +++ b/frontend/src/lib/components/EnrichmentBlock.svelte.spec.ts @@ -2,14 +2,20 @@ import { describe, it, expect, afterEach, vi } from 'vitest'; import { cleanup, render } from 'vitest-browser-svelte'; import { page } from 'vitest/browser'; +// The store must live in a separate module because vi.mock factories are +// hoisted and cannot reference top-level variables defined in this file. +import { navigatingStore } from './__mocks__/navigatingStore'; import EnrichmentBlock from './EnrichmentBlock.svelte'; vi.mock('$app/stores', async () => { - const { writable } = await import('svelte/store'); - return { navigating: writable(null) }; + const mod = await import('./__mocks__/navigatingStore'); + return { navigating: mod.navigatingStore }; }); -afterEach(cleanup); +afterEach(() => { + cleanup(); + navigatingStore.set(null); +}); type Doc = { id: string; title: string; uploadedAt: string }; @@ -58,4 +64,26 @@ describe('EnrichmentBlock', () => { await expect.element(page.getByRole('status')).toBeInTheDocument(); await expect.element(page.getByTestId('dashboard-needs-metadata')).toBeInTheDocument(); }); + + it('renders the skeleton when $navigating is active and topDocs is empty', async () => { + navigatingStore.set({ 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 $navigating', async () => { + navigatingStore.set({ type: 'link' }); + render(EnrichmentBlock, { + topDocs: [doc('d1')], + totalCount: 1, + bannerCount: 0, + onBannerClose: vi.fn() + }); + await expect.element(page.getByTestId('enrichment-block-skeleton')).not.toBeInTheDocument(); + }); }); diff --git a/frontend/src/lib/components/__mocks__/navigatingStore.ts b/frontend/src/lib/components/__mocks__/navigatingStore.ts new file mode 100644 index 00000000..932122e4 --- /dev/null +++ b/frontend/src/lib/components/__mocks__/navigatingStore.ts @@ -0,0 +1,3 @@ +import { writable } from 'svelte/store'; + +export const navigatingStore = writable(null);