import { describe, it, expect, vi, beforeEach } from 'vitest'; import { mkdirSync } from 'node:fs'; vi.mock('./daemon.js', () => ({ GATEWAY_HOME: '/tmp/u-test-gateway-home', getDaemonPid: vi.fn().mockReturnValue(null), readMeta: vi.fn(), stopDaemon: vi.fn(), uninstallGatewayPackage: vi.fn(), })); import { runUninstall } from './uninstall.js'; import { readMeta, uninstallGatewayPackage } from './daemon.js'; describe('gateway uninstall — #1390 headless semantics', () => { beforeEach(() => { vi.clearAllMocks(); }); it('non-TTY without --yes FAILS LOUD (exit 1, nothing touched)', async () => { vi.mocked(readMeta).mockReturnValue({ version: '0.0.7', installedAt: '', entryPoint: '', host: 'localhost', port: 14242, }); const exit = vi.spyOn(process, 'exit').mockImplementation((() => { throw new Error('EXIT'); }) as never); const err = vi.spyOn(console, 'error').mockImplementation(() => {}); await expect(runUninstall()).rejects.toThrow('EXIT'); expect(exit).toHaveBeenCalledWith(1); expect(err).toHaveBeenCalledWith(expect.stringContaining('stdin is not a TTY')); expect(uninstallGatewayPackage).not.toHaveBeenCalled(); exit.mockRestore(); err.mockRestore(); }); it('--yes proceeds headlessly WITHOUT removing data (never implied)', async () => { const meta = { version: '0.0.7', installedAt: '', entryPoint: '', host: 'localhost', port: 14242, }; vi.mocked(readMeta).mockReturnValue(meta); const log = vi.spyOn(console, 'log').mockImplementation(() => {}); await runUninstall({ yes: true }); expect(uninstallGatewayPackage).toHaveBeenCalledTimes(1); expect(log).toHaveBeenCalledWith(expect.stringContaining('Gateway data kept')); log.mockRestore(); }); it('--yes --remove-data removes data headlessly', async () => { vi.mocked(readMeta).mockReturnValue({ version: '0.0.7', installedAt: '', entryPoint: '', host: 'localhost', port: 14242, }); mkdirSync('/tmp/u-test-gateway-home', { recursive: true }); // existsSync gate const log = vi.spyOn(console, 'log').mockImplementation(() => {}); await runUninstall({ yes: true, removeData: true }); expect(uninstallGatewayPackage).toHaveBeenCalledTimes(1); expect(log).toHaveBeenCalledWith(expect.stringContaining('Gateway data removed')); log.mockRestore(); }); it('no meta → clean no-op even with --yes', async () => { vi.mocked(readMeta).mockReturnValue(null); const log = vi.spyOn(console, 'log').mockImplementation(() => {}); await runUninstall({ yes: true }); expect(log).toHaveBeenCalledWith('Gateway is not installed.'); expect(uninstallGatewayPackage).not.toHaveBeenCalled(); log.mockRestore(); }); });