import { describe, it, expect, beforeEach, vi } from 'vitest'; import type { Note } from '@shared/types'; const mockApi = { listNotes: vi.fn(async () => [] as Note[]), listTrash: vi.fn(async () => [] as Note[]), listByStatus: vi.fn(async () => [] as Note[]), countsByStatus: vi.fn(async () => ({ active: 0, completed: 0, trashed: 0 })), getTrashCount: vi.fn(async () => 0), getContinuity: vi.fn(async () => ({ weekStart: '', weekCount: 0, weekTarget: 7, consecutiveCompleteWeeks: 0, showRecoveryToast: false, lastNoteAt: null })), getPendingCount: vi.fn(async () => 0), getOllamaStatus: vi.fn(async () => ({ ok: true })), getTodayCount: vi.fn(async () => 0), getFailedCount: vi.fn(async () => 0), listExpired: vi.fn(async () => [] as Note[]), listRecallCandidate: vi.fn(async () => null), restoreNote: vi.fn(async () => {}), permanentDeleteNote: vi.fn(async () => ({ confirmed: true })), emptyTrash: vi.fn(async () => ({ confirmed: true, count: 0 })), trashExpiredBatch: vi.fn(async () => ({ confirmed: true, trashedCount: 0 })), onNoteUpdated: vi.fn(() => () => {}), updateAiFields: vi.fn(async () => {}), setDueDate: vi.fn(async () => {}), setIntent: vi.fn(async () => {}), dismissIntent: vi.fn(async () => {}), ollamaRecheck: vi.fn(async () => ({ ok: true })), retryAllFailed: vi.fn(async () => {}), markRecallOpened: vi.fn(async () => {}), dismissRecall: vi.fn(async () => {}), emitRecallSnoozed: vi.fn(async () => {}) }; vi.mock('../../src/renderer/inbox/api.js', () => ({ inboxApi: mockApi })); describe('inbox store — view enum', () => { beforeEach(async () => { const { useInbox } = await import('../../src/renderer/inbox/store.js'); useInbox.setState({ view: 'inbox', counts: { active: 0, completed: 0, trashed: 0 }, notes: [], trashNotes: [], trashCount: 0, showTrash: false, showSettings: false, loading: false, tagFilter: null, pendingCount: 0, todayCount: 0, ollamaStatus: { ok: true }, continuity: { weekStart: '', weekCount: 0, weekTarget: 7, consecutiveCompleteWeeks: 0, showRecoveryToast: false, lastNoteAt: null }, expiredCandidates: [], expiredSnoozeUntilMs: null, failedCount: 0, recallCandidate: null, recallSnoozeUntilMs: null }); Object.values(mockApi).forEach((fn) => 'mockClear' in fn && (fn as any).mockClear()); }); it('initial view is inbox', async () => { const { useInbox } = await import('../../src/renderer/inbox/store.js'); expect(useInbox.getState().view).toBe('inbox'); }); it('setView changes view', async () => { const { useInbox } = await import('../../src/renderer/inbox/store.js'); useInbox.getState().setView('completed'); expect(useInbox.getState().view).toBe('completed'); }); it('counts initialized to zero per status', async () => { const { useInbox } = await import('../../src/renderer/inbox/store.js'); expect(useInbox.getState().counts).toEqual({ active: 0, completed: 0, trashed: 0 }); }); it('backward-compat: showTrash mirrors view==="trash"', async () => { const { useInbox } = await import('../../src/renderer/inbox/store.js'); useInbox.getState().setView('trash'); expect(useInbox.getState().showTrash).toBe(true); useInbox.getState().setView('inbox'); expect(useInbox.getState().showTrash).toBe(false); }); it('backward-compat: showSettings mirrors view==="settings"', async () => { const { useInbox } = await import('../../src/renderer/inbox/store.js'); useInbox.getState().setView('settings'); expect(useInbox.getState().showSettings).toBe(true); useInbox.getState().setView('inbox'); expect(useInbox.getState().showSettings).toBe(false); }); });