wip
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { OverlaySyncService } from 'packages/application/services/OverlaySyncService';
|
||||
import type { AutomationEvent } from 'packages/application/ports/IAutomationEventPublisher';
|
||||
import type {
|
||||
IAutomationLifecycleEmitter,
|
||||
LifecycleCallback,
|
||||
} from 'packages/infrastructure/adapters/IAutomationLifecycleEmitter';
|
||||
import type {
|
||||
OverlayAction,
|
||||
ActionAck,
|
||||
} from 'packages/application/ports/IOverlaySyncPort';
|
||||
|
||||
class TestLifecycleEmitter 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): Promise<void> {
|
||||
for (const cb of Array.from(this.callbacks)) {
|
||||
await cb(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class RecordingPublisher {
|
||||
public events: AutomationEvent[] = [];
|
||||
|
||||
async publish(event: AutomationEvent): Promise<void> {
|
||||
this.events.push(event);
|
||||
}
|
||||
}
|
||||
|
||||
describe('Overlay lifecycle (integration)', () => {
|
||||
it('emits modal-opened and confirms after action-started in sane order', async () => {
|
||||
const lifecycleEmitter = new TestLifecycleEmitter();
|
||||
const publisher = new RecordingPublisher();
|
||||
const logger = console as any;
|
||||
|
||||
const service = new OverlaySyncService({
|
||||
lifecycleEmitter,
|
||||
publisher,
|
||||
logger,
|
||||
defaultTimeoutMs: 1_000,
|
||||
});
|
||||
|
||||
const action: OverlayAction = {
|
||||
id: 'hosted-session',
|
||||
label: 'Starting hosted session',
|
||||
};
|
||||
|
||||
const ackPromise: Promise<ActionAck> = service.startAction(action);
|
||||
|
||||
expect(publisher.events.length).toBe(1);
|
||||
const first = publisher.events[0];
|
||||
expect(first.type).toBe('modal-opened');
|
||||
expect(first.actionId).toBe('hosted-session');
|
||||
|
||||
await lifecycleEmitter.emit({
|
||||
type: 'panel-attached',
|
||||
actionId: 'hosted-session',
|
||||
timestamp: Date.now(),
|
||||
payload: { selector: '#gridpilot-overlay' },
|
||||
});
|
||||
|
||||
await lifecycleEmitter.emit({
|
||||
type: 'action-started',
|
||||
actionId: 'hosted-session',
|
||||
timestamp: Date.now(),
|
||||
});
|
||||
|
||||
const ack = await ackPromise;
|
||||
expect(ack.id).toBe('hosted-session');
|
||||
expect(ack.status).toBe('confirmed');
|
||||
|
||||
expect(publisher.events[0].type).toBe('modal-opened');
|
||||
expect(publisher.events[0].actionId).toBe('hosted-session');
|
||||
});
|
||||
|
||||
it('emits panel-missing when cancelAction is called', async () => {
|
||||
const lifecycleEmitter = new TestLifecycleEmitter();
|
||||
const publisher = new RecordingPublisher();
|
||||
const logger = console as any;
|
||||
|
||||
const service = new OverlaySyncService({
|
||||
lifecycleEmitter,
|
||||
publisher,
|
||||
logger,
|
||||
});
|
||||
|
||||
await service.cancelAction('hosted-session-cancel');
|
||||
|
||||
expect(publisher.events.length).toBe(1);
|
||||
const ev = publisher.events[0];
|
||||
expect(ev.type).toBe('panel-missing');
|
||||
expect(ev.actionId).toBe('hosted-session-cancel');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user