"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
const mongodb_1 = require("mongodb");
const utils = __importStar(require("../../../src/utils"));
const redactUrl_1 = require("../../../src/utils/redactUrl");
const chai_1 = require("chai");
describe('Utils', function () {
    describe('range', function () {
        it('should return an array of ascending numbers if start < end', function () {
            const result = utils.range(23, 35);
            (0, chai_1.expect)(result).to.deep.equal([23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34]);
        });
        it('should return an array of descending numbers if start > end', function () {
            const result = utils.range(7, 1);
            (0, chai_1.expect)(result).to.deep.equal([7, 6, 5, 4, 3, 2]);
        });
        it('should handle negative start', function () {
            const result = utils.range(-5, 3);
            (0, chai_1.expect)(result).to.deep.equal([-5, -4, -3, -2, -1, 0, 1, 2]);
        });
        it('should handle negative end', function () {
            const result = utils.range(0, -6);
            (0, chai_1.expect)(result).to.deep.equal([0, -1, -2, -3, -4, -5]);
        });
        it('should handle negative start and end', function () {
            const result = utils.range(-5, -10);
            (0, chai_1.expect)(result).to.deep.equal([-5, -6, -7, -8, -9]);
        });
        it('should handle negative params with start < end', function () {
            const result = utils.range(-5, -1);
            (0, chai_1.expect)(result).to.deep.equal([-5, -4, -3, -2]);
        });
        it('should handle negative params with start > end', function () {
            const result = utils.range(-1, -5);
            (0, chai_1.expect)(result).to.deep.equal([-1, -2, -3, -4]);
        });
        it('should handle optional end param', function () {
            const result = utils.range(5);
            (0, chai_1.expect)(result).to.deep.equal([0, 1, 2, 3, 4]);
        });
        it('should handle optional end param with negative start', function () {
            const result = utils.range(-5);
            (0, chai_1.expect)(result).to.deep.equal([0, -1, -2, -3, -4]);
        });
        it('should return an empty array if start equals end', function () {
            const result = utils.range(5, 5);
            (0, chai_1.expect)(result).to.deep.equal([]);
        });
        it('should return an empty array if no params given', function () {
            const result = utils.range();
            (0, chai_1.expect)(result).to.deep.equal([]);
        });
    });
    describe('uniqBy', function () {
        it('should remove the redundant mongo object pairs without messing with order', function () {
            const objectIds = [
                new mongodb_1.ObjectID('56d6a232ead1dc6e4f565e78'),
                // redundant pair
                new mongodb_1.ObjectID('65e7573610d3fa8bc4930869'),
                new mongodb_1.ObjectID('65e7573610d3fa8bc4930869'),
                new mongodb_1.ObjectID('6f0d45b6dfeafa40f958afbf'),
                // redundant pair
                new mongodb_1.ObjectID('e3b4cff2794d399d10f0a683'),
                new mongodb_1.ObjectID('e3b4cff2794d399d10f0a683'),
                new mongodb_1.ObjectID('d6faff1f3d1ea0cd1ed847a3')
            ];
            const result = utils.uniqBy(objectIds, id => id.toHexString());
            const expectedResult = [
                new mongodb_1.ObjectID('56d6a232ead1dc6e4f565e78'),
                new mongodb_1.ObjectID('65e7573610d3fa8bc4930869'),
                new mongodb_1.ObjectID('6f0d45b6dfeafa40f958afbf'),
                new mongodb_1.ObjectID('e3b4cff2794d399d10f0a683'),
                new mongodb_1.ObjectID('d6faff1f3d1ea0cd1ed847a3')
            ];
            (0, chai_1.expect)(result).deep.equal(expectedResult);
        });
        it('should remove all but one mongo object if all are redundant', function () {
            const objectIds = [
                // all redundant
                new mongodb_1.ObjectID('56d6a232ead1dc6e4f565e78'),
                new mongodb_1.ObjectID('56d6a232ead1dc6e4f565e78'),
                new mongodb_1.ObjectID('56d6a232ead1dc6e4f565e78'),
                new mongodb_1.ObjectID('56d6a232ead1dc6e4f565e78'),
                new mongodb_1.ObjectID('56d6a232ead1dc6e4f565e78')
            ];
            const result = utils.uniqBy(objectIds, id => id.toHexString());
            const expectedResult = [
                new mongodb_1.ObjectID('56d6a232ead1dc6e4f565e78')
            ];
            (0, chai_1.expect)(result).deep.equal(expectedResult);
        });
        it('should remove objects with redundant names and not redundant values', function () {
            const array = [
                {
                    name: 'a',
                    value: 10
                },
                {
                    name: 'b',
                    value: 3.1
                },
                {
                    name: 'a',
                    value: 2.7
                },
                {
                    name: 'c',
                    value: 10
                },
                {
                    name: 'b',
                    value: 6
                }
            ];
            const result = utils.uniqBy(array, item => item.name);
            const expectedResult = [
                {
                    name: 'a',
                    value: 10
                },
                {
                    name: 'b',
                    value: 3.1
                },
                {
                    name: 'c',
                    value: 10
                },
            ];
            (0, chai_1.expect)(result).deep.equal(expectedResult);
        });
        it('should handle null, undefined, and NaN', function () {
            const array = [
                {
                    name: null,
                    value: 10
                },
                {
                    name: undefined,
                    value: 3.1
                },
                {
                    name: null,
                    value: 2.7
                },
                {
                    name: 'c',
                    value: 10
                },
                {
                    name: NaN,
                    value: 10
                },
                {
                    name: NaN,
                    value: 101
                },
                {
                    name: undefined,
                    value: 6
                }
            ];
            const result = utils.uniqBy(array, item => item.name);
            const expectedResult = [
                {
                    name: null,
                    value: 10
                },
                {
                    name: undefined,
                    value: 3.1
                },
                {
                    name: 'c',
                    value: 10
                },
                {
                    name: NaN,
                    value: 10
                },
            ];
            (0, chai_1.expect)(result).deep.equal(expectedResult);
        });
        it('should work using property string', function () {
            const array = [
                {
                    name: 'a',
                    value: 10
                },
                {
                    name: 'b',
                    value: 3.1
                },
                {
                    name: 'a',
                    value: 2.7
                },
                {
                    name: 'c',
                    value: 10
                },
                {
                    name: 'b',
                    value: 6
                }
            ];
            const result = utils.uniqBy(array, 'name');
            const expectedResult = [
                {
                    name: 'a',
                    value: 10
                },
                {
                    name: 'b',
                    value: 3.1
                },
                {
                    name: 'c',
                    value: 10
                },
            ];
            (0, chai_1.expect)(result).deep.equal(expectedResult);
        });
    });
    describe('uniq', function () {
        it('should remove redundant values in numbers array', function () {
            const array = [3, 1, 4, 1, 5];
            const result = utils.uniq(array);
            const expectedResult = [3, 1, 4, 5];
            (0, chai_1.expect)(result).deep.equal(expectedResult);
        });
        it('should handle first and last element redundancy', function () {
            const array = [1, 2, 3, 1];
            const result = utils.uniq(array);
            const expectedResult = [1, 2, 3];
            (0, chai_1.expect)(result).deep.equal(expectedResult);
        });
        it('should handle null, undefined, NaN, objects and strings', function () {
            const array = [NaN, NaN, new mongodb_1.ObjectID('6f0d45b6dfeafa40f958afbf'), undefined,
                'bitcoin', null, 'bitcoin', undefined, 'txs', null];
            const result = utils.uniq(array);
            const expectedResult = [NaN, new mongodb_1.ObjectID('6f0d45b6dfeafa40f958afbf'), undefined, 'bitcoin', null, 'txs'];
            (0, chai_1.expect)(result).deep.equal(expectedResult);
        });
    });
    describe('merge', function () {
        it('should merge objects realistic to a config', function () {
            const config = {
                maxPoolSize: 50,
                port: 3000,
                chains: {},
                aliasMapping: {
                    chains: {},
                    networks: {}
                },
                services: {
                    api: {
                        rateLimiter: {
                            disabled: false,
                            whitelist: ['::ffff:127.0.0.1', '::1']
                        },
                        wallets: {
                            allowCreationBeforeCompleteSync: false,
                            allowUnauthenticatedCalls: false
                        }
                    },
                    storage: {}
                }
            };
            const foundConfig = {
                chains: {
                    BTC: {
                        mainnet: {},
                        regtest: {
                            chainSource: 'p2p',
                            trustedPeers: [
                                {
                                    host: '127.0.0.1',
                                    port: 20020
                                }
                            ],
                            rpc: {
                                host: '127.0.0.1',
                                port: 20021,
                                username: 'username',
                                password: 'password'
                            }
                        }
                    }
                }
            };
            const expectedResult = {
                maxPoolSize: 50,
                port: 3000,
                chains: {
                    BTC: {
                        mainnet: {},
                        regtest: {
                            chainSource: 'p2p',
                            trustedPeers: [
                                {
                                    host: '127.0.0.1',
                                    port: 20020
                                }
                            ],
                            rpc: {
                                host: '127.0.0.1',
                                port: 20021,
                                username: 'username',
                                password: 'password'
                            }
                        }
                    }
                },
                aliasMapping: {
                    chains: {},
                    networks: {}
                },
                services: {
                    api: {
                        rateLimiter: {
                            disabled: false,
                            whitelist: ['::ffff:127.0.0.1', '::1']
                        },
                        wallets: {
                            allowCreationBeforeCompleteSync: false,
                            allowUnauthenticatedCalls: false
                        }
                    },
                    storage: {}
                }
            };
            const result = utils.merge(config, foundConfig);
            (0, chai_1.expect)(result).to.deep.equal(expectedResult);
        });
    });
    describe('redactUrl', function () {
        it('should redact Alchemy v2 API key from URL', function () {
            const url = 'https://eth-mainnet.g.alchemy.com/v2/abc123def456';
            (0, chai_1.expect)((0, redactUrl_1.redactUrl)(url)).to.not.include('abc123def456');
            (0, chai_1.expect)((0, redactUrl_1.redactUrl)(url)).to.include('REDACTED');
        });
        it('should redact Alchemy v3 API key and preserve version', function () {
            const url = 'https://eth-mainnet.g.alchemy.com/v3/abc123def456';
            const redacted = (0, redactUrl_1.redactUrl)(url);
            (0, chai_1.expect)(redacted).to.not.include('abc123def456');
            (0, chai_1.expect)(redacted).to.include('/v3/***REDACTED***');
        });
        it('should redact apikey query parameter', function () {
            const url = 'https://api.example.com/data?apikey=secretkey123&chain=eth';
            (0, chai_1.expect)((0, redactUrl_1.redactUrl)(url)).to.not.include('secretkey123');
            (0, chai_1.expect)((0, redactUrl_1.redactUrl)(url)).to.include('chain=eth');
        });
        it('should redact api_key query parameter', function () {
            const url = 'https://api.example.com/data?api_key=secretkey123';
            (0, chai_1.expect)((0, redactUrl_1.redactUrl)(url)).to.not.include('secretkey123');
        });
        it('should redact key query parameter', function () {
            const url = 'https://api.example.com/data?key=secretkey123';
            (0, chai_1.expect)((0, redactUrl_1.redactUrl)(url)).to.not.include('secretkey123');
        });
        it('should return URL unchanged if no keys present', function () {
            const url = 'https://api.example.com/data?chain=eth';
            (0, chai_1.expect)((0, redactUrl_1.redactUrl)(url)).to.eq(url);
        });
        it('should handle empty string', function () {
            (0, chai_1.expect)((0, redactUrl_1.redactUrl)('')).to.eq('');
        });
    });
});
//# sourceMappingURL=index.test.js.map