diff --git a/src/main/ipc/settingsApi.ts b/src/main/ipc/settingsApi.ts index 1d51f7f..121e949 100644 --- a/src/main/ipc/settingsApi.ts +++ b/src/main/ipc/settingsApi.ts @@ -8,6 +8,7 @@ import type { ExportService } from '../services/ExportService.js'; import type { ImportService } from '../services/ImportService.js'; import type { SyncService } from '../services/SyncService.js'; import type { TelemetryService } from '../services/TelemetryService.js'; +import { collectAutostartState } from '../services/AutostartDiagnostic.js'; import { getInboxWindow as getInboxWindowSingleton } from '../windows/inboxWindow.js'; /** @@ -58,6 +59,13 @@ export function registerSettingsApi(deps?: SettingsIpcDeps): void { return { openAtLogin: r.openAtLogin }; }); + // v0.2.7 F12 deeper fix (Task 21) — 진단 정보 포함된 정식 autostart 상태 조회. + // Task 22 에서 옛 'settings:get-autostart' 를 제거하고 본 채널로 통일 예정. + ipcMain.handle('settings:autostart-state', async () => { + const diag = await collectAutostartState(); + return { openAtLogin: diag.withArgs.openAtLogin, diagnostic: diag }; + }); + // v0.2.7 정보 섹션 (Task 11) — 트레이 showAboutDialog 의 detail 형식 그대로 (clipboard 일관성). // 트레이 showAboutDialog 자체 제거는 Task 25 (Phase 6 cleanup) — 본 task 는 추가만. ipcMain.handle('settings:get-app-info', () => ({ diff --git a/tests/unit/settingsApi.test.ts b/tests/unit/settingsApi.test.ts new file mode 100644 index 0000000..9688850 --- /dev/null +++ b/tests/unit/settingsApi.test.ts @@ -0,0 +1,68 @@ +import { describe, it, expect, vi, beforeEach } from 'vitest'; + +const { handlers, mockApp, mockCollectAutostartState } = vi.hoisted(() => ({ + handlers: {} as Record unknown>, + mockApp: { + getLoginItemSettings: vi.fn(), + setLoginItemSettings: vi.fn(), + getVersion: vi.fn(() => '0.2.7'), + getPath: vi.fn(() => '/profile') + }, + mockCollectAutostartState: vi.fn() +})); + +vi.mock('electron', () => ({ + default: { + ipcMain: { + handle: (ch: string, fn: (...args: unknown[]) => unknown) => { + handlers[ch] = fn; + } + }, + app: mockApp, + dialog: {}, + Notification: vi.fn(function (this: unknown) { + Object.assign(this as object, { show: vi.fn() }); + }), + shell: { openPath: vi.fn() }, + clipboard: { writeText: vi.fn() } + } +})); + +vi.mock('../../src/main/services/AutostartDiagnostic', () => ({ + collectAutostartState: mockCollectAutostartState +})); + +vi.mock('../../src/main/windows/inboxWindow.js', () => ({ + getInboxWindow: vi.fn(() => null) +})); + +import { registerSettingsApi } from '../../src/main/ipc/settingsApi'; + +describe('settingsApi — autostart IPC', () => { + beforeEach(() => { + Object.keys(handlers).forEach((k) => delete handlers[k]); + mockApp.getLoginItemSettings.mockReset(); + mockApp.setLoginItemSettings.mockReset(); + mockCollectAutostartState.mockReset(); + }); + + it('settings:autostart-state returns AutostartState wrapped with openAtLogin', async () => { + mockCollectAutostartState.mockResolvedValue({ + withArgs: { openAtLogin: true, executableWillLaunchAtLogin: true }, + noArgs: { openAtLogin: false, executableWillLaunchAtLogin: true }, + execPath: '/path/to/exe' + }); + + registerSettingsApi(); + + const r = await handlers['settings:autostart-state']!() as { + openAtLogin: boolean; + diagnostic: { withArgs: { openAtLogin: boolean } }; + }; + + expect(r.openAtLogin).toBe(true); + expect(r.diagnostic.withArgs.openAtLogin).toBe(true); + expect(r.diagnostic).toHaveProperty('noArgs'); + expect(r.diagnostic).toHaveProperty('execPath'); + }); +});