UNPKG

@getclave/lifi-sdk

Version:

LI.FI Any-to-Any Cross-Chain-Swap SDK

224 lines (223 loc) 11.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const vitest_1 = require("vitest"); const fixtures_1 = require("../tests/fixtures"); const setup_1 = require("../tests/setup"); const StatusManager_1 = require("./StatusManager"); const executionState_1 = require("./executionState"); // Note: using structuredClone when passing objects to the StatusManager shall make sure that we are not facing any unknown call-by-reference-issues anymore (0, vitest_1.beforeAll)(setup_1.setupTestEnvironment); (0, vitest_1.describe)('StatusManager', () => { let statusManager; let updateRouteHookMock; let route; let step; const expectCallbacksToHaveBeenCalledWith = (route) => { (0, vitest_1.expect)(updateRouteHookMock).toHaveBeenCalledWith(route); }; const initializeStatusManager = ({ includingExecution, }) => { step = (0, fixtures_1.buildStepObject)({ includingExecution }); route = (0, fixtures_1.buildRouteObject)({ step }); executionState_1.executionState.create({ route, executionOptions: { updateRouteHook: updateRouteHookMock, }, }); return new StatusManager_1.StatusManager(route.id); }; (0, vitest_1.beforeEach)(() => { updateRouteHookMock = vitest_1.vi.fn(); vitest_1.vi.spyOn(Date, 'now').mockImplementation(() => fixtures_1.SOME_DATE); }); (0, vitest_1.describe)('initExecutionObject', () => { (0, vitest_1.describe)('when no execution is defined yet', () => { (0, vitest_1.beforeEach)(() => { statusManager = initializeStatusManager({ includingExecution: false }); statusManager.initExecutionObject(step); }); (0, vitest_1.it)('should create an empty execution & call the callbacks with the updated route', () => { const updatedStep = Object.assign({}, step, { execution: { status: 'PENDING', process: [], startedAt: fixtures_1.SOME_DATE, }, }); const updatedRoute = Object.assign({}, route, { steps: [updatedStep], }); expectCallbacksToHaveBeenCalledWith(updatedRoute); }); }); (0, vitest_1.describe)('when an execution is already defined', () => { (0, vitest_1.beforeEach)(() => { statusManager = initializeStatusManager({ includingExecution: true }); statusManager.initExecutionObject(structuredClone(step)); }); (0, vitest_1.it)('should not call the callbacks', () => { (0, vitest_1.expect)(updateRouteHookMock).not.toHaveBeenCalled(); }); }); }); (0, vitest_1.describe)('updateExecution', () => { (0, vitest_1.beforeEach)(() => { vitest_1.vi.spyOn(Date, 'now').mockImplementation(() => fixtures_1.SOME_DATE + 10); }); (0, vitest_1.describe)('when no execution is defined yet', () => { (0, vitest_1.beforeEach)(() => { statusManager = initializeStatusManager({ includingExecution: false }); }); (0, vitest_1.it)('should throw an error', () => { // function has to be wrapped into a function https://jestjs.io/docs/expect#tothrowerror (0, vitest_1.expect)(() => statusManager.updateExecution(structuredClone(step), 'DONE')).toThrow("Can't update empty execution."); }); }); (0, vitest_1.describe)('when an execution is defined', () => { (0, vitest_1.beforeEach)(() => { statusManager = initializeStatusManager({ includingExecution: true }); statusManager.updateExecution(structuredClone(step), 'DONE', { fromAmount: '123', toAmount: '312', }); }); (0, vitest_1.it)('should update the execution & call the callbacks with the updated route', () => { const updatedExecution = Object.assign({}, step.execution, { fromAmount: '123', toAmount: '312', status: 'DONE', }); const updatedStep = Object.assign({}, step, { execution: updatedExecution, }); const updatedRoute = Object.assign({}, route, { steps: [updatedStep], }); expectCallbacksToHaveBeenCalledWith(updatedRoute); }); }); }); (0, vitest_1.describe)('findOrCreateProcess', () => { (0, vitest_1.describe)('when no execution is defined yet', () => { (0, vitest_1.beforeEach)(() => { statusManager = initializeStatusManager({ includingExecution: false }); }); (0, vitest_1.it)('should throw an error', () => { (0, vitest_1.expect)(() => statusManager.findOrCreateProcess({ step: structuredClone(step), type: 'SWAP', })).toThrow("Execution hasn't been initialized."); }); }); (0, vitest_1.describe)('when an execution is defined', () => { (0, vitest_1.beforeEach)(() => { statusManager = initializeStatusManager({ includingExecution: true }); }); (0, vitest_1.describe)('and the process already exists', () => { (0, vitest_1.it)('should return the process and not call the callbacks', () => { const process = statusManager.findOrCreateProcess({ step: structuredClone(step), type: 'TOKEN_ALLOWANCE', }); (0, vitest_1.expect)(process).toEqual(step.execution?.process[0]); (0, vitest_1.expect)(updateRouteHookMock).not.toHaveBeenCalled(); }); }); (0, vitest_1.describe)("and the process doesn't exist", () => { (0, vitest_1.it)('should create a process and call the callbacks with the updated route', () => { const process = statusManager.findOrCreateProcess({ step: structuredClone(step), type: 'CROSS_CHAIN', }); (0, vitest_1.expect)(process.type).toEqual('CROSS_CHAIN'); (0, vitest_1.expect)(process.status).toEqual('STARTED'); (0, vitest_1.expect)(process.message).toEqual('Preparing bridge transaction'); const updatedExecution = Object.assign({}, step.execution, { process: [...step.execution.process, process], }); const updatedStep = Object.assign({}, step, { execution: updatedExecution, }); const updatedRoute = Object.assign({}, route, { steps: [updatedStep], }); expectCallbacksToHaveBeenCalledWith(updatedRoute); }); }); }); }); (0, vitest_1.describe)('updateProcess', () => { (0, vitest_1.beforeEach)(() => { statusManager = initializeStatusManager({ includingExecution: true }); }); (0, vitest_1.describe)('when no process can be found', () => { (0, vitest_1.it)('should throw an error', () => { (0, vitest_1.expect)(() => statusManager.updateProcess(structuredClone(step), 'CROSS_CHAIN', 'CANCELLED')).toThrow("Can't find a process for the given type."); }); }); (0, vitest_1.describe)('when a process is found', () => { const statuses = [ { status: 'ACTION_REQUIRED' }, { status: 'PENDING' }, { status: 'FAILED', doneAt: true }, { status: 'DONE', doneAt: true }, { status: 'CANCELLED', doneAt: true }, ]; for (const { status, doneAt } of statuses) { (0, vitest_1.describe)(`and the status is ${status}`, () => { (0, vitest_1.it)('should update the process and call the callbacks', () => { const process = statusManager.updateProcess(structuredClone(step), 'SWAP', status); (0, vitest_1.expect)(process.type).toEqual('SWAP'); (0, vitest_1.expect)(process.status).toEqual(status); // expect(process.message).toEqual( // getProcessMessage('SWAP', status as Status) // ) doneAt ? (0, vitest_1.expect)(process.doneAt).toBeDefined() : (0, vitest_1.expect)(process.doneAt).toBeUndefined(); const notUpdateableStatus = status === 'DONE' || status === 'CANCELLED'; const updatedExecution = Object.assign({}, step.execution, { process: [step.execution.process[0], process], status: notUpdateableStatus ? step.execution.status : status, }); const updatedStep = { ...step, execution: updatedExecution }; const updatedRoute = Object.assign({}, route, { steps: [updatedStep], }); expectCallbacksToHaveBeenCalledWith(updatedRoute); }); }); } }); }); (0, vitest_1.describe)('removeProcess', () => { (0, vitest_1.describe)('when no execution is defined yet', () => { (0, vitest_1.beforeEach)(() => { statusManager = initializeStatusManager({ includingExecution: false }); }); (0, vitest_1.it)('should throw an error', () => { (0, vitest_1.expect)(() => statusManager.removeProcess(structuredClone(step), 'TOKEN_ALLOWANCE')).toThrow("Execution hasn't been initialized."); }); }); (0, vitest_1.describe)('when an execution is defined', () => { (0, vitest_1.beforeEach)(() => { statusManager = initializeStatusManager({ includingExecution: true }); statusManager.removeProcess(structuredClone(step), 'TOKEN_ALLOWANCE'); }); (0, vitest_1.it)('should remove the process and call the callbacks', () => { const updatedExecution = Object.assign({}, step.execution, { process: [step.execution.process[1]], }); const updatedStep = Object.assign({}, step, { execution: updatedExecution, }); const updatedRoute = Object.assign({}, route, { steps: [updatedStep], }); expectCallbacksToHaveBeenCalledWith(updatedRoute); }); }); }); });