"use strict";
/**
 * Token state management test
 *
 *  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 Affero 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 Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
Object.defineProperty(exports, "__esModule", { value: true });
var MongoTokenDao_1 = require("../../../src/server/token/MongoTokenDao");
var Token_1 = require("../../../src/server/token/Token");
var UnknownTokenError_1 = require("../../../src/server/token/UnknownTokenError");
var ContextError_1 = require("../../../src/error/ContextError");
var chai_1 = require("chai");
chai_1.use(require('chai-as-promised'));
describe('server.token.TokenDao', function () {
    describe('#updateToken', function () {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
        var field = 'foo_field';
        var did = 12345;
        var ns = 'namespace';
        var tok_id = 'tok123';
        var tok_type = Token_1.TokenState.DONE;
        var data = 'some data';
        var timestamp = 12345;
        var root = field + '.' + ns;
        var last_tok_id = 'last-tok';
        var last = {
            type: Token_1.TokenState.DEAD,
            timestamp: 4567,
            data: 'last token',
        };
        var prev = {
            type: Token_1.TokenState.ACTIVE,
            timestamp: 11111,
            data: 'prev status',
        };
        [
            {
                label: 'updates token and returns previous data',
                given: (_a = {},
                    _a[field] = (_b = {},
                        _b[ns] = (_c = {
                                last: last_tok_id,
                                lastState: (_d = {},
                                    _d[prev.type] = last_tok_id,
                                    _d),
                                lastStatus: {
                                    type: last.type,
                                    timestamp: last.timestamp,
                                    data: last.data,
                                }
                            },
                            _c[tok_id] = {
                                status: {
                                    type: prev.type,
                                    timestamp: prev.timestamp,
                                    data: prev.data,
                                },
                            },
                            _c),
                        _b),
                    _a),
                expected: {
                    id: tok_id,
                    status: {
                        type: tok_type,
                        timestamp: timestamp,
                        data: data,
                    },
                    prev_state: (_e = {},
                        _e[prev.type] = last_tok_id,
                        _e),
                    prev_status: prev,
                    prev_last: {
                        id: last_tok_id,
                        status: last,
                        prev_status: null,
                        prev_last: null,
                        prev_state: {},
                    },
                },
            },
            {
                label: 'returns null for prev status if missing data',
                given: (_f = {},
                    _f[field] = (_g = {},
                        _g[ns] = {
                            last: last_tok_id,
                            lastStatus: {
                                type: last.type,
                                timestamp: last.timestamp,
                                data: last.data,
                            },
                        },
                        _g),
                    _f),
                expected: {
                    id: tok_id,
                    status: {
                        type: tok_type,
                        timestamp: timestamp,
                        data: data,
                    },
                    prev_status: null,
                    prev_state: {},
                    prev_last: {
                        id: last_tok_id,
                        status: last,
                        prev_status: null,
                        prev_last: null,
                        prev_state: {},
                    },
                },
            },
            {
                label: 'returns null for missing namespace data',
                given: (_h = {},
                    _h[field] = (_j = {},
                        _j[ns] = {},
                        _j),
                    _h),
                expected: {
                    id: tok_id,
                    status: {
                        type: tok_type,
                        timestamp: timestamp,
                        data: data,
                    },
                    prev_status: null,
                    prev_state: {},
                    prev_last: null,
                },
            },
            {
                label: 'returns null for missing namespace',
                given: (_k = {},
                    _k[field] = {},
                    _k),
                expected: {
                    id: tok_id,
                    status: {
                        type: tok_type,
                        timestamp: timestamp,
                        data: data,
                    },
                    prev_status: null,
                    prev_state: {},
                    prev_last: null,
                },
            },
            {
                label: 'returns null for missing root field',
                given: {},
                expected: {
                    id: tok_id,
                    status: {
                        type: tok_type,
                        timestamp: timestamp,
                        data: data,
                    },
                    prev_status: null,
                    prev_state: {},
                    prev_last: null,
                },
            },
        ].forEach(function (_a) {
            var given = _a.given, expected = _a.expected, label = _a.label;
            return it(label, function () {
                var coll = {
                    findAndModify: function (selector, _sort, given_data, options, callback) {
                        var _a, _b, _c;
                        var expected_entry = {
                            type: tok_type,
                            timestamp: timestamp,
                            data: data,
                        };
                        chai_1.expect(selector.id).to.equal(did);
                        chai_1.expect(given_data).to.deep.equal({
                            $set: (_a = {},
                                _a[root + ".last"] = tok_id,
                                _a[root + ".lastState." + tok_type] = tok_id,
                                _a[root + ".lastStatus"] = expected_entry,
                                _a[root + "." + tok_id + ".status"] = expected_entry,
                                _a),
                            $push: (_b = {},
                                _b[root + "." + tok_id + ".statusLog"] = expected_entry,
                                _b),
                        });
                        chai_1.expect(options).to.deep.equal({
                            upsert: true,
                            new: false,
                            fields: (_c = {},
                                _c[root + ".last"] = 1,
                                _c[root + ".lastState"] = 1,
                                _c[root + ".lastStatus"] = 1,
                                _c[root + "." + tok_id + ".status"] = 1,
                                _c),
                        });
                        callback(null, given);
                    },
                    update: function () { },
                    findOne: function () { },
                    find: function () { },
                    createIndex: function () { },
                    insert: function () { },
                };
                return chai_1.expect(new MongoTokenDao_1.MongoTokenDao(coll, field, function () { return timestamp; }).updateToken(did, ns, tok_id, tok_type, data)).to.eventually.deep.equal(expected);
            });
        });
        it('proxies error to callback', function () {
            var expected_error = Error('expected error');
            var coll = {
                findAndModify: function (_selector, _sort, _update, _options, callback) {
                    callback(expected_error, {});
                },
                update: function () { },
                findOne: function () { },
                find: function () { },
                createIndex: function () { },
                insert: function () { },
            };
            return chai_1.expect(new MongoTokenDao_1.MongoTokenDao(coll, 'foo', function () { return 0; }).updateToken(0, 'ns', 'id', Token_1.TokenState.DONE, null)).to.eventually.be.rejectedWith(expected_error);
        });
    });
    describe('#getToken', function () {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
        var field = 'get_field';
        var did = 12345;
        var ns = 'get_ns';
        var expected_status = {
            type: Token_1.TokenState.ACTIVE,
            timestamp: 0,
            data: '',
        };
        var last_tok_id = 'last-tok';
        var last = {
            type: Token_1.TokenState.DEAD,
            timestamp: 4567,
            data: 'last token',
        };
        [
            [
                'retrieves token by id',
                'tok123',
                (_a = {},
                    _a[field] = (_b = {},
                        _b[ns] = {
                            last: last_tok_id,
                            lastState: (_c = {},
                                _c[Token_1.TokenState.ACTIVE] = last_tok_id,
                                _c[Token_1.TokenState.DONE] = last_tok_id,
                                _c),
                            lastStatus: last,
                            tok123: {
                                status: expected_status,
                                statusLog: [expected_status],
                            },
                        },
                        _b),
                    _a),
                {
                    id: 'tok123',
                    status: expected_status,
                    prev_status: expected_status,
                    prev_state: (_d = {},
                        _d[Token_1.TokenState.ACTIVE] = last_tok_id,
                        _d[Token_1.TokenState.DONE] = last_tok_id,
                        _d),
                    prev_last: {
                        id: last_tok_id,
                        status: last,
                        prev_status: null,
                        prev_last: null,
                        prev_state: {},
                    },
                },
                null,
                null,
            ],
            [
                'rejects for namespace if token is not found',
                'tok123',
                (_e = {},
                    _e[field] = (_f = {},
                        _f[ns] = {
                            last: last_tok_id,
                            lastStatus: last,
                            // just to make sure we don't grab another tok
                            othertok: {
                                status: expected_status,
                                statusLog: [expected_status],
                            },
                        },
                        _f),
                    _e),
                null,
                ns + ".tok123",
                {
                    doc_id: did,
                    quote_id: did,
                    ns: ns,
                    token_id: 'tok123',
                },
            ],
            [
                'rejects if namespace is not found',
                'tok123',
                (_g = {},
                    _g[field] = {},
                    _g),
                null,
                ns,
                {
                    doc_id: did,
                    quote_id: did,
                    ns: ns,
                },
            ],
            [
                'returns last modified token given no token id',
                '',
                (_h = {},
                    _h[field] = (_j = {},
                        _j[ns] = (_k = {
                                last: last_tok_id,
                                lastState: (_l = {},
                                    _l[Token_1.TokenState.DEAD] = last_tok_id,
                                    _l),
                                lastStatus: last
                            },
                            _k[last_tok_id] = {
                                status: expected_status,
                                statusLog: [expected_status],
                            },
                            _k),
                        _j),
                    _h),
                {
                    id: last_tok_id,
                    status: last,
                    prev_status: last,
                    prev_state: (_m = {},
                        _m[Token_1.TokenState.DEAD] = last_tok_id,
                        _m),
                    prev_last: {
                        id: last_tok_id,
                        status: last,
                        prev_status: null,
                        prev_last: null,
                        prev_state: {},
                    },
                },
                null,
                null,
            ],
            [
                'rejects unknown last modified token given no token id',
                '',
                (_o = {},
                    _o[field] = (_p = {},
                        _p[ns] = {},
                        _p),
                    _o),
                null,
                ns,
                {
                    doc_id: did,
                    quote_id: did,
                    ns: ns,
                },
            ],
            [
                'rejects unknown namespace token given no token id',
                '',
                (_q = {},
                    _q[field] = {},
                    _q),
                null,
                ns,
                {
                    doc_id: did,
                    quote_id: did,
                    ns: ns,
                },
            ],
        ].forEach(function (_a) {
            var label = _a[0], tok_id = _a[1], dbresult = _a[2], expected = _a[3], fmsg = _a[4], fcontext = _a[5];
            return it(label, function () {
                var coll = {
                    findOne: function (selector, _a, callback) {
                        var _b;
                        var fields = _a.fields;
                        var expected_fields = (_b = {},
                            _b[field + "." + ns + ".last"] = 1,
                            _b[field + "." + ns + ".lastState"] = 1,
                            _b[field + "." + ns + ".lastStatus"] = 1,
                            _b);
                        if (tok_id) {
                            expected_fields[field + "." + ns + "." + tok_id] = 1;
                        }
                        chai_1.expect(fields).to.deep.equal(expected_fields);
                        chai_1.expect(selector).to.deep.equal({ id: did });
                        callback(null, dbresult);
                    },
                    update: function () { },
                    findAndModify: function () { },
                    find: function () { },
                    createIndex: function () { },
                    insert: function () { },
                };
                var result = new MongoTokenDao_1.MongoTokenDao(coll, field, function () { return 0; }).getToken(did, ns, tok_id);
                return fmsg !== null
                    ? Promise.all([
                        chai_1.expect(result).to.eventually.be.rejectedWith(UnknownTokenError_1.UnknownTokenError, fmsg),
                        chai_1.expect(result).to.eventually.be.rejectedWith(UnknownTokenError_1.UnknownTokenError, '' + did),
                        result.catch(function (e) {
                            if (!ContextError_1.hasContext(e)) {
                                // TS will soon have type assertions and
                                // then this conditional and return can be
                                // removed
                                return chai_1.expect.fail();
                            }
                            return chai_1.expect(e.context).to.deep.equal(fcontext);
                        }),
                    ])
                    : chai_1.expect(result).to.eventually.deep.equal(expected);
            });
        });
        it('proxies error to callback', function () {
            var expected_error = Error('expected error');
            var coll = {
                findOne: function (_selector, _fields, callback) {
                    callback(expected_error, {});
                },
                update: function () { },
                findAndModify: function () { },
                find: function () { },
                createIndex: function () { },
                insert: function () { },
            };
            return chai_1.expect(new MongoTokenDao_1.MongoTokenDao(coll, 'foo', function () { return 0; }).getToken(0, 'ns', 'id')).to.eventually.be.rejectedWith(expected_error);
        });
    });
});
//# sourceMappingURL=data:application/json;base64, 