import { Eltro as t, spy, assert} from 'eltro' import { Flaska } from '../flaska.mjs' import { fakeHttp, createReq, createRes } from './helper.mjs' const faker = fakeHttp() t.describe('#requestStart()', function() { t.test('calls on correct events on both req and res', function(cb) { const assertErrorOne = new Error('Erics Birth') const assertErrorTwo = new Error('Contactic Eric') const onReqError = spy() const onResError = spy() const onEnded = spy() const assertReq = createReq({ url: '', a: 1 }) const assertRes = createRes({ b: 2 }) let flaska = new Flaska({}, faker) flaska.onreqerror(onReqError) flaska.onreserror(onResError) flaska.requestEnded = onEnded flaska.requestEnd = function(err, ctx) { try { assert.ok(err) assert.strictEqual(assertReq.on.callCount, 2) assert.strictEqual(assertRes.on.callCount, 2) assert.strictEqual(assertRes.on.firstCall[0], 'error') assert.strictEqual(typeof(assertRes.on.firstCall[1]), 'function') assertRes.on.firstCall[1](assertErrorTwo, ctx) assert.strictEqual(onResError.callCount, 1) assert.strictEqual(onResError.firstCall[0], assertErrorTwo) assert.strictEqual(onResError.firstCall[1], ctx) assert.strictEqual(assertRes.on.secondCall[0], 'finish') assert.strictEqual(typeof(assertRes.on.secondCall[1]), 'function') assert.strictEqual(onEnded.callCount, 0) assertRes.on.secondCall[1]() assert.strictEqual(onEnded.callCount, 1) assert.strictEqual(onEnded.firstCall[0], ctx) assert.strictEqual(assertReq.on.firstCall[0], 'error') assert.strictEqual(typeof(assertReq.on.firstCall[1]), 'function') assertReq.on.firstCall[1](assertErrorOne, ctx) assert.strictEqual(onReqError.callCount, 1) assert.strictEqual(onReqError.firstCall[0], assertErrorOne) assert.strictEqual(onReqError.firstCall[1], ctx) assert.strictEqual(assertReq.on.secondCall[0], 'aborted') assert.strictEqual(typeof(assertReq.on.secondCall[1]), 'function') assert.notStrictEqual(ctx.aborted, false) assertReq.on.secondCall[1]() assert.strictEqual(ctx.aborted, true) // Test abort and close cb() } catch (err) { cb(err) } } flaska._beforeCompiled = function(ctx) { throw new Error() } flaska.requestStart(assertReq, assertRes) }) t.test('calls beforeCompiled correctly', function(cb) { const assertError = new Error('test') const assertReq = createReq({ url: '', a: 1 }) const assertRes = createRes({ b: 2 }) let flaska = new Flaska({}, faker) flaska.requestEnd = function(err, ctx) { if (err && err !== assertError) return cb(err) try { assert.ok(err) assert.strictEqual(err, assertError) assert.deepStrictEqual(ctx.state, {}) assert.strictEqual(ctx.req, assertReq) assert.strictEqual(ctx.res, assertRes) cb() } catch (err) { cb(err) } } flaska._beforeCompiled = function(ctx) { assert.strictEqual(ctx.req, assertReq) assert.strictEqual(ctx.res, assertRes) throw assertError } flaska.requestStart(assertReq, assertRes) }) t.test('calls beforeAsyncCompiled correctly if defined', function(cb) { const assertError = new Error('test') const assertReq = createReq({ url: '', a: 1 }) const assertRes = createRes({ b: 2 }) let flaska = new Flaska({}, faker) flaska.compile() flaska._beforeAsyncCompiled = function(ctx) { assert.strictEqual(ctx.req, assertReq) assert.strictEqual(ctx.res, assertRes) return Promise.resolve().then(function() { return Promise.reject(assertError) }) } flaska.requestEnd = function(err, ctx) { if (err && err !== assertError) return cb(err) try { assert.ok(err) assert.strictEqual(err, assertError) assert.deepStrictEqual(ctx.state, {}) assert.strictEqual(ctx.req, assertReq) assert.strictEqual(ctx.res, assertRes) cb() } catch (err) { cb(err) } } flaska.requestStart(assertReq, assertRes) }) t.test('calls correct router with correct url and context', function(cb) { const assertError = new Error('test') const assertMethod = 'test' const assertPath = '/test/me' const assertSearch = '?asdf=test' const assertLog = { info: function() {}, error: function() {} } let flaska = new Flaska({ log: assertLog }, faker) assert.strictEqual(flaska.log, assertLog) flaska.compile() flaska.routers.test = { match: function(path) { assert.strictEqual(path, assertPath) throw assertError } } flaska.requestEnd = function(err, ctx) { if (err && err !== assertError) return cb(err) try { assert.ok(err) assert.strictEqual(err, assertError) assert.strictEqual(ctx.url, assertPath) assert.strictEqual(ctx.search, assertSearch) assert.strictEqual(ctx.method, assertMethod) assert.strictEqual(ctx.status, 200) assert.strictEqual(ctx.body, null) assert.strictEqual(ctx.type, null) assert.strictEqual(ctx.length, null) assert.strictEqual(ctx.log, assertLog) assert.ok(ctx.query) assert.ok(ctx.query.get) assert.ok(ctx.query.set) assert.ok(ctx.query.delete) cb() } catch (err) { cb(err) } } flaska.requestStart(createReq({ url: assertPath + assertSearch, method: assertMethod, }), createRes()) }) t.test('calls correct router with correct url and context if beforeAsync', function(cb) { const assertError = new Error('test') const assertMethod = 'test' const assertPath = '/test/me' const assertSearch = '?asdf=test' let flaska = new Flaska({}, faker) flaska.compile() flaska._beforeAsyncCompiled = function() { return Promise.resolve() } flaska.routers.test = { match: function(path) { assert.strictEqual(path, assertPath) throw assertError } } flaska.requestEnd = function(err, ctx) { if (err && err !== assertError) return cb(err) try { assert.ok(err) assert.strictEqual(err, assertError) assert.strictEqual(ctx.url, assertPath) assert.strictEqual(ctx.search, assertSearch) assert.strictEqual(ctx.method, assertMethod) cb() } catch (err) { cb(err) } } flaska.requestStart(createReq({ url: assertPath + assertSearch, method: assertMethod, }), createRes()) }) t.test('calls handleMiddleware correctly', function(cb) { const assertError = new Error('test') const assertMiddles = [1, 2] const assertParams = { a: 1, b: 2 } let checkMiddleCtx = null let flaska = new Flaska({}, faker) flaska.compile() flaska.routers.GET.match = function() { return { handler: function() {}, middlewares: assertMiddles, params: assertParams, } } flaska.handleMiddleware = function(ctx, middles, index) { assert.strictEqual(index, 0) assert.strictEqual(middles, assertMiddles) checkMiddleCtx = ctx throw assertError } flaska.requestEnd = function(err, ctx) { if (err && err !== assertError) return cb(err) try { assert.ok(err) assert.ok(ctx) assert.strictEqual(err, assertError) assert.strictEqual(ctx, checkMiddleCtx) assert.strictEqual(ctx.params, assertParams) cb() } catch (err) { cb(err) } } flaska.requestStart(createReq({ url: '', method: 'GET', }), createRes({})) }) t.test('calls route handler correctly', function(cb) { const assertError = new Error('test') let checkHandlerCtx = null let handler = function(ctx) { assert.strictEqual(ctx.params.id, 'test') checkHandlerCtx = ctx throw assertError } let flaska = new Flaska({}, faker) flaska.get('/:id', handler) flaska.compile() flaska.requestEnd = function(err, ctx) { if (err && err !== assertError) return cb(err) try { assert.ok(err) assert.ok(ctx) assert.strictEqual(err, assertError) assert.strictEqual(ctx, checkHandlerCtx) cb() } catch (err) { cb(err) } } flaska.requestStart(createReq({ url: '/test', method: 'GET', }), createRes()) }) t.test('calls 404 if route handler is not found', function(cb) { const on404Error = spy() let handler = function() { throw new Error('should not be called') } let flaska = new Flaska({}, faker) flaska.on404(on404Error) flaska.get('/test', function() { throw new Error('should not be called') }) flaska.compile() flaska.requestEnd = function(err, ctx) { if (err) return cb(err) try { assert.ok(ctx) assert.strictEqual(on404Error.callCount, 1) assert.strictEqual(on404Error.firstCall[0], ctx) cb() } catch (err) { cb(err) } } flaska.requestStart(createReq({ url: '/nope', method: 'GET', }), createRes()) }) t.test('calls 404 if route handler is not found and supports promise', function(cb) { let checkCtx = null const assertError = new Error('should be seen') const on404Error = function(ctx) { checkCtx = ctx return Promise.resolve().then(function() { return Promise.reject(assertError) }) } let flaska = new Flaska({}, faker) flaska.on404(on404Error) flaska.get('/test', function() { throw new Error('should not be called') }) flaska.compile() flaska.requestEnd = function(err, ctx) { if (err && err !== assertError) return cb(err) try { assert.ok(err) assert.ok(ctx) assert.strictEqual(ctx, checkCtx) assert.strictEqual(err, assertError) cb() } catch (err) { cb(err) } } flaska.requestStart(createReq({ url: '/nope', method: 'GET', }), createRes()) }) t.test(`should handle unexpected errors in on404 correctly`, function(cb) { const assertError = new Error('should be seen') let checkCtx = null let flaska = new Flaska({}, faker) flaska.on404(function(ctx) { checkCtx = ctx throw assertError }) flaska.get('/test', function() { throw new Error('should not be called') }) flaska.compile() flaska.requestEnd = function(err, ctx) { if (err && err !== assertError) return cb(err) try { assert.ok(err) assert.ok(ctx) assert.strictEqual(ctx, checkCtx) assert.strictEqual(err, assertError) cb() } catch (err) { cb(err) } } flaska.requestStart(createReq({ url: '/nope', method: 'GET', }), createRes()) }) t.test(`should handle unexpected errors in middleware correctly`, function(cb) { const assertError = new Error('should be seen') let checkCtx = null let flaska = new Flaska({}, faker) let middles = [function(ctx) { checkCtx = ctx throw assertError }] flaska.get('/test', middles, function() { throw new Error('should not be called') }) flaska.compile() flaska.requestEnd = function(err, ctx) { if (err && err !== assertError) return cb(err) try { assert.ok(err) assert.ok(ctx) assert.strictEqual(ctx, checkCtx) assert.strictEqual(err, assertError) cb() } catch (err) { cb(err) } } flaska.requestStart(createReq({ url: '/test', method: 'GET', }), createRes()) }) t.test('should work with synchronous handler', function(cb) { const assertBody = { a: 1 } let handler = function(ctx) { assert.strictEqual(ctx.params.path, 'test/something/here') ctx.body = assertBody } let flaska = new Flaska({}, faker) flaska.get('/::path', handler) flaska.compile() flaska.handleMiddleware = function() { throw new Error('should not be called') } flaska.requestEnd = function(err, ctx) { try { assert.notOk(err) assert.ok(ctx) assert.strictEqual(ctx.body, assertBody) cb() } catch (err) { cb(err) } } flaska.requestStart(createReq({ url: '/test/something/here', method: 'GET', }), createRes()) }) t.test('calls handleMiddleware correctly if is promise', function(cb) { const assertError = new Error('test') const assertMiddles = [1] let flaska = new Flaska({}, faker) flaska.compile() flaska.routers.GET.match = function() { return { handler: function() {}, middlewares: assertMiddles, } } flaska.handleMiddleware = function() { return Promise.resolve().then(function() { return Promise.reject(assertError) }) } flaska.requestEnd = function(err, ctx) { if (err && err !== assertError) return cb(err) try { assert.ok(err) assert.ok(ctx) assert.strictEqual(err, assertError) cb() } catch (err) { cb(err) } } flaska.requestStart(createReq({ url: '', method: 'GET', }), createRes()) }) t.test('calls route handler correctly with promise middle', function(cb) { const assertError = new Error('test') let checkHandlerCtx = null let handler = function(ctx) { assert.strictEqual(ctx.params.id, 'test') checkHandlerCtx = ctx throw assertError } let flaska = new Flaska({}, faker) flaska.get('/:id', [function() { return Promise.resolve() }], handler) flaska.compile() flaska.requestEnd = function(err, ctx) { if (err && err !== assertError) return cb(err) try { assert.ok(err) assert.ok(ctx) assert.strictEqual(err, assertError) assert.strictEqual(ctx, checkHandlerCtx) cb() } catch (err) { cb(err) } } flaska.requestStart(createReq({ url: '/test', method: 'GET', }), createRes()) }) t.test('calls promise route handler correctly with promise middle', function(cb) { const assertError = new Error('test') let checkHandlerCtx = null let handler = function(ctx) { assert.strictEqual(ctx.params.id, 'test') checkHandlerCtx = ctx return Promise.resolve().then(function() { return Promise.reject(assertError) }) } let flaska = new Flaska({}, faker) flaska.get('/:id', [function() { return Promise.resolve() }], handler) flaska.compile() flaska.requestEnd = function(err, ctx) { if (err && err !== assertError) return cb(err) try { assert.ok(err) assert.ok(ctx) assert.strictEqual(err, assertError) assert.strictEqual(ctx, checkHandlerCtx) cb() } catch (err) { cb(err) } } flaska.requestStart(createReq({ url: '/test', method: 'GET', }), createRes()) }) t.test('should work with promise middle and promise handler correctly', function(cb) { const assertBody = { a: 1 } const assertState = { b: 2 } let middle = function(ctx) { return Promise.resolve().then(function() { ctx.state = assertState }) } let handler = function(ctx) { assert.strictEqual(ctx.params.path, 'test/something/here') assert.strictEqual(ctx.state, assertState) return Promise.resolve().then(function() { ctx.body = assertBody }) } let flaska = new Flaska({}, faker) flaska.get('/::path', [middle], handler) flaska.compile() flaska.requestEnd = function(err, ctx) { try { assert.notOk(err) assert.ok(ctx) assert.strictEqual(ctx.body, assertBody) assert.strictEqual(ctx.state, assertState) cb() } catch (err) { cb(err) } } flaska.requestStart(createReq({ url: '/test/something/here', method: 'GET', }), createRes()) }) t.test('calls route handler correctly if promise', function(cb) { const assertError = new Error('test') let checkHandlerCtx = null let handler = function(ctx) { assert.strictEqual(ctx.params.id, 'test') checkHandlerCtx = ctx return Promise.resolve().then(function() { return Promise.reject(assertError) }) } let flaska = new Flaska({}, faker) flaska.get('/:id', handler) flaska.compile() flaska.requestEnd = function(err, ctx) { if (err && err !== assertError) return cb(err) try { assert.ok(err) assert.ok(ctx) assert.strictEqual(err, assertError) assert.strictEqual(ctx, checkHandlerCtx) cb() } catch (err) { cb(err) } } flaska.requestStart(createReq({ url: '/test', method: 'GET', }), createRes()) }) t.test('should work with promise handler', function(cb) { const assertBody = { a: 1 } let handler = function(ctx) { return Promise.resolve().then(function() { assert.strictEqual(ctx.params.path, 'test/something/here') ctx.body = assertBody }) } let flaska = new Flaska({}, faker) flaska.get('/::path', [], handler) flaska.compile() flaska.handleMiddleware = function() { throw new Error('should not be called') } flaska.requestEnd = function(err, ctx) { try { assert.notOk(err) assert.ok(ctx) assert.strictEqual(ctx.body, assertBody) cb() } catch (err) { cb(err) } } flaska.requestStart(createReq({ url: '/test/something/here', method: 'GET', }), createRes()) }) })