UNPKG

@condor-labs/redis

Version:

This module provide and usefull helper to use the official Node_redis library.

321 lines (272 loc) 13.6 kB
'use strict'; const logger = require('@condor-labs/logger'); const sinon = require('sinon'); const helper = require('./index'); const fs = require('fs'); const redis = require('redis'); const os = require("os") const { assert, expect } = require('chai'); const invalidSettings = { bar: 'foo' }; const validSettings = { socket: { host: 'mhost', port: 1234, }, prefix: 'mprefix', password: 'mpass', clientName: 'test_service_api_0' }; const ClienList = ['id=8104296001002 addr=186.99.6.38:58898 laddr=172.16.0.38:12726 fd=4501 name=test_service_api_0 age=3 idle=1 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=2147483647 obl=0 oll=0 omem=0 totMem=0 events=r cmd=CLIENT user=default redir=r\r', 'id=8104296001003 addr=186.99.6.38:58898 laddr=172.16.0.38:12726 fd=4501 name=test_service_api_0 age=1 idle=1 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=2147483647 obl=0 oll=0 omem=0 totMem=0 events=r cmd=CLIENT user=default redir=r\r'] const ClientInfo = 'id=8104296001002 addr=186.99.6.38:58898 laddr=172.16.0.38:12726 fd=4501 name=test_service_api_0 age=2 idle=1 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=2147483647 obl=0 oll=0 omem=0 totMem=0 events=r cmd=CLIENT user=default redir=r\r' describe('REDIS TESTINGS', () => { //helper._setSettings describe('When _setSettings function is called', () => { let _validateSettingsStub = {}; beforeEach(() => { _validateSettingsStub = sinon.stub(helper, "_validateSettings"); }); afterEach(() => { _validateSettingsStub.restore(); }); it('Should call the helper._validateSettings method once', () => { _validateSettingsStub.returns(true); helper._setSettings(); assert.equal(helper._validateSettings.calledOnce, true); }); it('when the clientName is empty it Should set hostname as clientName', () => { _validateSettingsStub.returns(true); validSettings.clientName = null helper._setSettings({ ...validSettings }); assert.equal(helper._settings.clientName.includes(os.hostname()), true); }); it('when the clientName is not empty it Should set clientName as clientName', () => { _validateSettingsStub.returns(true); helper._setSettings(validSettings); assert.equal(helper._settings.clientName.includes(validSettings.clientName), true); }); it('Should throws an error when the settings are invalid and should not set the settings', () => { try { helper._settings = void 0 _validateSettingsStub.returns(false); helper._setSettings(invalidSettings); } catch (error) { expect(error).to.be.instanceOf(Error); expect(error.message).to.be.equal(helper._errorMsgInvalidSetting); expect(helper._settings).to.be.equal(undefined); } }); it('Should set the settings when they are valid', () => { _validateSettingsStub.returns(true); helper._setSettings(validSettings); expect(helper._settings).to.be.equal(validSettings); }); }); //helper._validateSettings describe('When _validateSettings function is called', () => { let loggerErrorStub = {}; beforeEach(() => { loggerErrorStub = sinon.stub(logger, "error").callsFake(() => { }); }); afterEach(() => { loggerErrorStub.restore(); }); it('Should log the right error message when no settings are passed', () => { helper._validateSettings(); expect(loggerErrorStub.calledOnce).to.be.true; expect(loggerErrorStub.calledWith(helper._errorMsgUndefinedSetting)).to.be.true; }); it('Should return false when no settings are passed', () => { expect(helper._validateSettings()).to.be.equal(false); }); it('Should log the right error message when settings passed have an invalid format', () => { helper._validateSettings(invalidSettings); expect(loggerErrorStub.calledOnce).to.be.true; }); it('Should returns false when settings passed have an invalid format', () => { const result = helper._validateSettings(invalidSettings); expect(result).to.be.equal(false); }); it('Should returns false when settings.ssl is true and not sslKeys paths are present', () => { const settings = { ...validSettings, ssl: true } const result = helper._validateSettings(settings); expect(result).to.be.equal(false); }); it('Should not log any error message when settings passed are valid', () => { helper._validateSettings(validSettings); expect(loggerErrorStub.calledOnce).to.be.equal(false); }); it('Should return true when settings passed are valid', () => { const result = helper._validateSettings(validSettings); expect(result).to.be.equal(true); }); }); describe('When getClient function is called', () => { let _validateSettingstub = {}; let readFileSyncStub = {}; let createClientStub = {}; let _verifyUniqueConnection = {}; beforeEach(() => { _validateSettingstub = sinon.stub(helper, "_validateSettings"); _verifyUniqueConnection = sinon.stub(helper, "_verifyUniqueConnection"); readFileSyncStub = sinon.stub(fs, "readFileSync").callsFake((param) => { return param }); createClientStub = sinon.stub(redis, "createClient").callsFake(() => ({ on: () => { }, connect: () => { }, sendCommand: () => { } })); }); afterEach(() => { _validateSettingstub.restore(); readFileSyncStub.restore(); createClientStub.restore(); _verifyUniqueConnection.restore(); helper._client = void 0 }); it('Should return a valid client when it is already initialized', async () => { helper._client = {} const client = await helper.getClient(); expect(client).to.be.equal(helper._client); helper._client = undefined; }); it('Should calls validateSetting function once when the client has not been initialized', async () => { _validateSettingstub.returns(true); await helper.getClient(); expect(_validateSettingstub.calledOnce).to.be.true; }); it('Should throws an error when the settings are invalid', async () => { _validateSettingstub.returns(false); try { await helper.getClient(); } catch (error) { expect(error.message).to.be.equal(helper._errorMsgInvalidSetting); expect(error).to.be.instanceOf(Error); } }); it('Should set the tls object property to redisOptions object with the right properties when ssl property is configured to true', async () => { _validateSettingstub.returns(true); validSettings.socket.tls = true; validSettings.socket.key = "sslKeyPath"; validSettings.socket.cert = "sslCertPath"; validSettings.socket.ca = "sslCaPath"; helper._setSettings(validSettings) await helper.getClient(); expect(helper._settings.socket).to.have.property('tls'); expect(helper._settings.socket).to.have.property('key'); expect(helper._settings.socket).to.have.property('cert'); expect(helper._settings.socket).to.have.property('ca'); expect(helper._settings.socket.tls).to.be.equal(true); expect(readFileSyncStub.callCount).to.be.equal(3); expect(readFileSyncStub.getCalls()[0].args).be.deep.equal([validSettings.socket.key, { encoding: 'ascii' }]); expect(readFileSyncStub.getCalls()[1].args).be.deep.equal([validSettings.socket.cert, { encoding: 'ascii' }]); expect(readFileSyncStub.getCalls()[2].args).be.deep.equal([validSettings.socket.ca[0], { encoding: 'ascii' }]); }); it('Should calls redis.createClient once with the right params', async () => { _validateSettingstub.returns(true); validSettings.socket.tls = false; await helper.getClient(); expect(createClientStub.calledOnce).to.be.true; expect(createClientStub.calledWith(helper._settings)).to.be.true; }); it('Should calls _verifyUniqueConnection function once when the client has not been initialized', async () => { _validateSettingstub.returns(true); await helper.getClient(); expect(_verifyUniqueConnection.calledOnce).to.be.true; }); }); describe('When _verifyUniqueConnection function is called', () => { let _clientInfo = {}; let _killClient = {}; let _clientList = {}; beforeEach(() => { _clientInfo = sinon.stub(helper, "_clientInfo").returns(ClientInfo); _clientList = sinon.stub(helper, "_clientList").returns(ClienList); _killClient = sinon.stub(helper, "_killClient").returns(); }); afterEach(() => { _clientInfo.restore(); _killClient.restore(); _clientList.restore(); }); it('the list have two clients with the same name Should kill one', async () => { helper._settings.name = 'test_service_api_0' await helper._verifyUniqueConnection(true); expect(_clientInfo.calledOnce).to.be.true; expect(_clientList.calledOnce).to.be.true; expect(_killClient.calledOnce).to.be.true; }); it('the list have no clients duplicated with the same name Should kill no one', async () => { helper._settings.name = 'test_service_api_1' await helper._verifyUniqueConnection(true); expect(_clientInfo.calledOnce).to.be.true; expect(_clientList.calledOnce).to.be.true; expect(_killClient.calledOnce).to.be.false; }); it('the list have unnamed clients just created it Should kill no one', async () => { helper._settings.name = 'test_service_api_1' ClienList.push('id=8104296001004 addr=186.99.6.38:58898 laddr=172.16.0.38:12726 fd=4501 name= age=1 idle=1 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=2147483647 obl=0 oll=0 omem=0 totMem=0 events=r cmd=CLIENT user=default redir=r\r') await helper._verifyUniqueConnection(true); expect(_clientInfo.calledOnce).to.be.true; expect(_clientList.calledOnce).to.be.true; expect(_killClient.calledOnce).to.be.false; }); it('the list have one unnamed clients old aged it Should kill one', async () => { helper._settings.name = 'test_service_api_1' ClienList.push('id=8104296001005 addr=186.99.6.38:58898 laddr=172.16.0.38:12726 fd=4501 name= age=200 idle=1 flags=N db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=2147483647 obl=0 oll=0 omem=0 totMem=0 events=r cmd=CLIENT user=default redir=r\r') await helper._verifyUniqueConnection(true); expect(_clientInfo.calledOnce).to.be.true; expect(_clientList.calledOnce).to.be.true; expect(_killClient.calledOnce).to.be.true; }); }); describe('When call _killClient', () => { let clientKill = {}; beforeEach(() => { helper._client = { clientKill: () => { }, }; clientKill = sinon.stub(helper._client, "clientKill").callsFake(() => { }); }); afterEach(() => { clientKill.restore(); }); it('when id is null it Should not call to clientKill', async () => { await helper._killClient(''); expect(clientKill.calledOnce).to.be.false; }); it('when id is not null it Should call to clientKill', async () => { const id = 23 await helper._killClient(id); expect(clientKill.calledOnce).to.be.true; expect(clientKill.getCalls()[0].args).be.deep.equal([{ filter: 'ID', id: id }]); }); }); describe('When call _clientInfo or _clientList', () => { let sendCommand = {}; beforeEach(() => { helper._client = { sendCommand: () => { } }; sendCommand = sinon.stub(helper._client, "sendCommand").callsFake(() => { }); }); afterEach(() => { sendCommand.restore(); }); it('when _clientList is called it Should call to sendCommand with rigth params', async () => { sendCommand.returns(ClienList.join('\n')) await helper._clientList(); expect(sendCommand.calledOnce).to.be.true; expect(sendCommand.getCalls()[0].args).be.deep.equal([['CLIENT', 'LIST']]); }); it('when _clientInfo is called it Should call to sendCommand with rigth params', async () => { await helper._clientInfo(); expect(sendCommand.calledOnce).to.be.true; expect(sendCommand.getCalls()[0].args).be.deep.equal([['CLIENT', 'INFO']]); }); }); });