/**
 * Tests MongoServerDao
 *
 *  Copyright (C) 2010-2019 R-T Specialty, LLC.
 *
 *  This file is part of the Liza Data Collection Framework.
 *
 *  liza is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var MongoServerDao_1 = require("../../../src/server/db/MongoServerDao");
var chai_1 = require("chai");
chai_1.use(require('chai-as-promised'));
describe('MongoServerDao', function () {
    describe('#saveQuote', function () {
        [
            {
                label: 'will not unset last updated by user when session data is unavailable',
                username: '',
                expected_set_username: undefined,
            },
            {
                label: 'will set last updated by user when session data is available',
                username: 'foo',
                expected_set_username: ['foo'],
            },
        ].forEach(function (_a) {
            var label = _a.label, username = _a.username, expected_set_username = _a.expected_set_username;
            it(label, function (done) {
                var quote = createStubQuote({});
                quote.getUserName = function () { return username; };
                var sut = new MongoServerDao_1.MongoServerDao(createMockDb(
                // update
                function (_selector, data) {
                    chai_1.expect(data.$set['meta.last_updated_by_username']).to.deep.equal(expected_set_username);
                    done();
                }), 'test', function () { return 123; });
                sut.init(function () {
                    return sut.saveQuote(quote, function () { }, function () { });
                });
            });
        });
        describe('with no save data or push data', function () {
            it('saves initial rated individually', function (done) {
                var expected = 123321;
                var expected_username = 'foo@foo.com';
                var quote = createStubQuote({});
                quote.getRatedDate = function () {
                    return expected;
                };
                quote.getUserName = function () { return expected_username; };
                var sut = new MongoServerDao_1.MongoServerDao(createMockDb(
                // update
                function (_selector, data) {
                    chai_1.expect(data.$set['meta.liza_timestamp_initial_rated']).to.deep.equal([expected]);
                    chai_1.expect(data.$setOnInsert['meta.created_by_username']).to.deep.equal([expected_username]);
                    chai_1.expect(data.$push).to.equal(undefined);
                    done();
                }), 'test', function () {
                    return 123;
                });
                sut.init(function () {
                    return sut.saveQuote(quote, function () { }, function () { });
                });
            });
        });
        describe('bound by username', function () {
            [
                {
                    label: 'will set bound_by_username when quote is imported',
                    username: 'foo@foo.com',
                    expected_bound_username: ['foo@foo.com'],
                    is_imported: true,
                },
                {
                    label: 'will not set bound_by_username when quote is not imported',
                    username: 'foo@foo.com',
                    expected_bound_username: undefined,
                    is_imported: false,
                },
            ].forEach(function (_a) {
                var label = _a.label, username = _a.username, expected_bound_username = _a.expected_bound_username, is_imported = _a.is_imported;
                it(label, function (done) {
                    var quote = createStubQuote({});
                    quote.getUserName = function () { return username; };
                    quote.isImported = function () { return is_imported; };
                    var sut = new MongoServerDao_1.MongoServerDao(createMockDb(
                    // update
                    function (_selector, data) {
                        chai_1.expect(data.$set['meta.bound_by_username']).to.deep.equal(expected_bound_username);
                        done();
                    }), 'test', function () {
                        return 123;
                    });
                    sut.init(function () {
                        return sut.saveQuote(quote, function () { }, function () { });
                    });
                });
            });
        });
        describe('with force_publish', function () {
            it('forced_reset resets published indicator', function (done) {
                var expected_ts = 12345;
                var quote = createStubQuote({ published: true });
                var sut = new MongoServerDao_1.MongoServerDao(createMockDb(
                // update
                function (_selector, data) {
                    chai_1.expect(data.$set['published']).to.deep.equal(false);
                    chai_1.expect(data.$set['publishResetTs']).to.deep.equal(expected_ts);
                    done();
                }), 'test', function () {
                    return expected_ts;
                });
                sut.init(function () {
                    return sut.saveQuote(quote, function () { }, function () { }, undefined, {}, true);
                });
            });
            it('not forced will not change published indicator', function (done) {
                var quote = createStubQuote({ published: true });
                var sut = new MongoServerDao_1.MongoServerDao(createMockDb(
                // update
                function (_selector, data) {
                    chai_1.expect(data.$set['published']).to.not.exist;
                    chai_1.expect(data.$set['publishResetTs']).to.not.exist;
                    done();
                }), 'test', function () {
                    return 123;
                });
                sut.init(function () {
                    return sut.saveQuote(quote, function () { }, function () { }, undefined, {}, false);
                });
            });
        });
        describe('with push data', function () {
            it('adds push data to the collection', function (done) {
                var push_data = {
                    foo: ['bar', 'baz'],
                    bar: [{ quux: 'quuux' }],
                };
                var quote = createStubQuote({});
                var sut = new MongoServerDao_1.MongoServerDao(createMockDb(
                // update
                function (_selector, data) {
                    chai_1.expect(data.$push['foo']).to.deep.equal(push_data.foo);
                    chai_1.expect(data.$push['bar']).to.deep.equal(push_data.bar);
                    done();
                }), 'test', function () {
                    return 123;
                });
                sut.init(function () {
                    return sut.saveQuote(quote, function () { }, function () { }, undefined, push_data);
                });
            });
            it('skips push data when it is an empty object', function (done) {
                var push_data = {};
                var quote = createStubQuote({});
                var sut = new MongoServerDao_1.MongoServerDao(createMockDb(
                // update
                function (_selector, data) {
                    chai_1.expect(data.$push).to.equal(undefined);
                    done();
                }), 'test', function () {
                    return 123;
                });
                sut.init(function () {
                    return sut.saveQuote(quote, function () { }, function () { }, undefined, push_data);
                });
            });
        });
    });
    describe('#saveState', function () {
        [
            {
                label: 'does not set field state if undefined',
                given: undefined,
                expected: undefined,
            },
            {
                label: 'does not set field state if empty',
                given: {},
                expected: undefined,
            },
            {
                label: 'sets field state if non-empty',
                given: { foo: 1 },
                expected: { foo: 1 },
            },
        ].forEach(function (_a) {
            var label = _a.label, given = _a.given, expected = _a.expected;
            return it(label, function (done) {
                var update_data = { __not: 'updated' };
                var sut = new MongoServerDao_1.MongoServerDao(createMockDb(
                // update
                function (_selector, data, _options, callback) {
                    update_data = data;
                    callback(null, null);
                }), 'test', function () { return 123; });
                sut.connect(function () { });
                var quote = createStubQuote({});
                quote.getFieldState = function () { return given; };
                var success = function () {
                    chai_1.expect(update_data['$set'].fieldState).to.deep.equal(expected);
                    if (expected === undefined) {
                        chai_1.expect(Object.prototype.hasOwnProperty.call(update_data, 'fieldState')).to.be.false;
                    }
                    done();
                };
                var failure = function (e) {
                    throw e;
                };
                sut.saveQuoteState(quote, success, failure);
            });
        });
    });
});
function createMockDb(on_update) {
    var collection_quotes = {
        update: on_update,
        createIndex: function (_, __, c) { return c(); },
    };
    var collection_seq = {
        find: function (_, __, c) {
            c(null, {
                toArray: function (c) { return c(null, { length: 5 }); },
            });
        },
    };
    var db = {
        collection: function (id, c) {
            var coll = id === 'quotes' ? collection_quotes : collection_seq;
            c(null, coll);
        },
    };
    var driver = {
        open: function (c) { return c(null, db); },
        close: function () { },
        on: function () { },
    };
    return driver;
}
function createStubQuote(metadata) {
    var program = {
        clearNaFields: false,
        naFieldValue: '',
        getId: function () { return '1'; },
        ineligibleLockCount: 0,
        cretain: {},
        defaults: {},
        apis: {},
        internal: {},
        autosave: false,
        whens: {},
        groupWhens: {},
        meta: {
            arefs: {},
            fields: {},
            groups: {},
            qdata: {},
            qtypes: {},
        },
        mapis: {},
        rateSteps: [],
        dapi: function () { return ({}); },
        initQuote: function () { },
        getClassifierKnownFields: function () { return ({}); },
        classify: function () { return ({}); },
        hasNaField: function () { return false; },
        hasKnownType: function () { return true; },
        getFirstStepId: function () { return 0; },
        groupExclusiveFields: {},
        processNaFields: function () { },
        groupIndexField: {},
    };
    var quote = {
        getBucket: function () {
            return ({
                getData: function () {
                    return {};
                },
            });
        },
        getMetabucket: function () {
            return ({
                getData: function () { return metadata; },
            });
        },
        getId: function () { return 123; },
        getProgramVersion: function () { return 'Foo'; },
        getLastPremiumDate: function () { return 0; },
        getUserName: function () { return 'foo@foo.com'; },
        getRatedDate: function () { return 0; },
        getExplicitLockReason: function () { return ''; },
        getExplicitLockStep: function () { return 1; },
        isImported: function () { return false; },
        isBound: function () { return false; },
        getTopVisitedStepId: function () { return 1; },
        getTopSavedStepId: function () { return 1; },
        setTopSavedStepId: function () { return quote; },
        getMetaUpdatedDate: function () { return 0; },
        setRatedDate: function () { return quote; },
        setRateBucket: function () { return quote; },
        setRatingData: function () { return quote; },
        getRatingData: function () { return ({ _unavailable_all: '0' }); },
        getProgram: function () { return program; },
        setExplicitLock: function () { return quote; },
        getProgramId: function () { return 'Foo'; },
        getCurrentStepId: function () { return 0; },
        setCurrentStepId: function () { return quote; },
        setLastPremiumDate: function () { return quote; },
        setRetryAttempts: function () { return quote; },
        getRetryAttempts: function () { return 1; },
        retryAttempted: function () { return quote; },
        setMetadata: function () { return quote; },
        setInitialRatedDate: function () { return quote; },
        getExpirationDate: function () { return 123; },
    };
    return quote;
}
//# sourceMappingURL=data:application/json;base64, 