"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const chai_1 = require("chai");
const mongodb_1 = require("mongodb");
const sinon_1 = __importDefault(require("sinon"));
const block_1 = require("../../../src/models/block");
const coin_1 = require("../../../src/models/coin");
const helpers_1 = require("../../helpers");
const unit_1 = require("../../helpers/unit");
describe('Coin Model', function () {
    before(unit_1.unitBeforeHelper);
    after(unit_1.unitAfterHelper);
    describe('_apiTransform', () => {
        it('should return the transform object with coin info', () => {
            const id = new mongodb_1.ObjectId();
            const coin = {
                _id: id,
                network: 'regtest',
                chain: 'BTC',
                mintTxid: '81f24ac62a6ffb634b74e6278997f0788f3c64e844453f8831d2a526dc3ecb13',
                mintIndex: 0,
                mintHeight: 1,
                coinbase: true,
                value: 5000000000.0,
                address: 'n1ojJtS98D2VRLcTkaHH4YXLG4ytCyS7AL',
                script: Buffer.from(''),
                wallets: [],
                spentTxid: '',
                spentHeight: -2 /* SpentHeightIndicators.unspent */
            };
            const result = coin_1.CoinStorage._apiTransform(coin, { object: false });
            const parseResult = JSON.parse(result.toString());
            (0, chai_1.expect)(parseResult).to.deep.equal({
                mintTxid: '81f24ac62a6ffb634b74e6278997f0788f3c64e844453f8831d2a526dc3ecb13',
                mintHeight: 1,
                network: 'regtest',
                confirmations: -1,
                mintIndex: 0,
                chain: 'BTC',
                spentTxid: '',
                address: 'n1ojJtS98D2VRLcTkaHH4YXLG4ytCyS7AL',
                coinbase: true,
                script: '',
                spentHeight: -2 /* SpentHeightIndicators.unspent */,
                value: 5000000000.0
            });
        });
        it('should return the raw transform object if options field exists and set to true', () => {
            const id = new mongodb_1.ObjectId();
            const coin = {
                _id: id,
                network: 'regtest',
                chain: 'BTC',
                mintTxid: '81f24ac62a6ffb634b74e6278997f0788f3c64e844453f8831d2a526dc3ecb13',
                mintIndex: 0,
                mintHeight: 1,
                coinbase: true,
                value: 5000000000.0,
                address: 'n1ojJtS98D2VRLcTkaHH4YXLG4ytCyS7AL',
                script: Buffer.from(''),
                sequenceNumber: undefined,
                wallets: [],
                spentTxid: '',
                spentHeight: -2 /* SpentHeightIndicators.unspent */
            };
            const result = coin_1.CoinStorage._apiTransform(coin, { object: true });
            (0, chai_1.expect)(result).to.deep.equal({
                mintTxid: '81f24ac62a6ffb634b74e6278997f0788f3c64e844453f8831d2a526dc3ecb13',
                network: 'regtest',
                chain: 'BTC',
                spentTxid: '',
                mintHeight: 1,
                mintIndex: 0,
                spentHeight: -2 /* SpentHeightIndicators.unspent */,
                address: 'n1ojJtS98D2VRLcTkaHH4YXLG4ytCyS7AL',
                coinbase: true,
                confirmations: -1,
                script: '',
                sequenceNumber: undefined,
                value: 5000000000.0
            });
        });
    });
    describe('getBalanceAtTime', () => {
        let sandbox;
        beforeEach(() => {
            sandbox = sinon_1.default.sandbox.create();
        });
        afterEach(() => {
            sandbox.restore();
        });
        it('should return an object with confirmed, unconfirmed, and balance when additional time parameter is passed in', async () => {
            const id = new mongodb_1.ObjectId('5c364e342ab5602e97a56f0e');
            const chain = 'BTC';
            const network = 'regtest';
            const time = new Date().toISOString();
            const query = { wallets: id, 'wallets.0': { $exists: true } };
            const matchObject = {
                $or: [
                    {
                        spentHeight: {
                            $gt: 123
                        }
                    },
                    {
                        spentHeight: {
                            $lt: 0
                        }
                    }
                ],
                mintHeight: {
                    $lte: 123
                },
                wallets: new mongodb_1.ObjectId('5c364e342ab5602e97a56f0e'),
                'wallets.0': { $exists: true }
            };
            const blockModelHeight = { height: 123 };
            (0, helpers_1.mockModel)('coins', [
                { _id: 'confirmed', balance: 123123 },
                { _id: 'unconfirmed', balance: 1 }
            ]);
            (0, helpers_1.mockModel)('blocks', blockModelHeight);
            const coinModelAggregateSpy = coin_1.CoinStorage.collection.aggregate;
            const blockModelFindSpy = block_1.BitcoinBlockStorage.collection.find;
            const result = await coin_1.CoinStorage.getBalanceAtTime({ query, time, chain, network });
            (0, chai_1.expect)(coinModelAggregateSpy.called).to.deep.equal(true, 'CoinStorage.aggregation should have been called');
            (0, chai_1.expect)(blockModelFindSpy.called).to.deep.equal(true, 'BlockModel.find should have been called');
            (0, chai_1.expect)(coinModelAggregateSpy.getCall(0).args[0][0].$match).to.deep.equal(matchObject);
            (0, chai_1.expect)(result).to.has.property('confirmed');
            (0, chai_1.expect)(result).to.has.property('unconfirmed');
            (0, chai_1.expect)(result).to.has.property('balance');
            (0, chai_1.expect)(result).to.deep.equal({ confirmed: 123123, unconfirmed: 1, balance: 123124 });
        });
    });
    describe('getBalance', () => {
        let sandbox;
        beforeEach(() => {
            sandbox = sinon_1.default.sandbox.create();
        });
        afterEach(() => {
            sandbox.restore();
        });
        it('should return an object with confirmed, unconfirmed, and balance', async () => {
            const id = new mongodb_1.ObjectId('5c364e342ab5602e97a56f0e');
            const query = {
                wallets: id,
                'wallets.0': { $exists: true },
                spentHeight: { $lt: 0 },
                mintHeight: { $gt: -3 }
            };
            (0, helpers_1.mockStorage)([
                { _id: 'confirmed', balance: 123123 },
                { _id: 'unconfirmed', balance: 1 }
            ]);
            const coinModelAggregateSpy = coin_1.CoinStorage.collection.aggregate;
            const result = await coin_1.CoinStorage.getBalance({ query });
            (0, chai_1.expect)(coinModelAggregateSpy.called).to.deep.equal(true, 'CoinStorage.aggregation should have been called');
            (0, chai_1.expect)(coinModelAggregateSpy.getCall(0).args[0][0].$match).to.deep.equal(query);
            (0, chai_1.expect)(result).to.has.property('confirmed');
            (0, chai_1.expect)(result).to.has.property('unconfirmed');
            (0, chai_1.expect)(result).to.has.property('balance');
            (0, chai_1.expect)(result).to.deep.equal({ confirmed: 123123, unconfirmed: 1, balance: 123124 });
        });
    });
});
//# sourceMappingURL=coin.test.js.map