/** * Mock for window.electronAPI used in tests. * Provides typed mocks for all IPC methods. */ import { vi } from 'vitest'; import type { Project, Session, SessionDetail } from '../../src/renderer/types/data'; export interface MockElectronAPI { getProjects: ReturnType Promise>>; getSessions: ReturnType Promise>>; getSessionsPaginated: ReturnType< typeof vi.fn< ( projectId: string, cursor: string | null, limit?: number, options?: { includeTotalCount?: boolean; prefilterAll?: boolean } ) => Promise<{ sessions: Session[]; nextCursor: string | null; hasMore: boolean; totalCount: number; }> > >; getSessionDetail: ReturnType< typeof vi.fn<(projectId: string, sessionId: string) => Promise> >; getRepositoryGroups: ReturnType; getWorktreeSessions: ReturnType; getSubagentDetail: ReturnType; searchSessions: ReturnType; readClaudeMdFiles: ReturnType; readDirectoryClaudeMd: ReturnType; readMentionedFile: ReturnType; validateMentions: ReturnType; openPath: ReturnType; openExternal: ReturnType; notifications: { onNew: ReturnType; onUpdated: ReturnType; getUnread: ReturnType; markAsRead: ReturnType; markAllAsRead: ReturnType; // Methods used by notificationSlice get: ReturnType; markRead: ReturnType; markAllRead: ReturnType; delete: ReturnType; clear: ReturnType; }; onFileChange: ReturnType; onTodoChange: ReturnType; config: { get: ReturnType; update: ReturnType; addIgnoreRegex: ReturnType; removeIgnoreRegex: ReturnType; addIgnoreRepository: ReturnType; removeIgnoreRepository: ReturnType; snooze: ReturnType; clearSnooze: ReturnType; addTrigger: ReturnType; updateTrigger: ReturnType; removeTrigger: ReturnType; getTriggers: ReturnType; testTrigger: ReturnType; selectFolders: ReturnType; selectClaudeRootFolder: ReturnType; getClaudeRootInfo: ReturnType; openInEditor: ReturnType; pinSession: ReturnType; unpinSession: ReturnType; }; } /** * Create a fresh mock electronAPI instance. */ export function createMockElectronAPI(): MockElectronAPI { return { getProjects: vi.fn().mockResolvedValue([]), getSessions: vi.fn().mockResolvedValue([]), getSessionsPaginated: vi.fn().mockResolvedValue({ sessions: [], nextCursor: null, hasMore: false, totalCount: 0, }), getSessionDetail: vi.fn().mockResolvedValue(null), getRepositoryGroups: vi.fn().mockResolvedValue([]), getWorktreeSessions: vi.fn().mockResolvedValue([]), getSubagentDetail: vi.fn().mockResolvedValue(null), searchSessions: vi.fn().mockResolvedValue({ results: [], totalMatches: 0, sessionsSearched: 0, query: '', }), readClaudeMdFiles: vi.fn().mockResolvedValue({}), readDirectoryClaudeMd: vi.fn().mockResolvedValue({ path: '', exists: false, charCount: 0, estimatedTokens: 0, }), readMentionedFile: vi.fn().mockResolvedValue(null), validateMentions: vi.fn().mockResolvedValue({}), openPath: vi.fn().mockResolvedValue({ success: true }), openExternal: vi.fn().mockResolvedValue({ success: true }), notifications: { onNew: vi.fn().mockReturnValue(() => undefined), onUpdated: vi.fn().mockReturnValue(() => undefined), getUnread: vi.fn().mockResolvedValue([]), markAsRead: vi.fn().mockResolvedValue(undefined), markAllAsRead: vi.fn().mockResolvedValue(undefined), // Methods used by notificationSlice get: vi.fn().mockResolvedValue({ notifications: [] }), markRead: vi.fn().mockResolvedValue(true), markAllRead: vi.fn().mockResolvedValue(true), delete: vi.fn().mockResolvedValue(true), clear: vi.fn().mockResolvedValue(true), }, onFileChange: vi.fn().mockReturnValue(() => undefined), onTodoChange: vi.fn().mockReturnValue(() => undefined), config: { get: vi.fn().mockResolvedValue({ notifications: { enabled: true, soundEnabled: true, ignoredRegex: [], ignoredRepositories: [], snoozedUntil: null, snoozeMinutes: 30, triggers: [], }, general: { launchAtLogin: false, showDockIcon: true, theme: 'dark', defaultTab: 'dashboard', claudeRootPath: null, }, display: { showTimestamps: true, compactMode: false, syntaxHighlighting: true, }, sessions: { pinnedSessions: {}, }, }), update: vi.fn(), addIgnoreRegex: vi.fn(), removeIgnoreRegex: vi.fn(), addIgnoreRepository: vi.fn(), removeIgnoreRepository: vi.fn(), snooze: vi.fn(), clearSnooze: vi.fn(), addTrigger: vi.fn(), updateTrigger: vi.fn(), removeTrigger: vi.fn(), getTriggers: vi.fn().mockResolvedValue([]), testTrigger: vi.fn(), selectFolders: vi.fn().mockResolvedValue([]), selectClaudeRootFolder: vi.fn().mockResolvedValue(null), getClaudeRootInfo: vi.fn().mockResolvedValue({ defaultPath: '~/.claude', resolvedPath: '~/.claude', customPath: null, }), openInEditor: vi.fn(), pinSession: vi.fn(), unpinSession: vi.fn(), }, }; } /** * Install mock electronAPI on window object. * Returns the mock instance for assertions. */ export function installMockElectronAPI(): MockElectronAPI { const mock = createMockElectronAPI(); vi.stubGlobal('window', { ...window, electronAPI: mock, }); return mock; }