48 lines
2.0 KiB
TypeScript
48 lines
2.0 KiB
TypeScript
import { jest } from '@jest/globals'
|
|
import { OverlayAction, ActionAck } from '../../../../packages/application/ports/IOverlaySyncPort'
|
|
import { IAutomationEventPublisher, AutomationEvent } from '../../../../packages/application/ports/IAutomationEventPublisher'
|
|
import { IAutomationLifecycleEmitter, LifecycleCallback } from '../../../../packages/infrastructure/adapters/IAutomationLifecycleEmitter'
|
|
import { OverlaySyncService } from '../../../../packages/application/services/OverlaySyncService'
|
|
|
|
class MockLifecycleEmitter implements IAutomationLifecycleEmitter {
|
|
private callbacks: Set<LifecycleCallback> = new Set()
|
|
onLifecycle(cb: LifecycleCallback): void {
|
|
this.callbacks.add(cb)
|
|
}
|
|
offLifecycle(cb: LifecycleCallback): void {
|
|
this.callbacks.delete(cb)
|
|
}
|
|
async emit(event: AutomationEvent) {
|
|
for (const cb of Array.from(this.callbacks)) {
|
|
// fire without awaiting to simulate async emitter
|
|
cb(event)
|
|
}
|
|
}
|
|
}
|
|
|
|
describe('OverlaySyncService (unit)', () => {
|
|
test('startAction resolves as confirmed only after action-started event is emitted', async () => {
|
|
const emitter = new MockLifecycleEmitter()
|
|
// create service wiring: pass emitter as dependency (constructor shape expected)
|
|
const svc = new OverlaySyncService({ lifecycleEmitter: emitter as any, logger: console as any, publisher: { publish: async () => {} } as any })
|
|
|
|
const action: OverlayAction = { id: 'add-car', label: 'Adding...' }
|
|
|
|
// start the action but don't emit event yet
|
|
const promise = svc.startAction(action)
|
|
|
|
// wait a small tick to ensure promise hasn't resolved prematurely
|
|
await new Promise((r) => setTimeout(r, 10))
|
|
|
|
let resolved = false
|
|
promise.then(() => (resolved = true))
|
|
expect(resolved).toBe(false)
|
|
|
|
// now emit action-started
|
|
await emitter.emit({ type: 'action-started', actionId: 'add-car', timestamp: Date.now() })
|
|
|
|
const ack = await promise
|
|
expect(ack.status).toBe('confirmed')
|
|
expect(ack.id).toBe('add-car')
|
|
})
|
|
}) |