import type { ComponentProps } from 'react' import { render } from '@testing-library/react' import { vi } from 'vitest' import { NoteList } from '../components/NoteList' import type { NoteListFilter } from '../utils/noteListHelpers' import type { VaultEntry, SidebarSelection } from '../types' type NoteListProps = ComponentProps export const allSelection: SidebarSelection = { kind: 'filter', filter: 'all' } export const makeEntry = (overrides: Partial = {}): VaultEntry => ({ path: '/test.md', filename: 'test.md', title: 'Test', isA: null, aliases: [], belongsTo: [], relatedTo: [], status: null, archived: false, modifiedAt: null, createdAt: null, fileSize: 100, snippet: '', wordCount: 0, relationships: {}, icon: null, color: null, order: null, sidebarLabel: null, template: null, sort: null, view: null, visible: null, organized: false, favorite: false, favoriteIndex: null, listPropertiesDisplay: [], outgoingLinks: [], properties: {}, hasH1: false, ...overrides, }) export const mockEntries: VaultEntry[] = [ makeEntry({ path: '/Users/luca/Laputa/project/26q1-laputa-app.md', filename: '26q1-laputa-app.md', title: 'Build Laputa App', isA: 'Project', relatedTo: ['[[topic/software-development]]'], status: 'Active', modifiedAt: 1700000000, createdAt: null, fileSize: 1024, snippet: 'Build a personal knowledge management app.', relationships: { 'Related to': ['[[topic/software-development]]'], }, }), makeEntry({ path: '/Users/luca/Laputa/note/facebook-ads-strategy.md', filename: 'facebook-ads-strategy.md', title: 'Facebook Ads Strategy', isA: 'Note', belongsTo: ['[[project/26q1-laputa-app]]'], relatedTo: ['[[topic/growth]]'], modifiedAt: 1700000000, createdAt: null, fileSize: 847, snippet: 'Lookalike audiences convert 3x better.', relationships: { 'Belongs to': ['[[project/26q1-laputa-app]]'], 'Related to': ['[[topic/growth]]'], }, }), makeEntry({ path: '/Users/luca/Laputa/person/matteo-cellini.md', filename: 'matteo-cellini.md', title: 'Matteo Cellini', isA: 'Person', modifiedAt: 1700000000, createdAt: null, fileSize: 320, snippet: 'Sponsorship manager.', }), makeEntry({ path: '/Users/luca/Laputa/event/2026-02-14-kickoff.md', filename: '2026-02-14-kickoff.md', title: 'Kickoff Meeting', isA: 'Event', modifiedAt: 1700000000, createdAt: null, fileSize: 512, snippet: 'Project kickoff meeting notes.', }), makeEntry({ path: '/Users/luca/Laputa/topic/software-development.md', filename: 'software-development.md', title: 'Software Development', isA: 'Topic', modifiedAt: 1700000000, createdAt: null, fileSize: 256, snippet: 'Frontend, backend, and systems programming.', }), ] export const makeIndexedEntry = (index: number, overrides?: Partial): VaultEntry => makeEntry({ path: `/vault/note/note-${index}.md`, filename: `note-${index}.md`, title: `Note ${index}`, isA: 'Note', modifiedAt: 1700000000 - index * 60, fileSize: 500, snippet: `Content of note ${index}`, ...overrides, }) export const makeTypeDefinition = (title: string, displayProps: string[] = []): VaultEntry => makeEntry({ path: `/vault/type/${title.toLowerCase()}.md`, filename: `${title.toLowerCase()}.md`, title, isA: 'Type', listPropertiesDisplay: displayProps, }) export function createNoteListSpies() { return { onSelectNote: vi.fn(), onReplaceActiveTab: vi.fn(), onCreateNote: vi.fn(), onNoteListFilterChange: vi.fn(), } } export function buildNoteListProps(overrides: Partial = {}) { const spies = createNoteListSpies() const props: NoteListProps = { entries: mockEntries, selection: allSelection, selectedNote: null, noteListFilter: 'open' as NoteListFilter, onNoteListFilterChange: spies.onNoteListFilterChange, onSelectNote: spies.onSelectNote, onReplaceActiveTab: spies.onReplaceActiveTab, onCreateNote: spies.onCreateNote, ...overrides, } return { props, ...spies } } export function renderNoteList(overrides: Partial = {}) { const built = buildNoteListProps(overrides) return { ...render(), ...built, } }