n8n/packages/cli/src/services/__tests__/engine-data-plane-proxy.service.test.ts
Tomi Turtiainen ae26d9599d
feat(engine): Return run data for engine 2.0 executions (#37486)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-03 15:41:04 +00:00

71 lines
2.5 KiB
TypeScript

import type { ExecutionSnapshot, StartExecutionRequest } from '@n8n/engine';
import { UserError } from 'n8n-workflow';
import { mock } from 'vitest-mock-extended';
import type { ExecutionIdV2 } from '@/executions/execution-id';
import type { EngineDataPlaneProvider } from '../engine-data-plane-proxy.service';
import { EngineDataPlaneProxyService } from '../engine-data-plane-proxy.service';
describe('EngineDataPlaneProxyService', () => {
const executionId = '01a038ae-c4a8-7799-8a3e-e3c2ca055cfa' as ExecutionIdV2;
const request: StartExecutionRequest = {
workflowId: 'wf-1',
graph: { nodes: [], edges: [] },
executionId,
};
let proxy: EngineDataPlaneProxyService;
beforeEach(() => {
proxy = new EngineDataPlaneProxyService();
});
it('is unavailable until a provider registers', () => {
expect(proxy.isAvailable()).toBe(false);
proxy.registerProvider(mock<EngineDataPlaneProvider>());
expect(proxy.isAvailable()).toBe(true);
});
it('explains how to enable the engine when no provider is registered', async () => {
await expect(proxy.startExecution(request)).rejects.toThrow(UserError);
await expect(proxy.startExecution(request)).rejects.toThrow('N8N_ENABLED_MODULES');
});
it('delegates to the registered provider', async () => {
const provider = mock<EngineDataPlaneProvider>();
provider.startExecution.mockResolvedValue({ executionId: 'exec-1' });
proxy.registerProvider(provider);
await expect(proxy.startExecution(request)).resolves.toEqual({ executionId: 'exec-1' });
expect(provider.startExecution).toHaveBeenCalledWith(request);
});
it('reads no execution when no provider is registered', async () => {
// A read degrades to a miss; only a start is worth failing loudly.
await expect(proxy.getExecution(executionId)).resolves.toBeUndefined();
});
it('delegates a read to the registered provider', async () => {
const provider = mock<EngineDataPlaneProvider>();
const snapshot = mock<ExecutionSnapshot>({ id: executionId });
provider.getExecution.mockResolvedValue(snapshot);
proxy.registerProvider(provider);
await expect(proxy.getExecution(executionId)).resolves.toBe(snapshot);
expect(provider.getExecution).toHaveBeenCalledWith(executionId, undefined);
});
it('passes the read options through to the provider', async () => {
const provider = mock<EngineDataPlaneProvider>();
proxy.registerProvider(provider);
await proxy.getExecution(executionId, { includeSteps: true });
expect(provider.getExecution).toHaveBeenCalledWith(executionId, { includeSteps: true });
});
});