UNPKG

express-keenio

Version:

Express middleware for creating events from request-responses.

328 lines (297 loc) 9.62 kB
"use strict"; var should = require('chai').should(); var EventEmitter = require('events').EventEmitter; var KeenEventModule = require('../lib/keen-event'); describe("_isValidProperty()", function () { var keenEventHandler; beforeEach(function () { keenEventHandler = new KeenEventModule({}, new EventEmitter()); }); it("should accept valid properties", function () { var tests = [ "abc", // less than 256 characters long "^$%&", // a dollar sign cannot be the first character "separated-by-a-dash", // there cannot be periods in the name "cannot-be-a-null-value" // cannot be a null value ]; tests.forEach(function (test) { keenEventHandler._isValidProperty(test).should.be.true; }); }); it("should not accept invalid properties", function () { var tests = [ "abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc", "$^%&", "separated.by.a.period", "", undefined, null ]; tests.forEach(function (test) { keenEventHandler._isValidProperty(test).should.be.false; }); }); }); describe("_sanitizeData()", function () { var keenEventHandler; it("should wipe out the value inside a 'password' key, even inside hierarchy", function () { var inputData = { user: { password: 'abc123' }, otherProperty: 'def456' }, outputData = { user: { }, otherProperty: 'def456' }; keenEventHandler = new KeenEventModule({}, new EventEmitter()); keenEventHandler._sanitizeData(inputData).should.eql(outputData); }); it("should wipe out the value inside a user-defined bad property", function () { var inputData = { property: 'abc123', otherProperty: 'def456' }, outputData = { property: 'abc123' }; keenEventHandler = new KeenEventModule({ blacklistProperties: ['otherProperty'] }, new EventEmitter()); keenEventHandler._sanitizeData(inputData).should.eql(outputData); }); it("should wipe out all keys which are invalid Keen.IO properties", function () { var inputData = { '$^%&': 'abc123', 'separated.by.a.period': 'def456', validProperty: 'ghi789', otherValidProperty: 'here-it-is' }, outputData = { validProperty: 'ghi789', otherValidProperty: 'here-it-is' }; keenEventHandler = new KeenEventModule({}, new EventEmitter()); keenEventHandler._sanitizeData(inputData).should.eql(outputData); }); it("should return the same object when given no arrays-of-objects", function () { var obj = { a: 2, deeper: { b: 3, c: [1, 2, 3] } }; keenEventHandler._sanitizeData(obj).should.eql(obj); }); it("should remove arrays-of-objects if they are found", function () { var obj = { a: 2, deeper: { b: 3, c: [{ id: 1 }, { id: 2 }, { id: 3 }] } }; var smitten = { a: 2, deeper: { b: 3 } }; keenEventHandler._sanitizeData(obj).should.eql(smitten); }); it("should return the same object when given no extremely long strings", function () { var obj = { a: 2, aString: 'abc' }; keenEventHandler._sanitizeData(obj).should.eql(obj); }); it("should remove extremely long strings from an object", function () { var obj = { a: 2, aString: Array(1000).join("abc") }; var smitten = { a: 2 }; keenEventHandler._sanitizeData(obj).should.eql(smitten); }); it("should return the same object when given no functions", function () { var obj = { a: 2, notAFunction: 'hey' }; keenEventHandler._sanitizeData(obj).should.eql(obj); }); it("should remove functions from an object", function () { var obj = { a: 2, deep: { aFunction: function () {} } }; var smitten = { a: 2, deep: {} }; keenEventHandler._sanitizeData(obj).should.eql(smitten); }); it('should not remove array-of-objects that define keen addons', function () { var obj = { a: 2, deeper: { b: 3, c: [1, 2, 3] }, addons: [{}, {}, {}] }; keenEventHandler._sanitizeData(obj).should.eql(obj); }); it("should remove extra properties from objects with masses of properties", function () { // A little bit nasty, but it's just a sanity check in case hundreds of properties are added at once... var inputData = { user: { name: 'jim', type: 'human' }, abc: 'def456', def: 'def456', ghi: 'def456', jkl: 'def456', mno: 'def456', pqr: 'def456', stu: 'def456' }, outputData = { user: { name: 'jim', type: 'human' }, abc: 'def456', def: 'def456' }; keenEventHandler = new KeenEventModule({ defaults: { MAX_PROPERTY_QUANTITY: 5 }}, new EventEmitter()); keenEventHandler._sanitizeData(inputData).should.eql(outputData); }); }); describe("_checkPropertyDepth()", function () { var keenEventHandler; beforeEach(function () { keenEventHandler = new KeenEventModule({}, new EventEmitter()); }); it("should give the correct depth of the deepest property of an empty object", function () { var obj = {}; keenEventHandler._checkPropertyDepth(obj).should.equal(1); }); it("should give the correct depth of the deepest property of an object with two levels", function () { var obj = { a: { b: 'at depth 2' }}; keenEventHandler._checkPropertyDepth(obj).should.equal(2); }); it("should give the correct depth of the deepest property of an object with five levels", function () { var obj = { a: { b: 'at depth 2', h: { i: 'at depth 3'} }, c: { d: { e: { f: { g: 'at depth 5' }}}}}; keenEventHandler._checkPropertyDepth(obj).should.equal(5); }); it("will not smite unless it is told to", function () { var rigorMortis = { a: { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: 'wow so deep' }}}}}}}}}}}}; var notSmitten = { a: { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: 'wow so deep' }}}}}}}}}}}}; keenEventHandler._checkPropertyDepth(notSmitten); notSmitten.should.eql(rigorMortis); }); it("will do its master's bidding and smite if it is told to", function () { var rigorMortis = { a: { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: 'wow so deep' }}}}}}}}}}}}; var smitten = { a: { b: { c: { d: { e: { f: { g: { h: { i: { j: { k: { l: 'wow so deep' }}}}}}}}}}}}; keenEventHandler._checkPropertyDepth(smitten, true); smitten.should.not.eql(rigorMortis); // good boy! *pat pat* }); }); describe("_checkForNonWhitelist()", function () { var keenEventHandler; beforeEach(function () { keenEventHandler = new KeenEventModule({}, new EventEmitter()); }); it("should return the same object when given no whitelists", function () { var obj = { intention: { query: { a: 5 }, body: { b: 6 } }, reaction: { c: 7 } }; var output = { intention: { query: { a: 5 }, body: { b: 6 } }, reaction: { c: 7 } }; keenEventHandler._checkForNonWhitelist(obj, {}); obj.should.eql(output); }); it("should return a different object when given some whitelists", function () { var obj = { intention: { query: { a: 5 }, body: { b: 6 } }, reaction: { c: 7 } }; var output = { intention: { query: { a: 5 }, body: { b: 6 } }, reaction: { c: 7 } }; keenEventHandler._checkForNonWhitelist(obj, { query: ['not-there'] }); obj.should.not.eql(output); }); }); describe("_stripNonWhitelistedProperties()", function () { var keenEventHandler; beforeEach(function () { keenEventHandler = new KeenEventModule({}, new EventEmitter()); }); it('should wipe out properties not in the whitelist, leaving those that are in the whitelist', function () { var obj = { a: 5, keepThis: 'still here', andThis: 'also still here', z: 11 }; var output = { keepThis: 'still here', andThis: 'also still here' }; keenEventHandler._stripNonWhitelistedProperties(obj, ['keepThis', 'andThis']); obj.should.eql(output); }); }); describe("_stripNonWhitelistedDeepProperties()", function () { var keenEventHandler; beforeEach(function () { keenEventHandler = new KeenEventModule({}, new EventEmitter()); }); it('should wipe out deep properties not in the whitelist, leaving those that are in the whitelist', function () { var obj = { deep: { property: { isHere: 7, andHere: 9, removeMe: 11 } }, arrOfStrings: ['goes'], arrOfObjects: [ { name: 'Keep This', types: {} }, { name: 'And This 2', types: {} } ], keepMe: 23 }; var output = { deep: { property: { isHere: 7, andHere: 9 } }, arrOfObjects: [ { name: 'Keep This' }, { name: 'And This 2' } ], keepMe: 23 }; keenEventHandler._stripNonWhitelistedDeepProperties(obj, ['deep.property.isHere', 'deep.property.andHere', 'arrOfObjects[].name', 'keepMe' ]); obj.should.eql(output); }); });