// Mock chalk to avoid ESM import issues jest.mock('chalk', () => ({ __esModule: true, blue: (s: string) => s, green: (s: string) => s, red: (s: string) => s, })); // Mock child_process.spawn to be a Jest mock jest.mock('child_process', () => ({ spawn: jest.fn(), })); import * as cp from 'child_process'; import fs from 'fs'; import { teleportBotAgent } from '../src/services/teleportBotAgent'; describe('teleportBotAgent', () => { let logSpy: jest.SpyInstance; beforeAll(() => { logSpy = jest.spyOn(console, 'log').mockImplementation(() => {}); }); afterAll(() => { logSpy.mockRestore(); }); it('should spawn tbot with correct args and return pid info', async () => { // Stub filesystem operations const mkdirSpy = jest.spyOn(fs, 'mkdirSync').mockImplementation(() => undefined); const existsSpy = jest.spyOn(fs, 'existsSync').mockReturnValue(false); const rmSpy = jest.spyOn(fs, 'rmSync').mockImplementation(() => undefined); const writeSpy = jest.spyOn(fs, 'writeFileSync').mockImplementation(() => {}); const openSpy = jest.spyOn(fs, 'openSync').mockReturnValue(4242); const closeSpy = jest.spyOn(fs, 'closeSync').mockImplementation(() => undefined); // Mock spawn to return a fake process const fakeProc = { pid: 1234, unref: jest.fn() } as unknown as cp.ChildProcess; (cp.spawn as jest.Mock).mockReturnValue(fakeProc); const result = await teleportBotAgent({ appName: 'myApp', joinToken: 'myToken', workDir: '/tmp/work', }); expect(cp.spawn).toHaveBeenCalledWith( 'tbot', [ 'start', 'application', '--storage=file:///tmp/work/data', '--destination=file:///tmp/work/dest', '--app=myApp', '--token=myToken', '--join-method=token', '--proxy-server=teleport.ftprod.fr:443', '--specific-tls-extensions', '--certificate-ttl=8h', '--renewal-interval=1h', ], { detached: true, stdio: ['ignore', 4242, 4242] }, ); expect(result).toEqual({ pid: 1234, appName: 'myApp', proxyServer: 'teleport.ftprod.fr:443', certPath: '/tmp/work/dest/tls.crt', keyPath: '/tmp/work/dest/tls.key', logPath: '/tmp/work/tbot.log', }); // Restore mocked functions mkdirSpy.mockRestore(); existsSpy.mockRestore(); rmSpy.mockRestore(); writeSpy.mockRestore(); openSpy.mockRestore(); closeSpy.mockRestore(); }); });