import { isValidElement, type ReactElement } from 'react' import { describe, expect, it, vi } from 'vitest' import { ExportNotesButton } from '@/features/export-notes' import { UploadsLeft } from '@/features/rate-limit' import { SearchNotes } from '@/features/search-notes' import { panelSlots } from '@/widgets/module-panel/model/slots' import type { ModuleName } from '@/widgets/module-panel/model/view' // The features' actions reach the shared API barrel; the slot mapping calls none of it. vi.mock('@/shared/api', () => ({})) const none: Record = { kv: false, nats: false, qdrant: false, git: false, s3: false } const enable = (service: string) => function slotFor(name: ModuleName, linked: Record) { const slot = panelSlots({ linked, query: 'budget', gitHost: 'git.example.test', enable }).find((s) => s.name === name) if (!slot) throw new Error(`no slot for ${name}`) return slot.content } describe('panelSlots', () => { it.each([ ['kv', 'kv'], ['nats', 'nats'], ['qdrant', 'qdrant'], ['git', 'git'], ['s3', 's3'], ] as const)('renders the enable card for %s, naming %s, when its variables are absent', (name, service) => { const content = slotFor(name, none) as ReactElement<{ 'data-enable': string }> expect(isValidElement(content)).toBe(true) expect(content.props['data-enable']).toBe(service) }) it('renders the uploads counter for kv when linked', () => { expect((slotFor('kv', { ...none, kv: true }) as ReactElement).type).toBe(UploadsLeft) }) it('renders the similarity search for qdrant when linked, with the query', () => { const content = slotFor('qdrant', { ...none, qdrant: true }) as ReactElement<{ query: string }> expect(content.type).toBe(SearchNotes) expect(content.props.query).toBe('budget') }) it('renders the export button for s3 when linked', () => { expect((slotFor('s3', { ...none, s3: true }) as ReactElement).type).toBe(ExportNotesButton) }) it('names the git host the packages install from when git is linked', () => { const content = slotFor('git', { ...none, git: true }) as ReactElement<{ children: unknown[] }> expect(content.type).toBe('p') expect(content.props.children).toContain('git.example.test') }) it('renders no feature for a module whose variables are absent', () => { const content = slotFor('kv', none) as ReactElement expect(content.type).not.toBe(UploadsLeft) }) })