// @vitest-environment jsdom
import { describe, it, expect, vi, beforeEach } from 'vitest';
import '@testing-library/jest-dom/vitest';
import { render, screen, fireEvent, waitFor, cleanup } from '@testing-library/react';
function makeDiag(open: boolean, platform: NodeJS.Platform = 'win32'): {
withArgs: { openAtLogin: boolean; executableWillLaunchAtLogin: boolean };
noArgs: { openAtLogin: boolean; executableWillLaunchAtLogin: boolean };
execPath: string;
platform: NodeJS.Platform;
} {
return {
withArgs: { openAtLogin: open, executableWillLaunchAtLogin: open },
noArgs: { openAtLogin: open, executableWillLaunchAtLogin: open },
execPath: '/path/to/exe',
platform
};
}
vi.mock('../../src/renderer/inbox/api.js', () => ({
inboxApi: {
getAutostart: vi.fn(async () => ({ openAtLogin: true, diagnostic: makeDiag(true) })),
setAutostart: vi.fn(async (open: boolean) => ({ openAtLogin: open, diagnostic: makeDiag(open) }))
}
}));
import { AutostartSection } from '../../src/renderer/inbox/components/settings/AutostartSection';
describe('AutostartSection', () => {
beforeEach(() => {
vi.clearAllMocks();
cleanup();
});
it('renders toggle reflecting current state', async () => {
render();
const toggle = await screen.findByRole('checkbox');
expect(toggle).toBeChecked();
});
it('clicking toggle calls setAutostart', async () => {
const { inboxApi } = await import('../../src/renderer/inbox/api.js');
render();
const toggle = await screen.findByRole('checkbox');
fireEvent.click(toggle);
await waitFor(() => expect(inboxApi.setAutostart).toHaveBeenCalledWith(false));
});
it('renders diagnostic panel when expanded, shows mismatch warning + execPath', async () => {
const { inboxApi } = await import('../../src/renderer/inbox/api.js');
vi.mocked(inboxApi.getAutostart).mockResolvedValueOnce({
openAtLogin: true,
diagnostic: {
withArgs: { openAtLogin: true, executableWillLaunchAtLogin: true },
noArgs: { openAtLogin: false, executableWillLaunchAtLogin: true },
execPath: '/path/to/Inkling.exe',
platform: 'win32'
}
});
render();
await screen.findByRole('checkbox');
fireEvent.click(screen.getByRole('button', { name: /진단 정보/ }));
expect(await screen.findByText(/⚠️/)).toBeInTheDocument();
expect(screen.getByText(/path\/to\/Inkling\.exe/)).toBeInTheDocument();
expect(screen.getByText(/표준 \(--hidden 인자\)/)).toBeInTheDocument();
expect(screen.getByText(/비교 \(인자 없이\)/)).toBeInTheDocument();
});
it('shows registry info when present (Win)', async () => {
const { inboxApi } = await import('../../src/renderer/inbox/api.js');
vi.mocked(inboxApi.getAutostart).mockResolvedValueOnce({
openAtLogin: true,
diagnostic: {
withArgs: { openAtLogin: true, executableWillLaunchAtLogin: true },
noArgs: { openAtLogin: true, executableWillLaunchAtLogin: true },
execPath: 'C:\\app.exe',
platform: 'win32',
registryPath: 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run\\Inkling',
registryValue: '"C:\\app.exe" --hidden'
}
});
render();
await screen.findByRole('checkbox');
fireEvent.click(screen.getByRole('button', { name: /진단 정보/ }));
expect(screen.getByText(/registry 경로/)).toBeInTheDocument();
expect(screen.getByText(/registry 값/)).toBeInTheDocument();
});
it('no mismatch warning when withArgs == noArgs and willLaunch=true', async () => {
const { inboxApi } = await import('../../src/renderer/inbox/api.js');
vi.mocked(inboxApi.getAutostart).mockResolvedValueOnce({
openAtLogin: true,
diagnostic: {
withArgs: { openAtLogin: true, executableWillLaunchAtLogin: true },
noArgs: { openAtLogin: true, executableWillLaunchAtLogin: true },
execPath: '/p',
platform: 'win32'
}
});
render();
await screen.findByRole('checkbox');
expect(screen.queryByText(/⚠️/)).not.toBeInTheDocument();
});
it('macOS: no false-positive mismatch when willLaunch=false (SMAppService 한계)', async () => {
const { inboxApi } = await import('../../src/renderer/inbox/api.js');
vi.mocked(inboxApi.getAutostart).mockResolvedValueOnce({
openAtLogin: true,
diagnostic: {
withArgs: { openAtLogin: true, executableWillLaunchAtLogin: false },
noArgs: { openAtLogin: true, executableWillLaunchAtLogin: false },
execPath: '/Applications/Inkling.app',
platform: 'darwin'
}
});
render();
await screen.findByRole('checkbox');
expect(screen.queryByText(/⚠️/)).not.toBeInTheDocument();
});
it('Win: mismatch warning when openAtLogin=true but willLaunch=false', async () => {
const { inboxApi } = await import('../../src/renderer/inbox/api.js');
vi.mocked(inboxApi.getAutostart).mockResolvedValueOnce({
openAtLogin: true,
diagnostic: {
withArgs: { openAtLogin: true, executableWillLaunchAtLogin: false },
noArgs: { openAtLogin: true, executableWillLaunchAtLogin: false },
execPath: 'C:\\app.exe',
platform: 'win32'
}
});
render();
await screen.findByRole('checkbox');
expect(await screen.findByText(/⚠️/)).toBeInTheDocument();
});
it('"재등록" button calls setAutostart with current openAtLogin value', async () => {
const { inboxApi } = await import('../../src/renderer/inbox/api.js');
vi.mocked(inboxApi.getAutostart).mockResolvedValueOnce({
openAtLogin: true,
diagnostic: {
withArgs: { openAtLogin: true, executableWillLaunchAtLogin: true },
noArgs: { openAtLogin: true, executableWillLaunchAtLogin: true },
execPath: '/p',
platform: 'win32'
}
});
render();
await screen.findByRole('checkbox');
fireEvent.click(screen.getByRole('button', { name: /재등록/ }));
await waitFor(() => expect(inboxApi.setAutostart).toHaveBeenCalledWith(true));
});
});