import { describe, expect, test } from 'vitest' import { OverlayAction } from '@core/automation/application/ports/OverlaySyncPort' import { IAutomationLifecycleEmitter, LifecycleCallback } from '@core/automation/infrastructure//IAutomationLifecycleEmitter' import { OverlaySyncService } from '@core/automation/application/services/OverlaySyncService' class MockLifecycleEmitter implements IAutomationLifecycleEmitter { private callbacks: Set = new Set() onLifecycle(cb: LifecycleCallback): void { this.callbacks.add(cb) } offLifecycle(cb: LifecycleCallback): void { this.callbacks.delete(cb) } async emit(event: { type: 'panel-attached'|'modal-opened'|'action-started'|'action-complete'|'action-failed'|'panel-missing'; actionId: string; timestamp: number }) { for (const cb of Array.from(this.callbacks)) { cb(event) } } } describe('OverlaySyncService timeout (unit)', () => { test('startAction with short timeout resolves as tentative when no events', async () => { const emitter = new MockLifecycleEmitter() const svc = new OverlaySyncService({ lifecycleEmitter: emitter, logger: console as any, publisher: { publish: async () => {} }, }) const action: OverlayAction = { id: 'add-car', label: 'Adding...', timeoutMs: 50 } const start = Date.now() const ack = await svc.startAction(action) const elapsed = Date.now() - start expect(ack.status).toBe('tentative') expect(ack.id).toBe('add-car') expect(elapsed).toBeGreaterThanOrEqual(40) }) })