node-sagas
Version:
Library for handling distributed transactions in the microservices architecture
100 lines • 4.21 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const step_1 = require("../step");
const saga_params_1 = require("./saga-params");
const saga_flow_1 = require("../saga-flow");
const expectInvokeBehavior = (stepMock, sagaParams) => {
expect(stepMock.invoke).toHaveBeenCalledTimes(1);
expect(stepMock.invoke).toHaveBeenCalledWith(sagaParams);
};
const expectStepsBehavior = (stepMock1, stepMock2, sagaParams) => {
expectInvokeBehavior(stepMock1, sagaParams);
expect(stepMock1.compensate).toHaveBeenCalledTimes(1);
expect(stepMock1.compensate).toHaveBeenCalledWith(sagaParams);
expectInvokeBehavior(stepMock2, sagaParams);
expect(stepMock2.compensate).toHaveBeenCalledTimes(1);
expect(stepMock2.compensate).toHaveBeenCalledWith(sagaParams);
};
describe('Saga Flow', () => {
test('construct', () => {
const sagaFlow = new saga_flow_1.SagaFlow();
expect(sagaFlow).toBeInstanceOf(saga_flow_1.SagaFlow);
});
test('invoke with empty steps', async () => {
const sagaFlow = new saga_flow_1.SagaFlow();
const params = {};
await expect(sagaFlow.invoke(params)).resolves.toBeUndefined();
});
test('compensate with empty steps', async () => {
const sagaFlow = new saga_flow_1.SagaFlow();
const params = {};
await expect(sagaFlow.compensate(params)).resolves.toBeUndefined();
});
test('execute with positive flow', async () => {
const executionOrder = [];
const stepMock1 = new step_1.Step();
stepMock1.invoke = jest.fn(async () => {
executionOrder.push(1);
});
const stepMock2 = new step_1.Step();
stepMock2.invoke = jest.fn(async () => {
executionOrder.push(2);
});
const saga = new saga_flow_1.SagaFlow([stepMock1, stepMock2]);
const sagaParams = new saga_params_1.SagaParams();
await saga.invoke(sagaParams);
expectInvokeBehavior(stepMock1, sagaParams);
expectInvokeBehavior(stepMock2, sagaParams);
expect(executionOrder).toEqual([1, 2]);
});
test('execute with compensation flow', async () => {
const executionOrder = [];
const stepMock1 = new step_1.Step();
stepMock1.invoke = jest.fn(async () => {
executionOrder.push(1);
});
stepMock1.compensate = jest.fn(async () => {
executionOrder.push(4);
});
const stepMock2 = new step_1.Step();
stepMock2.invoke = jest.fn(() => {
executionOrder.push(2);
return Promise.reject(new Error());
});
stepMock2.compensate = jest.fn(async () => {
executionOrder.push(3);
});
const sagaParams = new saga_params_1.SagaParams();
const saga = new saga_flow_1.SagaFlow([stepMock1, stepMock2]);
await expect(saga.invoke(sagaParams)).rejects.toEqual(new Error());
await saga.compensate(sagaParams);
expectStepsBehavior(stepMock1, stepMock2, sagaParams);
expect(executionOrder).toEqual([1, 2, 3, 4]);
});
test('execute with errors in compensation flow', async () => {
const executionOrder = [];
const stepMock1 = new step_1.Step();
stepMock1.invoke = jest.fn(async () => {
executionOrder.push(1);
});
stepMock1.compensate = jest.fn(() => {
executionOrder.push(4);
throw new Error();
});
const stepMock2 = new step_1.Step();
stepMock2.invoke = jest.fn(() => {
executionOrder.push(2);
throw new Error();
});
stepMock2.compensate = jest.fn(async () => {
executionOrder.push(3);
});
const sagaParams = new saga_params_1.SagaParams();
const saga = new saga_flow_1.SagaFlow([stepMock1, stepMock2]);
await expect(saga.invoke(sagaParams)).rejects.toEqual(new Error());
await expect(saga.compensate(sagaParams)).rejects.toEqual(new Error());
expectStepsBehavior(stepMock1, stepMock2, sagaParams);
expect(executionOrder).toEqual([1, 2, 3, 4]);
});
});
//# sourceMappingURL=saga-flow.spec.js.map