Compare commits
17 Commits
Author | SHA1 | Date |
---|---|---|
Jonatan Nilsson | d5459cbcb9 | |
Jonatan Nilsson | 01a916eb2d | |
Jonatan Nilsson | 598548d97b | |
TheThing | 8a49e38285 | |
Jonatan Nilsson | 6d4d62e79c | |
Jonatan Nilsson | 7401b3bd2c | |
Jonatan Nilsson | 95e6c2dcac | |
Jonatan Nilsson | 74771d92cf | |
Jonatan Nilsson | 2b69013c04 | |
Jonatan Nilsson | 8a56969015 | |
Jonatan Nilsson | 5f916e97ea | |
Jonatan Nilsson | baf2d896c1 | |
Jonatan Nilsson | e9c600b869 | |
Jonatan Nilsson | 568c620782 | |
Jonatan Nilsson | 0c22fe9577 | |
Jonatan Nilsson | 3a0064c563 | |
Jonatan Nilsson | e7909cc84b |
20
README.md
20
README.md
|
@ -126,9 +126,9 @@ flaska.get('/api/test', function(ctx) {
|
|||
})
|
||||
```
|
||||
|
||||
### File stream/pipe
|
||||
### pipe
|
||||
|
||||
In cases where the response body is a pipe object (detected from the existance of `.pipe` property), flaska will automatically pipe the file for you. In addition, if a file stream is used, it will read the extension of the file being streamed and automatically fill in the mime-type for you in the `Content-Type` header.
|
||||
In cases where the response body is a pipe object (detected from the existance of `.pipe` property), flaska will automatically pipe it for you. In addition, if a file stream is used, it will read the extension of the file being streamed and automatically fill in the mime-type for you in the `Content-Type` header.
|
||||
|
||||
```
|
||||
flaska.get('/test.png', function(ctx) {
|
||||
|
@ -138,6 +138,22 @@ flaska.get('/test.png', function(ctx) {
|
|||
|
||||
Flaska will automatically close the file stream for you so you don't have to worry about that.
|
||||
|
||||
### FileResponse
|
||||
|
||||
Alternatively, if you want proper file support, I recommend using FileResponse object:
|
||||
|
||||
```
|
||||
import { FileResponse } from '../flaska.mjs'
|
||||
|
||||
flaska.get('/test.txt', function(ctx) {
|
||||
return fs.stat('./test/test.txt').then(function(stat) {
|
||||
ctx.body = new FileResponse('./test/test.txt', stat)
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
This performs a real file stream support, uses pipes and supports all the HTTP shenanigans when it comes to dealing with files, including sending proper etag header, supporting partial response and lots of other things. This is one of the few libraries that actually implements full HTTP partial and etag support in a proper way, almost all other have one or two quirks that don't follow the spec properly.
|
||||
|
||||
### String
|
||||
|
||||
In other instances, Flaska will `.toString()` the body and send it in response with the specified type or default to `text/plain` if unspecified.
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
import crypto from 'crypto'
|
||||
import Benchmark from 'benchmarkjs-pretty'
|
||||
|
||||
function TestGenerateRandomString() {
|
||||
|
||||
return new Benchmark.default('test different method to generate random string)')
|
||||
.add('crypto.randomBytes(16)', function() {
|
||||
for (let i = 0; i < 25; i++) {
|
||||
crypto.randomBytes(16).toString('base64')
|
||||
}
|
||||
})
|
||||
.add('crypto.randomBytes(32)', function() {
|
||||
for (let i = 0; i < 25; i++) {
|
||||
crypto.randomBytes(32).toString('base64')
|
||||
}
|
||||
})
|
||||
.add('random (11 characters long)', function() {
|
||||
for (let i = 0; i < 25; i++) {
|
||||
let out = Math.random().toString(36).substring(2, 14)
|
||||
}
|
||||
})
|
||||
.add('random (22 characters long)', function() {
|
||||
for (let i = 0; i < 25; i++) {
|
||||
let out = Math.random().toString(36).substring(2, 24)
|
||||
+ Math.random().toString(36).substring(2, 24)
|
||||
}
|
||||
})
|
||||
.add('random (44 characters long)', function() {
|
||||
for (let i = 0; i < 25; i++) {
|
||||
let out = Math.random().toString(36).substring(2, 24)
|
||||
+ Math.random().toString(36).substring(2, 24)
|
||||
+ Math.random().toString(36).substring(2, 24)
|
||||
+ Math.random().toString(36).substring(2, 24)
|
||||
}
|
||||
})
|
||||
.run()
|
||||
.then(function() {}, function(e) {
|
||||
console.error('error:', e)
|
||||
process.exit(1)
|
||||
})
|
||||
}
|
||||
|
||||
TestGenerateRandomString()
|
||||
.then(function() {
|
||||
process.exit(0)
|
||||
})
|
92
flaska.mjs
92
flaska.mjs
|
@ -139,6 +139,7 @@ export function CorsHandler(opts = {}) {
|
|||
exposeHeaders: opts.exposeHeaders || '',
|
||||
maxAge: opts.maxAge || '',
|
||||
}
|
||||
const allowAll = options.allowedOrigins.includes('*')
|
||||
|
||||
return function(ctx) {
|
||||
// Always add vary header on origin. Prevent caches from
|
||||
|
@ -154,7 +155,7 @@ export function CorsHandler(opts = {}) {
|
|||
// Check origin is specified. Nothing needs to be done if
|
||||
// there is no origin or it doesn't match
|
||||
let origin = ctx.req.headers['origin']
|
||||
if (!origin || !options.allowedOrigins.includes(origin)) {
|
||||
if (!origin || (!allowAll && !options.allowedOrigins.includes(origin))) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -237,7 +238,7 @@ export function FormidableHandler(formidable, org = {}) {
|
|||
|
||||
return new Promise(function(res, rej) {
|
||||
form.parse(ctx.req, function(err, fields, files) {
|
||||
if (err) return rej(err)
|
||||
if (err) return rej(new HttpError(400, err.message))
|
||||
|
||||
if (opts.parseFields) {
|
||||
Object.keys(fields).forEach(function(key) {
|
||||
|
@ -248,29 +249,45 @@ export function FormidableHandler(formidable, org = {}) {
|
|||
}
|
||||
|
||||
ctx.req.body = fields
|
||||
ctx.req.file = files?.file || null
|
||||
ctx.req.files = files
|
||||
ctx.req.file = null
|
||||
|
||||
if (!ctx.req.file) {
|
||||
|
||||
if (!ctx.req.files) {
|
||||
return res()
|
||||
}
|
||||
|
||||
let filename
|
||||
let target
|
||||
let keys = Object.keys(files).filter(key => Boolean(ctx.req.files[key]))
|
||||
|
||||
try {
|
||||
filename = opts.filename(ctx.req.file) || ctx.req.file.name
|
||||
target = path.join(opts.uploadDir, filename)
|
||||
} catch (err) {
|
||||
return rej(err)
|
||||
}
|
||||
|
||||
rename(ctx.req.file.path, target)
|
||||
.then(function() {
|
||||
ctx.req.file.path = target
|
||||
ctx.req.file.filename = filename
|
||||
})
|
||||
.then(res, rej)
|
||||
Promise.all(
|
||||
keys.map(key => {
|
||||
let filename
|
||||
let target
|
||||
|
||||
try {
|
||||
filename = opts.filename(ctx.req.files[key]) || ctx.req.files[key].name
|
||||
target = path.join(opts.uploadDir, filename)
|
||||
} catch (err) {
|
||||
return Promise.reject(err)
|
||||
}
|
||||
|
||||
return rename(ctx.req.files[key].path, target)
|
||||
.then(function() {
|
||||
if (!ctx.req.files[key].type || ctx.req.files[key].type === 'application/octet-stream') {
|
||||
let found = MimeTypeDb[path.extname(filename).slice(1)]
|
||||
ctx.req.files[key].type = found && found[0] || 'application/octet-stream'
|
||||
}
|
||||
ctx.req.files[key].path = target
|
||||
ctx.req.files[key].filename = filename
|
||||
})
|
||||
})
|
||||
)
|
||||
.then(() => {
|
||||
if (keys.length === 1 && keys[0] === 'file') {
|
||||
ctx.req.file = ctx.req.files.file
|
||||
}
|
||||
res()
|
||||
}, rej)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
@ -626,7 +643,7 @@ export class Flaska {
|
|||
defaultHeaders: opts.defaultHeaders || {
|
||||
'Server': 'Flaska',
|
||||
'X-Content-Type-Options': 'nosniff',
|
||||
'Content-Security-Policy': `default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * data: blob:; object-src 'none'; frame-ancestors 'none'`,
|
||||
'Content-Security-Policy': `default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * data: blob:; font-src 'self' data:; object-src 'none'; frame-ancestors 'none'`,
|
||||
'Cross-Origin-Opener-Policy': 'same-origin',
|
||||
'Cross-Origin-Resource-Policy': 'same-origin',
|
||||
'Cross-Origin-Embedder-Policy': 'require-corp',
|
||||
|
@ -644,6 +661,13 @@ export class Flaska {
|
|||
nonceCacheLength: opts.nonceCacheLength || 25
|
||||
}
|
||||
|
||||
if (opts.appendHeaders) {
|
||||
let appendKeys = Object.keys(opts.appendHeaders)
|
||||
for (let key of appendKeys) {
|
||||
options.defaultHeaders[key] = opts.appendHeaders[key]
|
||||
}
|
||||
}
|
||||
|
||||
if (!options.defaultHeaders && options.nonce.length) {
|
||||
// throw error
|
||||
}
|
||||
|
@ -966,7 +990,10 @@ ctx.state.nonce = nonce;
|
|||
|
||||
let length = 0
|
||||
|
||||
if (typeof(body) === 'object' && body) {
|
||||
if (body instanceof Buffer) {
|
||||
length = body.byteLength
|
||||
ctx.type = ctx.type || 'application/octet-stream'
|
||||
} else if (typeof(body) === 'object' && body) {
|
||||
body = JSON.stringify(body)
|
||||
length = Buffer.byteLength(body)
|
||||
ctx.type = 'application/json; charset=utf-8'
|
||||
|
@ -1035,6 +1062,22 @@ ctx.state.nonce = nonce;
|
|||
}
|
||||
}
|
||||
|
||||
create() {
|
||||
this.compile()
|
||||
this.server = this.http.createServer(this.requestStart.bind(this))
|
||||
|
||||
this.server.on('connection', function (socket) {
|
||||
// Set socket idle timeout in milliseconds
|
||||
socket.setTimeout(1000 * 60 * 5) // 5 minutes
|
||||
|
||||
// Wait for timeout event (socket will emit it when idle timeout elapses)
|
||||
socket.on('timeout', function () {
|
||||
// Call destroy again
|
||||
socket.destroy();
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
listen(port, orgIp, orgcb) {
|
||||
let ip = orgIp
|
||||
let cb = orgcb
|
||||
|
@ -1045,8 +1088,8 @@ ctx.state.nonce = nonce;
|
|||
if (typeof(port) !== 'number') {
|
||||
throw new Error('Flaska.listen() called with non-number in port')
|
||||
}
|
||||
this.compile()
|
||||
this.server = this.http.createServer(this.requestStart.bind(this))
|
||||
|
||||
this.create()
|
||||
|
||||
this.server.listen(port, ip, cb)
|
||||
}
|
||||
|
@ -1056,8 +1099,7 @@ ctx.state.nonce = nonce;
|
|||
return Promise.reject(new Error('Flaska.listen() called with non-number in port'))
|
||||
}
|
||||
|
||||
this.compile()
|
||||
this.server = this.http.createServer(this.requestStart.bind(this))
|
||||
this.create()
|
||||
|
||||
if (this.server.listenAsync && typeof(this.server.listenAsync) === 'function') {
|
||||
return this.server.listenAsync(port, ip)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "flaska",
|
||||
"version": "1.2.3",
|
||||
"version": "1.3.5",
|
||||
"description": "Flaska is a micro web-framework for node. It is designed to be fast, simple and lightweight, and is distributed as a single file module with no dependencies.",
|
||||
"main": "flaska.mjs",
|
||||
"scripts": {
|
||||
|
@ -39,7 +39,7 @@
|
|||
},
|
||||
"homepage": "https://git.nfp.is/TheThing/flaska/#readme",
|
||||
"devDependencies": {
|
||||
"eltro": "^1.2.3",
|
||||
"eltro": "^1.3.2",
|
||||
"formidable": "^1.2.2"
|
||||
},
|
||||
"files": [
|
||||
|
|
|
@ -126,34 +126,54 @@ const random = (length = 8) => {
|
|||
return str;
|
||||
}
|
||||
|
||||
Client.prototype.upload = function(url, file, method = 'POST', body = {}) {
|
||||
return fs.readFile(file).then(data => {
|
||||
const crlf = '\r\n'
|
||||
Client.prototype.upload = function(url, files, method = 'POST', body = {}, overrideType = null) {
|
||||
const boundary = `---------${random(32)}`
|
||||
const crlf = '\r\n'
|
||||
let upload = files
|
||||
|
||||
if (typeof(upload) === 'string') {
|
||||
upload = {
|
||||
file: files
|
||||
}
|
||||
}
|
||||
let keys = Object.keys(upload)
|
||||
let uploadBody = []
|
||||
|
||||
return Promise.all(keys.map(key => {
|
||||
let file = upload[key]
|
||||
return fs.readFile(file).then(data => {
|
||||
const filename = path.basename(file)
|
||||
const boundary = `---------${random(32)}`
|
||||
|
||||
const multipartBody = Buffer.concat([
|
||||
Buffer.from(
|
||||
`${crlf}--${boundary}${crlf}` +
|
||||
`Content-Disposition: form-data; name="file"; filename="${filename}"` + crlf + crlf
|
||||
),
|
||||
data,
|
||||
Buffer.concat(Object.keys(body).map(function(key) {
|
||||
return Buffer.from(''
|
||||
+ `${crlf}--${boundary}${crlf}`
|
||||
+ `Content-Disposition: form-data; name="${key}"` + crlf + crlf
|
||||
+ JSON.stringify(body[key])
|
||||
)
|
||||
})),
|
||||
Buffer.from(`${crlf}--${boundary}--`),
|
||||
])
|
||||
uploadBody.push(Buffer.from(
|
||||
`${crlf}--${boundary}${crlf}`
|
||||
+ `Content-Disposition: form-data; name="${key}"; filename="${filename}"`
|
||||
+ (overrideType ? crlf + `Content-Type: ${overrideType}`: '')
|
||||
+ crlf
|
||||
+ crlf
|
||||
))
|
||||
uploadBody.push(data)
|
||||
})
|
||||
}))
|
||||
.then(() => {
|
||||
uploadBody.push(
|
||||
Buffer.concat(Object.keys(body).map(function(key) {
|
||||
return Buffer.from(''
|
||||
+ `${crlf}--${boundary}${crlf}`
|
||||
+ `Content-Disposition: form-data; name="${key}"` + crlf + crlf
|
||||
+ JSON.stringify(body[key])
|
||||
)
|
||||
}))
|
||||
)
|
||||
uploadBody.push(Buffer.from(`${crlf}--${boundary}--`))
|
||||
|
||||
return this.customRequest(method, url, multipartBody, {
|
||||
timeout: 5000,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data; boundary=' + boundary,
|
||||
'Content-Length': multipartBody.length,
|
||||
},
|
||||
})
|
||||
let multipartBody = Buffer.concat(uploadBody)
|
||||
|
||||
return this.customRequest(method, url, multipartBody, {
|
||||
timeout: 5000,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data; boundary=' + boundary,
|
||||
'Content-Length': multipartBody.length,
|
||||
},
|
||||
})
|
||||
})
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ t.describe('#constructor', function() {
|
|||
|
||||
assert.strictEqual(ctx.headers['Server'], 'Flaska')
|
||||
assert.strictEqual(ctx.headers['X-Content-Type-Options'], 'nosniff')
|
||||
assert.strictEqual(ctx.headers['Content-Security-Policy'], `default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * data: blob:; object-src 'none'; frame-ancestors 'none'`)
|
||||
assert.strictEqual(ctx.headers['Content-Security-Policy'], `default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * data: blob:; font-src 'self' data:; object-src 'none'; frame-ancestors 'none'`)
|
||||
assert.strictEqual(ctx.headers['Cross-Origin-Opener-Policy'], 'same-origin')
|
||||
assert.strictEqual(ctx.headers['Cross-Origin-Resource-Policy'], 'same-origin')
|
||||
assert.strictEqual(ctx.headers['Cross-Origin-Embedder-Policy'], 'require-corp')
|
||||
|
@ -80,8 +80,7 @@ t.describe('#constructor', function() {
|
|||
flaska._before[0](ctx)
|
||||
|
||||
let keys = Object.keys(defaultHeaders)
|
||||
console.log(Object.keys(ctx.headers).sort())
|
||||
console.log(keys.sort())
|
||||
|
||||
assert.strictEqual(Object.keys(ctx.headers).length, keys.length + 1)
|
||||
for (let key of keys) {
|
||||
assert.strictEqual(ctx.headers[key], defaultHeaders[key])
|
||||
|
@ -90,6 +89,38 @@ t.describe('#constructor', function() {
|
|||
|
||||
assert.strictEqual(flaska._after.length, 0)
|
||||
})
|
||||
|
||||
t.test('should have before ready setting headers on context if appendHeaders is specified', function() {
|
||||
const appendHeaders = {
|
||||
'Server': 'nginx/1.16.1',
|
||||
'Herp': 'Derp',
|
||||
}
|
||||
let flaska = new Flaska({
|
||||
appendHeaders: appendHeaders,
|
||||
}, faker)
|
||||
assert.strictEqual(flaska._before.length, 1)
|
||||
|
||||
let ctx = {}
|
||||
|
||||
flaska._before[0](ctx)
|
||||
|
||||
assert.deepEqual(
|
||||
Object.keys(ctx.headers).sort(),
|
||||
['Server', 'Herp', 'X-Content-Type-Options','Content-Security-Policy','Cross-Origin-Opener-Policy','Cross-Origin-Resource-Policy','Cross-Origin-Embedder-Policy','Date'].sort()
|
||||
)
|
||||
|
||||
assert.notStrictEqual(ctx.headers['Server'], 'Flaska')
|
||||
assert.strictEqual(ctx.headers['Server'], appendHeaders.Server)
|
||||
assert.strictEqual(ctx.headers['Herp'], 'Derp')
|
||||
assert.strictEqual(ctx.headers['X-Content-Type-Options'], 'nosniff')
|
||||
assert.strictEqual(ctx.headers['Content-Security-Policy'], `default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * data: blob:; font-src 'self' data:; object-src 'none'; frame-ancestors 'none'`)
|
||||
assert.strictEqual(ctx.headers['Cross-Origin-Opener-Policy'], 'same-origin')
|
||||
assert.strictEqual(ctx.headers['Cross-Origin-Resource-Policy'], 'same-origin')
|
||||
assert.strictEqual(ctx.headers['Cross-Origin-Embedder-Policy'], 'require-corp')
|
||||
assert.ok(new Date(ctx.headers['Date']).getDate())
|
||||
|
||||
assert.strictEqual(flaska._after.length, 0)
|
||||
})
|
||||
})
|
||||
|
||||
t.describe('#_nonce', function() {
|
||||
|
@ -125,7 +156,7 @@ t.describe('#_nonce', function() {
|
|||
|
||||
assert.strictEqual(ctx.headers['Server'], 'Flaska')
|
||||
assert.strictEqual(ctx.headers['X-Content-Type-Options'], 'nosniff')
|
||||
assert.strictEqual(ctx.headers['Content-Security-Policy'], `default-src 'self'; style-src 'self' 'unsafe-inline' 'nonce-${ctx.state.nonce}'; img-src * data: blob:; object-src 'none'; frame-ancestors 'none'; script-src 'nonce-${ctx.state.nonce}'`)
|
||||
assert.strictEqual(ctx.headers['Content-Security-Policy'], `default-src 'self'; style-src 'self' 'unsafe-inline' 'nonce-${ctx.state.nonce}'; img-src * data: blob:; font-src 'self' data:; object-src 'none'; frame-ancestors 'none'; script-src 'nonce-${ctx.state.nonce}'`)
|
||||
assert.strictEqual(ctx.headers['Cross-Origin-Opener-Policy'], 'same-origin')
|
||||
assert.strictEqual(ctx.headers['Cross-Origin-Resource-Policy'], 'same-origin')
|
||||
assert.strictEqual(ctx.headers['Cross-Origin-Embedder-Policy'], 'require-corp')
|
||||
|
@ -143,7 +174,7 @@ t.describe('#_nonce', function() {
|
|||
let nextNonce = flaska._nonces[flaska._noncesIndex]
|
||||
flaska._before[0](ctx)
|
||||
assert.strictEqual(ctx.state.nonce, nextNonce)
|
||||
assert.strictEqual(ctx.headers['Content-Security-Policy'], `default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * data: blob:; object-src 'none'; frame-ancestors 'none'; script-src 'nonce-${ctx.state.nonce}'`)
|
||||
assert.strictEqual(ctx.headers['Content-Security-Policy'], `default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * data: blob:; font-src 'self' data:; object-src 'none'; frame-ancestors 'none'; script-src 'nonce-${ctx.state.nonce}'`)
|
||||
}
|
||||
|
||||
assert.notOk(flaska._nonces[flaska._noncesIndex])
|
||||
|
@ -157,7 +188,7 @@ t.describe('#_nonce', function() {
|
|||
assert.notStrictEqual(ctx.state.nonce, flaska._nonces[i])
|
||||
}
|
||||
|
||||
assert.strictEqual(ctx.headers['Content-Security-Policy'], `default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * data: blob:; object-src 'none'; frame-ancestors 'none'; script-src 'nonce-${ctx.state.nonce}'`)
|
||||
assert.strictEqual(ctx.headers['Content-Security-Policy'], `default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * data: blob:; font-src 'self' data:; object-src 'none'; frame-ancestors 'none'; script-src 'nonce-${ctx.state.nonce}'`)
|
||||
})
|
||||
|
||||
t.test('should have after that regenerates lost hashes', function() {
|
||||
|
@ -914,6 +945,7 @@ t.describe('#listenAsync()', function() {
|
|||
checkIp = ip
|
||||
cb()
|
||||
})
|
||||
|
||||
let flaska = new Flaska({}, testFaker)
|
||||
assert.ok(flaska.requestStart)
|
||||
flaska.requestStart = function() {
|
||||
|
@ -956,6 +988,7 @@ t.describe('#listenAsync()', function() {
|
|||
createServer: function() {
|
||||
return {
|
||||
listenAsync: stubListenAsync,
|
||||
on: stub(),
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -979,6 +1012,7 @@ t.describe('#listenAsync()', function() {
|
|||
createServer: function() {
|
||||
return {
|
||||
listenAsync: stubListenAsync,
|
||||
on: stub(),
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -19,39 +19,32 @@ t.describe('#requestStart()', function() {
|
|||
flaska.onreserror(onResError)
|
||||
flaska.requestEnded = onEnded
|
||||
|
||||
flaska.requestEnd = function(err, ctx) {
|
||||
try {
|
||||
assert.ok(err)
|
||||
assert.strictEqual(assertReq.on.callCount, 1)
|
||||
assert.strictEqual(assertRes.on.callCount, 2)
|
||||
flaska.requestEnd = cb.finish(function(err, ctx) {
|
||||
assert.ok(err)
|
||||
assert.strictEqual(assertReq.on.callCount, 1)
|
||||
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(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)
|
||||
|
||||
// Test abort and close
|
||||
|
||||
cb()
|
||||
} catch (err) { cb(err) }
|
||||
}
|
||||
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)
|
||||
})
|
||||
flaska._beforeCompiled = function(ctx) {
|
||||
throw new Error()
|
||||
}
|
||||
|
@ -65,18 +58,13 @@ t.describe('#requestStart()', function() {
|
|||
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.requestEnd = cb.finish(function(err, ctx) {
|
||||
assert.ok(err)
|
||||
assert.strictEqual(err, assertError)
|
||||
assert.deepStrictEqual(ctx.state, {})
|
||||
assert.strictEqual(ctx.req, assertReq)
|
||||
assert.strictEqual(ctx.res, assertRes)
|
||||
})
|
||||
flaska._beforeCompiled = function(ctx) {
|
||||
assert.strictEqual(ctx.req, assertReq)
|
||||
assert.strictEqual(ctx.res, assertRes)
|
||||
|
@ -99,18 +87,13 @@ t.describe('#requestStart()', 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.strictEqual(err, assertError)
|
||||
assert.deepStrictEqual(ctx.state, {})
|
||||
assert.strictEqual(ctx.req, assertReq)
|
||||
assert.strictEqual(ctx.res, assertRes)
|
||||
cb()
|
||||
} catch (err) { cb(err) }
|
||||
}
|
||||
flaska.requestEnd = cb.finish(function(err, ctx) {
|
||||
assert.ok(err)
|
||||
assert.strictEqual(err, assertError)
|
||||
assert.deepStrictEqual(ctx.state, {})
|
||||
assert.strictEqual(ctx.req, assertReq)
|
||||
assert.strictEqual(ctx.res, assertRes)
|
||||
})
|
||||
|
||||
flaska.requestStart(assertReq, assertRes)
|
||||
})
|
||||
|
@ -132,39 +115,35 @@ t.describe('#requestStart()', function() {
|
|||
}
|
||||
}
|
||||
|
||||
flaska.requestEnd = function(err, ctx) {
|
||||
if (err && err !== assertError) return cb(err)
|
||||
flaska.requestEnd = cb.finish(function(err, ctx) {
|
||||
|
||||
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)
|
||||
assert.deepEqual(
|
||||
Object.keys(ctx.headers).sort(),
|
||||
['Server','X-Content-Type-Options','Content-Security-Policy','Cross-Origin-Opener-Policy','Cross-Origin-Resource-Policy','Cross-Origin-Embedder-Policy','Date'].sort()
|
||||
)
|
||||
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)
|
||||
assert.deepEqual(
|
||||
Object.keys(ctx.headers).sort(),
|
||||
['Server','X-Content-Type-Options','Content-Security-Policy','Cross-Origin-Opener-Policy','Cross-Origin-Resource-Policy','Cross-Origin-Embedder-Policy','Date'].sort()
|
||||
)
|
||||
|
||||
assert.strictEqual(ctx.headers['Server'], 'Flaska')
|
||||
assert.strictEqual(ctx.headers['X-Content-Type-Options'], 'nosniff')
|
||||
assert.strictEqual(ctx.headers['Content-Security-Policy'], `default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * data: blob:; object-src 'none'; frame-ancestors 'none'`)
|
||||
assert.strictEqual(ctx.headers['Cross-Origin-Opener-Policy'], 'same-origin')
|
||||
assert.strictEqual(ctx.headers['Cross-Origin-Resource-Policy'], 'same-origin')
|
||||
assert.strictEqual(ctx.headers['Cross-Origin-Embedder-Policy'], 'require-corp')
|
||||
assert.ok(new Date(ctx.headers['Date']).getDate())
|
||||
cb()
|
||||
} catch (err) { cb(err) }
|
||||
}
|
||||
assert.strictEqual(ctx.headers['Server'], 'Flaska')
|
||||
assert.strictEqual(ctx.headers['X-Content-Type-Options'], 'nosniff')
|
||||
assert.strictEqual(ctx.headers['Content-Security-Policy'], `default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * data: blob:; font-src 'self' data:; object-src 'none'; frame-ancestors 'none'`)
|
||||
assert.strictEqual(ctx.headers['Cross-Origin-Opener-Policy'], 'same-origin')
|
||||
assert.strictEqual(ctx.headers['Cross-Origin-Resource-Policy'], 'same-origin')
|
||||
assert.strictEqual(ctx.headers['Cross-Origin-Embedder-Policy'], 'require-corp')
|
||||
assert.ok(new Date(ctx.headers['Date']).getDate())
|
||||
})
|
||||
|
||||
flaska.requestStart(createReq({
|
||||
url: assertPath + assertSearch,
|
||||
|
@ -189,21 +168,16 @@ t.describe('#requestStart()', function() {
|
|||
}
|
||||
}
|
||||
|
||||
flaska.requestEnd = function(err, ctx) {
|
||||
if (err && err !== assertError) return cb(err)
|
||||
|
||||
try {
|
||||
assert.ok(err)
|
||||
assert.strictEqual(err, assertError)
|
||||
let keys = Object.keys(defaultHeaders)
|
||||
assert.strictEqual(Object.keys(ctx.headers).length, keys.length + 1)
|
||||
for (let key of keys) {
|
||||
assert.strictEqual(ctx.headers[key], defaultHeaders[key])
|
||||
}
|
||||
assert.ok(ctx.headers['Date'])
|
||||
cb()
|
||||
} catch (err) { cb(err) }
|
||||
}
|
||||
flaska.requestEnd = cb.finish(function(err, ctx) {
|
||||
assert.ok(err)
|
||||
assert.strictEqual(err, assertError)
|
||||
let keys = Object.keys(defaultHeaders)
|
||||
assert.strictEqual(Object.keys(ctx.headers).length, keys.length + 1)
|
||||
for (let key of keys) {
|
||||
assert.strictEqual(ctx.headers[key], defaultHeaders[key])
|
||||
}
|
||||
assert.ok(ctx.headers['Date'])
|
||||
})
|
||||
|
||||
flaska.requestStart(createReq({
|
||||
url: '/',
|
||||
|
@ -216,9 +190,13 @@ t.describe('#requestStart()', function() {
|
|||
const assertMethod = 'test'
|
||||
const assertPath = '/test/me'
|
||||
const assertSearch = '?asdf=test'
|
||||
let calledBefore = false
|
||||
let flaska = new Flaska({}, faker)
|
||||
flaska.compile()
|
||||
flaska._beforeAsyncCompiled = function() { return Promise.resolve() }
|
||||
flaska._beforeAsyncCompiled = function() {
|
||||
calledBefore = true
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
flaska.routers.test = {
|
||||
match: function(path) {
|
||||
|
@ -227,18 +205,14 @@ t.describe('#requestStart()', function() {
|
|||
}
|
||||
}
|
||||
|
||||
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.requestEnd = cb.finish(function(err, ctx) {
|
||||
assert.ok(err)
|
||||
assert.ok(calledBefore)
|
||||
assert.strictEqual(err, assertError)
|
||||
assert.strictEqual(ctx.url, assertPath)
|
||||
assert.strictEqual(ctx.search, assertSearch)
|
||||
assert.strictEqual(ctx.method, assertMethod)
|
||||
})
|
||||
|
||||
flaska.requestStart(createReq({
|
||||
url: assertPath + assertSearch,
|
||||
|
@ -269,18 +243,13 @@ t.describe('#requestStart()', function() {
|
|||
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.requestEnd = cb.finish(function(err, ctx) {
|
||||
assert.ok(err)
|
||||
assert.ok(ctx)
|
||||
assert.strictEqual(err, assertError)
|
||||
assert.strictEqual(ctx, checkMiddleCtx)
|
||||
assert.strictEqual(ctx.params, assertParams)
|
||||
})
|
||||
|
||||
flaska.requestStart(createReq({
|
||||
url: '',
|
||||
|
@ -301,17 +270,12 @@ t.describe('#requestStart()', function() {
|
|||
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.requestEnd = cb.finish(function(err, ctx) {
|
||||
assert.ok(err)
|
||||
assert.ok(ctx)
|
||||
assert.strictEqual(err, assertError)
|
||||
assert.strictEqual(ctx, checkHandlerCtx)
|
||||
})
|
||||
|
||||
flaska.requestStart(createReq({
|
||||
url: '/test',
|
||||
|
@ -331,16 +295,12 @@ t.describe('#requestStart()', function() {
|
|||
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.requestEnd = cb.finish(function(err, ctx) {
|
||||
assert.notOk(err)
|
||||
assert.ok(ctx)
|
||||
assert.strictEqual(on404Error.callCount, 1)
|
||||
assert.strictEqual(on404Error.firstCall[0], ctx)
|
||||
})
|
||||
|
||||
flaska.requestStart(createReq({
|
||||
url: '/nope',
|
||||
|
@ -361,17 +321,11 @@ t.describe('#requestStart()', function() {
|
|||
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.requestEnd = cb.finish(function(err, ctx) {
|
||||
assert.strictEqual(err, assertError)
|
||||
assert.ok(ctx)
|
||||
assert.strictEqual(ctx, checkCtx)
|
||||
})
|
||||
|
||||
flaska.requestStart(createReq({
|
||||
url: '/nope',
|
||||
|
@ -391,17 +345,11 @@ t.describe('#requestStart()', function() {
|
|||
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.requestEnd = cb.finish(function(err, ctx) {
|
||||
assert.strictEqual(err, assertError)
|
||||
assert.ok(ctx)
|
||||
assert.strictEqual(ctx, checkCtx)
|
||||
})
|
||||
|
||||
flaska.requestStart(createReq({
|
||||
url: '/nope',
|
||||
|
@ -421,17 +369,11 @@ t.describe('#requestStart()', function() {
|
|||
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.requestEnd = cb.finish(function(err, ctx) {
|
||||
assert.strictEqual(err, assertError)
|
||||
assert.ok(ctx)
|
||||
assert.strictEqual(ctx, checkCtx)
|
||||
})
|
||||
|
||||
flaska.requestStart(createReq({
|
||||
url: '/test',
|
||||
|
@ -453,14 +395,11 @@ t.describe('#requestStart()', 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.requestEnd = cb.finish(function(err, ctx) {
|
||||
assert.notOk(err)
|
||||
assert.ok(ctx)
|
||||
assert.strictEqual(ctx.body, assertBody)
|
||||
})
|
||||
|
||||
flaska.requestStart(createReq({
|
||||
url: '/test/something/here',
|
||||
|
@ -485,16 +424,11 @@ t.describe('#requestStart()', 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.requestEnd = cb.finish(function(err, ctx) {
|
||||
assert.ok(err)
|
||||
assert.ok(ctx)
|
||||
assert.strictEqual(err, assertError)
|
||||
})
|
||||
|
||||
flaska.requestStart(createReq({
|
||||
url: '',
|
||||
|
@ -515,17 +449,12 @@ t.describe('#requestStart()', function() {
|
|||
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.requestEnd = cb.finish(function(err, ctx) {
|
||||
assert.ok(err)
|
||||
assert.ok(ctx)
|
||||
assert.strictEqual(err, assertError)
|
||||
assert.strictEqual(ctx, checkHandlerCtx)
|
||||
})
|
||||
|
||||
flaska.requestStart(createReq({
|
||||
url: '/test',
|
||||
|
@ -546,17 +475,12 @@ t.describe('#requestStart()', function() {
|
|||
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.requestEnd = cb.finish(function(err, ctx) {
|
||||
assert.ok(err)
|
||||
assert.ok(ctx)
|
||||
assert.strictEqual(err, assertError)
|
||||
assert.strictEqual(ctx, checkHandlerCtx)
|
||||
})
|
||||
|
||||
flaska.requestStart(createReq({
|
||||
url: '/test',
|
||||
|
@ -585,15 +509,12 @@ t.describe('#requestStart()', function() {
|
|||
flaska.get('/::path', [middle], handler)
|
||||
flaska.compile()
|
||||
|
||||
flaska.requestEnd = function(err, ctx) {
|
||||
try {
|
||||
flaska.requestEnd = cb.finish(function(err, ctx) {
|
||||
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',
|
||||
|
@ -616,17 +537,12 @@ t.describe('#requestStart()', function() {
|
|||
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.requestEnd = cb.finish(function(err, ctx) {
|
||||
assert.ok(err)
|
||||
assert.ok(ctx)
|
||||
assert.strictEqual(err, assertError)
|
||||
assert.strictEqual(ctx, checkHandlerCtx)
|
||||
})
|
||||
|
||||
flaska.requestStart(createReq({
|
||||
url: '/test',
|
||||
|
@ -651,14 +567,11 @@ t.describe('#requestStart()', 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.requestEnd = cb.finish(function(err, ctx) {
|
||||
assert.notOk(err)
|
||||
assert.ok(ctx)
|
||||
assert.strictEqual(ctx.body, assertBody)
|
||||
})
|
||||
|
||||
flaska.requestStart(createReq({
|
||||
url: '/test/something/here',
|
||||
|
|
|
@ -12,20 +12,17 @@ t.describe('#requestEnd()', function() {
|
|||
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.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) }
|
||||
}
|
||||
let onFinish = cb.finish(function(body) {
|
||||
assert.strictEqual(ctx.status, assertStatus)
|
||||
assert.strictEqual(ctx.body, assertBody)
|
||||
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)
|
||||
})
|
||||
const ctx = createCtx({}, onFinish)
|
||||
|
||||
let flaska = new Flaska({}, fakerHttp, fakeStream)
|
||||
|
@ -43,14 +40,11 @@ t.describe('#requestEnd()', function() {
|
|||
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) }
|
||||
}
|
||||
let onFinish = cb.finish(function(body) {
|
||||
assert.strictEqual(ctx.status, 500)
|
||||
assert.strictEqual(ctx.body.status, 500)
|
||||
assert.strictEqual(ctx.body.message, 'Internal Server Error')
|
||||
})
|
||||
const ctx = createCtx({}, onFinish)
|
||||
|
||||
let flaska = new Flaska({}, fakerHttp, fakeStream)
|
||||
|
@ -70,26 +64,55 @@ t.describe('#requestEnd()', function() {
|
|||
// 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.headers['Content-Type'], 'application/json; charset=utf-8')
|
||||
assert.strictEqual(ctx.headers['Content-Length'], assertBodyLength)
|
||||
let onFinish = cb.finish(function(body) {
|
||||
assert.strictEqual(ctx.status, assertStatus)
|
||||
assert.strictEqual(ctx.body, assertBody)
|
||||
assert.strictEqual(ctx.headers['Content-Type'], 'application/json; charset=utf-8')
|
||||
assert.strictEqual(ctx.headers['Content-Length'], assertBodyLength)
|
||||
|
||||
if (method === 'GET') {
|
||||
assert.ok(body)
|
||||
assert.strictEqual(body, '{"a":1}')
|
||||
} else {
|
||||
assert.notOk(body)
|
||||
}
|
||||
if (method === 'GET') {
|
||||
assert.ok(body)
|
||||
assert.strictEqual(body, '{"a":1}')
|
||||
} else {
|
||||
assert.notOk(body)
|
||||
}
|
||||
|
||||
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) }
|
||||
}
|
||||
assert.ok(ctx.res.writeHead.called)
|
||||
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
|
||||
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
|
||||
})
|
||||
const ctx = createCtx({
|
||||
method: method,
|
||||
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 buffers', function(cb) {
|
||||
const assertStatus = 202
|
||||
// Calculated manually just in case
|
||||
const assertBodyLength = 11
|
||||
const assertBody = Buffer.from('hello world')
|
||||
let onFinish = cb.finish(function(body) {
|
||||
assert.strictEqual(ctx.status, assertStatus)
|
||||
assert.strictEqual(ctx.body, assertBody)
|
||||
assert.strictEqual(ctx.headers['Content-Type'], 'application/octet-stream')
|
||||
assert.strictEqual(ctx.headers['Content-Length'], assertBodyLength)
|
||||
|
||||
if (method === 'GET') {
|
||||
assert.ok(body)
|
||||
assert.strictEqual(body, assertBody)
|
||||
} else {
|
||||
assert.notOk(body)
|
||||
}
|
||||
|
||||
assert.ok(ctx.res.writeHead.called)
|
||||
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
|
||||
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
|
||||
})
|
||||
const ctx = createCtx({
|
||||
method: method,
|
||||
status: assertStatus,
|
||||
|
@ -104,21 +127,18 @@ t.describe('#requestEnd()', function() {
|
|||
// Calculated manually just in case
|
||||
const assertBodyLength = 0
|
||||
const assertBody = null
|
||||
let onFinish = function(body) {
|
||||
try {
|
||||
assert.strictEqual(ctx.status, 204)
|
||||
assert.strictEqual(ctx.body, assertBody)
|
||||
assert.notOk(ctx.headers['Content-Type'])
|
||||
assert.notOk(ctx.headers['Content-Length'])
|
||||
let onFinish = cb.finish(function(body) {
|
||||
assert.strictEqual(ctx.status, 204)
|
||||
assert.strictEqual(ctx.body, assertBody)
|
||||
assert.notOk(ctx.headers['Content-Type'])
|
||||
assert.notOk(ctx.headers['Content-Length'])
|
||||
|
||||
assert.strictEqual(body, undefined)
|
||||
assert.strictEqual(body, undefined)
|
||||
|
||||
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) }
|
||||
}
|
||||
assert.ok(ctx.res.writeHead.called)
|
||||
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
|
||||
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
|
||||
})
|
||||
const ctx = createCtx({
|
||||
method: method,
|
||||
status: 200,
|
||||
|
@ -133,21 +153,18 @@ t.describe('#requestEnd()', function() {
|
|||
const assertStatus = 202
|
||||
// Calculated manually just in case
|
||||
const assertBody = null
|
||||
let onFinish = function(body) {
|
||||
try {
|
||||
assert.strictEqual(ctx.status, assertStatus)
|
||||
assert.strictEqual(ctx.body, assertBody)
|
||||
assert.notOk(ctx.headers['Content-Type'])
|
||||
assert.strictEqual(ctx.headers['Content-Length'], 0)
|
||||
let onFinish = cb.finish(function(body) {
|
||||
assert.strictEqual(ctx.status, assertStatus)
|
||||
assert.strictEqual(ctx.body, assertBody)
|
||||
assert.notOk(ctx.headers['Content-Type'])
|
||||
assert.strictEqual(ctx.headers['Content-Length'], 0)
|
||||
|
||||
assert.strictEqual(body, undefined)
|
||||
assert.strictEqual(body, undefined)
|
||||
|
||||
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) }
|
||||
}
|
||||
assert.ok(ctx.res.writeHead.called)
|
||||
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
|
||||
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
|
||||
})
|
||||
const ctx = createCtx({
|
||||
method: method,
|
||||
status: assertStatus,
|
||||
|
@ -163,26 +180,23 @@ t.describe('#requestEnd()', function() {
|
|||
// 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.headers['Content-Type'], 'text/plain; charset=utf-8')
|
||||
assert.strictEqual(ctx.headers['Content-Length'], assertBodyLength)
|
||||
let onFinish = cb.finish(function(body) {
|
||||
assert.strictEqual(ctx.status, assertStatus)
|
||||
assert.strictEqual(ctx.body, assertBody)
|
||||
assert.strictEqual(ctx.headers['Content-Type'], 'text/plain; charset=utf-8')
|
||||
assert.strictEqual(ctx.headers['Content-Length'], assertBodyLength)
|
||||
|
||||
if (method === 'GET') {
|
||||
assert.ok(body)
|
||||
assert.strictEqual(body, assertBody)
|
||||
} else {
|
||||
assert.notOk(body)
|
||||
}
|
||||
if (method === 'GET') {
|
||||
assert.ok(body)
|
||||
assert.strictEqual(body, assertBody)
|
||||
} else {
|
||||
assert.notOk(body)
|
||||
}
|
||||
|
||||
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) }
|
||||
}
|
||||
assert.ok(ctx.res.writeHead.called)
|
||||
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
|
||||
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
|
||||
})
|
||||
const ctx = createCtx({
|
||||
method: method,
|
||||
status: assertStatus,
|
||||
|
@ -198,25 +212,22 @@ t.describe('#requestEnd()', function() {
|
|||
// 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.headers['Content-Type'], 'text/plain; charset=utf-8')
|
||||
assert.strictEqual(ctx.headers['Content-Length'], assertBodyLength)
|
||||
let onFinish = cb.finish(function(body) {
|
||||
assert.strictEqual(ctx.status, assertStatus)
|
||||
assert.strictEqual(ctx.body, assertBody)
|
||||
assert.strictEqual(ctx.headers['Content-Type'], 'text/plain; charset=utf-8')
|
||||
assert.strictEqual(ctx.headers['Content-Length'], assertBodyLength)
|
||||
|
||||
if (method === 'GET') {
|
||||
assert.ok(body)
|
||||
assert.strictEqual(body, assertBody.toString())
|
||||
} else {
|
||||
assert.notOk(body)
|
||||
}
|
||||
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) }
|
||||
}
|
||||
if (method === 'GET') {
|
||||
assert.ok(body)
|
||||
assert.strictEqual(body, assertBody.toString())
|
||||
} else {
|
||||
assert.notOk(body)
|
||||
}
|
||||
assert.ok(ctx.res.writeHead.called)
|
||||
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
|
||||
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
|
||||
})
|
||||
const ctx = createCtx({
|
||||
method: method,
|
||||
status: assertStatus,
|
||||
|
@ -242,22 +253,19 @@ t.describe('#requestEnd()', function() {
|
|||
|
||||
let body = new FileResponse()
|
||||
let assertBody = { pipe: function() {} }
|
||||
let onFinish = function(source, target, callback) {
|
||||
try {
|
||||
assert.ok(assertHandle.called)
|
||||
assert.ok(ctx.res.writeHead)
|
||||
assert.strictEqual(ctx.body, assertBody)
|
||||
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)
|
||||
assert.strictEqual(ctx.headers['Content-Type'], assertContentType)
|
||||
assert.strictEqual(ctx.headers['Content-Length'], assertContentLength)
|
||||
cb()
|
||||
} catch (err) { cb(err) }
|
||||
}
|
||||
let onFinish = cb.finish(function(source, target, callback) {
|
||||
assert.ok(assertHandle.called)
|
||||
assert.ok(ctx.res.writeHead)
|
||||
assert.strictEqual(ctx.body, assertBody)
|
||||
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)
|
||||
assert.strictEqual(ctx.headers['Content-Type'], assertContentType)
|
||||
assert.strictEqual(ctx.headers['Content-Length'], assertContentLength)
|
||||
})
|
||||
const ctx = createCtx({
|
||||
})
|
||||
ctx.body = body
|
||||
|
@ -278,19 +286,16 @@ t.describe('#requestEnd()', function() {
|
|||
const assertType = 'herp/derp'
|
||||
const assertBody = { pipe: function() {} }
|
||||
|
||||
let onFinish = function(source, target, callback) {
|
||||
try {
|
||||
assert.strictEqual(ctx.status, 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) }
|
||||
}
|
||||
let onFinish = cb.finish(function(source, target, callback) {
|
||||
assert.strictEqual(ctx.status, 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)
|
||||
})
|
||||
const ctx = createCtx({
|
||||
status: assertStatus,
|
||||
})
|
||||
|
@ -315,20 +320,18 @@ t.describe('#requestEnd()', function() {
|
|||
})
|
||||
|
||||
let body = new FileResponse()
|
||||
let onFinish = function(body) {
|
||||
try {
|
||||
assert.ok(assertHandle.called)
|
||||
assert.ok(ctx.res.writeHead)
|
||||
assert.strictEqual(ctx.body, null)
|
||||
assert.notOk(body)
|
||||
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.strictEqual(ctx.headers['Content-Type'], assertContentType)
|
||||
assert.strictEqual(ctx.headers['Content-Length'], assertContentLength)
|
||||
cb()
|
||||
} catch (err) { cb(err) }
|
||||
}
|
||||
let onFinish = cb.finish(function(body) {
|
||||
assert.ok(assertHandle.called)
|
||||
assert.ok(ctx.res.writeHead)
|
||||
assert.strictEqual(ctx.body, null)
|
||||
assert.notOk(body)
|
||||
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.strictEqual(ctx.headers['Content-Type'], assertContentType)
|
||||
assert.strictEqual(ctx.headers['Content-Length'], assertContentLength)
|
||||
})
|
||||
|
||||
const ctx = createCtx({
|
||||
method: method,
|
||||
}, onFinish)
|
||||
|
@ -349,20 +352,17 @@ t.describe('#requestEnd()', function() {
|
|||
const assertType = 'herp/derp'
|
||||
const assertBody = { pipe: function() {}, destroy: stub() }
|
||||
|
||||
let onFinish = function(body) {
|
||||
try {
|
||||
assert.strictEqual(ctx.status, assertStatus)
|
||||
assert.strictEqual(ctx.headers['Content-Type'], assertType)
|
||||
assert.notOk(ctx.headers['Content-Length'])
|
||||
assert.notOk(body)
|
||||
|
||||
assert.ok(assertBody.destroy.called)
|
||||
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) }
|
||||
}
|
||||
let onFinish = cb.finish(function(body) {
|
||||
assert.strictEqual(ctx.status, assertStatus)
|
||||
assert.strictEqual(ctx.headers['Content-Type'], assertType)
|
||||
assert.notOk(ctx.headers['Content-Length'])
|
||||
assert.notOk(body)
|
||||
|
||||
assert.ok(assertBody.destroy.called)
|
||||
assert.ok(ctx.res.writeHead.called)
|
||||
assert.strictEqual(ctx.res.writeHead.firstCall[0], ctx.status)
|
||||
assert.strictEqual(ctx.res.writeHead.firstCall[1], ctx.headers)
|
||||
})
|
||||
const ctx = createCtx({
|
||||
method: method,
|
||||
status: assertStatus,
|
||||
|
@ -405,17 +405,14 @@ t.describe('#requestEnd()', function() {
|
|||
const assertStatus = 209
|
||||
const assertBody = 'test'
|
||||
const assertType = 'something/else'
|
||||
let onFinish = function(body) {
|
||||
try {
|
||||
assert.strictEqual(ctx.status, 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) }
|
||||
}
|
||||
let onFinish = cb.finish(function(body) {
|
||||
assert.strictEqual(ctx.status, 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)
|
||||
})
|
||||
const ctx = createCtx({
|
||||
status: assertStatus,
|
||||
body: assertBody,
|
||||
|
@ -427,18 +424,15 @@ t.describe('#requestEnd()', function() {
|
|||
})
|
||||
|
||||
t.test('call pipe should have default type', function(cb) {
|
||||
let onFinish = function(source, target) {
|
||||
try {
|
||||
assert.strictEqual(ctx.status, 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) }
|
||||
}
|
||||
let onFinish = cb.finish(function(source, target) {
|
||||
assert.strictEqual(ctx.status, 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)
|
||||
})
|
||||
const ctx = createCtx({})
|
||||
ctx.body = { pipe: function() {} }
|
||||
fakeStream.pipeline = onFinish
|
||||
|
@ -456,18 +450,15 @@ t.describe('#requestEnd()', function() {
|
|||
|
||||
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.status, 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) }
|
||||
}
|
||||
let onFinish = cb.finish(function(source, target) {
|
||||
assert.strictEqual(ctx.status, 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)
|
||||
})
|
||||
const ctx = createCtx({})
|
||||
ctx.body = { pipe: function() {}, path: './bla/test/temp.' + test[0] }
|
||||
fakeStream.pipeline = onFinish
|
||||
|
@ -495,17 +486,14 @@ t.describe('#requestEnd()', function() {
|
|||
const assertStatus = status
|
||||
const assertNotBody = 'test'
|
||||
const assertNotType = 'something/else'
|
||||
let onFinish = function(body) {
|
||||
try {
|
||||
assert.strictEqual(ctx.status, 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) }
|
||||
}
|
||||
let onFinish = cb.finish(function(body) {
|
||||
assert.strictEqual(ctx.status, 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)
|
||||
})
|
||||
const ctx = createCtx({
|
||||
status: assertStatus,
|
||||
body: assertNotBody,
|
||||
|
|
|
@ -6,7 +6,7 @@ const indexMap = [
|
|||
'thirdCall',
|
||||
]
|
||||
|
||||
export function fakeHttp(inj1, inj2) {
|
||||
export function fakeHttp(inj1, inj2, inj3) {
|
||||
let intermediate = {
|
||||
createServer: function(cb) {
|
||||
if (inj1) inj1(cb)
|
||||
|
@ -15,6 +15,9 @@ export function fakeHttp(inj1, inj2) {
|
|||
listen: function(port, ip, cb) {
|
||||
if (inj2) inj2(port, ip, cb)
|
||||
else if (cb) cb()
|
||||
},
|
||||
on: function(name, handler) {
|
||||
if (inj3) inj3(name, handler)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,13 @@ flaska.post('/file/upload', FormidableHandler(formidable, {
|
|||
uploaded.push(ctx.req.file)
|
||||
ctx.body = ctx.req.file
|
||||
})
|
||||
flaska.post('/file/upload/many', FormidableHandler(formidable, {
|
||||
uploadDir: './test/upload',
|
||||
}), function(ctx) {
|
||||
uploaded.push(ctx.req.files.herp)
|
||||
uploaded.push(ctx.req.files.derp)
|
||||
ctx.body = ctx.req.files
|
||||
})
|
||||
flaska.get('/file/leak', function(ctx) {
|
||||
file = fsSync.createReadStream('./test/test.png')
|
||||
ctx.body = file
|
||||
|
@ -138,15 +145,15 @@ t.describe('/json', function() {
|
|||
t.test('should fail if not a valid json', async function() {
|
||||
reset()
|
||||
|
||||
let err = await assert.isRejected(client.customRequest('POST', '/json', 'aaaa'))
|
||||
let err = await assert.isRejected(client.customRequest('POST', '/json', 'XXXXX'))
|
||||
|
||||
assert.strictEqual(err.body.status, 400)
|
||||
assert.match(err.body.message, /invalid json/i)
|
||||
assert.match(err.body.message, /token a/i)
|
||||
assert.strictEqual(err.body.request, 'aaaa')
|
||||
assert.match(err.body.message, /token[^X]+X/i)
|
||||
assert.strictEqual(err.body.request, 'XXXXX')
|
||||
assert.strictEqual(log.error.callCount, 1)
|
||||
assert.match(log.error.firstCall[0].message, /invalid json/i)
|
||||
assert.match(log.error.firstCall[0].message, /token a/i)
|
||||
assert.match(log.error.firstCall[0].message, /token[^X]+X/i)
|
||||
})
|
||||
|
||||
t.test('should handle incomplete requests correctly', async function() {
|
||||
|
@ -305,6 +312,82 @@ t.describe('/file/upload', function() {
|
|||
|
||||
assert.strictEqual(statSource.size, statTarget.size)
|
||||
assert.strictEqual(statSource.size, res.size)
|
||||
assert.strictEqual(res.type, 'image/png')
|
||||
})
|
||||
t.test('server should have correct type', async function() {
|
||||
let res = await client.upload('/file/upload', './test/test.jpg')
|
||||
|
||||
let [statSource, statTarget] = await Promise.all([
|
||||
fs.stat('./test/test.jpg'),
|
||||
fs.stat(res.path),
|
||||
])
|
||||
|
||||
assert.strictEqual(statSource.size, statTarget.size)
|
||||
assert.strictEqual(statSource.size, res.size)
|
||||
assert.strictEqual(res.type, 'image/jpeg')
|
||||
})
|
||||
t.test('server should use type from user', async function() {
|
||||
const assertType = 'some/test/here'
|
||||
let res = await client.upload('/file/upload', './test/test.jpg', 'POST', {}, assertType)
|
||||
|
||||
let [statSource, statTarget] = await Promise.all([
|
||||
fs.stat('./test/test.jpg'),
|
||||
fs.stat(res.path),
|
||||
])
|
||||
|
||||
assert.strictEqual(statSource.size, statTarget.size)
|
||||
assert.strictEqual(statSource.size, res.size)
|
||||
assert.strictEqual(res.type, assertType)
|
||||
})
|
||||
t.test('server should attempt to correct type if type is application/octet-stream', async function() {
|
||||
const assertNotType = 'application/octet-stream'
|
||||
let res = await client.upload('/file/upload', './test/test.jpg', 'POST', {}, assertNotType)
|
||||
|
||||
let [statSource, statTarget] = await Promise.all([
|
||||
fs.stat('./test/test.jpg'),
|
||||
fs.stat(res.path),
|
||||
])
|
||||
|
||||
assert.strictEqual(statSource.size, statTarget.size)
|
||||
assert.strictEqual(statSource.size, res.size)
|
||||
assert.notStrictEqual(res.type, assertNotType)
|
||||
assert.strictEqual(res.type, 'image/jpeg')
|
||||
})
|
||||
t.test('server fall back to type application/octet-stream if unknown', async function() {
|
||||
let res = await client.upload('/file/upload', './test/test.gibberish')
|
||||
|
||||
let [statSource, statTarget] = await Promise.all([
|
||||
fs.stat('./test/test.gibberish'),
|
||||
fs.stat(res.path),
|
||||
])
|
||||
|
||||
assert.strictEqual(statSource.size, statTarget.size)
|
||||
assert.strictEqual(statSource.size, res.size)
|
||||
assert.strictEqual(res.type, 'application/octet-stream')
|
||||
|
||||
res = await client.upload('/file/upload', './test/test.gibberish', 'POST', {}, 'application/octet-stream')
|
||||
assert.strictEqual(res.type, 'application/octet-stream')
|
||||
})
|
||||
})
|
||||
|
||||
t.describe('/file/upload/many', function() {
|
||||
t.test('server should upload file', async function() {
|
||||
let res = await client.upload('/file/upload/many', {
|
||||
herp: './test/test.jpg',
|
||||
derp: './test/test.png',
|
||||
})
|
||||
|
||||
let [statSourcePng, statSourceJpg, statTargetHerp, statTargetDerp] = await Promise.all([
|
||||
fs.stat('./test/test.png'),
|
||||
fs.stat('./test/test.jpg'),
|
||||
fs.stat(res.herp.path),
|
||||
fs.stat(res.derp.path),
|
||||
])
|
||||
|
||||
assert.strictEqual(statSourceJpg.size, statTargetHerp.size)
|
||||
assert.strictEqual(statSourceJpg.size, res.herp.size)
|
||||
assert.strictEqual(statSourcePng.size, statTargetDerp.size)
|
||||
assert.strictEqual(statSourcePng.size, res.derp.size)
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
@ -253,6 +253,27 @@ t.describe('#CorsHandler()', function() {
|
|||
assert.notOk(ctx.headers['Access-Control-Allow-Headers'])
|
||||
assert.strictEqual(ctx.status, 204)
|
||||
})
|
||||
|
||||
t.test('should set headers if allowedOrigins has a *', function() {
|
||||
const assertOrigin = 'http://my.site.here'
|
||||
|
||||
corsHandler = CorsHandler({
|
||||
allowedOrigins: ['*'],
|
||||
})
|
||||
ctx.req.headers['origin'] = assertOrigin
|
||||
ctx.req.headers['access-control-request-method'] = 'GET'
|
||||
|
||||
assert.notOk(ctx.headers['Access-Control-Allow-Origin'])
|
||||
assert.notOk(ctx.headers['Access-Control-Allow-Methods'])
|
||||
assert.notOk(ctx.headers['Access-Control-Allow-Headers'])
|
||||
|
||||
corsHandler(ctx)
|
||||
|
||||
assert.strictEqual(ctx.headers['Vary'], 'Origin')
|
||||
assert.strictEqual(ctx.headers['Access-Control-Allow-Origin'], assertOrigin)
|
||||
assert.ok(ctx.headers['Access-Control-Allow-Methods'])
|
||||
assert.strictEqual(ctx.status, 204)
|
||||
})
|
||||
})
|
||||
|
||||
t.describe('GET/POST/DELETE/PATCH/PUT', function() {
|
||||
|
@ -498,8 +519,8 @@ t.describe('#JsonHandler()', function() {
|
|||
finished = true
|
||||
})
|
||||
|
||||
ctx.req.on.firstCall[1](Buffer.alloc(10, 'a'))
|
||||
ctx.req.on.firstCall[1](Buffer.alloc(10, 'a'))
|
||||
ctx.req.on.firstCall[1](Buffer.alloc(10, 'X'))
|
||||
ctx.req.on.firstCall[1](Buffer.alloc(10, 'X'))
|
||||
ctx.req.on.secondCall[1]()
|
||||
|
||||
await setTimeout(10)
|
||||
|
@ -510,11 +531,11 @@ t.describe('#JsonHandler()', function() {
|
|||
assert.ok(err instanceof HttpError)
|
||||
assert.strictEqual(err.status, 400)
|
||||
assert.match(err.message, /JSON/)
|
||||
assert.match(err.message, /Unexpected token a in/i)
|
||||
assert.match(err.message, /Unexpected token[^X]+X/i)
|
||||
assert.strictEqual(err.body.status, 400)
|
||||
assert.match(err.body.message, /Invalid JSON/i)
|
||||
assert.match(err.body.message, /Unexpected token a in/i)
|
||||
assert.strictEqual(err.body.request, 'aaaaaaaaaaaaaaaaaaaa')
|
||||
assert.match(err.body.message, /Unexpected token[^X]+X/i)
|
||||
assert.strictEqual(err.body.request, 'XXXXXXXXXXXXXXXXXXXX')
|
||||
})
|
||||
|
||||
t.test('should not throw if body is empty', async function() {
|
||||
|
@ -615,7 +636,10 @@ t.describe('#FormidableHandler()', function() {
|
|||
|
||||
let err = await assert.isRejected(handler(ctx))
|
||||
|
||||
assert.strictEqual(err, assertError)
|
||||
assert.notStrictEqual(err, assertError)
|
||||
assert.ok(err instanceof HttpError)
|
||||
assert.strictEqual(err.message, assertError.message)
|
||||
assert.strictEqual(err.status, 400)
|
||||
})
|
||||
|
||||
t.test('should throw rename error if rename fails', async function() {
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
Loading…
Reference in New Issue