const fs = require('fs');
const Dingus = require('../../lib/dingus');
-const { DingusError } = require('../../lib/errors');
+const { DingusError, RouterNoMethodError } = require('../../lib/errors');
const Enum = require('../../lib/enum');
const noExpectedException = 'did not get expected exception';
+const _nop = () => undefined;
+const _logFn = (process.env['VERBOSE_TESTS'] && console.log) || _nop;
+const noLogger = {
+ debug: _logFn,
+ error: _logFn,
+};
+sinon.spy(noLogger, 'debug');
+sinon.spy(noLogger, 'error');
+
describe('Dingus', function () {
let dingus;
beforeEach(function () {
- dingus = new Dingus();
+ dingus = new Dingus(noLogger, {});
});
afterEach(function () {
sinon.restore();
describe('constructor', function () {
it('covers', function () {
- const d = new Dingus({}, {});
+ const d = new Dingus();
assert(d);
});
}); // constructor
});
it('returns normal path', function () {
const p = '////a///b/./bar/..///c';
- const expected = '/a/b/c'
+ const expected = '/a/b/c';
const r = dingus._normalizePath(p);
assert.strictEqual(r, expected);
});
const expected = {
clientAddress: '',
clientProtocol: 'http',
- }
+ };
dingus.clientAddressContext(req, res, ctx);
assert.deepStrictEqual(ctx, expected);
assert(!req.getHeader.called);
const expected = {
clientAddress: '::1',
clientProtocol: 'https',
- }
+ };
req.connection.remoteAddress = '::1';
req.connection.encrypted = true;
dingus.clientAddressContext(req, res, ctx);
});
}); // clientAddressContext
+ describe('ingestCookie', function () {
+ let req, res, ctx;
+ beforeEach(function () {
+ req = {
+ getHeader: sinon.stub(),
+ };
+ ctx = {};
+ });
+ it('covers no header', function () {
+ const expected = {};
+ Dingus.ingestCookie(req, res, ctx);
+ assert.deepStrictEqual(ctx.cookie, expected);
+ });
+ it('covers non variable', function () {
+ req.getHeader.returns('foo');
+ const expected = {
+ foo: null,
+ };
+ Dingus.ingestCookie(req, res, ctx);
+ assert.deepStrictEqual(ctx.cookie, expected);
+ });
+ it('parses cookies', function () {
+ req.getHeader.returns('foo=bar; baz="quux"');
+ const expected = {
+ foo: 'bar',
+ baz: 'quux',
+ };
+ Dingus.ingestCookie(req, res, ctx);
+ assert.deepStrictEqual(ctx.cookie, expected);
+ });
+ it('parses nulls', function () {
+ req.getHeader.returns('foo=; bar=');
+ const expected = {
+ foo: '',
+ bar: '',
+ };
+ Dingus.ingestCookie(req, res, ctx);
+ assert.deepStrictEqual(ctx.cookie, expected);
+ });
+ it('parses non-uri-encoded', function () {
+ req.getHeader.returns('foo%=%qux');
+ const expected = {
+ 'foo%': '%qux',
+ };
+ Dingus.ingestCookie(req, res, ctx);
+ assert.deepStrictEqual(ctx.cookie, expected);
+ });
+ it('covers nameless cookie', function () {
+ req.getHeader.returns('=bar');
+ const expected = {
+ };
+ Dingus.ingestCookie(req, res, ctx);
+ assert.deepStrictEqual(ctx.cookie, expected);
+
+ });
+ it('covers duplicate cookie', function () {
+ req.getHeader.returns('foo=bar; foo="quux"');
+ const expected = {
+ foo: 'bar',
+ };
+ Dingus.ingestCookie(req, res, ctx);
+ assert.deepStrictEqual(ctx.cookie, expected);
+ });
+ }); // ingestCookie
+
describe('getRequestContentType', function () {
let req;
beforeEach(function () {
sinon.spy(dingus, 'handlerNotFound');
sinon.spy(dingus, 'handlerBadRequest');
sinon.spy(dingus, 'handlerInternalServerError');
+ sinon.spy(Dingus, 'setHeadHandler');
stubHandler = sinon.stub();
});
afterEach(function () {
assert.strictEqual(stubHandler.args[0][3], 'foo');
assert.strictEqual(stubHandler.args[0][4], 'bar');
});
+ describe('intrinsic HEAD handling', function () {
+ it('covers no intrinsic HEAD handling', async function () {
+ dingus.intrinsicHeadMethod = false;
+ dingus.on('GET', '/', stubHandler);
+ req.method = 'HEAD';
+ await dingus.dispatch(req, res, ctx);
+ assert(!stubHandler.called);
+ assert(dingus.handlerMethodNotAllowed.called);
+ });
+ it('calls HEAD setup and GET handler', async function () {
+ dingus.on('GET', '/', stubHandler);
+ req.method = 'HEAD';
+ await dingus.dispatch(req, res, ctx);
+ assert(Dingus.setHeadHandler.called);
+ assert(stubHandler.called);
+ });
+ it('covers no GET handler', async function () {
+ dingus.on('POST', '/', stubHandler);
+ req.method = 'HEAD';
+ await dingus.dispatch(req, res, ctx);
+ assert(!stubHandler.called);
+ assert(dingus.handlerMethodNotAllowed.called);
+ });
+ it('covers unexpected router error', async function () {
+ sinon.stub(dingus.router, 'lookup')
+ .onFirstCall().throws(new RouterNoMethodError())
+ .onSecondCall().throws(new DingusError())
+ ;
+ dingus.on('GET', '/', stubHandler);
+ req.method = 'HEAD';
+ await dingus.dispatch(req, res, ctx);
+ assert(dingus.handlerInternalServerError.called);
+ });
+ });
}); // dispatch
describe('parseBody', function () {
});
it('parses json', function () {
const src = { foo: 'bar' };
- ctx.rawBody = JSON.stringify(src);
- dingus.parseBody(Enum.ContentType.ApplicationJson, ctx);
+ const rawBody = JSON.stringify(src);
+ dingus.parseBody(Enum.ContentType.ApplicationJson, ctx, rawBody);
assert.deepStrictEqual(ctx.parsedBody, src);
});
it('handles unparsable json', function () {
- ctx.rawBody = 'not json';
+ const rawBody = 'not json';
try {
- dingus.parseBody(Enum.ContentType.ApplicationJson, ctx);
+ dingus.parseBody(Enum.ContentType.ApplicationJson, ctx, rawBody);
assert.fail(noExpectedException);
} catch (e) {
assert.strictEqual(e.statusCode, 400);
const expected = Object.assign(Object.create(null), {
foo: 'bar',
});
- ctx.rawBody = 'foo=bar';
- dingus.parseBody('application/x-www-form-urlencoded', ctx);
+ const rawBody = 'foo=bar';
+ dingus.parseBody('application/x-www-form-urlencoded', ctx, rawBody);
assert.deepStrictEqual(ctx.parsedBody, expected);
});
const req = {};
const res = {};
const ctx = {};
- sinon.stub(dingus, 'bodyData').resolves('{"foo":"bar"}')
+ sinon.stub(dingus, 'bodyData').resolves('{"foo":"bar"}');
sinon.stub(Dingus, 'getRequestContentType').returns(Enum.ContentType.ApplicationJson);
await dingus.ingestBody(req, res, ctx);
assert.deepStrictEqual(ctx.parsedBody, { foo: 'bar' });
});
it('covers no meta file', async function() {
dingus._readFileInfo.resolves([null, null]);
- await dingus._serveFileMetaHeaders(res, directory, fileName);
+ const result = await dingus._serveFileMetaHeaders(res, directory, fileName);
assert(!res.setHeader.called);
+ assert.strictEqual(result, false);
});
it('adds extra headers', async function () {
dingus._readFileInfo.resolves([{}, Buffer.from(`Link: <https://example.com/>; rel="relation"
the fold
Content-Type: image/sgi
`)]);
- await dingus._serveFileMetaHeaders(res, directory, fileName);
+ const result = await dingus._serveFileMetaHeaders(res, directory, fileName);
assert(res.setHeader.called);
+ assert.strictEqual(result, true);
});
}); // _serveFileMetaHeaders