flaska/test/flaska.out.test.mjs
Jonatan Nilsson cfd56f83ae
All checks were successful
continuous-integration/appveyor/branch AppVeyor build succeeded
requestEnd: Now properly supports ctx.headers and properly sends all headers to res with status code using writeHead
FileResponse: Initial development started to serve files
2022-03-25 13:26:13 +00:00

364 lines
12 KiB
JavaScript

import { Eltro as t, spy, assert, stub} from 'eltro'
import { Flaska, FlaskaRouter } from '../flaska.mjs'
import { fakeHttp, createCtx } from './helper.mjs'
const fakerHttp = fakeHttp()
const fakeStream = { pipeline: spy() }
t.describe('#requestEnd()', function() {
t.test('calls onerror correctly on error', function(cb) {
const assertError = new Error('test')
const assertBody = { a: 1 }
const assertStatus = 501
// Calculated manually just in case
const assertBodyLength = 7
let onFinish = function(body) {
try {
assert.strictEqual(ctx.status, assertStatus)
assert.strictEqual(ctx.body, assertBody)
assert.strictEqual(ctx.res.statusCode, assertStatus)
assert.strictEqual(ctx.headers['Content-Type'], 'application/json; charset=utf-8')
assert.strictEqual(ctx.headers['Content-Length'], assertBodyLength)
assert.ok(body)
assert.strictEqual(body, '{"a":1}')
assert.ok(ctx.res.writeHead.called)
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
cb()
} catch (err) { cb(err) }
}
const ctx = createCtx({}, onFinish)
let flaska = new Flaska({}, fakerHttp, fakeStream)
flaska.onerror(function(err, inctx) {
assert.strictEqual(err, assertError)
assert.strictEqual(inctx, ctx)
inctx.status = assertStatus
inctx.body = assertBody
})
flaska.requestEnd(assertError, ctx)
})
t.test('calls backup onerror correctly if error throws', function(cb) {
const assertErrorNotSeen = new Error('should not be seen')
const assertError = new Error('test')
let onFinish = function(body) {
try {
assert.strictEqual(ctx.status, 500)
assert.strictEqual(ctx.body.status, 500)
assert.strictEqual(ctx.body.message, 'Internal Server Error')
cb()
} catch (err) { cb(err) }
}
const ctx = createCtx({}, onFinish)
let flaska = new Flaska({}, fakerHttp, fakeStream)
flaska.onerror(function() {
throw assertError
})
flaska.requestEnd(assertErrorNotSeen, ctx)
})
t.test('call res and end correctly when dealing with objects', function(cb) {
const assertStatus = 202
// Calculated manually just in case
const assertBodyLength = 7
const assertBody = { a: 1 }
let onFinish = function(body) {
try {
assert.strictEqual(ctx.status, assertStatus)
assert.strictEqual(ctx.body, assertBody)
assert.strictEqual(ctx.res.statusCode, assertStatus)
assert.strictEqual(ctx.headers['Content-Type'], 'application/json; charset=utf-8')
assert.strictEqual(ctx.headers['Content-Length'], assertBodyLength)
assert.ok(body)
assert.strictEqual(body, '{"a":1}')
assert.ok(ctx.res.writeHead.called)
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
cb()
} catch (err) { cb(err) }
}
const ctx = createCtx({
status: assertStatus,
}, onFinish)
ctx.body = assertBody
let flaska = new Flaska({}, fakerHttp, fakeStream)
flaska.requestEnd(null, ctx)
})
t.test('call res and end correctly when dealing with strings', function(cb) {
const assertStatus = 206
// Calculated manually just in case
const assertBodyLength = 4
const assertBody = 'eða'
let onFinish = function(body) {
try {
assert.strictEqual(ctx.status, assertStatus)
assert.strictEqual(ctx.body, assertBody)
assert.strictEqual(ctx.res.statusCode, assertStatus)
assert.strictEqual(ctx.headers['Content-Type'], 'text/plain; charset=utf-8')
assert.strictEqual(ctx.headers['Content-Length'], assertBodyLength)
assert.ok(body)
assert.strictEqual(body, assertBody)
assert.ok(ctx.res.writeHead.called)
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
cb()
} catch (err) { cb(err) }
}
const ctx = createCtx({
status: assertStatus,
}, onFinish)
ctx.body = assertBody
let flaska = new Flaska({}, fakerHttp, fakeStream)
flaska.requestEnd(null, ctx)
})
t.test('call res and end correctly when dealing with numbers', function(cb) {
const assertStatus = 211
// Calculated manually just in case
const assertBodyLength = 7
const assertBody = 4214124
let onFinish = function(body) {
try {
assert.strictEqual(ctx.status, assertStatus)
assert.strictEqual(ctx.body, assertBody)
assert.strictEqual(ctx.res.statusCode, assertStatus)
assert.strictEqual(ctx.headers['Content-Type'], 'text/plain; charset=utf-8')
assert.strictEqual(ctx.headers['Content-Length'], assertBodyLength)
assert.ok(body)
assert.strictEqual(body, assertBody.toString())
assert.ok(ctx.res.writeHead.called)
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
cb()
} catch (err) { cb(err) }
}
const ctx = createCtx({
status: assertStatus,
}, onFinish)
ctx.body = assertBody
let flaska = new Flaska({}, fakerHttp, fakeStream)
flaska.requestEnd(null, ctx)
})
t.test('call res and end correctly when dealing with custom type', function(cb) {
const assertStatus = 209
const assertBody = 'test'
const assertType = 'something/else'
let onFinish = function(body) {
try {
assert.strictEqual(ctx.status, assertStatus)
assert.strictEqual(ctx.res.statusCode, assertStatus)
assert.strictEqual(ctx.headers['Content-Type'], assertType)
assert.strictEqual(body, assertBody)
assert.ok(ctx.res.writeHead.called)
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
cb()
} catch (err) { cb(err) }
}
const ctx = createCtx({
status: assertStatus,
body: assertBody,
}, onFinish)
ctx.type = assertType
let flaska = new Flaska({}, fakerHttp, fakeStream)
flaska.requestEnd(null, ctx)
})
t.test('call pipeline correctly when dealing with pipe', function(cb) {
const assertStatus = 211
const assertType = 'herp/derp'
const assertBody = { pipe: function() {} }
let onFinish = function(source, target, callback) {
try {
assert.strictEqual(ctx.status, assertStatus)
assert.strictEqual(ctx.res.statusCode, assertStatus)
assert.strictEqual(ctx.headers['Content-Type'], assertType)
assert.strictEqual(source, assertBody)
assert.strictEqual(target, ctx.res)
assert.strictEqual(typeof(callback), 'function')
assert.ok(ctx.res.writeHead.called)
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
cb()
} catch (err) { cb(err) }
}
const ctx = createCtx({
status: assertStatus,
})
fakeStream.pipeline = onFinish
ctx.body = assertBody
ctx.type = assertType
let flaska = new Flaska({}, fakerHttp, fakeStream)
flaska.requestEnd(null, ctx)
})
t.test('call pipe should have default type', function(cb) {
let onFinish = function(source, target) {
try {
assert.strictEqual(ctx.res.statusCode, 200)
assert.strictEqual(ctx.headers['Content-Type'], 'application/octet-stream')
assert.strictEqual(source, ctx.body)
assert.strictEqual(target, ctx.res)
assert.ok(ctx.res.writeHead.called)
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
cb()
} catch (err) { cb(err) }
}
const ctx = createCtx({})
ctx.body = { pipe: function() {} }
fakeStream.pipeline = onFinish
let flaska = new Flaska({}, fakerHttp, fakeStream)
flaska.requestEnd(null, ctx)
})
let tests = [
['png', 'image/png'],
['jpg', 'image/jpeg'],
['bmp', 'image/bmp'],
['js', 'text/javascript'],
]
tests.forEach(function(test) {
t.test(`call pipe with file extension ${test[0]} should mimetype ${test[1]}`, function(cb) {
let onFinish = function(source, target) {
try {
assert.strictEqual(ctx.res.statusCode, 200)
assert.strictEqual(ctx.headers['Content-Type'], test[1])
assert.strictEqual(source, ctx.body)
assert.strictEqual(target, ctx.res)
assert.ok(ctx.res.writeHead.called)
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
cb()
} catch (err) { cb(err) }
}
const ctx = createCtx({})
ctx.body = { pipe: function() {}, path: './bla/test/temp.' + test[0] }
fakeStream.pipeline = onFinish
let flaska = new Flaska({}, fakerHttp, fakeStream)
flaska.requestEnd(null, ctx)
})
})
t.test('should return immediately if req is finished', function() {
let onFinish = function() {
throw new Error('should not be called')
}
const ctx = createCtx({ }, onFinish)
ctx.res.writableEnded = true
let flaska = new Flaska({}, fakerHttp, fakeStream)
flaska.requestEnd(null, ctx)
})
const emptyStatuses = [204, 205, 304]
emptyStatuses.forEach(function(status) {
t.test('call res and end correctly when dealing with status ' + status, function(cb) {
const assertStatus = status
const assertNotBody = 'test'
const assertNotType = 'something/else'
let onFinish = function(body) {
try {
assert.strictEqual(ctx.status, assertStatus)
assert.strictEqual(ctx.res.statusCode, assertStatus)
assert.strictEqual(ctx.res.setHeader.callCount, 0)
assert.ok(ctx.res.writeHead.called)
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
assert.notOk(body)
cb()
} catch (err) { cb(err) }
}
const ctx = createCtx({
status: assertStatus,
body: assertNotBody,
}, onFinish)
ctx.type = assertNotType
let flaska = new Flaska({}, fakerHttp, fakeStream)
flaska.requestEnd(null, ctx)
})
})
})
t.describe('#requestEnded()', function() {
t.test('calls destroy if body is pipe and is not closed', function() {
const ctx = createCtx({
body: {
pipe: {},
closed: false,
destroy: spy(),
},
})
let flaska = new Flaska({}, fakerHttp)
flaska._afterCompiled = function() {}
flaska.requestEnded(ctx)
assert.ok(ctx.body.destroy.called)
})
t.test('not call destroy if body is pipe but is closed', function() {
const ctx = createCtx({
body: {
pipe: {},
closed: true,
destroy: spy(),
}
})
let flaska = new Flaska({}, fakerHttp)
flaska._afterCompiled = function() {}
flaska.requestEnded(ctx)
assert.notOk(ctx.body.destroy.called)
})
t.test('calls afterCompiled correctly', function() {
const assertError = new Error('test')
const assertCtx = createCtx()
let flaska = new Flaska({}, fakerHttp)
flaska._afterCompiled = function(ctx) {
assert.strictEqual(ctx, assertCtx)
throw assertError
}
assert.throws(function() {
flaska.requestEnded(assertCtx)
}, /test/)
})
t.test('calls afterAsyncCompiled correctly if defined', async function() {
const assertError = new Error('test')
const assertCtx = createCtx()
let flaska = new Flaska({}, fakerHttp)
flaska.compile()
flaska._afterAsyncCompiled = function(ctx) {
assert.strictEqual(ctx, assertCtx)
return Promise.resolve().then(function() { return Promise.reject(assertError) })
}
let err = await assert.isRejected(flaska.requestEnded(assertCtx))
assert.strictEqual(err, assertError)
})
})