"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const bluebird_1 = __importDefault(require("bluebird"));
const lodash_1 = require("lodash");
const sinon_1 = __importDefault(require("sinon"));
const internal_1 = require("../../internal");
const queries_1 = require("../../middleware/queries");
const testUtils_1 = require("../../testUtils");
const mocks_1 = require("../../testUtils/mocks");
const types_1 = require("../../types");
jest.mock('~/base/PolymeshTransaction', require("../../testUtils/mocks/polymeshTransaction").mockPolymeshTransactionModule('~/base/PolymeshTransaction'));
describe('Transaction Queue class', () => {
    let context;
    beforeAll(() => {
        jest.useFakeTimers('legacy');
        mocks_1.polymeshTransactionMockUtils.initMocks();
        mocks_1.entityMockUtils.initMocks();
        mocks_1.dsMockUtils.initMocks({ contextOptions: { middlewareEnabled: false } });
    });
    beforeEach(() => {
        context = mocks_1.dsMockUtils.getContextInstance();
    });
    afterEach(() => {
        mocks_1.polymeshTransactionMockUtils.reset();
        mocks_1.entityMockUtils.reset();
        mocks_1.dsMockUtils.reset();
    });
    afterAll(() => {
        jest.useRealTimers();
        mocks_1.dsMockUtils.cleanup();
    });
    describe('constructor', () => {
        test('should set the arguments, fees and list of transactions', () => {
            const transactionSpecs = [
                {
                    args: [1],
                    isCritical: false,
                    autoResolve: types_1.TransactionStatus.Succeeded,
                },
            ];
            const transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            const procedureResult = 3;
            const queue = new internal_1.TransactionQueue({ transactions, procedureResult }, context);
            expect(queue.transactions).toEqual(transactions);
        });
    });
    describe('method: run', () => {
        test("should run each transaction in the queue and return the queue's return value, unwrapping it if it is a PostTransactionValue and transforming it if there is a transform function", () => __awaiter(void 0, void 0, void 0, function* () {
            const transactionSpecs = [
                {
                    args: [1],
                    isCritical: false,
                    autoResolve: types_1.TransactionStatus.Succeeded,
                },
                {
                    args: ['someArg'],
                    isCritical: true,
                    autoResolve: types_1.TransactionStatus.Succeeded,
                },
            ];
            let transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            const procedureResult = new bignumber_js_1.default(3);
            let queue = new internal_1.TransactionQueue({ transactions, procedureResult, transformer: (val) => val.toString() }, context);
            let returned = yield queue.run();
            expect(returned).toBe('3');
            transactions.forEach(transaction => {
                sinon_1.default.assert.calledOnce(transaction.run);
            });
            transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            const returnPostTransactionValue = new internal_1.PostTransactionValue(() => Promise.resolve(procedureResult));
            yield returnPostTransactionValue.run({});
            queue = new internal_1.TransactionQueue({ transactions, procedureResult: returnPostTransactionValue }, context);
            returned = yield queue.run();
            expect(returned).toBe(procedureResult);
        }));
        test('should update the queue status', () => __awaiter(void 0, void 0, void 0, function* () {
            const transactionSpecs = [
                {
                    args: [12],
                    isCritical: true,
                    autoResolve: false,
                },
            ];
            let transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            const procedureResult = 3;
            let queue = new internal_1.TransactionQueue({ transactions, procedureResult }, context);
            // Idle -> Running -> Succeeded
            expect(queue.status).toBe(types_1.TransactionQueueStatus.Idle);
            queue.run();
            yield testUtils_1.fakePromise();
            expect(queue.status).toBe(types_1.TransactionQueueStatus.Running);
            mocks_1.polymeshTransactionMockUtils.updateTransactionStatus(transactions[0], types_1.TransactionStatus.Succeeded);
            yield testUtils_1.fakePromise();
            expect(queue.status).toBe(types_1.TransactionQueueStatus.Succeeded);
            transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            // Idle -> Running -> Failed
            queue = new internal_1.TransactionQueue({ transactions, procedureResult }, context);
            queue.run().catch(lodash_1.noop);
            yield testUtils_1.fakePromise();
            mocks_1.polymeshTransactionMockUtils.updateTransactionStatus(transactions[0], types_1.TransactionStatus.Failed);
            yield testUtils_1.fakePromise();
            expect(queue.status).toBe(types_1.TransactionQueueStatus.Failed);
        }));
        test('should throw an error if a critical transaction fails', () => {
            const transactionSpecs = [
                {
                    args: [1],
                    isCritical: false,
                    autoResolve: types_1.TransactionStatus.Succeeded,
                },
                {
                    args: ['someArg'],
                    isCritical: true,
                    autoResolve: types_1.TransactionStatus.Failed,
                },
            ];
            const transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            const procedureResult = 3;
            const queue = new internal_1.TransactionQueue({ transactions, procedureResult }, context);
            const runPromise = queue.run();
            return expect(runPromise).rejects.toThrow('Transaction Error');
        });
        test("should throw an error if the current Account doesn't have enough balance to pay the transaction fees", () => {
            const transactionSpecs = [
                {
                    args: [1],
                    isCritical: false,
                    fees: {
                        protocol: new bignumber_js_1.default(200),
                        gas: new bignumber_js_1.default(200),
                    },
                    autoResolve: types_1.TransactionStatus.Succeeded,
                },
                {
                    args: ['someArg'],
                    isCritical: true,
                    autoResolve: types_1.TransactionStatus.Failed,
                },
            ];
            const transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            mocks_1.dsMockUtils.setContextAccountBalance({
                free: new bignumber_js_1.default(100),
                locked: new bignumber_js_1.default(0),
                total: new bignumber_js_1.default(100),
            });
            const procedureResult = 3;
            const queue = new internal_1.TransactionQueue({ transactions, procedureResult }, context);
            const runPromise = queue.run();
            return expect(runPromise).rejects.toThrow("Not enough POLYX balance to pay for this procedure's fees");
        });
        test("should throw an error if any third party Account doesn't have enough balance to pay the transaction fees", () => {
            const account1 = mocks_1.entityMockUtils.getAccountInstance({
                address: 'account1',
                getBalance: {
                    free: new bignumber_js_1.default(100),
                    locked: new bignumber_js_1.default(0),
                    total: new bignumber_js_1.default(100),
                },
            });
            const account2 = mocks_1.entityMockUtils.getAccountInstance({
                address: 'account2',
                getBalance: {
                    free: new bignumber_js_1.default(100),
                    locked: new bignumber_js_1.default(0),
                    total: new bignumber_js_1.default(100),
                },
            });
            const transactionSpecs = [
                {
                    args: [1],
                    isCritical: false,
                    fees: {
                        protocol: new bignumber_js_1.default(100),
                        gas: new bignumber_js_1.default(100),
                    },
                    payingAccount: {
                        type: types_1.PayingAccountType.Subsidy,
                        account: account1,
                        allowance: new bignumber_js_1.default(500),
                    },
                    autoResolve: types_1.TransactionStatus.Succeeded,
                },
                {
                    args: ['someArg'],
                    isCritical: true,
                    fees: {
                        protocol: new bignumber_js_1.default(100),
                        gas: new bignumber_js_1.default(100),
                    },
                    payingAccount: {
                        type: types_1.PayingAccountType.Other,
                        account: account2,
                        allowance: null,
                    },
                    autoResolve: types_1.TransactionStatus.Failed,
                },
            ];
            const transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            const procedureResult = 3;
            const queue = new internal_1.TransactionQueue({ transactions, procedureResult }, context);
            const runPromise = queue.run();
            return expect(runPromise).rejects.toThrow("Not enough POLYX third party balance to pay for this procedure's fees");
        });
        test("should throw an error if any third party Account doesn't have enough allowance to pay the transaction fees", () => {
            const account = mocks_1.entityMockUtils.getAccountInstance({
                getBalance: {
                    free: new bignumber_js_1.default(1000),
                    locked: new bignumber_js_1.default(0),
                    total: new bignumber_js_1.default(1000),
                },
            });
            const transactionSpecs = [
                {
                    args: [1],
                    isCritical: false,
                    fees: {
                        protocol: new bignumber_js_1.default(100),
                        gas: new bignumber_js_1.default(100),
                    },
                    payingAccount: {
                        type: types_1.PayingAccountType.Subsidy,
                        account,
                        allowance: new bignumber_js_1.default(100),
                    },
                    autoResolve: types_1.TransactionStatus.Succeeded,
                },
                {
                    args: ['someArg'],
                    isCritical: true,
                    fees: {
                        protocol: new bignumber_js_1.default(100),
                        gas: new bignumber_js_1.default(100),
                    },
                    payingAccount: {
                        type: types_1.PayingAccountType.Subsidy,
                        account,
                        allowance: new bignumber_js_1.default(100),
                    },
                    autoResolve: types_1.TransactionStatus.Failed,
                },
            ];
            const transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            const procedureResult = 3;
            const queue = new internal_1.TransactionQueue({ transactions, procedureResult }, context);
            const runPromise = queue.run();
            return expect(runPromise).rejects.toThrow("Not enough POLYX third party allowance to pay for this procedure's fees");
        });
        test('should throw an error if the caller is subsidized but one or more transactions cannot be subsidized', () => {
            const account1 = mocks_1.entityMockUtils.getAccountInstance({
                address: 'account1',
                getBalance: {
                    free: new bignumber_js_1.default(100),
                    locked: new bignumber_js_1.default(0),
                    total: new bignumber_js_1.default(100),
                },
            });
            const account2 = mocks_1.entityMockUtils.getAccountInstance({
                address: 'account2',
                getBalance: {
                    free: new bignumber_js_1.default(100),
                    locked: new bignumber_js_1.default(0),
                    total: new bignumber_js_1.default(100),
                },
            });
            const transactionSpecs = [
                {
                    args: [1],
                    isCritical: false,
                    fees: {
                        protocol: new bignumber_js_1.default(100),
                        gas: new bignumber_js_1.default(100),
                    },
                    payingAccount: {
                        type: types_1.PayingAccountType.Subsidy,
                        account: account1,
                        allowance: new bignumber_js_1.default(500),
                    },
                    autoResolve: types_1.TransactionStatus.Succeeded,
                    supportsSubsidy: false,
                },
                {
                    args: ['someArg'],
                    isCritical: true,
                    fees: {
                        protocol: new bignumber_js_1.default(100),
                        gas: new bignumber_js_1.default(100),
                    },
                    payingAccount: {
                        type: types_1.PayingAccountType.Other,
                        account: account2,
                        allowance: null,
                    },
                    autoResolve: types_1.TransactionStatus.Failed,
                },
            ];
            const transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            const procedureResult = 3;
            const queue = new internal_1.TransactionQueue({ transactions, procedureResult }, context);
            const runPromise = queue.run();
            return expect(runPromise).rejects.toThrow('Some of the transactions in the queue cannot be run with a subsidized Account');
        });
        test('should succeed if the only failures are from non-critical transactions', () => __awaiter(void 0, void 0, void 0, function* () {
            const transactionSpecs = [
                {
                    args: [1],
                    isCritical: false,
                    autoResolve: types_1.TransactionStatus.Failed,
                },
                {
                    args: ['someArg'],
                    isCritical: true,
                    autoResolve: types_1.TransactionStatus.Succeeded,
                },
            ];
            const transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            const procedureResult = 3;
            const queue = new internal_1.TransactionQueue({ transactions, procedureResult }, context);
            let err;
            try {
                yield queue.run();
            }
            catch (e) {
                err = e;
            }
            expect(err).toBeUndefined();
        }));
        test('should throw an error if attempting to run a queue that has already run', () => __awaiter(void 0, void 0, void 0, function* () {
            const transactionSpecs = [
                {
                    args: [1],
                    isCritical: false,
                    autoResolve: types_1.TransactionStatus.Succeeded,
                },
                {
                    args: ['someArg'],
                    isCritical: true,
                    autoResolve: types_1.TransactionStatus.Succeeded,
                },
            ];
            const transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            const procedureResult = 3;
            const queue = new internal_1.TransactionQueue({ transactions, procedureResult }, context);
            yield queue.run();
            return expect(queue.run()).rejects.toThrow('Cannot re-run a Transaction Queue');
        }));
    });
    describe('method: onStatusChange', () => {
        test("should execute a callback when the queue's status changes", () => __awaiter(void 0, void 0, void 0, function* () {
            const transactionSpecs = [
                {
                    args: [1],
                    isCritical: false,
                    autoResolve: types_1.TransactionStatus.Succeeded,
                },
            ];
            const transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            const procedureResult = 3;
            const queue = new internal_1.TransactionQueue({ transactions, procedureResult }, context);
            const listenerStub = sinon_1.default.stub();
            queue.onStatusChange(q => listenerStub(q.status));
            yield queue.run();
            sinon_1.default.assert.calledWith(listenerStub.firstCall, types_1.TransactionQueueStatus.Running);
            sinon_1.default.assert.calledWith(listenerStub.secondCall, types_1.TransactionQueueStatus.Succeeded);
        }));
        test('should return an unsubscribe function', () => __awaiter(void 0, void 0, void 0, function* () {
            const transactionSpecs = [
                {
                    args: [1],
                    isCritical: false,
                    autoResolve: false,
                },
            ];
            const transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            const procedureResult = 3;
            const queue = new internal_1.TransactionQueue({ transactions, procedureResult }, context);
            const listenerStub = sinon_1.default.stub();
            const unsub = queue.onStatusChange(q => listenerStub(q.status));
            queue.run();
            yield testUtils_1.fakePromise();
            unsub();
            mocks_1.polymeshTransactionMockUtils.updateTransactionStatus(transactions[0], types_1.TransactionStatus.Succeeded);
            sinon_1.default.assert.calledWith(listenerStub.firstCall, types_1.TransactionQueueStatus.Running);
            sinon_1.default.assert.callCount(listenerStub, 1);
        }));
    });
    describe('method: onTransactionStatusChange', () => {
        test("should execute a callback when the a transaction's status changes", () => __awaiter(void 0, void 0, void 0, function* () {
            const transactionSpecs = [
                {
                    args: [1],
                    isCritical: false,
                    autoResolve: false,
                },
            ];
            const transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            const procedureResult = 3;
            const queue = new internal_1.TransactionQueue({ transactions, procedureResult }, context);
            const listenerStub = sinon_1.default.stub();
            queue.onTransactionStatusChange(transaction => {
                listenerStub(transaction.status);
            });
            const runPromise = queue.run();
            mocks_1.polymeshTransactionMockUtils.updateTransactionStatus(transactions[0], types_1.TransactionStatus.Running);
            mocks_1.polymeshTransactionMockUtils.updateTransactionStatus(transactions[0], types_1.TransactionStatus.Succeeded);
            yield runPromise;
            sinon_1.default.assert.calledWith(listenerStub.firstCall, types_1.TransactionStatus.Running);
            sinon_1.default.assert.calledWith(listenerStub.secondCall, types_1.TransactionStatus.Succeeded);
        }));
        test('should return an unsubscribe function', () => __awaiter(void 0, void 0, void 0, function* () {
            const transactionSpecs = [
                {
                    args: [1],
                    isCritical: false,
                    autoResolve: false,
                },
            ];
            const transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            const procedureResult = 3;
            const queue = new internal_1.TransactionQueue({ transactions, procedureResult }, context);
            const listenerStub = sinon_1.default.stub();
            const unsub = queue.onTransactionStatusChange(transaction => {
                listenerStub(transaction.status);
            });
            const runPromise = queue.run();
            mocks_1.polymeshTransactionMockUtils.updateTransactionStatus(transactions[0], types_1.TransactionStatus.Running);
            yield testUtils_1.fakePromise();
            unsub();
            mocks_1.polymeshTransactionMockUtils.updateTransactionStatus(transactions[0], types_1.TransactionStatus.Succeeded);
            yield runPromise;
            sinon_1.default.assert.calledWith(listenerStub.firstCall, types_1.TransactionStatus.Running);
            sinon_1.default.assert.callCount(listenerStub, 1);
        }));
    });
    describe('method: onProcessedByMiddleware', () => {
        let blockNumber;
        beforeEach(() => {
            blockNumber = new bignumber_js_1.default(100);
            mocks_1.dsMockUtils.initMocks({
                contextOptions: { latestBlock: blockNumber, middlewareEnabled: true },
            });
        });
        test("should execute a callback when the queue's data has been processed", () => __awaiter(void 0, void 0, void 0, function* () {
            const transactionSpecs = [
                {
                    args: [1],
                    isCritical: false,
                    autoResolve: types_1.TransactionStatus.Succeeded,
                },
            ];
            const transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            const procedureResult = 3;
            const queue = new internal_1.TransactionQueue({ transactions, procedureResult }, context);
            const listenerStub = sinon_1.default.stub();
            queue.onProcessedByMiddleware(err => listenerStub(err));
            const stub = mocks_1.dsMockUtils.createApolloQueryStub(queries_1.latestProcessedBlock(), {
                latestBlock: { id: blockNumber.minus(1).toNumber() },
            });
            stub
                .withArgs(queries_1.latestProcessedBlock())
                .onCall(3)
                .resolves({ data: { latestBlock: { id: blockNumber.toNumber() } } });
            yield queue.run();
            yield bluebird_1.default.each(lodash_1.range(6), () => __awaiter(void 0, void 0, void 0, function* () {
                yield testUtils_1.fakePromise();
                jest.advanceTimersByTime(2000);
            }));
            sinon_1.default.assert.calledWith(listenerStub.firstCall, undefined);
        }));
        test('should execute a callback with an error if 10 seconds pass without the data being processed', () => __awaiter(void 0, void 0, void 0, function* () {
            const transactionSpecs = [
                {
                    args: [1],
                    isCritical: false,
                    autoResolve: types_1.TransactionStatus.Succeeded,
                },
            ];
            const transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            const procedureResult = 3;
            const queue = new internal_1.TransactionQueue({ transactions, procedureResult }, context);
            const listenerStub = sinon_1.default.stub();
            queue.onProcessedByMiddleware(err => listenerStub(err));
            mocks_1.dsMockUtils.createApolloQueryStub(queries_1.latestProcessedBlock(), {
                latestBlock: { id: blockNumber.minus(1).toNumber() },
            });
            yield queue.run();
            yield bluebird_1.default.each(lodash_1.range(6), () => __awaiter(void 0, void 0, void 0, function* () {
                yield testUtils_1.fakePromise();
                jest.advanceTimersByTime(2000);
            }));
            expect(listenerStub.getCall(0).args[0].message).toBe('Timed out');
        }));
        test('should throw an error if the middleware is not enabled', () => __awaiter(void 0, void 0, void 0, function* () {
            mocks_1.dsMockUtils.initMocks({ contextOptions: { middlewareEnabled: false } });
            const transactionSpecs = [
                {
                    args: [1],
                    isCritical: false,
                    autoResolve: types_1.TransactionStatus.Succeeded,
                },
            ];
            const transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            const procedureResult = 3;
            const queue = new internal_1.TransactionQueue({ transactions, procedureResult }, context);
            const listenerStub = sinon_1.default.stub();
            expect(() => queue.onProcessedByMiddleware(err => listenerStub(err))).toThrow('Cannot subscribe without an enabled middleware connection');
        }));
        test('should return an unsubscribe function', () => __awaiter(void 0, void 0, void 0, function* () {
            const transactionSpecs = [
                {
                    args: [1],
                    isCritical: false,
                    autoResolve: types_1.TransactionStatus.Succeeded,
                },
            ];
            const transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            const procedureResult = 3;
            const queue = new internal_1.TransactionQueue({ transactions, procedureResult }, context);
            const listenerStub = sinon_1.default.stub();
            const unsub = queue.onProcessedByMiddleware(err => listenerStub(err));
            mocks_1.dsMockUtils.createApolloQueryStub(queries_1.latestProcessedBlock(), {
                latestBlock: { id: blockNumber.minus(1).toNumber() },
            });
            yield queue.run();
            yield bluebird_1.default.each(lodash_1.range(6), () => __awaiter(void 0, void 0, void 0, function* () {
                yield testUtils_1.fakePromise();
                jest.advanceTimersByTime(2000);
            }));
            unsub();
            // eslint-disable-next-line @typescript-eslint/no-explicit-any
            queue.emitter.emit('ProcessedByMiddleware');
            sinon_1.default.assert.callCount(listenerStub, 1);
        }));
    });
    describe('method: getMinFees', () => {
        test('should return the sum of all transaction fees', () => __awaiter(void 0, void 0, void 0, function* () {
            const account = mocks_1.entityMockUtils.getAccountInstance({
                getBalance: {
                    free: new bignumber_js_1.default(1000),
                    locked: new bignumber_js_1.default(0),
                    total: new bignumber_js_1.default(1000),
                },
            });
            const transactionSpecs = [
                {
                    args: [1],
                    isCritical: true,
                    fees: {
                        protocol: new bignumber_js_1.default(100),
                        gas: new bignumber_js_1.default(1),
                    },
                    autoResolve: types_1.TransactionStatus.Succeeded,
                },
                {
                    args: ['someArg'],
                    isCritical: true,
                    fees: {
                        protocol: new bignumber_js_1.default(50),
                        gas: new bignumber_js_1.default(2),
                    },
                    autoResolve: types_1.TransactionStatus.Succeeded,
                },
                {
                    args: [{ foo: 'bar' }],
                    isCritical: true,
                    fees: {
                        protocol: new bignumber_js_1.default(10),
                        gas: new bignumber_js_1.default(5),
                    },
                    autoResolve: types_1.TransactionStatus.Succeeded,
                    payingAccount: {
                        type: types_1.PayingAccountType.Subsidy,
                        account,
                        allowance: new bignumber_js_1.default(100),
                    },
                },
                {
                    args: [{ foo: 'bar' }],
                    isCritical: true,
                    fees: {
                        protocol: new bignumber_js_1.default(10),
                        gas: new bignumber_js_1.default(5),
                    },
                    autoResolve: types_1.TransactionStatus.Succeeded,
                    payingAccount: {
                        type: types_1.PayingAccountType.Subsidy,
                        account,
                        allowance: new bignumber_js_1.default(100),
                    },
                },
            ];
            const transactions = mocks_1.polymeshTransactionMockUtils.setupNextTransactions(transactionSpecs);
            const procedureResult = 3;
            const queue = new internal_1.TransactionQueue({ transactions, procedureResult }, context);
            const balance = new bignumber_js_1.default(500);
            mocks_1.dsMockUtils.setContextAccountBalance({
                free: balance,
                locked: new bignumber_js_1.default(0),
                total: balance,
            });
            const fees = yield queue.getMinFees();
            expect(fees).toEqual({
                thirdPartyFees: [
                    {
                        account,
                        fees: {
                            protocol: new bignumber_js_1.default(20),
                            gas: new bignumber_js_1.default(10),
                        },
                        allowance: new bignumber_js_1.default(100),
                        balance: new bignumber_js_1.default(1000),
                        type: types_1.PayingAccountType.Subsidy,
                    },
                ],
                accountFees: {
                    protocol: new bignumber_js_1.default(150),
                    gas: new bignumber_js_1.default(3),
                },
                accountBalance: balance,
            });
        }));
    });
});
//# sourceMappingURL=TransactionQueue.js.map