From c903a25bac16313984444536d46dc4f605d4aa48 Mon Sep 17 00:00:00 2001 From: Jean-Francois Lavoie Date: Mon, 4 Feb 2019 15:16:25 -0500 Subject: [PATCH 1/3] support logger factory --- Readme.md | 6 +- index.js | 46 +- test/test.js | 1192 +++++++++++++++++++++++++++++--------------------- 3 files changed, 738 insertions(+), 506 deletions(-) diff --git a/Readme.md b/Readme.md index 994970a..9eb05b0 100644 --- a/Readme.md +++ b/Readme.md @@ -131,7 +131,11 @@ The logger needs to be added AFTER the express router(`app.router)`) and BEFORE To use winston's existing transports, set `transports` to the values (as in key-value) of the `winston.default.transports` object. This may be done, for example, by using underscorejs: `transports: _.values(winston.default.transports)`. -Alternatively, if you're using a winston logger instance elsewhere and have already set up levels and transports, pass the instance into expressWinston with the `winstonInstance` option. The `transports` option is then ignored. +Alternatively, if you're using a winston logger instance elsewhere and have already set up levels and transports, the `winstonInstance` option can be used. It has 2 forms: ++ an actual `winston` logger instance. In the case, the logger is used as is. ++ a factory function that takes parameters `req` and `res` of the middleware. The function is expected to return a `winston` logger instance. + +When using any version of `winstonInstance`, the `transports` option is then ignored. ## Examples diff --git a/index.js b/index.js index 9df1e84..d52834f 100644 --- a/index.js +++ b/index.js @@ -116,16 +116,15 @@ exports.errorLogger = function errorLogger(options) { options.requestWhitelist = options.requestWhitelist || exports.requestWhitelist; options.requestFilter = options.requestFilter || exports.defaultRequestFilter; - options.winstonInstance = options.winstonInstance || (winston.createLogger({ - transports: options.transports, - format: options.format - })); + const getLogger = loggerFactory(options); options.msg = options.msg || 'middlewareError'; options.baseMeta = options.baseMeta || {}; options.metaField = options.metaField || null; options.level = options.level || 'error'; options.dynamicMeta = options.dynamicMeta || function(req, res, err) { return null; }; - const exceptionHandler = new winston.ExceptionHandler(options.winstonInstance); + // TODO: improve the default exception meta information by not calling a + // constructor than a function that does nothing with the constructor parameter. + const exceptionHandler = new winston.ExceptionHandler({}); options.exceptionToMeta = options.exceptionToMeta || exceptionHandler.getAllInfo.bind(exceptionHandler); options.blacklistedMetaFields = options.blacklistedMetaFields || []; @@ -158,7 +157,7 @@ exports.errorLogger = function errorLogger(options) { options.msg = typeof options.msg === 'function' ? options.msg(req, res) : options.msg; // This is fire and forget, we don't want logging to hold up the request so don't wait for the callback - options.winstonInstance.log({ + getLogger(req, res).log({ level, message: getTemplate(options.msg, {err: err, req: req, res: res}), meta: exceptionMeta @@ -178,12 +177,35 @@ function levelFromStatus(options) { } } +/** + * returns a factory function to get a logger instance. + * The output function expect a request and result as parameters + * @param options - the library options + * @return func + */ +function loggerFactory(options) { + + if(options.winstonInstance) { + + if(_.isFunction(options.winstonInstance)) + return options.winstonInstance; + + const originalInstance = options.winstonInstance; + return function() { return originalInstance; }; + } + + const localLogger = winston.createLogger({ + transports: options.transports, + format: options.format + }); + return function() { return localLogger;}; +} + // // ### function logger(options) // #### @options {Object} options to initialize the middleware. // exports.logger = function logger(options) { - ensureValidOptions(options); ensureValidLoggerOptions(options); @@ -194,10 +216,8 @@ exports.logger = function logger(options) { options.requestFilter = options.requestFilter || exports.defaultRequestFilter; options.responseFilter = options.responseFilter || exports.defaultResponseFilter; options.ignoredRoutes = options.ignoredRoutes || exports.ignoredRoutes; - options.winstonInstance = options.winstonInstance || (winston.createLogger({ - transports: options.transports, - format: options.format - })); + + const getLogger = loggerFactory(options); options.statusLevels = options.statusLevels || false; options.level = options.statusLevels ? levelFromStatus(options) : (options.level || "info"); options.msg = options.msg || "HTTP {{req.method}} {{req.url}}"; @@ -346,7 +366,7 @@ exports.logger = function logger(options) { // This is fire and forget, we don't want logging to hold up the request so don't wait for the callback if (!options.skip(req, res)) { var level = _.isFunction(options.level) ? options.level(req, res) : options.level; - options.winstonInstance.log({level, message: msg, meta}); + getLogger(req, res).log({level, message: msg, meta}); } }; @@ -372,9 +392,11 @@ function bodyToString(body, isJSON) { function ensureValidOptions(options) { if(!options) throw new Error("options are required by express-winston middleware"); + if(!((options.transports && (options.transports.length > 0)) || options.winstonInstance)) throw new Error("transports or a winstonInstance are required by express-winston middleware"); + if (options.dynamicMeta && !_.isFunction(options.dynamicMeta)) { throw new Error("`dynamicMeta` express-winston option should be a function"); } diff --git a/test/test.js b/test/test.js index 8cbc3ec..7dd8dac 100644 --- a/test/test.js +++ b/test/test.js @@ -1,16 +1,15 @@ -var util = require('util'); +var util = require("util"); -var mocks = require('node-mocks-http'); -var should = require('should'); -var _ = require('lodash'); -var winston = require('winston'); -var Transport = require('winston-transport'); +var mocks = require("node-mocks-http"); +var should = require("should"); +var _ = require("lodash"); +var Transport = require("winston-transport"); -var expressWinston = require('../index.js'); +var expressWinston = require("../index.js"); -expressWinston.ignoredRoutes.push('/ignored'); -expressWinston.responseWhitelist.push('body'); -expressWinston.bodyBlacklist.push('potato'); +expressWinston.ignoredRoutes.push("/ignored"); +expressWinston.responseWhitelist.push("body"); +expressWinston.bodyBlacklist.push("potato"); class MockTransport extends Transport { constructor(test, options) { @@ -25,25 +24,38 @@ class MockTransport extends Transport { this._test.log.level = info.level; this._test.log.msg = info.message; this._test.log.meta = info.meta; - this.emit('logged'); + this.emit("logged"); return cb(); } } +class MockWinston { + constructor(test) { + this.invoked = false; + } + + log(options) { + this.invoked = true; + } +} + function mockReq(reqMock) { - var reqSpec = _.extend({ - method: 'GET', - url: '/hello', - headers: { - 'header-1': 'value 1' - }, - query: { - val: '1' - }, - params: { - id: 20 + var reqSpec = _.extend( + { + method: "GET", + url: "/hello", + headers: { + "header-1": "value 1" + }, + query: { + val: "1" + }, + params: { + id: 20 + } }, - }, reqMock); + reqMock + ); return mocks.createRequest(reqSpec); } @@ -55,15 +67,18 @@ function mockRes() { } function loggerTestHelper(providedOptions) { - var options = _.extend({ - loggerOptions: null, - req: null, - res: null, - transportOptions: null, - next: function (req, res, next) { - res.end('{ "message": "Hi! I\'m a chunk!" }'); - } - }, providedOptions); + var options = _.extend( + { + loggerOptions: null, + req: null, + res: null, + transportOptions: null, + next: function(req, res, next) { + res.end('{ "message": "Hi! I\'m a chunk!" }'); + } + }, + providedOptions + ); var req = mockReq(options.req); var res = _.extend(mockRes(), options.res); @@ -74,12 +89,17 @@ function loggerTestHelper(providedOptions) { log: {} }; - return new Promise(function (resolve, reject) { - var middleware = expressWinston.logger(_.extend({ - transports: [new MockTransport(result, options.transportOptions)] - }, options.loggerOptions)); + return new Promise(function(resolve, reject) { + var middleware = expressWinston.logger( + _.extend( + { + transports: [new MockTransport(result, options.transportOptions)] + }, + options.loggerOptions + ) + ); - middleware(req, res, function (_req, _res, next) { + middleware(req, res, function(_req, _res, next) { options.next(req, res, next); resolve(result); }); @@ -87,14 +107,17 @@ function loggerTestHelper(providedOptions) { } function errorLoggerTestHelper(providedOptions) { - var options = _.extend({ - loggerOptions: null, - originalError: new Error('This is the Error'), - req: null, - res: null, - transportOptions: null, - next: function () {} - }, providedOptions); + var options = _.extend( + { + loggerOptions: null, + originalError: new Error("This is the Error"), + req: null, + res: null, + transportOptions: null, + next: function() {} + }, + providedOptions + ); var req = mockReq(options.req); var res = _.extend(mockRes(), options.res); @@ -107,12 +130,17 @@ function errorLoggerTestHelper(providedOptions) { pipelineError: null }; - return new Promise(function (resolve, reject) { - var middleware = expressWinston.errorLogger(_.extend({ - transports: [new MockTransport(result, options.transportOptions)] - }, options.loggerOptions)); + return new Promise(function(resolve, reject) { + var middleware = expressWinston.errorLogger( + _.extend( + { + transports: [new MockTransport(result, options.transportOptions)] + }, + options.loggerOptions + ) + ); - middleware(options.originalError, req, res, function (pipelineError) { + middleware(options.originalError, req, res, function(pipelineError) { options.next(pipelineError); result.pipelineError = pipelineError; resolve(result); @@ -120,31 +148,30 @@ function errorLoggerTestHelper(providedOptions) { }); } -describe('express-winston', function () { - - describe('.errorLogger()', function () { - it('should be a function', function () { +describe("express-winston", function() { + describe(".errorLogger()", function() { + it("should be a function", function() { expressWinston.errorLogger.should.be.a.Function(); }); - it('should throw an error when no options are provided', function () { + it("should throw an error when no options are provided", function() { var errorLoggerFn = expressWinston.errorLogger.bind(expressWinston); errorLoggerFn.should.throw(); }); - it('should throw an error when no transport is specified', function () { + it("should throw an error when no transport is specified", function() { var errorLoggerFn = expressWinston.errorLogger.bind(expressWinston, {}); errorLoggerFn.should.throw(); }); - it('should throw an error when provided with an empty list of transports', function () { + it("should throw an error when provided with an empty list of transports", function() { var errorLoggerFn = expressWinston.errorLogger.bind(expressWinston, { transports: [] }); errorLoggerFn.should.throw(); }); - it('should return a middleware function with four arguments that fit (err, req, res, next)', function () { + it("should return a middleware function with four arguments that fit (err, req, res, next)", function() { var middleware = expressWinston.errorLogger({ transports: [new MockTransport({})] }); @@ -152,165 +179,250 @@ describe('express-winston', function () { middleware.length.should.eql(4); }); - it('should use the exported requestWhitelist', function() { + it("should use the exported requestWhitelist", function() { var originalWhitelist = expressWinston.requestWhitelist; - expressWinston.requestWhitelist = ['foo']; + expressWinston.requestWhitelist = ["foo"]; var options = { - req: {foo: "bar"} + req: { foo: "bar" } }; - return errorLoggerTestHelper(options).then(function (result) { + return errorLoggerTestHelper(options).then(function(result) { // Return to the original value for later tests expressWinston.requestWhitelist = originalWhitelist; - result.log.meta.req.should.have.property('foo'); - result.log.meta.req.should.not.have.property('url'); + result.log.meta.req.should.have.property("foo"); + result.log.meta.req.should.not.have.property("url"); }); }); - it('should use the exported defaultRequestFilter', function() { + it("should use the exported defaultRequestFilter", function() { var originalRequestFilter = expressWinston.defaultRequestFilter; expressWinston.defaultRequestFilter = function() { - return 'foo'; + return "foo"; }; var options = { - req: {foo: "bar"} + req: { foo: "bar" } }; - return errorLoggerTestHelper(options).then(function (result) { + return errorLoggerTestHelper(options).then(function(result) { // Return to the original value for later tests expressWinston.defaultRequestFilter = originalRequestFilter; - result.log.meta.req.url.should.equal('foo'); + result.log.meta.req.url.should.equal("foo"); }); }); - describe('when middleware function encounters an error in the pipeline', function () { - it('should invoke the transport', function () { - return errorLoggerTestHelper().then(function (result) { + describe("when providing logger instance", function() { + + it("should use the winstonInstance", function() { + + const winstonMock = new MockWinston(); + const localOptions = { + loggerOptions: { + winstonInstance: winstonMock, + transports: null + } + }; + + return errorLoggerTestHelper(localOptions).then(function(result) { + winstonMock.invoked.should.eql(true); + }); + }); + it("should use the winstonInstance in favor of transport specification", function() { + + const winstonMock = new MockWinston(); + const localOptions = { + loggerOptions: { + winstonInstance: winstonMock, + transports: [new MockTransport({})] + } + }; + + + return errorLoggerTestHelper(localOptions).then(function(result) { + winstonMock.invoked.should.eql(true); + }); + }); + + it('should invoke the winstonInstance factory if provided', function() { + const mockWinston = new MockWinston(); + + const loggerFactory = function() { + return mockWinston; + } + const localOptions = { + loggerOptions: { + winstonInstance: loggerFactory, + transports: null, + } + }; + return errorLoggerTestHelper(localOptions).then(function(result) { + mockWinston.invoked.should.eql(true); + }); + }); + + it('should have the req and res as parameters when invoking the winstonInstance factory', function() { + + const mockWinston = new MockWinston(); + let factoryReq; + let factoryRes; + const loggerFactory = function(req, res) { + factoryReq = req; + factoryRes = res; + return mockWinston; + } + const localOptions = { + loggerOptions: { + winstonInstance: loggerFactory, + transports: null, + } + }; + + return errorLoggerTestHelper(localOptions).then(function(result) { + mockWinston.invoked.should.eql(true); + factoryReq.should.be.deepEqual(result.req); + factoryRes.should.be.deepEqual(result.res); + }); + }); + + }); + + describe("when middleware function encounters an error in the pipeline", function() { + it("should invoke the transport", function() { + return errorLoggerTestHelper().then(function(result) { result.transportInvoked.should.eql(true); }); }); - it('should find the default level of "error"', function () { - return errorLoggerTestHelper().then(function (result) { - result.log.level.should.eql('error'); + it('should find the default level of "error"', function() { + return errorLoggerTestHelper().then(function(result) { + result.log.level.should.eql("error"); }); }); - it('should find a custom level of "warn"', function () { - var testHelperOptions = {loggerOptions: {level:'warn'}}; - return errorLoggerTestHelper(testHelperOptions).then(function (result) { - result.log.level.should.eql('warn'); + it('should find a custom level of "warn"', function() { + var testHelperOptions = { loggerOptions: { level: "warn" } }; + return errorLoggerTestHelper(testHelperOptions).then(function(result) { + result.log.level.should.eql("warn"); }); }); - it('should find a message of "middlewareError"', function () { - return errorLoggerTestHelper().then(function (result) { - result.log.msg.should.eql('middlewareError'); + it('should find a message of "middlewareError"', function() { + return errorLoggerTestHelper().then(function(result) { + result.log.msg.should.eql("middlewareError"); }); }); - it('should contain a filtered request', function () { - return errorLoggerTestHelper().then(function (result) { + it("should contain a filtered request", function() { + return errorLoggerTestHelper().then(function(result) { result.log.meta.req.should.be.ok(); - result.log.meta.req.method.should.eql('GET'); + result.log.meta.req.method.should.eql("GET"); result.log.meta.req.query.should.eql({ - val: '1' + val: "1" }); - result.log.meta.req.should.not.have.property('nonWhitelistedProperty'); + result.log.meta.req.should.not.have.property( + "nonWhitelistedProperty" + ); }); }); - it('should not swallow the pipeline error', function () { - return errorLoggerTestHelper().then(function (result) { + it("should not swallow the pipeline error", function() { + return errorLoggerTestHelper().then(function(result) { result.pipelineError.should.be.ok(); result.pipelineError.should.eql(result.originalError); }); }); }); - describe('exceptionToMeta option', function () { - it('should, use exceptionToMeta function when given', function () { + describe("exceptionToMeta option", function() { + it("should, use exceptionToMeta function when given", function() { function exceptionToMeta(error) { return { - stack: error.stack && error.stack.split('\n') + stack: error.stack && error.stack.split("\n") }; } - var testHelperOptions = { loggerOptions: { exceptionToMeta: exceptionToMeta } }; - return errorLoggerTestHelper(testHelperOptions).then(function (result) { + var testHelperOptions = { + loggerOptions: { exceptionToMeta: exceptionToMeta } + }; + return errorLoggerTestHelper(testHelperOptions).then(function(result) { result.log.meta.stack.should.be.ok(); - result.log.meta.should.not.have.property('trace'); + result.log.meta.should.not.have.property("trace"); }); }); - it('should, use getAllInfo function when not given', function () { - var testHelperOptions = { loggerOptions: { } }; - return errorLoggerTestHelper(testHelperOptions).then(function (result) { - result.log.meta.should.have.property('date'); - result.log.meta.should.have.property('process'); - result.log.meta.should.have.property('os'); - result.log.meta.should.have.property('trace'); - result.log.meta.should.have.property('stack'); + it("should, use getAllInfo function when not given", function() { + var testHelperOptions = { loggerOptions: {} }; + return errorLoggerTestHelper(testHelperOptions).then(function(result) { + result.log.meta.should.have.property("date"); + result.log.meta.should.have.property("process"); + result.log.meta.should.have.property("os"); + result.log.meta.should.have.property("trace"); + result.log.meta.should.have.property("stack"); }); }); }); - describe('blacklistedMetaFields option', function () { - it('should, remove given fields from the meta result', function () { - var testHelperOptionsWithBlacklist = { loggerOptions: { blacklistedMetaFields: ['trace'] } }; - return errorLoggerTestHelper(testHelperOptionsWithBlacklist).then(function (result) { - result.log.meta.should.not.have.property('trace'); - }); + describe("blacklistedMetaFields option", function() { + it("should, remove given fields from the meta result", function() { + var testHelperOptionsWithBlacklist = { + loggerOptions: { blacklistedMetaFields: ["trace"] } + }; + return errorLoggerTestHelper(testHelperOptionsWithBlacklist).then( + function(result) { + result.log.meta.should.not.have.property("trace"); + } + ); var testHelperOptionsWithoutBlacklist = { loggerOptions: {} }; - return errorLoggerTestHelper(testHelperOptionsWithoutBlacklist).then(function (result) { - result.log.meta.should.have.property('trace'); - }); + return errorLoggerTestHelper(testHelperOptionsWithoutBlacklist).then( + function(result) { + result.log.meta.should.have.property("trace"); + } + ); }); }); - describe('metaField option', function () { - it('should, when using a custom metaField, log the custom metaField', function () { - var testHelperOptions = {loggerOptions: {metaField: 'metaField'}}; - return errorLoggerTestHelper(testHelperOptions).then(function (result) { + describe("metaField option", function() { + it("should, when using a custom metaField, log the custom metaField", function() { + var testHelperOptions = { loggerOptions: { metaField: "metaField" } }; + return errorLoggerTestHelper(testHelperOptions).then(function(result) { result.log.meta.metaField.req.should.be.ok(); }); }); }); - describe('requestWhitelist option', function () { - it('should default to global requestWhitelist', function () { + describe("requestWhitelist option", function() { + it("should default to global requestWhitelist", function() { var options = { - req: {foo: "bar"} + req: { foo: "bar" } }; - return errorLoggerTestHelper(options).then(function (result) { - result.log.meta.req.should.not.have.property('foo'); + return errorLoggerTestHelper(options).then(function(result) { + result.log.meta.req.should.not.have.property("foo"); }); }); - it('should use specified requestWhitelist', function () { + it("should use specified requestWhitelist", function() { var options = { - req: {foo: "bar"}, + req: { foo: "bar" }, loggerOptions: { - requestWhitelist: ['foo'] + requestWhitelist: ["foo"] } }; - return errorLoggerTestHelper(options).then(function (result) { - result.log.meta.req.should.have.property('foo'); - result.log.meta.req.should.not.have.property('method'); + return errorLoggerTestHelper(options).then(function(result) { + result.log.meta.req.should.have.property("foo"); + result.log.meta.req.should.not.have.property("method"); }); }); }); - describe('dynamicMeta option', function () { + describe("dynamicMeta option", function() { var testHelperOptions = { req: { body: { age: 42, - potato: 'Russet' + potato: "Russet" }, user: { username: "john@doe.com", @@ -318,9 +430,9 @@ describe('express-winston', function () { } }, res: { - custom: 'custom response runtime field' + custom: "custom response runtime field" }, - originalError: new Error('FOO'), + originalError: new Error("FOO"), loggerOptions: { meta: true, dynamicMeta: function(req, res, err) { @@ -329,35 +441,37 @@ describe('express-winston', function () { role: req.user.role, custom: res.custom, errMessage: err.message - } + }; } } }; - it('should contain dynamic meta data if meta and dynamicMeta activated', function () { - return errorLoggerTestHelper(testHelperOptions).then(function (result) { + it("should contain dynamic meta data if meta and dynamicMeta activated", function() { + return errorLoggerTestHelper(testHelperOptions).then(function(result) { result.log.meta.req.should.be.ok(); - result.log.meta.user.should.equal('john@doe.com'); - result.log.meta.role.should.equal('operator'); - result.log.meta.custom.should.equal('custom response runtime field'); - result.log.meta.errMessage.should.equal('FOO'); + result.log.meta.user.should.equal("john@doe.com"); + result.log.meta.role.should.equal("operator"); + result.log.meta.custom.should.equal("custom response runtime field"); + result.log.meta.errMessage.should.equal("FOO"); }); }); - it('should work with metaField option', function () { - testHelperOptions.loggerOptions.metaField = 'metaField'; - return errorLoggerTestHelper(testHelperOptions).then(function (result) { + it("should work with metaField option", function() { + testHelperOptions.loggerOptions.metaField = "metaField"; + return errorLoggerTestHelper(testHelperOptions).then(function(result) { result.log.meta.metaField.req.should.be.ok(); - result.log.meta.metaField.user.should.equal('john@doe.com'); - result.log.meta.metaField.role.should.equal('operator'); - result.log.meta.metaField.custom.should.equal('custom response runtime field'); - result.log.meta.metaField.errMessage.should.equal('FOO'); + result.log.meta.metaField.user.should.equal("john@doe.com"); + result.log.meta.metaField.role.should.equal("operator"); + result.log.meta.metaField.custom.should.equal( + "custom response runtime field" + ); + result.log.meta.metaField.errMessage.should.equal("FOO"); }); }); - it('should not contain dynamic meta data if dynamicMeta activated but meta false', function () { + it("should not contain dynamic meta data if dynamicMeta activated but meta false", function() { testHelperOptions.loggerOptions.meta = false; - return errorLoggerTestHelper(testHelperOptions).then(function (result) { + return errorLoggerTestHelper(testHelperOptions).then(function(result) { should.not.exist(result.log.meta.req); should.not.exist(result.log.meta.user); should.not.exist(result.log.meta.role); @@ -366,36 +480,38 @@ describe('express-winston', function () { }); }); - it('should throw an error if dynamicMeta is not a function', function () { - var loggerFn = expressWinston.errorLogger.bind(expressWinston, {dynamicMeta: 12}); + it("should throw an error if dynamicMeta is not a function", function() { + var loggerFn = expressWinston.errorLogger.bind(expressWinston, { + dynamicMeta: 12 + }); loggerFn.should.throw(); }); }); }); - describe('.logger()', function () { - it('should be a function', function () { + describe(".logger()", function() { + it("should be a function", function() { expressWinston.logger.should.be.a.Function(); }); - it('should throw an error when no options are provided', function () { + it("should throw an error when no options are provided", function() { var loggerFn = expressWinston.logger.bind(expressWinston); loggerFn.should.throw(); }); - it('should throw an error when no transport is specified', function () { + it("should throw an error when no transport is specified", function() { var loggerFn = expressWinston.logger.bind(expressWinston, {}); loggerFn.should.throw(); }); - it('should throw an error when provided with an empty list of transports', function () { + it("should throw an error when provided with an empty list of transports", function() { var loggerFn = expressWinston.logger.bind(expressWinston, { transports: [] }); loggerFn.should.throw(); }); - it('should return a middleware function with three arguments that fit (req, res, next)', function () { + it("should return a middleware function with three arguments that fit (req, res, next)", function() { var middleware = expressWinston.logger({ transports: [new MockTransport({})] }); @@ -403,7 +519,7 @@ describe('express-winston', function () { middleware.length.should.eql(3); }); - it('should not have an empty body in meta.req when invoked on a route with an empty response body', function () { + it("should not have an empty body in meta.req when invoked on a route with an empty response body", function() { function next(req, res, next) { res.end(); } @@ -411,16 +527,18 @@ describe('express-winston', function () { next: next, req: { body: {}, - routeLevelAddedProperty: 'value that should be logged', - url: '/hello' - }, + routeLevelAddedProperty: "value that should be logged", + url: "/hello" + } }; - return loggerTestHelper(testHelperOptions).then(function (result) { - Object.keys(result.log.meta.req).indexOf('body').should.eql(-1); + return loggerTestHelper(testHelperOptions).then(function(result) { + Object.keys(result.log.meta.req) + .indexOf("body") + .should.eql(-1); }); }); - it('should log entire body when request whitelist contains body and there is no body whitelist or blacklist', function () { + it("should log entire body when request whitelist contains body and there is no body whitelist or blacklist", function() { function next(req, res, next) { res.end(); } @@ -428,30 +546,30 @@ describe('express-winston', function () { next: next, req: { body: { - foo: 'bar', - baz: 'qux' + foo: "bar", + baz: "qux" }, - routeLevelAddedProperty: 'value that should be logged', - url: '/hello' + routeLevelAddedProperty: "value that should be logged", + url: "/hello" }, loggerOptions: { bodyBlacklist: [], bodyWhitelist: [], - requestWhitelist: expressWinston.requestWhitelist.concat('body') + requestWhitelist: expressWinston.requestWhitelist.concat("body") } }; - return loggerTestHelper(testHelperOptions).then(function (result) { + return loggerTestHelper(testHelperOptions).then(function(result) { result.log.meta.req.body.should.eql({ - foo: 'bar', - baz: 'qux' + foo: "bar", + baz: "qux" }); }); }); - it('should not invoke the transport when invoked on a route with transport level of "error"', function () { + it('should not invoke the transport when invoked on a route with transport level of "error"', function() { function next(req, res, next) { - req._routeWhitelists.req = ['routeLevelAddedProperty']; - req._routeWhitelists.res = ['routeLevelAddedProperty']; + req._routeWhitelists.req = ["routeLevelAddedProperty"]; + req._routeWhitelists.res = ["routeLevelAddedProperty"]; res.end('{ "message": "Hi! I\'m a chunk!" }'); } @@ -462,130 +580,130 @@ describe('express-winston', function () { }, req: { body: {}, - routeLevelAddedProperty: 'value that should be logged', - url: '/hello', + routeLevelAddedProperty: "value that should be logged", + url: "/hello" }, res: { - nonWhitelistedProperty: 'value that should not be logged', - routeLevelAddedProperty: 'value that should be logged' + nonWhitelistedProperty: "value that should not be logged", + routeLevelAddedProperty: "value that should be logged" }, transportOptions: { - level: 'error' + level: "error" } }; - return loggerTestHelper(testHelperOptions).then(function (result) { + return loggerTestHelper(testHelperOptions).then(function(result) { result.transportInvoked.should.eql(false); }); }); - it('should use the exported requestWhitelist', function() { + it("should use the exported requestWhitelist", function() { var originalWhitelist = expressWinston.requestWhitelist; - expressWinston.requestWhitelist = ['foo']; + expressWinston.requestWhitelist = ["foo"]; var options = { - req: {foo: "bar"} + req: { foo: "bar" } }; - return loggerTestHelper(options).then(function (result) { + return loggerTestHelper(options).then(function(result) { // Return to the original value for later tests expressWinston.requestWhitelist = originalWhitelist; - result.log.meta.req.should.have.property('foo'); - result.log.meta.req.should.not.have.property('url'); + result.log.meta.req.should.have.property("foo"); + result.log.meta.req.should.not.have.property("url"); }); }); - it('should use the exported bodyWhitelist', function() { + it("should use the exported bodyWhitelist", function() { var originalWhitelist = expressWinston.bodyWhitelist; - expressWinston.bodyWhitelist = ['foo']; + expressWinston.bodyWhitelist = ["foo"]; var options = { - req: {body: {foo: 'bar', baz: 'qux'}} + req: { body: { foo: "bar", baz: "qux" } } }; - return loggerTestHelper(options).then(function (result) { + return loggerTestHelper(options).then(function(result) { // Return to the original value for later tests expressWinston.bodyWhitelist = originalWhitelist; - result.log.meta.req.body.should.have.property('foo'); - result.log.meta.req.body.should.not.have.property('baz'); + result.log.meta.req.body.should.have.property("foo"); + result.log.meta.req.body.should.not.have.property("baz"); }); }); - it('should use the exported bodyBlacklist', function() { + it("should use the exported bodyBlacklist", function() { var originalBlacklist = expressWinston.bodyBlacklist; - expressWinston.bodyBlacklist = ['foo']; + expressWinston.bodyBlacklist = ["foo"]; var options = { - req: {body: {foo: 'bar', baz: 'qux'}} + req: { body: { foo: "bar", baz: "qux" } } }; - return loggerTestHelper(options).then(function (result) { + return loggerTestHelper(options).then(function(result) { // Return to the original value for later tests expressWinston.bodyBlacklist = originalBlacklist; - result.log.meta.req.body.should.not.have.property('foo'); - result.log.meta.req.body.should.have.property('baz'); + result.log.meta.req.body.should.not.have.property("foo"); + result.log.meta.req.body.should.have.property("baz"); }); }); - it('should use the exported responseWhitelist', function() { + it("should use the exported responseWhitelist", function() { var originalWhitelist = expressWinston.responseWhitelist; - expressWinston.responseWhitelist = ['foo']; + expressWinston.responseWhitelist = ["foo"]; var options = { - res: {foo: 'bar', baz: 'qux'} + res: { foo: "bar", baz: "qux" } }; - return loggerTestHelper(options).then(function (result) { + return loggerTestHelper(options).then(function(result) { // Return to the original value for later tests expressWinston.responseWhitelist = originalWhitelist; - result.log.meta.res.should.have.property('foo'); - result.log.meta.res.should.not.have.property('baz'); + result.log.meta.res.should.have.property("foo"); + result.log.meta.res.should.not.have.property("baz"); }); }); - it('should use the exported defaultRequestFilter', function() { + it("should use the exported defaultRequestFilter", function() { var originalRequestFilter = expressWinston.defaultRequestFilter; expressWinston.defaultRequestFilter = function() { - return 'foo'; + return "foo"; }; var options = { - req: {foo: "bar"} + req: { foo: "bar" } }; - return loggerTestHelper(options).then(function (result) { + return loggerTestHelper(options).then(function(result) { // Return to the original value for later tests expressWinston.defaultRequestFilter = originalRequestFilter; - result.log.meta.req.url.should.equal('foo'); + result.log.meta.req.url.should.equal("foo"); }); }); - it('should use the exported defaultResponseFilter', function() { + it("should use the exported defaultResponseFilter", function() { var originalResponseFilter = expressWinston.defaultResponseFilter; expressWinston.defaultResponseFilter = function() { - return 'foo'; + return "foo"; }; var options = { - req: {foo: "bar"} + req: { foo: "bar" } }; - return loggerTestHelper(options).then(function (result) { + return loggerTestHelper(options).then(function(result) { // Return to the original value for later tests expressWinston.defaultResponseFilter = originalResponseFilter; - result.log.meta.res.statusCode.should.equal('foo'); + result.log.meta.res.statusCode.should.equal("foo"); }); }); - it('should use the exported defaultSkip', function() { + it("should use the exported defaultSkip", function() { var originalSkip = expressWinston.defaultSkip; expressWinston.defaultSkip = function() { return true; }; var options = { - req: {foo: "bar"} + req: { foo: "bar" } }; - return loggerTestHelper(options).then(function (result) { + return loggerTestHelper(options).then(function(result) { // Return to the original value for later tests expressWinston.defaultSkip = originalSkip; @@ -593,14 +711,14 @@ describe('express-winston', function () { }); }); - it('should use the exported ignoredRoutes', function() { + it("should use the exported ignoredRoutes", function() { var originalIgnoredRoutes = expressWinston.ignoredRoutes; - expressWinston.ignoredRoutes = ['/foo-route']; + expressWinston.ignoredRoutes = ["/foo-route"]; var options = { - req: {url: '/foo-route'} + req: { url: "/foo-route" } }; - return loggerTestHelper(options).then(function (result) { + return loggerTestHelper(options).then(function(result) { // Return to the original value for later tests expressWinston.ignoredRoutes = originalIgnoredRoutes; @@ -608,15 +726,91 @@ describe('express-winston', function () { }); }); - describe('when middleware function is invoked on a route', function () { + describe("when providing logger instance", function() { + + it("should use the winstonInstance", function() { + + const winstonMock = new MockWinston(); + const localOptions = { + loggerOptions: { + winstonInstance: winstonMock, + transports: null + } + }; + + return loggerTestHelper(localOptions).then(function(result) { + winstonMock.invoked.should.eql(true); + }); + }); + it("should use the winstonInstance in favor of transport specification", function() { + + const winstonMock = new MockWinston(); + const localOptions = { + loggerOptions: { + winstonInstance: winstonMock, + transports: [new MockTransport({})] + } + }; + + + return loggerTestHelper(localOptions).then(function(result) { + winstonMock.invoked.should.eql(true); + }); + }); + + it('should invoke the winstonInstance factory if provided', function() { + const mockWinston = new MockWinston(); + + const loggerFactory = function() { + return mockWinston; + } + const localOptions = { + loggerOptions: { + winstonInstance: loggerFactory, + transports: null, + } + }; + return loggerTestHelper(localOptions).then(function(result) { + mockWinston.invoked.should.eql(true); + }); + }); + + it('should have the req and res as parameters when invoking the winstonInstance factory', function() { + + const mockWinston = new MockWinston(); + let factoryReq; + let factoryRes; + const loggerFactory = function(req, res) { + factoryReq = req; + factoryRes = res; + return mockWinston; + } + const localOptions = { + loggerOptions: { + winstonInstance: loggerFactory, + transports: null, + } + }; + + return loggerTestHelper(localOptions).then(function(result) { + mockWinston.invoked.should.eql(true); + factoryReq.should.be.deepEqual(result.req); + factoryRes.should.be.deepEqual(result.res); + }); + }); + + }); + + + describe("when middleware function is invoked on a route", function() { function next(req, res, next) { - req._startTime = (new Date()) - 125; + req._startTime = new Date() - 125; - req._routeWhitelists.req = ['routeLevelAddedProperty']; - req._routeWhitelists.res = ['routeLevelAddedProperty']; + req._routeWhitelists.req = ["routeLevelAddedProperty"]; + req._routeWhitelists.res = ["routeLevelAddedProperty"]; - req._routeWhitelists.body = ['username']; - req._routeBlacklists.body = ['age']; + req._routeWhitelists.body = ["username"]; + req._routeBlacklists.body = ["age"]; res.end('{ "message": "Hi! I\'m a chunk!" }'); } @@ -627,613 +821,623 @@ describe('express-winston', function () { username: "bobby", password: "top-secret", age: 42, - potato: 'Russet' + potato: "Russet" }, - routeLevelAddedProperty: 'value that should be logged' + routeLevelAddedProperty: "value that should be logged" }, res: { - nonWhitelistedProperty: 'value that should not be logged', - routeLevelAddedProperty: 'value that should be logged' - }, + nonWhitelistedProperty: "value that should not be logged", + routeLevelAddedProperty: "value that should be logged" + } }; - it('should invoke the transport', function () { - return loggerTestHelper(testHelperOptions).then(function (result) { + it("should invoke the transport", function() { + return loggerTestHelper(testHelperOptions).then(function(result) { result.transportInvoked.should.eql(true); }); }); - it('should contain a filtered request', function () { - return loggerTestHelper(testHelperOptions).then(function (result) { + it("should contain a filtered request", function() { + return loggerTestHelper(testHelperOptions).then(function(result) { result.log.meta.req.should.be.ok(); - result.log.meta.req.method.should.eql('GET'); + result.log.meta.req.method.should.eql("GET"); result.log.meta.req.query.should.eql({ - val: '1' + val: "1" }); - result.log.meta.req.body.should.not.have.property('age'); - result.log.meta.req.body.should.not.have.property('potato'); + result.log.meta.req.body.should.not.have.property("age"); + result.log.meta.req.body.should.not.have.property("potato"); }); }); - it('should contain a filtered response', function () { - return loggerTestHelper(testHelperOptions).then(function (result) { + it("should contain a filtered response", function() { + return loggerTestHelper(testHelperOptions).then(function(result) { result.log.meta.res.should.be.ok(); result.log.meta.res.statusCode.should.eql(200); result.log.meta.res.routeLevelAddedProperty.should.be.ok(); - result.log.meta.res.should.not.have.property('nonWhitelistedProperty'); + result.log.meta.res.should.not.have.property( + "nonWhitelistedProperty" + ); }); }); - it('should contain a response time', function () { - return loggerTestHelper(testHelperOptions).then(function (result) { + it("should contain a response time", function() { + return loggerTestHelper(testHelperOptions).then(function(result) { result.log.meta.responseTime.should.be.within(120, 130); }); }); }); - describe('when middleware function is invoked on a route that returns JSON', function() { - it('should parse JSON in response body', function() { - var bodyObject = { "message": "Hi! I\'m a chunk!" }; + describe("when middleware function is invoked on a route that returns JSON", function() { + it("should parse JSON in response body", function() { + var bodyObject = { message: "Hi! I'm a chunk!" }; function next(req, res, next) { // Set Content-Type in a couple different case types, just in case. // Seems like the mock response doesn't quite handle the case // translation on these right. - res.setHeader('Content-Type', 'application/json'); - res.setHeader('content-type', 'application/json'); + res.setHeader("Content-Type", "application/json"); + res.setHeader("content-type", "application/json"); res.end(JSON.stringify(bodyObject)); } - return loggerTestHelper({next: next}).then(function(result) { - result.log.meta.res.body.should.eql(bodyObject); + return loggerTestHelper({ next: next }).then(function(result) { + result.log.meta.res.body.should.eql(bodyObject); }); }); - it('should not blow up when response body is invalid JSON', function() { + it("should not blow up when response body is invalid JSON", function() { function next(req, res, next) { // Set Content-Type in a couple different case types, just in case. // Seems like the mock response doesn't quite handle the case // translation on these right. - res.setHeader('Content-Type', 'application/json'); - res.setHeader('content-type', 'application/json'); - res.end('}'); + res.setHeader("Content-Type", "application/json"); + res.setHeader("content-type", "application/json"); + res.end("}"); } - return loggerTestHelper({next: next}); + return loggerTestHelper({ next: next }); }); }); - describe('when middleware function is invoked on a route that should be ignored (by .ignoredRoutes)', function () { + describe("when middleware function is invoked on a route that should be ignored (by .ignoredRoutes)", function() { var testHelperOptions = { - req: {url: '/ignored'} + req: { url: "/ignored" } }; - it('should not invoke the transport', function () { - return loggerTestHelper(testHelperOptions).then(function (result) { + it("should not invoke the transport", function() { + return loggerTestHelper(testHelperOptions).then(function(result) { result.transportInvoked.should.eql(false); }); }); - it('should contain a filtered request', function () { - return loggerTestHelper(testHelperOptions).then(function (result) { + it("should contain a filtered request", function() { + return loggerTestHelper(testHelperOptions).then(function(result) { result.log.should.be.empty(); }); }); }); - describe('expressFormat option', function () { - it('should match the Express format when logging', function () { + describe("expressFormat option", function() { + it("should match the Express format when logging", function() { var testHelperOptions = { loggerOptions: { colorize: true, expressFormat: true }, req: { - url: '/all-the-things' + url: "/all-the-things" } }; - return loggerTestHelper(testHelperOptions).then(function (result) { + return loggerTestHelper(testHelperOptions).then(function(result) { var resultMsg = result.log.msg; - resultMsg.should.startWith('\u001b[90mGET /all-the-things\u001b[39m \u001b[32m200\u001b[39m \u001b[90m'); - resultMsg.should.endWith('ms\u001b[39m'); + resultMsg.should.startWith( + "\u001b[90mGET /all-the-things\u001b[39m \u001b[32m200\u001b[39m \u001b[90m" + ); + resultMsg.should.endWith("ms\u001b[39m"); }); }); - it('should not emit colors when colorize option is false', function() { + it("should not emit colors when colorize option is false", function() { var testHelperOptions = { loggerOptions: { colorize: false, expressFormat: true }, req: { - url: '/all-the-things' + url: "/all-the-things" } }; - return loggerTestHelper(testHelperOptions).then(function (result) { + return loggerTestHelper(testHelperOptions).then(function(result) { var resultMsg = result.log.msg; - resultMsg.should.startWith('GET /all-the-things 200 '); - resultMsg.should.endWith('ms'); + resultMsg.should.startWith("GET /all-the-things 200 "); + resultMsg.should.endWith("ms"); }); }); - it('should not emit colors when colorize option is not present', function() { + it("should not emit colors when colorize option is not present", function() { var testHelperOptions = { loggerOptions: { colorize: false, expressFormat: true }, req: { - url: '/all-the-things' + url: "/all-the-things" } }; - return loggerTestHelper(testHelperOptions).then(function (result) { + return loggerTestHelper(testHelperOptions).then(function(result) { var resultMsg = result.log.msg; - resultMsg.should.startWith('GET /all-the-things 200 '); - resultMsg.should.endWith('ms'); + resultMsg.should.startWith("GET /all-the-things 200 "); + resultMsg.should.endWith("ms"); }); }); }); - describe('colorize option', function () { - it('should make status code text green if < 300', function () { + describe("colorize option", function() { + it("should make status code text green if < 300", function() { var testHelperOptions = { loggerOptions: { colorize: true, - msg: '{{res.statusCode}} {{req.method}} {{req.url}}' + msg: "{{res.statusCode}} {{req.method}} {{req.url}}" }, req: { - url: '/all-the-things' + url: "/all-the-things" } }; - return loggerTestHelper(testHelperOptions).then(function (result) { + return loggerTestHelper(testHelperOptions).then(function(result) { var resultMsg = result.log.msg; - resultMsg.should.eql('\u001b[32m200\u001b[39m GET /all-the-things'); + resultMsg.should.eql("\u001b[32m200\u001b[39m GET /all-the-things"); }); }); - it('should make status code text cyan if >= 300 and < 400', function () { + it("should make status code text cyan if >= 300 and < 400", function() { var testHelperOptions = { loggerOptions: { colorize: true, - msg: '{{res.statusCode}} {{req.method}} {{req.url}}' + msg: "{{res.statusCode}} {{req.method}} {{req.url}}" }, req: { - url: '/all-the-things' + url: "/all-the-things" }, res: { statusCode: 302 } }; - return loggerTestHelper(testHelperOptions).then(function (result) { + return loggerTestHelper(testHelperOptions).then(function(result) { var resultMsg = result.log.msg; - resultMsg.should.eql('\u001b[36m302\u001b[39m GET /all-the-things'); + resultMsg.should.eql("\u001b[36m302\u001b[39m GET /all-the-things"); }); }); - it('should make status code text yellow if >= 400 and < 500', function () { + it("should make status code text yellow if >= 400 and < 500", function() { var testHelperOptions = { loggerOptions: { colorize: true, - msg: '{{res.statusCode}} {{req.method}} {{req.url}}' + msg: "{{res.statusCode}} {{req.method}} {{req.url}}" }, req: { - url: '/all-the-things' + url: "/all-the-things" }, res: { statusCode: 420 } }; - return loggerTestHelper(testHelperOptions).then(function (result) { + return loggerTestHelper(testHelperOptions).then(function(result) { var resultMsg = result.log.msg; - resultMsg.should.eql('\u001b[33m420\u001b[39m GET /all-the-things'); + resultMsg.should.eql("\u001b[33m420\u001b[39m GET /all-the-things"); }); }); - it('should make status code text red if >= 500', function () { + it("should make status code text red if >= 500", function() { var testHelperOptions = { loggerOptions: { colorize: true, - msg: '{{res.statusCode}} {{req.method}} {{req.url}}' + msg: "{{res.statusCode}} {{req.method}} {{req.url}}" }, req: { - url: '/all-the-things' + url: "/all-the-things" }, res: { statusCode: 500 } }; - return loggerTestHelper(testHelperOptions).then(function (result) { + return loggerTestHelper(testHelperOptions).then(function(result) { var resultMsg = result.log.msg; - resultMsg.should.eql('\u001b[31m500\u001b[39m GET /all-the-things'); + resultMsg.should.eql("\u001b[31m500\u001b[39m GET /all-the-things"); }); }); }); - describe('msg option', function () { - it('should have a default log msg', function () { + describe("msg option", function() { + it("should have a default log msg", function() { var testHelperOptions = { req: { - url: '/url-of-sandwich' + url: "/url-of-sandwich" } }; - return loggerTestHelper(testHelperOptions).then(function (result) { - result.log.msg.should.eql('HTTP GET /url-of-sandwich'); + return loggerTestHelper(testHelperOptions).then(function(result) { + result.log.msg.should.eql("HTTP GET /url-of-sandwich"); }); }); - it('should match the custom format when a custom format is provided', function () { + it("should match the custom format when a custom format is provided", function() { var testHelperOptions = { loggerOptions: { - msg: 'Foo {{ req.method }} {{ req.url }}' + msg: "Foo {{ req.method }} {{ req.url }}" }, req: { - url: '/all-the-things' + url: "/all-the-things" } }; - return loggerTestHelper(testHelperOptions).then(function (result) { - result.log.msg.should.eql('Foo GET /all-the-things'); + return loggerTestHelper(testHelperOptions).then(function(result) { + result.log.msg.should.eql("Foo GET /all-the-things"); }); }); }); - describe('ignoreRoute option', function () { + describe("ignoreRoute option", function() { var testHelperOptions = { req: { shouldSkip: true, - url: '/is-not-logged' + url: "/is-not-logged" }, loggerOptions: { - ignoreRoute: function (req, res) { + ignoreRoute: function(req, res) { return req.shouldSkip === true && req.url.match(/^\/is-not-log/); } } }; - it('should throw an error if ignoreRoute option is provided but not a function', function () { + it("should throw an error if ignoreRoute option is provided but not a function", function() { var loggerFn = expressWinston.logger.bind(expressWinston, { transports: [new MockTransport({})], - ignoreRoute: 'not a function' + ignoreRoute: "not a function" }); loggerFn.should.throw(); }); - it('should not invoke the transport when invoked on a route that should be ignored', function () { - return loggerTestHelper(testHelperOptions).then(function (result) { + it("should not invoke the transport when invoked on a route that should be ignored", function() { + return loggerTestHelper(testHelperOptions).then(function(result) { result.transportInvoked.should.eql(false); }); }); - it('should contain a filtered request when invoked on a route that should be ignored', function () { - return loggerTestHelper(testHelperOptions).then(function (result) { + it("should contain a filtered request when invoked on a route that should be ignored", function() { + return loggerTestHelper(testHelperOptions).then(function(result) { result.log.should.be.empty(); }); }); }); - describe('metaField option', function () { - it('should have a default meta field', function () { - return loggerTestHelper().then(function (result) { + describe("metaField option", function() { + it("should have a default meta field", function() { + return loggerTestHelper().then(function(result) { result.log.meta.req.should.be.ok(); }); }); - it('should use provided custom metaField', function () { + it("should use provided custom metaField", function() { var testHelperOptions = { loggerOptions: { - metaField: 'foobar' + metaField: "foobar" } }; - return loggerTestHelper(testHelperOptions).then(function (result) { + return loggerTestHelper(testHelperOptions).then(function(result) { result.log.meta.foobar.req.should.be.ok(); }); }); }); - describe('skip option', function () { - it('should not be logged when using custom function returning true', function () { + describe("skip option", function() { + it("should not be logged when using custom function returning true", function() { var testHelperOptions = { loggerOptions: { - skip: function (req, res) { - return req.url.indexOf('sandwich') != -1 + skip: function(req, res) { + return req.url.indexOf("sandwich") != -1; } }, req: { - url: '/url-of-sandwich' + url: "/url-of-sandwich" } }; - return loggerTestHelper(testHelperOptions).then(function (result) { + return loggerTestHelper(testHelperOptions).then(function(result) { should.not.exist(result.log.msg); }); }); - it('should be logged when using custom function returning false', function () { + it("should be logged when using custom function returning false", function() { var testHelperOptions = { loggerOptions: { - skip: function (req, res) { - return req.url.indexOf('sandwich') != -1 + skip: function(req, res) { + return req.url.indexOf("sandwich") != -1; } }, req: { - url: '/hello' + url: "/hello" } }; - return loggerTestHelper(testHelperOptions).then(function (result) { - result.log.msg.should.eql('HTTP GET /hello'); + return loggerTestHelper(testHelperOptions).then(function(result) { + result.log.msg.should.eql("HTTP GET /hello"); }); }); }); - describe('statusLevels option', function () { - it('should have status level of "info" by default', function () { + describe("statusLevels option", function() { + it('should have status level of "info" by default', function() { var testHelperOptions = { - next: function (req, res, next) { + next: function(req, res, next) { res.status(403).end('{ "message": "Hi! I\'m a chunk!" }'); } }; - return loggerTestHelper(testHelperOptions).then(function (result) { - result.log.level.should.equal('info'); + return loggerTestHelper(testHelperOptions).then(function(result) { + result.log.level.should.equal("info"); }); }); - describe('when statusLevels set to true', function () { - it('should have status level of "info" when 100 <= statusCode < 400', function () { + describe("when statusLevels set to true", function() { + it('should have status level of "info" when 100 <= statusCode < 400', function() { var testHelperOptions = { - next: function (req, res, next) { + next: function(req, res, next) { res.status(200).end('{ "message": "Hi! I\'m a chunk!" }'); }, loggerOptions: { statusLevels: true }, req: { - url: '/url-of-sandwich' + url: "/url-of-sandwich" } }; - return loggerTestHelper(testHelperOptions).then(function (result) { - result.log.level.should.equal('info'); + return loggerTestHelper(testHelperOptions).then(function(result) { + result.log.level.should.equal("info"); }); }); - it('should have status level of "warn" when 400 <= statusCode < 500', function () { + it('should have status level of "warn" when 400 <= statusCode < 500', function() { var testHelperOptions = { - next: function (req, res, next) { + next: function(req, res, next) { res.status(403).end('{ "message": "Hi! I\'m a chunk!" }'); }, loggerOptions: { statusLevels: true } }; - return loggerTestHelper(testHelperOptions).then(function (result) { - result.log.level.should.equal('warn'); + return loggerTestHelper(testHelperOptions).then(function(result) { + result.log.level.should.equal("warn"); }); }); - it('should have status level of "error" when statusCode >= 500', function () { + it('should have status level of "error" when statusCode >= 500', function() { var testHelperOptions = { - next: function (req, res, next) { + next: function(req, res, next) { res.status(500).end('{ "message": "Hi! I\'m a chunk!" }'); }, loggerOptions: { statusLevels: true } }; - return loggerTestHelper(testHelperOptions).then(function (result) { - result.log.level.should.equal('error'); + return loggerTestHelper(testHelperOptions).then(function(result) { + result.log.level.should.equal("error"); }); }); }); - describe('when statusLevels set to an object', function () { - it('should have custom status level provided by "success" key of object when 100 <= statusCode < 400', function () { + describe("when statusLevels set to an object", function() { + it('should have custom status level provided by "success" key of object when 100 <= statusCode < 400', function() { var testHelperOptions = { - next: function (req, res, next) { + next: function(req, res, next) { res.status(200).end('{ "message": "Hi! I\'m a chunk!" }'); }, loggerOptions: { - statusLevels: {success: 'silly'} + statusLevels: { success: "silly" } }, transportOptions: { - level: 'silly' + level: "silly" } }; - return loggerTestHelper(testHelperOptions).then(function (result) { - result.log.level.should.equal('silly'); + return loggerTestHelper(testHelperOptions).then(function(result) { + result.log.level.should.equal("silly"); }); }); - it('should have status level provided by "warn" key of object when 400 <= statusCode < 500', function () { + it('should have status level provided by "warn" key of object when 400 <= statusCode < 500', function() { var testHelperOptions = { - next: function (req, res, next) { + next: function(req, res, next) { res.status(403).end('{ "message": "Hi! I\'m a chunk!" }'); }, loggerOptions: { - statusLevels: {warn: 'debug'} + statusLevels: { warn: "debug" } }, transportOptions: { - level: 'silly' + level: "silly" } }; - return loggerTestHelper(testHelperOptions).then(function (result) { - result.log.level.should.equal('debug'); + return loggerTestHelper(testHelperOptions).then(function(result) { + result.log.level.should.equal("debug"); }); }); - it('should have status level provided by "error" key of object when statusCode >= 500', function () { + it('should have status level provided by "error" key of object when statusCode >= 500', function() { var testHelperOptions = { - next: function (req, res, next) { + next: function(req, res, next) { res.status(500).end('{ "message": "Hi! I\'m a chunk!" }'); }, loggerOptions: { - statusLevels: {error: 'verbose'} + statusLevels: { error: "verbose" } }, transportOptions: { - level: 'silly' + level: "silly" } }; - return loggerTestHelper(testHelperOptions).then(function (result) { - result.log.level.should.equal('verbose'); + return loggerTestHelper(testHelperOptions).then(function(result) { + result.log.level.should.equal("verbose"); }); }); }); }); - describe('when levels set to a function', function () { - it('should have custom status level provided by the function when 100 <= statusCode < 400', function () { - var testHelperOptions = { - next: function (req, res, next) { - res.status(200).end('{ "message": "Hi! I\'m a chunk!" }'); - }, - loggerOptions: { - level: function(req,res) { return 'silly'; } - }, - transportOptions: { - level: 'silly' + describe("when levels set to a function", function() { + it("should have custom status level provided by the function when 100 <= statusCode < 400", function() { + var testHelperOptions = { + next: function(req, res, next) { + res.status(200).end('{ "message": "Hi! I\'m a chunk!" }'); + }, + loggerOptions: { + level: function(req, res) { + return "silly"; } - }; - return loggerTestHelper(testHelperOptions).then(function (result) { - result.log.level.should.equal('silly'); - }); + }, + transportOptions: { + level: "silly" + } + }; + return loggerTestHelper(testHelperOptions).then(function(result) { + result.log.level.should.equal("silly"); }); + }); - it('should have custom status level provided by the function when 400 <= statusCode < 500', function () { - var testHelperOptions = { - next: function (req, res, next) { - res.status(403).end('{ "message": "Hi! I\'m a chunk!" }'); - }, - loggerOptions: { - level: function(req,res) { return 'silly'; } - }, - transportOptions: { - level: 'silly' + it("should have custom status level provided by the function when 400 <= statusCode < 500", function() { + var testHelperOptions = { + next: function(req, res, next) { + res.status(403).end('{ "message": "Hi! I\'m a chunk!" }'); + }, + loggerOptions: { + level: function(req, res) { + return "silly"; } - }; - return loggerTestHelper(testHelperOptions).then(function (result) { - result.log.level.should.equal('silly'); - }); + }, + transportOptions: { + level: "silly" + } + }; + return loggerTestHelper(testHelperOptions).then(function(result) { + result.log.level.should.equal("silly"); }); + }); - it('should have custom status level provided by the function when 500 <= statusCode', function () { - var testHelperOptions = { - next: function (req, res, next) { - res.status(500).end('{ "message": "Hi! I\'m a chunk!" }'); - }, - loggerOptions: { - level: function(req,res) { return 'silly'; } - }, - transportOptions: { - level: 'silly' + it("should have custom status level provided by the function when 500 <= statusCode", function() { + var testHelperOptions = { + next: function(req, res, next) { + res.status(500).end('{ "message": "Hi! I\'m a chunk!" }'); + }, + loggerOptions: { + level: function(req, res) { + return "silly"; } - }; - return loggerTestHelper(testHelperOptions).then(function (result) { - result.log.level.should.equal('silly'); - }); + }, + transportOptions: { + level: "silly" + } + }; + return loggerTestHelper(testHelperOptions).then(function(result) { + result.log.level.should.equal("silly"); }); + }); }); - describe('requestWhitelist option', function () { - it('should default to global requestWhitelist', function () { + describe("requestWhitelist option", function() { + it("should default to global requestWhitelist", function() { var options = { - req: {foo: "bar"} + req: { foo: "bar" } }; - return loggerTestHelper(options).then(function (result) { - result.log.meta.req.should.not.have.property('foo'); + return loggerTestHelper(options).then(function(result) { + result.log.meta.req.should.not.have.property("foo"); }); }); - it('should use specified requestWhitelist', function () { + it("should use specified requestWhitelist", function() { var options = { - req: {foo: "bar"}, + req: { foo: "bar" }, loggerOptions: { - requestWhitelist: ['foo'] + requestWhitelist: ["foo"] } }; - return loggerTestHelper(options).then(function (result) { - result.log.meta.req.should.have.property('foo'); - result.log.meta.req.should.not.have.property('method'); + return loggerTestHelper(options).then(function(result) { + result.log.meta.req.should.have.property("foo"); + result.log.meta.req.should.not.have.property("method"); }); }); - it('should not include a req in the log when there is no request whitelist', function() { + it("should not include a req in the log when there is no request whitelist", function() { var options = { loggerOptions: { - requestWhitelist: [], + requestWhitelist: [] } }; - return loggerTestHelper(options).then(function (result) { + return loggerTestHelper(options).then(function(result) { should.not.exist(result.log.meta.req); }); }); }); - describe('bodyBlacklist option', function () { - it('should remove the body if it is requestWhitelisted and the bodyBlacklist removes all properties', function() { + describe("bodyBlacklist option", function() { + it("should remove the body if it is requestWhitelisted and the bodyBlacklist removes all properties", function() { var options = { loggerOptions: { - bodyBlacklist: ['foo', 'baz'], - requestWhitelist: ['body'], + bodyBlacklist: ["foo", "baz"], + requestWhitelist: ["body"] }, req: { - body: {foo: 'bar', baz: 'qux'} + body: { foo: "bar", baz: "qux" } } }; - return loggerTestHelper(options).then(function (result) { - result.log.meta.req.should.not.have.property('body'); + return loggerTestHelper(options).then(function(result) { + result.log.meta.req.should.not.have.property("body"); }); }); }); - describe('responseWhitelist option', function () { - it('should default to global responseWhitelist', function () { + describe("responseWhitelist option", function() { + it("should default to global responseWhitelist", function() { var options = { - res: {foo: "bar"} + res: { foo: "bar" } }; - return loggerTestHelper(options).then(function (result) { - result.log.meta.res.should.not.have.property('foo'); + return loggerTestHelper(options).then(function(result) { + result.log.meta.res.should.not.have.property("foo"); }); }); - it('should use specified responseWhitelist', function () { + it("should use specified responseWhitelist", function() { var options = { - res: {foo: "bar"}, + res: { foo: "bar" }, loggerOptions: { - responseWhitelist: ['foo'] + responseWhitelist: ["foo"] } }; - return loggerTestHelper(options).then(function (result) { - result.log.meta.res.should.have.property('foo'); - result.log.meta.res.should.not.have.property('method'); + return loggerTestHelper(options).then(function(result) { + result.log.meta.res.should.have.property("foo"); + result.log.meta.res.should.not.have.property("method"); }); }); }); - describe('ignoredRoutes option', function () { - it('should default to global ignoredRoutes', function () { + describe("ignoredRoutes option", function() { + it("should default to global ignoredRoutes", function() { var options = { - req: {url: "/ignored"} + req: { url: "/ignored" } }; - return loggerTestHelper(options).then(function (result) { + return loggerTestHelper(options).then(function(result) { result.transportInvoked.should.eql(false); }); }); - it('should use specified ignoredRoutes', function () { + it("should use specified ignoredRoutes", function() { var options = { - req: {url: "/ignored-option"}, + req: { url: "/ignored-option" }, loggerOptions: { - ignoredRoutes: ['/ignored-option'] + ignoredRoutes: ["/ignored-option"] } }; - return loggerTestHelper(options).then(function (result) { + return loggerTestHelper(options).then(function(result) { result.transportInvoked.should.eql(false); }); }); }); - describe('dynamicMeta option', function () { + describe("dynamicMeta option", function() { var testHelperOptions = { req: { body: { age: 42, - potato: 'Russet' + potato: "Russet" }, user: { username: "john@doe.com", @@ -1241,7 +1445,7 @@ describe('express-winston', function () { } }, res: { - custom: 'custom response runtime field' + custom: "custom response runtime field" }, loggerOptions: { meta: true, @@ -1250,33 +1454,35 @@ describe('express-winston', function () { user: req.user.username, role: req.user.role, custom: res.custom - } + }; } } }; - it('should contain dynamic meta data if meta and dynamicMeta activated', function () { - return loggerTestHelper(testHelperOptions).then(function (result) { + it("should contain dynamic meta data if meta and dynamicMeta activated", function() { + return loggerTestHelper(testHelperOptions).then(function(result) { result.log.meta.req.should.be.ok(); - result.log.meta.user.should.equal('john@doe.com'); - result.log.meta.role.should.equal('operator'); - result.log.meta.custom.should.equal('custom response runtime field'); + result.log.meta.user.should.equal("john@doe.com"); + result.log.meta.role.should.equal("operator"); + result.log.meta.custom.should.equal("custom response runtime field"); }); }); - it('should work with metaField option', function () { - testHelperOptions.loggerOptions.metaField = 'metaField'; - return loggerTestHelper(testHelperOptions).then(function (result) { + it("should work with metaField option", function() { + testHelperOptions.loggerOptions.metaField = "metaField"; + return loggerTestHelper(testHelperOptions).then(function(result) { result.log.meta.metaField.req.should.be.ok(); - result.log.meta.metaField.user.should.equal('john@doe.com'); - result.log.meta.metaField.role.should.equal('operator'); - result.log.meta.metaField.custom.should.equal('custom response runtime field'); + result.log.meta.metaField.user.should.equal("john@doe.com"); + result.log.meta.metaField.role.should.equal("operator"); + result.log.meta.metaField.custom.should.equal( + "custom response runtime field" + ); }); }); - it('should not contain dynamic meta data if dynamicMeta activated but meta false', function () { + it("should not contain dynamic meta data if dynamicMeta activated but meta false", function() { testHelperOptions.loggerOptions.meta = false; - return loggerTestHelper(testHelperOptions).then(function (result) { + return loggerTestHelper(testHelperOptions).then(function(result) { should.not.exist(result.log.meta.req); should.not.exist(result.log.meta.user); should.not.exist(result.log.meta.role); @@ -1284,55 +1490,55 @@ describe('express-winston', function () { }); }); - it('should throw an error if dynamicMeta is not a function', function () { - var loggerFn = expressWinston.logger.bind(expressWinston, {dynamicMeta: 12}); + it("should throw an error if dynamicMeta is not a function", function() { + var loggerFn = expressWinston.logger.bind(expressWinston, { + dynamicMeta: 12 + }); loggerFn.should.throw(); }); }); }); - describe('.requestWhitelist', function () { - it('should be an array with all the properties whitelisted in the req object', function () { + describe(".requestWhitelist", function() { + it("should be an array with all the properties whitelisted in the req object", function() { expressWinston.requestWhitelist.should.be.an.Array(); }); }); - describe('.bodyWhitelist', function () { - it('should be an array with all the properties whitelisted in the body object', function () { + describe(".bodyWhitelist", function() { + it("should be an array with all the properties whitelisted in the body object", function() { expressWinston.bodyWhitelist.should.be.an.Array(); }); }); - describe('.bodyBlacklist', function () { - - }); + describe(".bodyBlacklist", function() {}); - describe('.responseWhitelist', function () { - it('should be an array with all the properties whitelisted in the res object', function () { + describe(".responseWhitelist", function() { + it("should be an array with all the properties whitelisted in the res object", function() { expressWinston.responseWhitelist.should.be.an.Array(); }); }); - describe('.defaultRequestFilter', function () { - it('should be a function', function () { + describe(".defaultRequestFilter", function() { + it("should be a function", function() { expressWinston.defaultRequestFilter.should.be.a.Function(); }); }); - describe('.defaultResponseFilter', function () { - it('should be a function', function () { + describe(".defaultResponseFilter", function() { + it("should be a function", function() { expressWinston.defaultResponseFilter.should.be.a.Function(); }); }); - describe('.defaultSkip', function () { - it('should be a function', function () { + describe(".defaultSkip", function() { + it("should be a function", function() { expressWinston.defaultSkip.should.be.a.Function(); }); }); - describe('.ignoredRoutes', function () { - it('should be an array for all the ignored routes', function () { + describe(".ignoredRoutes", function() { + it("should be an array for all the ignored routes", function() { expressWinston.ignoredRoutes.should.be.an.Array(); }); }); From 3c10ee9aa26467b47cd547818ee5583d654746d4 Mon Sep 17 00:00:00 2001 From: Jean-Francois Lavoie Date: Mon, 4 Feb 2019 15:40:30 -0500 Subject: [PATCH 2/3] removing custom formatting --- test/test.js | 1041 ++++++++++++++++++++++++-------------------------- 1 file changed, 498 insertions(+), 543 deletions(-) diff --git a/test/test.js b/test/test.js index 7dd8dac..60f1428 100644 --- a/test/test.js +++ b/test/test.js @@ -1,15 +1,16 @@ -var util = require("util"); +var util = require('util'); -var mocks = require("node-mocks-http"); -var should = require("should"); -var _ = require("lodash"); -var Transport = require("winston-transport"); +var mocks = require('node-mocks-http'); +var should = require('should'); +var _ = require('lodash'); +var winston = require('winston'); +var Transport = require('winston-transport'); -var expressWinston = require("../index.js"); +var expressWinston = require('../index.js'); -expressWinston.ignoredRoutes.push("/ignored"); -expressWinston.responseWhitelist.push("body"); -expressWinston.bodyBlacklist.push("potato"); +expressWinston.ignoredRoutes.push('/ignored'); +expressWinston.responseWhitelist.push('body'); +expressWinston.bodyBlacklist.push('potato'); class MockTransport extends Transport { constructor(test, options) { @@ -24,7 +25,7 @@ class MockTransport extends Transport { this._test.log.level = info.level; this._test.log.msg = info.message; this._test.log.meta = info.meta; - this.emit("logged"); + this.emit('logged'); return cb(); } } @@ -40,22 +41,19 @@ class MockWinston { } function mockReq(reqMock) { - var reqSpec = _.extend( - { - method: "GET", - url: "/hello", - headers: { - "header-1": "value 1" - }, - query: { - val: "1" - }, - params: { - id: 20 - } + var reqSpec = _.extend({ + method: 'GET', + url: '/hello', + headers: { + 'header-1': 'value 1' + }, + query: { + val: '1' + }, + params: { + id: 20 }, - reqMock - ); + }, reqMock); return mocks.createRequest(reqSpec); } @@ -67,18 +65,15 @@ function mockRes() { } function loggerTestHelper(providedOptions) { - var options = _.extend( - { - loggerOptions: null, - req: null, - res: null, - transportOptions: null, - next: function(req, res, next) { - res.end('{ "message": "Hi! I\'m a chunk!" }'); - } - }, - providedOptions - ); + var options = _.extend({ + loggerOptions: null, + req: null, + res: null, + transportOptions: null, + next: function (req, res, next) { + res.end('{ "message": "Hi! I\'m a chunk!" }'); + } + }, providedOptions); var req = mockReq(options.req); var res = _.extend(mockRes(), options.res); @@ -89,17 +84,12 @@ function loggerTestHelper(providedOptions) { log: {} }; - return new Promise(function(resolve, reject) { - var middleware = expressWinston.logger( - _.extend( - { - transports: [new MockTransport(result, options.transportOptions)] - }, - options.loggerOptions - ) - ); + return new Promise(function (resolve, reject) { + var middleware = expressWinston.logger(_.extend({ + transports: [new MockTransport(result, options.transportOptions)] + }, options.loggerOptions)); - middleware(req, res, function(_req, _res, next) { + middleware(req, res, function (_req, _res, next) { options.next(req, res, next); resolve(result); }); @@ -107,17 +97,14 @@ function loggerTestHelper(providedOptions) { } function errorLoggerTestHelper(providedOptions) { - var options = _.extend( - { - loggerOptions: null, - originalError: new Error("This is the Error"), - req: null, - res: null, - transportOptions: null, - next: function() {} - }, - providedOptions - ); + var options = _.extend({ + loggerOptions: null, + originalError: new Error('This is the Error'), + req: null, + res: null, + transportOptions: null, + next: function () {} + }, providedOptions); var req = mockReq(options.req); var res = _.extend(mockRes(), options.res); @@ -130,17 +117,12 @@ function errorLoggerTestHelper(providedOptions) { pipelineError: null }; - return new Promise(function(resolve, reject) { - var middleware = expressWinston.errorLogger( - _.extend( - { - transports: [new MockTransport(result, options.transportOptions)] - }, - options.loggerOptions - ) - ); + return new Promise(function (resolve, reject) { + var middleware = expressWinston.errorLogger(_.extend({ + transports: [new MockTransport(result, options.transportOptions)] + }, options.loggerOptions)); - middleware(options.originalError, req, res, function(pipelineError) { + middleware(options.originalError, req, res, function (pipelineError) { options.next(pipelineError); result.pipelineError = pipelineError; resolve(result); @@ -148,30 +130,31 @@ function errorLoggerTestHelper(providedOptions) { }); } -describe("express-winston", function() { - describe(".errorLogger()", function() { - it("should be a function", function() { +describe('express-winston', function () { + + describe('.errorLogger()', function () { + it('should be a function', function () { expressWinston.errorLogger.should.be.a.Function(); }); - it("should throw an error when no options are provided", function() { + it('should throw an error when no options are provided', function () { var errorLoggerFn = expressWinston.errorLogger.bind(expressWinston); errorLoggerFn.should.throw(); }); - it("should throw an error when no transport is specified", function() { + it('should throw an error when no transport is specified', function () { var errorLoggerFn = expressWinston.errorLogger.bind(expressWinston, {}); errorLoggerFn.should.throw(); }); - it("should throw an error when provided with an empty list of transports", function() { + it('should throw an error when provided with an empty list of transports', function () { var errorLoggerFn = expressWinston.errorLogger.bind(expressWinston, { transports: [] }); errorLoggerFn.should.throw(); }); - it("should return a middleware function with four arguments that fit (err, req, res, next)", function() { + it('should return a middleware function with four arguments that fit (err, req, res, next)', function () { var middleware = expressWinston.errorLogger({ transports: [new MockTransport({})] }); @@ -179,42 +162,42 @@ describe("express-winston", function() { middleware.length.should.eql(4); }); - it("should use the exported requestWhitelist", function() { + it('should use the exported requestWhitelist', function() { var originalWhitelist = expressWinston.requestWhitelist; - expressWinston.requestWhitelist = ["foo"]; + expressWinston.requestWhitelist = ['foo']; var options = { - req: { foo: "bar" } + req: {foo: "bar"} }; - return errorLoggerTestHelper(options).then(function(result) { + return errorLoggerTestHelper(options).then(function (result) { // Return to the original value for later tests expressWinston.requestWhitelist = originalWhitelist; - result.log.meta.req.should.have.property("foo"); - result.log.meta.req.should.not.have.property("url"); + result.log.meta.req.should.have.property('foo'); + result.log.meta.req.should.not.have.property('url'); }); }); - it("should use the exported defaultRequestFilter", function() { + it('should use the exported defaultRequestFilter', function() { var originalRequestFilter = expressWinston.defaultRequestFilter; expressWinston.defaultRequestFilter = function() { - return "foo"; + return 'foo'; }; var options = { - req: { foo: "bar" } + req: {foo: "bar"} }; - return errorLoggerTestHelper(options).then(function(result) { + return errorLoggerTestHelper(options).then(function (result) { // Return to the original value for later tests expressWinston.defaultRequestFilter = originalRequestFilter; - result.log.meta.req.url.should.equal("foo"); + result.log.meta.req.url.should.equal('foo'); }); }); - describe("when providing logger instance", function() { + describe('when providing logger instance', function() { - it("should use the winstonInstance", function() { + it('should use the winstonInstance', function() { const winstonMock = new MockWinston(); const localOptions = { @@ -228,7 +211,7 @@ describe("express-winston", function() { winstonMock.invoked.should.eql(true); }); }); - it("should use the winstonInstance in favor of transport specification", function() { + it('should use the winstonInstance in favor of transport specification', function() { const winstonMock = new MockWinston(); const localOptions = { @@ -287,142 +270,132 @@ describe("express-winston", function() { }); - describe("when middleware function encounters an error in the pipeline", function() { - it("should invoke the transport", function() { + describe('when middleware function encounters an error in the pipeline', function() { + it('should invoke the transport', function() { return errorLoggerTestHelper().then(function(result) { result.transportInvoked.should.eql(true); }); }); - it('should find the default level of "error"', function() { - return errorLoggerTestHelper().then(function(result) { - result.log.level.should.eql("error"); + it('should find the default level of "error"', function () { + return errorLoggerTestHelper().then(function (result) { + result.log.level.should.eql('error'); }); }); - it('should find a custom level of "warn"', function() { - var testHelperOptions = { loggerOptions: { level: "warn" } }; - return errorLoggerTestHelper(testHelperOptions).then(function(result) { - result.log.level.should.eql("warn"); + it('should find a custom level of "warn"', function () { + var testHelperOptions = {loggerOptions: {level:'warn'}}; + return errorLoggerTestHelper(testHelperOptions).then(function (result) { + result.log.level.should.eql('warn'); }); }); - it('should find a message of "middlewareError"', function() { - return errorLoggerTestHelper().then(function(result) { - result.log.msg.should.eql("middlewareError"); + it('should find a message of "middlewareError"', function () { + return errorLoggerTestHelper().then(function (result) { + result.log.msg.should.eql('middlewareError'); }); }); - it("should contain a filtered request", function() { - return errorLoggerTestHelper().then(function(result) { + it('should contain a filtered request', function () { + return errorLoggerTestHelper().then(function (result) { result.log.meta.req.should.be.ok(); - result.log.meta.req.method.should.eql("GET"); + result.log.meta.req.method.should.eql('GET'); result.log.meta.req.query.should.eql({ - val: "1" + val: '1' }); - result.log.meta.req.should.not.have.property( - "nonWhitelistedProperty" - ); + result.log.meta.req.should.not.have.property('nonWhitelistedProperty'); }); }); - it("should not swallow the pipeline error", function() { - return errorLoggerTestHelper().then(function(result) { + it('should not swallow the pipeline error', function () { + return errorLoggerTestHelper().then(function (result) { result.pipelineError.should.be.ok(); result.pipelineError.should.eql(result.originalError); }); }); }); - describe("exceptionToMeta option", function() { - it("should, use exceptionToMeta function when given", function() { + describe('exceptionToMeta option', function () { + it('should, use exceptionToMeta function when given', function () { function exceptionToMeta(error) { return { - stack: error.stack && error.stack.split("\n") + stack: error.stack && error.stack.split('\n') }; } - var testHelperOptions = { - loggerOptions: { exceptionToMeta: exceptionToMeta } - }; - return errorLoggerTestHelper(testHelperOptions).then(function(result) { + var testHelperOptions = { loggerOptions: { exceptionToMeta: exceptionToMeta } }; + return errorLoggerTestHelper(testHelperOptions).then(function (result) { result.log.meta.stack.should.be.ok(); - result.log.meta.should.not.have.property("trace"); + result.log.meta.should.not.have.property('trace'); }); }); - it("should, use getAllInfo function when not given", function() { - var testHelperOptions = { loggerOptions: {} }; - return errorLoggerTestHelper(testHelperOptions).then(function(result) { - result.log.meta.should.have.property("date"); - result.log.meta.should.have.property("process"); - result.log.meta.should.have.property("os"); - result.log.meta.should.have.property("trace"); - result.log.meta.should.have.property("stack"); + it('should, use getAllInfo function when not given', function () { + var testHelperOptions = { loggerOptions: { } }; + return errorLoggerTestHelper(testHelperOptions).then(function (result) { + result.log.meta.should.have.property('date'); + result.log.meta.should.have.property('process'); + result.log.meta.should.have.property('os'); + result.log.meta.should.have.property('trace'); + result.log.meta.should.have.property('stack'); }); }); }); - describe("blacklistedMetaFields option", function() { - it("should, remove given fields from the meta result", function() { - var testHelperOptionsWithBlacklist = { - loggerOptions: { blacklistedMetaFields: ["trace"] } - }; - return errorLoggerTestHelper(testHelperOptionsWithBlacklist).then( - function(result) { - result.log.meta.should.not.have.property("trace"); - } - ); + describe('blacklistedMetaFields option', function () { + it('should, remove given fields from the meta result', function () { + var testHelperOptionsWithBlacklist = { loggerOptions: { blacklistedMetaFields: ['trace'] } }; + return errorLoggerTestHelper(testHelperOptionsWithBlacklist).then(function (result) { + result.log.meta.should.not.have.property('trace'); + }); var testHelperOptionsWithoutBlacklist = { loggerOptions: {} }; - return errorLoggerTestHelper(testHelperOptionsWithoutBlacklist).then( - function(result) { - result.log.meta.should.have.property("trace"); - } - ); + return errorLoggerTestHelper(testHelperOptionsWithoutBlacklist).then(function (result) { + result.log.meta.should.have.property('trace'); + }); }); }); - describe("metaField option", function() { - it("should, when using a custom metaField, log the custom metaField", function() { - var testHelperOptions = { loggerOptions: { metaField: "metaField" } }; - return errorLoggerTestHelper(testHelperOptions).then(function(result) { + describe('metaField option', function () { + it('should, when using a custom metaField, log the custom metaField', function () { + var testHelperOptions = {loggerOptions: {metaField: 'metaField'}}; + return errorLoggerTestHelper(testHelperOptions).then(function (result) { result.log.meta.metaField.req.should.be.ok(); }); }); }); - describe("requestWhitelist option", function() { - it("should default to global requestWhitelist", function() { + describe('requestWhitelist option', function () { + it('should default to global requestWhitelist', function () { var options = { - req: { foo: "bar" } + req: {foo: "bar"} }; - return errorLoggerTestHelper(options).then(function(result) { - result.log.meta.req.should.not.have.property("foo"); + return errorLoggerTestHelper(options).then(function (result) { + result.log.meta.req.should.not.have.property('foo'); }); }); - it("should use specified requestWhitelist", function() { + it('should use specified requestWhitelist', function () { var options = { - req: { foo: "bar" }, + req: {foo: "bar"}, loggerOptions: { - requestWhitelist: ["foo"] + requestWhitelist: ['foo'] } }; - return errorLoggerTestHelper(options).then(function(result) { - result.log.meta.req.should.have.property("foo"); - result.log.meta.req.should.not.have.property("method"); + return errorLoggerTestHelper(options).then(function (result) { + result.log.meta.req.should.have.property('foo'); + result.log.meta.req.should.not.have.property('method'); }); }); }); - describe("dynamicMeta option", function() { + describe('dynamicMeta option', function () { var testHelperOptions = { req: { body: { age: 42, - potato: "Russet" + potato: 'Russet' }, user: { username: "john@doe.com", @@ -430,9 +403,9 @@ describe("express-winston", function() { } }, res: { - custom: "custom response runtime field" + custom: 'custom response runtime field' }, - originalError: new Error("FOO"), + originalError: new Error('FOO'), loggerOptions: { meta: true, dynamicMeta: function(req, res, err) { @@ -441,37 +414,35 @@ describe("express-winston", function() { role: req.user.role, custom: res.custom, errMessage: err.message - }; + } } } }; - it("should contain dynamic meta data if meta and dynamicMeta activated", function() { - return errorLoggerTestHelper(testHelperOptions).then(function(result) { + it('should contain dynamic meta data if meta and dynamicMeta activated', function () { + return errorLoggerTestHelper(testHelperOptions).then(function (result) { result.log.meta.req.should.be.ok(); - result.log.meta.user.should.equal("john@doe.com"); - result.log.meta.role.should.equal("operator"); - result.log.meta.custom.should.equal("custom response runtime field"); - result.log.meta.errMessage.should.equal("FOO"); + result.log.meta.user.should.equal('john@doe.com'); + result.log.meta.role.should.equal('operator'); + result.log.meta.custom.should.equal('custom response runtime field'); + result.log.meta.errMessage.should.equal('FOO'); }); }); - it("should work with metaField option", function() { - testHelperOptions.loggerOptions.metaField = "metaField"; - return errorLoggerTestHelper(testHelperOptions).then(function(result) { + it('should work with metaField option', function () { + testHelperOptions.loggerOptions.metaField = 'metaField'; + return errorLoggerTestHelper(testHelperOptions).then(function (result) { result.log.meta.metaField.req.should.be.ok(); - result.log.meta.metaField.user.should.equal("john@doe.com"); - result.log.meta.metaField.role.should.equal("operator"); - result.log.meta.metaField.custom.should.equal( - "custom response runtime field" - ); - result.log.meta.metaField.errMessage.should.equal("FOO"); + result.log.meta.metaField.user.should.equal('john@doe.com'); + result.log.meta.metaField.role.should.equal('operator'); + result.log.meta.metaField.custom.should.equal('custom response runtime field'); + result.log.meta.metaField.errMessage.should.equal('FOO'); }); }); - it("should not contain dynamic meta data if dynamicMeta activated but meta false", function() { + it('should not contain dynamic meta data if dynamicMeta activated but meta false', function () { testHelperOptions.loggerOptions.meta = false; - return errorLoggerTestHelper(testHelperOptions).then(function(result) { + return errorLoggerTestHelper(testHelperOptions).then(function (result) { should.not.exist(result.log.meta.req); should.not.exist(result.log.meta.user); should.not.exist(result.log.meta.role); @@ -480,38 +451,36 @@ describe("express-winston", function() { }); }); - it("should throw an error if dynamicMeta is not a function", function() { - var loggerFn = expressWinston.errorLogger.bind(expressWinston, { - dynamicMeta: 12 - }); + it('should throw an error if dynamicMeta is not a function', function () { + var loggerFn = expressWinston.errorLogger.bind(expressWinston, {dynamicMeta: 12}); loggerFn.should.throw(); }); }); }); - describe(".logger()", function() { - it("should be a function", function() { + describe('.logger()', function () { + it('should be a function', function () { expressWinston.logger.should.be.a.Function(); }); - it("should throw an error when no options are provided", function() { + it('should throw an error when no options are provided', function () { var loggerFn = expressWinston.logger.bind(expressWinston); loggerFn.should.throw(); }); - it("should throw an error when no transport is specified", function() { + it('should throw an error when no transport is specified', function () { var loggerFn = expressWinston.logger.bind(expressWinston, {}); loggerFn.should.throw(); }); - it("should throw an error when provided with an empty list of transports", function() { + it('should throw an error when provided with an empty list of transports', function () { var loggerFn = expressWinston.logger.bind(expressWinston, { transports: [] }); loggerFn.should.throw(); }); - it("should return a middleware function with three arguments that fit (req, res, next)", function() { + it('should return a middleware function with three arguments that fit (req, res, next)', function () { var middleware = expressWinston.logger({ transports: [new MockTransport({})] }); @@ -519,7 +488,7 @@ describe("express-winston", function() { middleware.length.should.eql(3); }); - it("should not have an empty body in meta.req when invoked on a route with an empty response body", function() { + it('should not have an empty body in meta.req when invoked on a route with an empty response body', function () { function next(req, res, next) { res.end(); } @@ -527,18 +496,16 @@ describe("express-winston", function() { next: next, req: { body: {}, - routeLevelAddedProperty: "value that should be logged", - url: "/hello" - } + routeLevelAddedProperty: 'value that should be logged', + url: '/hello' + }, }; - return loggerTestHelper(testHelperOptions).then(function(result) { - Object.keys(result.log.meta.req) - .indexOf("body") - .should.eql(-1); + return loggerTestHelper(testHelperOptions).then(function (result) { + Object.keys(result.log.meta.req).indexOf('body').should.eql(-1); }); }); - it("should log entire body when request whitelist contains body and there is no body whitelist or blacklist", function() { + it('should log entire body when request whitelist contains body and there is no body whitelist or blacklist', function () { function next(req, res, next) { res.end(); } @@ -546,30 +513,30 @@ describe("express-winston", function() { next: next, req: { body: { - foo: "bar", - baz: "qux" + foo: 'bar', + baz: 'qux' }, - routeLevelAddedProperty: "value that should be logged", - url: "/hello" + routeLevelAddedProperty: 'value that should be logged', + url: '/hello' }, loggerOptions: { bodyBlacklist: [], bodyWhitelist: [], - requestWhitelist: expressWinston.requestWhitelist.concat("body") + requestWhitelist: expressWinston.requestWhitelist.concat('body') } }; - return loggerTestHelper(testHelperOptions).then(function(result) { + return loggerTestHelper(testHelperOptions).then(function (result) { result.log.meta.req.body.should.eql({ - foo: "bar", - baz: "qux" + foo: 'bar', + baz: 'qux' }); }); }); - it('should not invoke the transport when invoked on a route with transport level of "error"', function() { + it('should not invoke the transport when invoked on a route with transport level of "error"', function () { function next(req, res, next) { - req._routeWhitelists.req = ["routeLevelAddedProperty"]; - req._routeWhitelists.res = ["routeLevelAddedProperty"]; + req._routeWhitelists.req = ['routeLevelAddedProperty']; + req._routeWhitelists.res = ['routeLevelAddedProperty']; res.end('{ "message": "Hi! I\'m a chunk!" }'); } @@ -580,130 +547,130 @@ describe("express-winston", function() { }, req: { body: {}, - routeLevelAddedProperty: "value that should be logged", - url: "/hello" + routeLevelAddedProperty: 'value that should be logged', + url: '/hello', }, res: { - nonWhitelistedProperty: "value that should not be logged", - routeLevelAddedProperty: "value that should be logged" + nonWhitelistedProperty: 'value that should not be logged', + routeLevelAddedProperty: 'value that should be logged' }, transportOptions: { - level: "error" + level: 'error' } }; - return loggerTestHelper(testHelperOptions).then(function(result) { + return loggerTestHelper(testHelperOptions).then(function (result) { result.transportInvoked.should.eql(false); }); }); - it("should use the exported requestWhitelist", function() { + it('should use the exported requestWhitelist', function() { var originalWhitelist = expressWinston.requestWhitelist; - expressWinston.requestWhitelist = ["foo"]; + expressWinston.requestWhitelist = ['foo']; var options = { - req: { foo: "bar" } + req: {foo: "bar"} }; - return loggerTestHelper(options).then(function(result) { + return loggerTestHelper(options).then(function (result) { // Return to the original value for later tests expressWinston.requestWhitelist = originalWhitelist; - result.log.meta.req.should.have.property("foo"); - result.log.meta.req.should.not.have.property("url"); + result.log.meta.req.should.have.property('foo'); + result.log.meta.req.should.not.have.property('url'); }); }); - it("should use the exported bodyWhitelist", function() { + it('should use the exported bodyWhitelist', function() { var originalWhitelist = expressWinston.bodyWhitelist; - expressWinston.bodyWhitelist = ["foo"]; + expressWinston.bodyWhitelist = ['foo']; var options = { - req: { body: { foo: "bar", baz: "qux" } } + req: {body: {foo: 'bar', baz: 'qux'}} }; - return loggerTestHelper(options).then(function(result) { + return loggerTestHelper(options).then(function (result) { // Return to the original value for later tests expressWinston.bodyWhitelist = originalWhitelist; - result.log.meta.req.body.should.have.property("foo"); - result.log.meta.req.body.should.not.have.property("baz"); + result.log.meta.req.body.should.have.property('foo'); + result.log.meta.req.body.should.not.have.property('baz'); }); }); - it("should use the exported bodyBlacklist", function() { + it('should use the exported bodyBlacklist', function() { var originalBlacklist = expressWinston.bodyBlacklist; - expressWinston.bodyBlacklist = ["foo"]; + expressWinston.bodyBlacklist = ['foo']; var options = { - req: { body: { foo: "bar", baz: "qux" } } + req: {body: {foo: 'bar', baz: 'qux'}} }; - return loggerTestHelper(options).then(function(result) { + return loggerTestHelper(options).then(function (result) { // Return to the original value for later tests expressWinston.bodyBlacklist = originalBlacklist; - result.log.meta.req.body.should.not.have.property("foo"); - result.log.meta.req.body.should.have.property("baz"); + result.log.meta.req.body.should.not.have.property('foo'); + result.log.meta.req.body.should.have.property('baz'); }); }); - it("should use the exported responseWhitelist", function() { + it('should use the exported responseWhitelist', function() { var originalWhitelist = expressWinston.responseWhitelist; - expressWinston.responseWhitelist = ["foo"]; + expressWinston.responseWhitelist = ['foo']; var options = { - res: { foo: "bar", baz: "qux" } + res: {foo: 'bar', baz: 'qux'} }; - return loggerTestHelper(options).then(function(result) { + return loggerTestHelper(options).then(function (result) { // Return to the original value for later tests expressWinston.responseWhitelist = originalWhitelist; - result.log.meta.res.should.have.property("foo"); - result.log.meta.res.should.not.have.property("baz"); + result.log.meta.res.should.have.property('foo'); + result.log.meta.res.should.not.have.property('baz'); }); }); - it("should use the exported defaultRequestFilter", function() { + it('should use the exported defaultRequestFilter', function() { var originalRequestFilter = expressWinston.defaultRequestFilter; expressWinston.defaultRequestFilter = function() { - return "foo"; + return 'foo'; }; var options = { - req: { foo: "bar" } + req: {foo: "bar"} }; - return loggerTestHelper(options).then(function(result) { + return loggerTestHelper(options).then(function (result) { // Return to the original value for later tests expressWinston.defaultRequestFilter = originalRequestFilter; - result.log.meta.req.url.should.equal("foo"); + result.log.meta.req.url.should.equal('foo'); }); }); - it("should use the exported defaultResponseFilter", function() { + it('should use the exported defaultResponseFilter', function() { var originalResponseFilter = expressWinston.defaultResponseFilter; expressWinston.defaultResponseFilter = function() { - return "foo"; + return 'foo'; }; var options = { - req: { foo: "bar" } + req: {foo: "bar"} }; - return loggerTestHelper(options).then(function(result) { + return loggerTestHelper(options).then(function (result) { // Return to the original value for later tests expressWinston.defaultResponseFilter = originalResponseFilter; - result.log.meta.res.statusCode.should.equal("foo"); + result.log.meta.res.statusCode.should.equal('foo'); }); }); - it("should use the exported defaultSkip", function() { + it('should use the exported defaultSkip', function() { var originalSkip = expressWinston.defaultSkip; expressWinston.defaultSkip = function() { return true; }; var options = { - req: { foo: "bar" } + req: {foo: "bar"} }; - return loggerTestHelper(options).then(function(result) { + return loggerTestHelper(options).then(function (result) { // Return to the original value for later tests expressWinston.defaultSkip = originalSkip; @@ -711,14 +678,14 @@ describe("express-winston", function() { }); }); - it("should use the exported ignoredRoutes", function() { + it('should use the exported ignoredRoutes', function() { var originalIgnoredRoutes = expressWinston.ignoredRoutes; - expressWinston.ignoredRoutes = ["/foo-route"]; + expressWinston.ignoredRoutes = ['/foo-route']; var options = { - req: { url: "/foo-route" } + req: {url: '/foo-route'} }; - return loggerTestHelper(options).then(function(result) { + return loggerTestHelper(options).then(function (result) { // Return to the original value for later tests expressWinston.ignoredRoutes = originalIgnoredRoutes; @@ -726,9 +693,9 @@ describe("express-winston", function() { }); }); - describe("when providing logger instance", function() { + describe('when providing logger instance', function() { - it("should use the winstonInstance", function() { + it('should use the winstonInstance', function() { const winstonMock = new MockWinston(); const localOptions = { @@ -742,7 +709,7 @@ describe("express-winston", function() { winstonMock.invoked.should.eql(true); }); }); - it("should use the winstonInstance in favor of transport specification", function() { + it('should use the winstonInstance in favor of transport specification', function() { const winstonMock = new MockWinston(); const localOptions = { @@ -802,15 +769,15 @@ describe("express-winston", function() { }); - describe("when middleware function is invoked on a route", function() { + describe('when middleware function is invoked on a route', function() { function next(req, res, next) { - req._startTime = new Date() - 125; + req._startTime = (new Date()) - 125; - req._routeWhitelists.req = ["routeLevelAddedProperty"]; - req._routeWhitelists.res = ["routeLevelAddedProperty"]; + req._routeWhitelists.req = ['routeLevelAddedProperty']; + req._routeWhitelists.res = ['routeLevelAddedProperty']; - req._routeWhitelists.body = ["username"]; - req._routeBlacklists.body = ["age"]; + req._routeWhitelists.body = ['username']; + req._routeBlacklists.body = ['age']; res.end('{ "message": "Hi! I\'m a chunk!" }'); } @@ -821,623 +788,613 @@ describe("express-winston", function() { username: "bobby", password: "top-secret", age: 42, - potato: "Russet" + potato: 'Russet' }, - routeLevelAddedProperty: "value that should be logged" + routeLevelAddedProperty: 'value that should be logged' }, res: { - nonWhitelistedProperty: "value that should not be logged", - routeLevelAddedProperty: "value that should be logged" - } + nonWhitelistedProperty: 'value that should not be logged', + routeLevelAddedProperty: 'value that should be logged' + }, }; - it("should invoke the transport", function() { - return loggerTestHelper(testHelperOptions).then(function(result) { + it('should invoke the transport', function () { + return loggerTestHelper(testHelperOptions).then(function (result) { result.transportInvoked.should.eql(true); }); }); - it("should contain a filtered request", function() { - return loggerTestHelper(testHelperOptions).then(function(result) { + it('should contain a filtered request', function () { + return loggerTestHelper(testHelperOptions).then(function (result) { result.log.meta.req.should.be.ok(); - result.log.meta.req.method.should.eql("GET"); + result.log.meta.req.method.should.eql('GET'); result.log.meta.req.query.should.eql({ - val: "1" + val: '1' }); - result.log.meta.req.body.should.not.have.property("age"); - result.log.meta.req.body.should.not.have.property("potato"); + result.log.meta.req.body.should.not.have.property('age'); + result.log.meta.req.body.should.not.have.property('potato'); }); }); - it("should contain a filtered response", function() { - return loggerTestHelper(testHelperOptions).then(function(result) { + it('should contain a filtered response', function () { + return loggerTestHelper(testHelperOptions).then(function (result) { result.log.meta.res.should.be.ok(); result.log.meta.res.statusCode.should.eql(200); result.log.meta.res.routeLevelAddedProperty.should.be.ok(); - result.log.meta.res.should.not.have.property( - "nonWhitelistedProperty" - ); + result.log.meta.res.should.not.have.property('nonWhitelistedProperty'); }); }); - it("should contain a response time", function() { - return loggerTestHelper(testHelperOptions).then(function(result) { + it('should contain a response time', function () { + return loggerTestHelper(testHelperOptions).then(function (result) { result.log.meta.responseTime.should.be.within(120, 130); }); }); }); - describe("when middleware function is invoked on a route that returns JSON", function() { - it("should parse JSON in response body", function() { - var bodyObject = { message: "Hi! I'm a chunk!" }; + describe('when middleware function is invoked on a route that returns JSON', function() { + it('should parse JSON in response body', function() { + var bodyObject = { "message": "Hi! I\'m a chunk!" }; function next(req, res, next) { // Set Content-Type in a couple different case types, just in case. // Seems like the mock response doesn't quite handle the case // translation on these right. - res.setHeader("Content-Type", "application/json"); - res.setHeader("content-type", "application/json"); + res.setHeader('Content-Type', 'application/json'); + res.setHeader('content-type', 'application/json'); res.end(JSON.stringify(bodyObject)); } - return loggerTestHelper({ next: next }).then(function(result) { - result.log.meta.res.body.should.eql(bodyObject); + return loggerTestHelper({next: next}).then(function(result) { + result.log.meta.res.body.should.eql(bodyObject); }); }); - it("should not blow up when response body is invalid JSON", function() { + it('should not blow up when response body is invalid JSON', function() { function next(req, res, next) { // Set Content-Type in a couple different case types, just in case. // Seems like the mock response doesn't quite handle the case // translation on these right. - res.setHeader("Content-Type", "application/json"); - res.setHeader("content-type", "application/json"); - res.end("}"); + res.setHeader('Content-Type', 'application/json'); + res.setHeader('content-type', 'application/json'); + res.end('}'); } - return loggerTestHelper({ next: next }); + return loggerTestHelper({next: next}); }); }); - describe("when middleware function is invoked on a route that should be ignored (by .ignoredRoutes)", function() { + describe('when middleware function is invoked on a route that should be ignored (by .ignoredRoutes)', function () { var testHelperOptions = { - req: { url: "/ignored" } + req: {url: '/ignored'} }; - it("should not invoke the transport", function() { - return loggerTestHelper(testHelperOptions).then(function(result) { + it('should not invoke the transport', function () { + return loggerTestHelper(testHelperOptions).then(function (result) { result.transportInvoked.should.eql(false); }); }); - it("should contain a filtered request", function() { - return loggerTestHelper(testHelperOptions).then(function(result) { + it('should contain a filtered request', function () { + return loggerTestHelper(testHelperOptions).then(function (result) { result.log.should.be.empty(); }); }); }); - describe("expressFormat option", function() { - it("should match the Express format when logging", function() { + describe('expressFormat option', function () { + it('should match the Express format when logging', function () { var testHelperOptions = { loggerOptions: { colorize: true, expressFormat: true }, req: { - url: "/all-the-things" + url: '/all-the-things' } }; - return loggerTestHelper(testHelperOptions).then(function(result) { + return loggerTestHelper(testHelperOptions).then(function (result) { var resultMsg = result.log.msg; - resultMsg.should.startWith( - "\u001b[90mGET /all-the-things\u001b[39m \u001b[32m200\u001b[39m \u001b[90m" - ); - resultMsg.should.endWith("ms\u001b[39m"); + resultMsg.should.startWith('\u001b[90mGET /all-the-things\u001b[39m \u001b[32m200\u001b[39m \u001b[90m'); + resultMsg.should.endWith('ms\u001b[39m'); }); }); - it("should not emit colors when colorize option is false", function() { + it('should not emit colors when colorize option is false', function() { var testHelperOptions = { loggerOptions: { colorize: false, expressFormat: true }, req: { - url: "/all-the-things" + url: '/all-the-things' } }; - return loggerTestHelper(testHelperOptions).then(function(result) { + return loggerTestHelper(testHelperOptions).then(function (result) { var resultMsg = result.log.msg; - resultMsg.should.startWith("GET /all-the-things 200 "); - resultMsg.should.endWith("ms"); + resultMsg.should.startWith('GET /all-the-things 200 '); + resultMsg.should.endWith('ms'); }); }); - it("should not emit colors when colorize option is not present", function() { + it('should not emit colors when colorize option is not present', function() { var testHelperOptions = { loggerOptions: { colorize: false, expressFormat: true }, req: { - url: "/all-the-things" + url: '/all-the-things' } }; - return loggerTestHelper(testHelperOptions).then(function(result) { + return loggerTestHelper(testHelperOptions).then(function (result) { var resultMsg = result.log.msg; - resultMsg.should.startWith("GET /all-the-things 200 "); - resultMsg.should.endWith("ms"); + resultMsg.should.startWith('GET /all-the-things 200 '); + resultMsg.should.endWith('ms'); }); }); }); - describe("colorize option", function() { - it("should make status code text green if < 300", function() { + describe('colorize option', function () { + it('should make status code text green if < 300', function () { var testHelperOptions = { loggerOptions: { colorize: true, - msg: "{{res.statusCode}} {{req.method}} {{req.url}}" + msg: '{{res.statusCode}} {{req.method}} {{req.url}}' }, req: { - url: "/all-the-things" + url: '/all-the-things' } }; - return loggerTestHelper(testHelperOptions).then(function(result) { + return loggerTestHelper(testHelperOptions).then(function (result) { var resultMsg = result.log.msg; - resultMsg.should.eql("\u001b[32m200\u001b[39m GET /all-the-things"); + resultMsg.should.eql('\u001b[32m200\u001b[39m GET /all-the-things'); }); }); - it("should make status code text cyan if >= 300 and < 400", function() { + it('should make status code text cyan if >= 300 and < 400', function () { var testHelperOptions = { loggerOptions: { colorize: true, - msg: "{{res.statusCode}} {{req.method}} {{req.url}}" + msg: '{{res.statusCode}} {{req.method}} {{req.url}}' }, req: { - url: "/all-the-things" + url: '/all-the-things' }, res: { statusCode: 302 } }; - return loggerTestHelper(testHelperOptions).then(function(result) { + return loggerTestHelper(testHelperOptions).then(function (result) { var resultMsg = result.log.msg; - resultMsg.should.eql("\u001b[36m302\u001b[39m GET /all-the-things"); + resultMsg.should.eql('\u001b[36m302\u001b[39m GET /all-the-things'); }); }); - it("should make status code text yellow if >= 400 and < 500", function() { + it('should make status code text yellow if >= 400 and < 500', function () { var testHelperOptions = { loggerOptions: { colorize: true, - msg: "{{res.statusCode}} {{req.method}} {{req.url}}" + msg: '{{res.statusCode}} {{req.method}} {{req.url}}' }, req: { - url: "/all-the-things" + url: '/all-the-things' }, res: { statusCode: 420 } }; - return loggerTestHelper(testHelperOptions).then(function(result) { + return loggerTestHelper(testHelperOptions).then(function (result) { var resultMsg = result.log.msg; - resultMsg.should.eql("\u001b[33m420\u001b[39m GET /all-the-things"); + resultMsg.should.eql('\u001b[33m420\u001b[39m GET /all-the-things'); }); }); - it("should make status code text red if >= 500", function() { + it('should make status code text red if >= 500', function () { var testHelperOptions = { loggerOptions: { colorize: true, - msg: "{{res.statusCode}} {{req.method}} {{req.url}}" + msg: '{{res.statusCode}} {{req.method}} {{req.url}}' }, req: { - url: "/all-the-things" + url: '/all-the-things' }, res: { statusCode: 500 } }; - return loggerTestHelper(testHelperOptions).then(function(result) { + return loggerTestHelper(testHelperOptions).then(function (result) { var resultMsg = result.log.msg; - resultMsg.should.eql("\u001b[31m500\u001b[39m GET /all-the-things"); + resultMsg.should.eql('\u001b[31m500\u001b[39m GET /all-the-things'); }); }); }); - describe("msg option", function() { - it("should have a default log msg", function() { + describe('msg option', function () { + it('should have a default log msg', function () { var testHelperOptions = { req: { - url: "/url-of-sandwich" + url: '/url-of-sandwich' } }; - return loggerTestHelper(testHelperOptions).then(function(result) { - result.log.msg.should.eql("HTTP GET /url-of-sandwich"); + return loggerTestHelper(testHelperOptions).then(function (result) { + result.log.msg.should.eql('HTTP GET /url-of-sandwich'); }); }); - it("should match the custom format when a custom format is provided", function() { + it('should match the custom format when a custom format is provided', function () { var testHelperOptions = { loggerOptions: { - msg: "Foo {{ req.method }} {{ req.url }}" + msg: 'Foo {{ req.method }} {{ req.url }}' }, req: { - url: "/all-the-things" + url: '/all-the-things' } }; - return loggerTestHelper(testHelperOptions).then(function(result) { - result.log.msg.should.eql("Foo GET /all-the-things"); + return loggerTestHelper(testHelperOptions).then(function (result) { + result.log.msg.should.eql('Foo GET /all-the-things'); }); }); }); - describe("ignoreRoute option", function() { + describe('ignoreRoute option', function () { var testHelperOptions = { req: { shouldSkip: true, - url: "/is-not-logged" + url: '/is-not-logged' }, loggerOptions: { - ignoreRoute: function(req, res) { + ignoreRoute: function (req, res) { return req.shouldSkip === true && req.url.match(/^\/is-not-log/); } } }; - it("should throw an error if ignoreRoute option is provided but not a function", function() { + it('should throw an error if ignoreRoute option is provided but not a function', function () { var loggerFn = expressWinston.logger.bind(expressWinston, { transports: [new MockTransport({})], - ignoreRoute: "not a function" + ignoreRoute: 'not a function' }); loggerFn.should.throw(); }); - it("should not invoke the transport when invoked on a route that should be ignored", function() { - return loggerTestHelper(testHelperOptions).then(function(result) { + it('should not invoke the transport when invoked on a route that should be ignored', function () { + return loggerTestHelper(testHelperOptions).then(function (result) { result.transportInvoked.should.eql(false); }); }); - it("should contain a filtered request when invoked on a route that should be ignored", function() { - return loggerTestHelper(testHelperOptions).then(function(result) { + it('should contain a filtered request when invoked on a route that should be ignored', function () { + return loggerTestHelper(testHelperOptions).then(function (result) { result.log.should.be.empty(); }); }); }); - describe("metaField option", function() { - it("should have a default meta field", function() { - return loggerTestHelper().then(function(result) { + describe('metaField option', function () { + it('should have a default meta field', function () { + return loggerTestHelper().then(function (result) { result.log.meta.req.should.be.ok(); }); }); - it("should use provided custom metaField", function() { + it('should use provided custom metaField', function () { var testHelperOptions = { loggerOptions: { - metaField: "foobar" + metaField: 'foobar' } }; - return loggerTestHelper(testHelperOptions).then(function(result) { + return loggerTestHelper(testHelperOptions).then(function (result) { result.log.meta.foobar.req.should.be.ok(); }); }); }); - describe("skip option", function() { - it("should not be logged when using custom function returning true", function() { + describe('skip option', function () { + it('should not be logged when using custom function returning true', function () { var testHelperOptions = { loggerOptions: { - skip: function(req, res) { - return req.url.indexOf("sandwich") != -1; + skip: function (req, res) { + return req.url.indexOf('sandwich') != -1 } }, req: { - url: "/url-of-sandwich" + url: '/url-of-sandwich' } }; - return loggerTestHelper(testHelperOptions).then(function(result) { + return loggerTestHelper(testHelperOptions).then(function (result) { should.not.exist(result.log.msg); }); }); - it("should be logged when using custom function returning false", function() { + it('should be logged when using custom function returning false', function () { var testHelperOptions = { loggerOptions: { - skip: function(req, res) { - return req.url.indexOf("sandwich") != -1; + skip: function (req, res) { + return req.url.indexOf('sandwich') != -1 } }, req: { - url: "/hello" + url: '/hello' } }; - return loggerTestHelper(testHelperOptions).then(function(result) { - result.log.msg.should.eql("HTTP GET /hello"); + return loggerTestHelper(testHelperOptions).then(function (result) { + result.log.msg.should.eql('HTTP GET /hello'); }); }); }); - describe("statusLevels option", function() { - it('should have status level of "info" by default', function() { + describe('statusLevels option', function () { + it('should have status level of "info" by default', function () { var testHelperOptions = { - next: function(req, res, next) { + next: function (req, res, next) { res.status(403).end('{ "message": "Hi! I\'m a chunk!" }'); } }; - return loggerTestHelper(testHelperOptions).then(function(result) { - result.log.level.should.equal("info"); + return loggerTestHelper(testHelperOptions).then(function (result) { + result.log.level.should.equal('info'); }); }); - describe("when statusLevels set to true", function() { - it('should have status level of "info" when 100 <= statusCode < 400', function() { + describe('when statusLevels set to true', function () { + it('should have status level of "info" when 100 <= statusCode < 400', function () { var testHelperOptions = { - next: function(req, res, next) { + next: function (req, res, next) { res.status(200).end('{ "message": "Hi! I\'m a chunk!" }'); }, loggerOptions: { statusLevels: true }, req: { - url: "/url-of-sandwich" + url: '/url-of-sandwich' } }; - return loggerTestHelper(testHelperOptions).then(function(result) { - result.log.level.should.equal("info"); + return loggerTestHelper(testHelperOptions).then(function (result) { + result.log.level.should.equal('info'); }); }); - it('should have status level of "warn" when 400 <= statusCode < 500', function() { + it('should have status level of "warn" when 400 <= statusCode < 500', function () { var testHelperOptions = { - next: function(req, res, next) { + next: function (req, res, next) { res.status(403).end('{ "message": "Hi! I\'m a chunk!" }'); }, loggerOptions: { statusLevels: true } }; - return loggerTestHelper(testHelperOptions).then(function(result) { - result.log.level.should.equal("warn"); + return loggerTestHelper(testHelperOptions).then(function (result) { + result.log.level.should.equal('warn'); }); }); - it('should have status level of "error" when statusCode >= 500', function() { + it('should have status level of "error" when statusCode >= 500', function () { var testHelperOptions = { - next: function(req, res, next) { + next: function (req, res, next) { res.status(500).end('{ "message": "Hi! I\'m a chunk!" }'); }, loggerOptions: { statusLevels: true } }; - return loggerTestHelper(testHelperOptions).then(function(result) { - result.log.level.should.equal("error"); + return loggerTestHelper(testHelperOptions).then(function (result) { + result.log.level.should.equal('error'); }); }); }); - describe("when statusLevels set to an object", function() { - it('should have custom status level provided by "success" key of object when 100 <= statusCode < 400', function() { + describe('when statusLevels set to an object', function () { + it('should have custom status level provided by "success" key of object when 100 <= statusCode < 400', function () { var testHelperOptions = { - next: function(req, res, next) { + next: function (req, res, next) { res.status(200).end('{ "message": "Hi! I\'m a chunk!" }'); }, loggerOptions: { - statusLevels: { success: "silly" } + statusLevels: {success: 'silly'} }, transportOptions: { - level: "silly" + level: 'silly' } }; - return loggerTestHelper(testHelperOptions).then(function(result) { - result.log.level.should.equal("silly"); + return loggerTestHelper(testHelperOptions).then(function (result) { + result.log.level.should.equal('silly'); }); }); - it('should have status level provided by "warn" key of object when 400 <= statusCode < 500', function() { + it('should have status level provided by "warn" key of object when 400 <= statusCode < 500', function () { var testHelperOptions = { - next: function(req, res, next) { + next: function (req, res, next) { res.status(403).end('{ "message": "Hi! I\'m a chunk!" }'); }, loggerOptions: { - statusLevels: { warn: "debug" } + statusLevels: {warn: 'debug'} }, transportOptions: { - level: "silly" + level: 'silly' } }; - return loggerTestHelper(testHelperOptions).then(function(result) { - result.log.level.should.equal("debug"); + return loggerTestHelper(testHelperOptions).then(function (result) { + result.log.level.should.equal('debug'); }); }); - it('should have status level provided by "error" key of object when statusCode >= 500', function() { + it('should have status level provided by "error" key of object when statusCode >= 500', function () { var testHelperOptions = { - next: function(req, res, next) { + next: function (req, res, next) { res.status(500).end('{ "message": "Hi! I\'m a chunk!" }'); }, loggerOptions: { - statusLevels: { error: "verbose" } + statusLevels: {error: 'verbose'} }, transportOptions: { - level: "silly" + level: 'silly' } }; - return loggerTestHelper(testHelperOptions).then(function(result) { - result.log.level.should.equal("verbose"); + return loggerTestHelper(testHelperOptions).then(function (result) { + result.log.level.should.equal('verbose'); }); }); }); }); - describe("when levels set to a function", function() { - it("should have custom status level provided by the function when 100 <= statusCode < 400", function() { - var testHelperOptions = { - next: function(req, res, next) { - res.status(200).end('{ "message": "Hi! I\'m a chunk!" }'); - }, - loggerOptions: { - level: function(req, res) { - return "silly"; + describe('when levels set to a function', function () { + it('should have custom status level provided by the function when 100 <= statusCode < 400', function () { + var testHelperOptions = { + next: function (req, res, next) { + res.status(200).end('{ "message": "Hi! I\'m a chunk!" }'); + }, + loggerOptions: { + level: function(req,res) { return 'silly'; } + }, + transportOptions: { + level: 'silly' } - }, - transportOptions: { - level: "silly" - } - }; - return loggerTestHelper(testHelperOptions).then(function(result) { - result.log.level.should.equal("silly"); + }; + return loggerTestHelper(testHelperOptions).then(function (result) { + result.log.level.should.equal('silly'); + }); }); - }); - it("should have custom status level provided by the function when 400 <= statusCode < 500", function() { - var testHelperOptions = { - next: function(req, res, next) { - res.status(403).end('{ "message": "Hi! I\'m a chunk!" }'); - }, - loggerOptions: { - level: function(req, res) { - return "silly"; + it('should have custom status level provided by the function when 400 <= statusCode < 500', function () { + var testHelperOptions = { + next: function (req, res, next) { + res.status(403).end('{ "message": "Hi! I\'m a chunk!" }'); + }, + loggerOptions: { + level: function(req,res) { return 'silly'; } + }, + transportOptions: { + level: 'silly' } - }, - transportOptions: { - level: "silly" - } - }; - return loggerTestHelper(testHelperOptions).then(function(result) { - result.log.level.should.equal("silly"); + }; + return loggerTestHelper(testHelperOptions).then(function (result) { + result.log.level.should.equal('silly'); + }); }); - }); - it("should have custom status level provided by the function when 500 <= statusCode", function() { - var testHelperOptions = { - next: function(req, res, next) { - res.status(500).end('{ "message": "Hi! I\'m a chunk!" }'); - }, - loggerOptions: { - level: function(req, res) { - return "silly"; + it('should have custom status level provided by the function when 500 <= statusCode', function () { + var testHelperOptions = { + next: function (req, res, next) { + res.status(500).end('{ "message": "Hi! I\'m a chunk!" }'); + }, + loggerOptions: { + level: function(req,res) { return 'silly'; } + }, + transportOptions: { + level: 'silly' } - }, - transportOptions: { - level: "silly" - } - }; - return loggerTestHelper(testHelperOptions).then(function(result) { - result.log.level.should.equal("silly"); + }; + return loggerTestHelper(testHelperOptions).then(function (result) { + result.log.level.should.equal('silly'); + }); }); - }); }); - describe("requestWhitelist option", function() { - it("should default to global requestWhitelist", function() { + describe('requestWhitelist option', function () { + it('should default to global requestWhitelist', function () { var options = { - req: { foo: "bar" } + req: {foo: "bar"} }; - return loggerTestHelper(options).then(function(result) { - result.log.meta.req.should.not.have.property("foo"); + return loggerTestHelper(options).then(function (result) { + result.log.meta.req.should.not.have.property('foo'); }); }); - it("should use specified requestWhitelist", function() { + it('should use specified requestWhitelist', function () { var options = { - req: { foo: "bar" }, + req: {foo: "bar"}, loggerOptions: { - requestWhitelist: ["foo"] + requestWhitelist: ['foo'] } }; - return loggerTestHelper(options).then(function(result) { - result.log.meta.req.should.have.property("foo"); - result.log.meta.req.should.not.have.property("method"); + return loggerTestHelper(options).then(function (result) { + result.log.meta.req.should.have.property('foo'); + result.log.meta.req.should.not.have.property('method'); }); }); - it("should not include a req in the log when there is no request whitelist", function() { + it('should not include a req in the log when there is no request whitelist', function() { var options = { loggerOptions: { - requestWhitelist: [] + requestWhitelist: [], } }; - return loggerTestHelper(options).then(function(result) { + return loggerTestHelper(options).then(function (result) { should.not.exist(result.log.meta.req); }); }); }); - describe("bodyBlacklist option", function() { - it("should remove the body if it is requestWhitelisted and the bodyBlacklist removes all properties", function() { + describe('bodyBlacklist option', function () { + it('should remove the body if it is requestWhitelisted and the bodyBlacklist removes all properties', function() { var options = { loggerOptions: { - bodyBlacklist: ["foo", "baz"], - requestWhitelist: ["body"] + bodyBlacklist: ['foo', 'baz'], + requestWhitelist: ['body'], }, req: { - body: { foo: "bar", baz: "qux" } + body: {foo: 'bar', baz: 'qux'} } }; - return loggerTestHelper(options).then(function(result) { - result.log.meta.req.should.not.have.property("body"); + return loggerTestHelper(options).then(function (result) { + result.log.meta.req.should.not.have.property('body'); }); }); }); - describe("responseWhitelist option", function() { - it("should default to global responseWhitelist", function() { + describe('responseWhitelist option', function () { + it('should default to global responseWhitelist', function () { var options = { - res: { foo: "bar" } + res: {foo: "bar"} }; - return loggerTestHelper(options).then(function(result) { - result.log.meta.res.should.not.have.property("foo"); + return loggerTestHelper(options).then(function (result) { + result.log.meta.res.should.not.have.property('foo'); }); }); - it("should use specified responseWhitelist", function() { + it('should use specified responseWhitelist', function () { var options = { - res: { foo: "bar" }, + res: {foo: "bar"}, loggerOptions: { - responseWhitelist: ["foo"] + responseWhitelist: ['foo'] } }; - return loggerTestHelper(options).then(function(result) { - result.log.meta.res.should.have.property("foo"); - result.log.meta.res.should.not.have.property("method"); + return loggerTestHelper(options).then(function (result) { + result.log.meta.res.should.have.property('foo'); + result.log.meta.res.should.not.have.property('method'); }); }); }); - describe("ignoredRoutes option", function() { - it("should default to global ignoredRoutes", function() { + describe('ignoredRoutes option', function () { + it('should default to global ignoredRoutes', function () { var options = { - req: { url: "/ignored" } + req: {url: "/ignored"} }; - return loggerTestHelper(options).then(function(result) { + return loggerTestHelper(options).then(function (result) { result.transportInvoked.should.eql(false); }); }); - it("should use specified ignoredRoutes", function() { + it('should use specified ignoredRoutes', function () { var options = { - req: { url: "/ignored-option" }, + req: {url: "/ignored-option"}, loggerOptions: { - ignoredRoutes: ["/ignored-option"] + ignoredRoutes: ['/ignored-option'] } }; - return loggerTestHelper(options).then(function(result) { + return loggerTestHelper(options).then(function (result) { result.transportInvoked.should.eql(false); }); }); }); - describe("dynamicMeta option", function() { + describe('dynamicMeta option', function () { var testHelperOptions = { req: { body: { age: 42, - potato: "Russet" + potato: 'Russet' }, user: { username: "john@doe.com", @@ -1445,7 +1402,7 @@ describe("express-winston", function() { } }, res: { - custom: "custom response runtime field" + custom: 'custom response runtime field' }, loggerOptions: { meta: true, @@ -1454,35 +1411,33 @@ describe("express-winston", function() { user: req.user.username, role: req.user.role, custom: res.custom - }; + } } } }; - it("should contain dynamic meta data if meta and dynamicMeta activated", function() { - return loggerTestHelper(testHelperOptions).then(function(result) { + it('should contain dynamic meta data if meta and dynamicMeta activated', function () { + return loggerTestHelper(testHelperOptions).then(function (result) { result.log.meta.req.should.be.ok(); - result.log.meta.user.should.equal("john@doe.com"); - result.log.meta.role.should.equal("operator"); - result.log.meta.custom.should.equal("custom response runtime field"); + result.log.meta.user.should.equal('john@doe.com'); + result.log.meta.role.should.equal('operator'); + result.log.meta.custom.should.equal('custom response runtime field'); }); }); - it("should work with metaField option", function() { - testHelperOptions.loggerOptions.metaField = "metaField"; - return loggerTestHelper(testHelperOptions).then(function(result) { + it('should work with metaField option', function () { + testHelperOptions.loggerOptions.metaField = 'metaField'; + return loggerTestHelper(testHelperOptions).then(function (result) { result.log.meta.metaField.req.should.be.ok(); - result.log.meta.metaField.user.should.equal("john@doe.com"); - result.log.meta.metaField.role.should.equal("operator"); - result.log.meta.metaField.custom.should.equal( - "custom response runtime field" - ); + result.log.meta.metaField.user.should.equal('john@doe.com'); + result.log.meta.metaField.role.should.equal('operator'); + result.log.meta.metaField.custom.should.equal('custom response runtime field'); }); }); - it("should not contain dynamic meta data if dynamicMeta activated but meta false", function() { + it('should not contain dynamic meta data if dynamicMeta activated but meta false', function () { testHelperOptions.loggerOptions.meta = false; - return loggerTestHelper(testHelperOptions).then(function(result) { + return loggerTestHelper(testHelperOptions).then(function (result) { should.not.exist(result.log.meta.req); should.not.exist(result.log.meta.user); should.not.exist(result.log.meta.role); @@ -1490,55 +1445,55 @@ describe("express-winston", function() { }); }); - it("should throw an error if dynamicMeta is not a function", function() { - var loggerFn = expressWinston.logger.bind(expressWinston, { - dynamicMeta: 12 - }); + it('should throw an error if dynamicMeta is not a function', function () { + var loggerFn = expressWinston.logger.bind(expressWinston, {dynamicMeta: 12}); loggerFn.should.throw(); }); }); }); - describe(".requestWhitelist", function() { - it("should be an array with all the properties whitelisted in the req object", function() { + describe('.requestWhitelist', function () { + it('should be an array with all the properties whitelisted in the req object', function () { expressWinston.requestWhitelist.should.be.an.Array(); }); }); - describe(".bodyWhitelist", function() { - it("should be an array with all the properties whitelisted in the body object", function() { + describe('.bodyWhitelist', function () { + it('should be an array with all the properties whitelisted in the body object', function () { expressWinston.bodyWhitelist.should.be.an.Array(); }); }); - describe(".bodyBlacklist", function() {}); + describe('.bodyBlacklist', function () { + + }); - describe(".responseWhitelist", function() { - it("should be an array with all the properties whitelisted in the res object", function() { + describe('.responseWhitelist', function () { + it('should be an array with all the properties whitelisted in the res object', function () { expressWinston.responseWhitelist.should.be.an.Array(); }); }); - describe(".defaultRequestFilter", function() { - it("should be a function", function() { + describe('.defaultRequestFilter', function () { + it('should be a function', function () { expressWinston.defaultRequestFilter.should.be.a.Function(); }); }); - describe(".defaultResponseFilter", function() { - it("should be a function", function() { + describe('.defaultResponseFilter', function () { + it('should be a function', function () { expressWinston.defaultResponseFilter.should.be.a.Function(); }); }); - describe(".defaultSkip", function() { - it("should be a function", function() { + describe('.defaultSkip', function () { + it('should be a function', function () { expressWinston.defaultSkip.should.be.a.Function(); }); }); - describe(".ignoredRoutes", function() { - it("should be an array for all the ignored routes", function() { + describe('.ignoredRoutes', function () { + it('should be an array for all the ignored routes', function () { expressWinston.ignoredRoutes.should.be.an.Array(); }); }); From 62b69b6f72c6bc032a420308dfa7bd982a6c2747 Mon Sep 17 00:00:00 2001 From: Jean-Francois Lavoie Date: Thu, 11 Apr 2019 16:06:48 -0400 Subject: [PATCH 3/3] fix white space issue --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index d52834f..2313a56 100644 --- a/index.js +++ b/index.js @@ -198,7 +198,7 @@ function loggerFactory(options) { transports: options.transports, format: options.format }); - return function() { return localLogger;}; + return function() { return localLogger; }; } //