import express from 'express'; import type { AddressInfo } from 'node:net'; import { describe, expect, it, vi } from 'vitest'; import type { WebContext } from '../../src/web/context.js'; import { createControlRouter } from '../../src/web/routes/control.js'; describe('control route realtime events', () => { it('publishes the authoritative bot state after each successful transition', async () => { let running = false; const bot = vi.fn(); const context = { config: { browser: { dryRun: true } }, services: { accountAuth: { isFullyAuthenticated: () => true } }, getBotRunning: () => running, setBotRunning: (next: boolean) => { running = next; }, activity: { push: vi.fn() }, logger: { info: vi.fn() }, broadcaster: { dashboardEvents: { bot } }, } as unknown as WebContext; const app = express().use('/api', createControlRouter(context)); const server = app.listen(0); await new Promise((resolve) => server.once('listening', resolve)); const port = (server.address() as AddressInfo).port; try { expect((await fetch(`http://127.0.0.1:${port}/api/start`, { method: 'POST' })).status).toBe(200); expect(running).toBe(true); expect(bot).toHaveBeenLastCalledWith({ running: true, dryRun: true }); expect((await fetch(`http://127.0.0.1:${port}/api/stop`, { method: 'POST' })).status).toBe(200); expect(running).toBe(false); expect(bot).toHaveBeenLastCalledWith({ running: false, dryRun: true }); } finally { await new Promise((resolve) => server.close(() => resolve())); } }); });