Initial commit
[squeep-logger-json-console] / test / lib / logger.js
diff --git a/test/lib/logger.js b/test/lib/logger.js
new file mode 100644 (file)
index 0000000..8c91b54
--- /dev/null
@@ -0,0 +1,127 @@
+/* eslint-env mocha */
+'use strict';
+
+const assert = require('assert');
+const sinon = require('sinon'); // eslint-disable-line node/no-unpublished-require
+const Logger = require('../../lib/logger');
+const http = require('http');
+
+describe('Logger', function () {
+  let config, logger, scope, message;
+
+  beforeEach(function () {
+    config = {
+      nodeId: '3c100e84-9a7f-11ec-9b4e-0025905f714a',
+      logger: {},
+    };
+    logger = new Logger(config);
+    Object.keys(Logger.nullLogger).forEach((level) => sinon.stub(logger.backend, level));
+    scope = 'testScope';
+    message = 'message';
+  });
+  this.afterEach(function () {
+    sinon.restore();
+  });
+
+  it('logs a message', function () {
+    logger.info(scope, message, { baz: 'quux' }, { foo: 1 }, 'more other');
+    assert(logger.backend.info.called);
+    assert(logger.backend.info.args[0][0].includes(message));
+  });
+
+  it('stubs missing levels', function () {
+    logger = new Logger(config);
+    assert.strictEqual(typeof logger.info, 'function');
+  });
+
+  it('logs BigInts', function () {
+    logger.info(scope, message, { aBigInteger: BigInt(2) });
+    assert(logger.backend.info.called);
+    assert(logger.backend.info.args[0][0].includes('"2"'));
+  });
+
+  it('logs Errors', function () {
+    logger.error(scope, message, { e: new Error('an error') });
+    assert(logger.backend.error.called);
+    assert(logger.backend.error.args[0][0].includes('an error'));
+  });
+
+  it('covers config settings', function () {
+    config.logger.ignoreBelowLevel = 'info';
+    logger = new Logger(config);
+    logger.debug(scope, message, {});
+    assert(logger.backend.debug.notCalled);
+  });
+
+  it('covers config error', function () {
+    config.logger.ignoreBelowLevel = 'not a level';
+    try {
+      logger = new Logger(config);
+      assert.fail('expected RangeError here');
+    } catch (e) {
+      assert(e instanceof RangeError);
+    }
+  });
+
+  it('covers empty fields', function () {
+    logger.info();
+    assert(logger.backend.info.called);
+    assert(logger.backend.info.args[0][0].includes('[unknown]'));
+  });
+
+  it('sanitizes', function () {
+    logger.dataSanitizers.push((data, sanitize = true) => {
+      let unclean = false;
+      const credentialLength = data && data.ctx && data.ctx.parsedBody && data.ctx.parsedBody.credential && data.ctx.parsedBody.credential.length;
+      if (credentialLength) {
+        unclean = true;
+      }
+      if (unclean && sanitize) {
+        data.ctx.parsedBody.credential = '*'.repeat(credentialLength);
+      }
+      return unclean;
+    });
+    logger.info(scope, message, {
+      ctx: {
+        parsedBody: {
+          credential: 'secret',
+        },
+      },
+    });
+    assert(logger.backend.info.called);
+    assert(logger.backend.info.args[0][0].includes('******'));
+  });
+
+  it('logs http client requests', function () {
+    const incomingMessage = new http.IncomingMessage();
+    incomingMessage.method = 'GET';
+    incomingMessage.url = new URL('http://example.com/');
+    logger.info(scope, message, { incomingMessage });
+    assert(logger.backend.info.called);
+    assert(logger.backend.info.args[0][0].includes('GET'));
+    assert(logger.backend.info.args[0][0].includes('http://example.com/'));
+  });
+
+  it('logs http client requests with scrubbed auth', function () {
+    const incomingMessage = Object.create(http.IncomingMessage.prototype);
+    incomingMessage.headers = {
+      authorization: 'Basic eW8=',
+    };
+    logger.info(scope, message, { incomingMessage });
+    assert(logger.backend.info.called);
+    assert(logger.backend.info.args[0][0].includes('****'));
+  });
+
+  it('logs http server responses', function () {
+    const serverResponse = Object.create(http.ServerResponse.prototype);
+    logger.info(scope, message, { serverResponse });
+    assert(logger.backend.info.args[0][0].includes('"statusCode":200'));
+  });
+
+  it('follows expected level ordering', function () {
+    const levels = Object.keys(Logger.nullLogger);
+    const expected = ['error', 'warn', 'info', 'log', 'debug'];
+    assert.deepStrictEqual(levels, expected);
+  });
+
+}); // Logger
\ No newline at end of file