- inbox:emitRecallShown / emitRecallSnoozed: ipcMain.handle → on (fire-and-forget honest pattern, return value 의존자 0) - preload: ipcRenderer.invoke → send (matching on the main side) - shared/types: Promise<void> → void on both recall emit methods - store.ts: drop await on emitRecallSnoozed (now void) - inboxApi-*.test.ts: add ipcMain.on to electron mock (broken by above) - tests/unit/recall-ipc.test.ts: new TDD test for handle→on migration Note: #20 CaptureService telemetry .catch debug log skipped — CaptureService has no logger field; adding one would require non-trivial constructor signature change. Reported as CONCERN below. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
66 lines
2.0 KiB
TypeScript
66 lines
2.0 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
|
|
// Track ipcMain.handle and ipcMain.on calls
|
|
const { handleCalls, onCalls } = vi.hoisted(() => ({
|
|
handleCalls: [] as string[],
|
|
onCalls: [] as string[]
|
|
}));
|
|
|
|
vi.mock('electron', () => ({
|
|
default: {
|
|
ipcMain: {
|
|
handle: (ch: string, _fn: unknown) => { handleCalls.push(ch); },
|
|
on: (ch: string, _fn: unknown) => { onCalls.push(ch); }
|
|
},
|
|
dialog: {},
|
|
shell: {}
|
|
}
|
|
}));
|
|
|
|
import { registerInboxApi } from '../../src/main/ipc/inboxApi.js';
|
|
import type { InboxIpcDeps } from '../../src/main/ipc/inboxApi.js';
|
|
|
|
function makeDeps(): InboxIpcDeps {
|
|
return {
|
|
repo: {} as never,
|
|
continuity: {} as never,
|
|
capture: {
|
|
emitRecallShown: vi.fn(async () => {}),
|
|
emitRecallSnoozed: vi.fn(async () => {})
|
|
} as never,
|
|
health: {} as never,
|
|
intent: {} as never,
|
|
getInboxWindow: () => null,
|
|
settings: {} as never,
|
|
providerHolder: {} as never,
|
|
paths: { profileDir: '/profile' }
|
|
};
|
|
}
|
|
|
|
describe('recall IPC channels (fire-and-forget)', () => {
|
|
beforeEach(() => {
|
|
handleCalls.length = 0;
|
|
onCalls.length = 0;
|
|
});
|
|
|
|
it('inbox:emitRecallShown is registered with ipcMain.on (not handle)', () => {
|
|
registerInboxApi(makeDeps());
|
|
expect(onCalls).toContain('inbox:emitRecallShown');
|
|
expect(handleCalls).not.toContain('inbox:emitRecallShown');
|
|
});
|
|
|
|
it('inbox:emitRecallSnoozed is registered with ipcMain.on (not handle)', () => {
|
|
registerInboxApi(makeDeps());
|
|
expect(onCalls).toContain('inbox:emitRecallSnoozed');
|
|
expect(handleCalls).not.toContain('inbox:emitRecallSnoozed');
|
|
});
|
|
|
|
it('each recall channel is registered exactly once with ipcMain.on', () => {
|
|
registerInboxApi(makeDeps());
|
|
const shownCount = onCalls.filter((ch) => ch === 'inbox:emitRecallShown').length;
|
|
const snoozedCount = onCalls.filter((ch) => ch === 'inbox:emitRecallSnoozed').length;
|
|
expect(shownCount).toBe(1);
|
|
expect(snoozedCount).toBe(1);
|
|
});
|
|
});
|