flaska/test/middlewares.test.mjs

729 lines
24 KiB
JavaScript

import os from 'os'
import path from 'path'
import { Buffer } from 'buffer'
import { Eltro as t, assert, stub} from 'eltro'
import { QueryHandler, JsonHandler, FormidableHandler, HttpError, CorsHandler } from '../flaska.mjs'
import { createCtx } from './helper.mjs'
import { finished } from 'stream'
import { setTimeout } from 'timers/promises'
t.describe('#QueryHandler()', function() {
let queryHandler = QueryHandler()
t.test('should return a handler', function() {
assert.strictEqual(typeof(queryHandler), 'function')
})
t.test('should support separating query from request url', function() {
const assertItem1 = 'safdsfdsag'
const assertItem2 = 'hello%20world'
const ctx = {
req: {
url: `/some/path?item1=${assertItem1}&ITEM2=${assertItem2}`
}
}
queryHandler(ctx)
assert.strictEqual(ctx.query.get('item1'), assertItem1)
assert.strictEqual(ctx.query.get('ITEM2'), 'hello world')
})
})
t.describe('#CorsHandler()', function() {
let corsHandler
let ctx
t.test('should return a handler', function() {
corsHandler = CorsHandler()
assert.strictEqual(typeof(corsHandler), 'function')
})
t.describe('OPTIONS', function() {
t.beforeEach(function() {
ctx = createCtx()
ctx.method = 'OPTIONS'
})
t.test('should set status and headers', function() {
const assertOrigin = 'http://my.site.here'
const assertRequestHeaders = 'asdf,foobar'
corsHandler = CorsHandler({
allowedOrigins: [assertOrigin],
})
ctx.req.headers['origin'] = assertOrigin
ctx.req.headers['access-control-request-method'] = 'GET'
ctx.req.headers['access-control-request-headers'] = assertRequestHeaders
assert.notOk(ctx.headers['Vary'])
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.strictEqual(ctx.headers['Access-Control-Allow-Methods'], 'GET,HEAD,PUT,POST,DELETE,PATCH')
assert.strictEqual(ctx.headers['Access-Control-Allow-Headers'], assertRequestHeaders)
assert.notOk(ctx.headers['Access-Control-Allow-Credentials'])
assert.notOk(ctx.headers['Access-Control-Max-Age'])
assert.strictEqual(ctx.status, 204)
})
t.test('should set Allow-Credentials if credentials is specified', function() {
const assertOrigin = 'http://my.site.here'
const assertRequestHeaders = 'asdf,foobar'
corsHandler = CorsHandler({
allowedOrigins: [assertOrigin],
credentials: true,
})
ctx.req.headers['origin'] = assertOrigin
ctx.req.headers['access-control-request-method'] = 'GET'
ctx.req.headers['access-control-request-headers'] = assertRequestHeaders
assert.notOk(ctx.headers['Vary'])
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-Credentials'], 'true')
assert.strictEqual(ctx.headers['Access-Control-Allow-Origin'], assertOrigin)
assert.strictEqual(ctx.headers['Access-Control-Allow-Methods'], 'GET,HEAD,PUT,POST,DELETE,PATCH')
assert.strictEqual(ctx.headers['Access-Control-Allow-Headers'], assertRequestHeaders)
assert.notOk(ctx.headers['Access-Control-Max-Age'])
assert.strictEqual(ctx.status, 204)
})
t.test('should set Max-Age if maxAge is specified', function() {
const assertOrigin = 'http://my.site.here'
const assertRequestHeaders = 'asdf,foobar'
const assertMaxAge = '600'
corsHandler = CorsHandler({
allowedOrigins: [assertOrigin],
maxAge: assertMaxAge,
})
ctx.req.headers['origin'] = assertOrigin
ctx.req.headers['access-control-request-method'] = 'GET'
ctx.req.headers['access-control-request-headers'] = assertRequestHeaders
assert.notOk(ctx.headers['Vary'])
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.strictEqual(ctx.headers['Access-Control-Max-Age'], assertMaxAge)
assert.strictEqual(ctx.headers['Access-Control-Allow-Methods'], 'GET,HEAD,PUT,POST,DELETE,PATCH')
assert.strictEqual(ctx.headers['Access-Control-Allow-Headers'], assertRequestHeaders)
assert.notOk(ctx.headers['Access-Control-Allow-Credentials'])
assert.strictEqual(ctx.status, 204)
})
t.test('should support custom allowed methods and headers', function() {
const assertOrigin = 'http://my.site.here'
const assertAllowedMethods = 'GET,HEAD'
const assertAllowedHeaders = 'test1,test2'
corsHandler = CorsHandler({
allowedOrigins: [assertOrigin],
allowedMethods: assertAllowedMethods,
allowedHeaders: assertAllowedHeaders,
})
ctx.req.headers['origin'] = assertOrigin
ctx.req.headers['access-control-request-method'] = 'GET'
ctx.req.headers['access-control-request-headers'] = 'asdfasdfasdfsfad'
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.notOk(ctx.headers['Access-Control-Allow-Credentials'])
assert.strictEqual(ctx.headers['Access-Control-Allow-Origin'], assertOrigin)
assert.strictEqual(ctx.headers['Access-Control-Allow-Methods'], assertAllowedMethods)
assert.strictEqual(ctx.headers['Access-Control-Allow-Headers'], assertAllowedHeaders)
assert.strictEqual(ctx.status, 204)
})
t.test('should not set any allowed headers if allowedHeaders is explicitly false', function() {
const assertOrigin = 'http://my.site.here'
const assertAllowedMethods = 'GET,HEAD'
corsHandler = CorsHandler({
allowedOrigins: [assertOrigin],
allowedMethods: assertAllowedMethods,
allowedHeaders: false,
})
ctx.req.headers['origin'] = assertOrigin
ctx.req.headers['access-control-request-method'] = 'GET'
ctx.req.headers['access-control-request-headers'] = 'asdfasdfasdfsfad'
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.notOk(ctx.headers['Access-Control-Allow-Credentials'])
assert.strictEqual(ctx.headers['Access-Control-Allow-Origin'], assertOrigin)
assert.strictEqual(ctx.headers['Access-Control-Allow-Methods'], assertAllowedMethods)
assert.strictEqual(ctx.headers['Access-Control-Allow-Headers'], undefined)
assert.strictEqual(ctx.status, 204)
})
t.test('should not add any headers if origin missing', function() {
corsHandler = CorsHandler({
allowedOrigins: ['https://test.com'],
})
ctx.req.headers['origin'] = null
ctx.req.headers['access-control-request-method'] = 'GET'
ctx.req.headers['access-control-request-headers'] = 'asdfasdfasdfsfad'
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.notOk(ctx.headers['Access-Control-Allow-Origin'])
assert.notOk(ctx.headers['Access-Control-Allow-Methods'])
assert.notOk(ctx.headers['Access-Control-Allow-Headers'])
assert.strictEqual(ctx.status, 204)
})
t.test('should not add any headers if origin not found', function() {
const assertOrigin = 'http://my.site.here'
const assertAllowedMethods = 'GET,HEAD'
corsHandler = CorsHandler({
allowedOrigins: ['https://my.site.here'],
allowedMethods: assertAllowedMethods,
allowedHeaders: false,
})
ctx.req.headers['origin'] = assertOrigin
ctx.req.headers['access-control-request-method'] = 'GET'
ctx.req.headers['access-control-request-headers'] = 'asdfasdfasdfsfad'
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.notOk(ctx.headers['Access-Control-Allow-Origin'])
assert.notOk(ctx.headers['Access-Control-Allow-Methods'])
assert.notOk(ctx.headers['Access-Control-Allow-Headers'])
assert.strictEqual(ctx.status, 204)
})
t.test('should not add any headers if request-method is missing', function() {
const assertOrigin = 'http://my.site.here'
corsHandler = CorsHandler({
allowedOrigins: ['http://my.site.here'],
})
ctx.req.headers['origin'] = assertOrigin
delete ctx.req.headers['access-control-request-method']
ctx.req.headers['access-control-request-headers'] = 'asdfasdfasdfsfad'
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.notOk(ctx.headers['Access-Control-Allow-Origin'])
assert.notOk(ctx.headers['Access-Control-Allow-Methods'])
assert.notOk(ctx.headers['Access-Control-Allow-Headers'])
assert.strictEqual(ctx.status, 204)
})
})
t.describe('GET/POST/DELETE/PATCH/PUT', function() {
let testMethods = ['GET', 'POST', 'DELETE', 'PATCH', 'PUT']
t.test('should set header but no status', function() {
testMethods.forEach(function(method) {
ctx = createCtx()
ctx.method = method
ctx.status = method
const assertOrigin = 'http://my.site.here'
corsHandler = CorsHandler({
allowedOrigins: [assertOrigin],
})
ctx.req.headers['origin'] = assertOrigin
ctx.req.headers['access-control-request-headers'] = 'asdfasdfasdfsfad'
assert.notOk(ctx.headers['Vary'])
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.notOk(ctx.headers['Access-Control-Allow-Credentials'])
assert.notOk(ctx.headers['Access-Control-Allow-Methods'])
assert.notOk(ctx.headers['Access-Control-Allow-Headers'])
assert.notOk(ctx.headers['Access-Control-Expose-Headers'])
assert.strictEqual(ctx.status, method)
})
})
t.test('should set credential header if specifed', function() {
testMethods.forEach(function(method) {
ctx = createCtx()
ctx.method = method
ctx.status = method
const assertOrigin = 'http://my.site.here'
corsHandler = CorsHandler({
allowedOrigins: [assertOrigin],
credentials: true,
})
ctx.req.headers['origin'] = assertOrigin
assert.notOk(ctx.headers['Vary'])
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-Credentials'], 'true')
assert.strictEqual(ctx.headers['Access-Control-Allow-Origin'], assertOrigin)
assert.notOk(ctx.headers['Access-Control-Allow-Methods'])
assert.notOk(ctx.headers['Access-Control-Allow-Headers'])
assert.notOk(ctx.headers['Access-Control-Expose-Headers'])
assert.strictEqual(ctx.status, method)
})
})
t.test('should set expose headers if specifed', function() {
testMethods.forEach(function(method) {
const assertExposeHeaders = 'Some, Test, Here'
ctx = createCtx()
ctx.method = method
ctx.status = method
const assertOrigin = 'http://my.site.here'
corsHandler = CorsHandler({
allowedOrigins: [assertOrigin],
exposeHeaders: assertExposeHeaders,
})
ctx.req.headers['origin'] = assertOrigin
assert.notOk(ctx.headers['Vary'])
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.notOk(ctx.headers['Access-Control-Allow-Credentials'])
assert.notOk(ctx.headers['Access-Control-Allow-Methods'])
assert.notOk(ctx.headers['Access-Control-Allow-Headers'])
assert.strictEqual(ctx.headers['Access-Control-Expose-Headers'], assertExposeHeaders)
assert.strictEqual(ctx.status, method)
})
})
t.test('should not add any headers if origin missing', function() {
testMethods.forEach(function(method) {
ctx = createCtx()
ctx.method = method
ctx.status = method
corsHandler = CorsHandler({
allowedOrigins: ['https://test.com'],
})
ctx.req.headers['origin'] = null
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.notOk(ctx.headers['Access-Control-Allow-Origin'])
assert.notOk(ctx.headers['Access-Control-Allow-Methods'])
assert.notOk(ctx.headers['Access-Control-Allow-Headers'])
assert.notOk(ctx.headers['Access-Control-Expose-Headers'])
assert.strictEqual(ctx.status, method)
})
})
t.test('should not add any headers if origin not found', function() {
testMethods.forEach(function(method) {
ctx = createCtx()
ctx.method = method
ctx.status = method
const assertOrigin = 'http://my.site.here'
const assertAllowedMethods = 'GET,HEAD'
corsHandler = CorsHandler({
allowedOrigins: ['https://my.site.here'],
allowedMethods: assertAllowedMethods,
allowedHeaders: false,
})
ctx.req.headers['origin'] = assertOrigin
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.notOk(ctx.headers['Access-Control-Allow-Origin'])
assert.notOk(ctx.headers['Access-Control-Allow-Methods'])
assert.notOk(ctx.headers['Access-Control-Allow-Headers'])
assert.notOk(ctx.headers['Access-Control-Expose-Headers'])
assert.strictEqual(ctx.status, method)
})
})
})
})
t.describe('#JsonHandler()', function() {
let jsonHandler = JsonHandler()
let ctx
t.beforeEach(function() {
ctx = createCtx()
})
t.test('should return a handler', function() {
assert.strictEqual(typeof(jsonHandler), 'function')
})
t.test('should support fetching body from request', async function() {
const assertBody = { a: 1, temp: 'test', hello: 'world'}
let parsed = JSON.stringify(assertBody)
let finished = false
let err = null
jsonHandler(ctx).catch(function(error) {
err = error
}).then(function() {
finished = true
})
assert.ok(ctx.req.on.called)
assert.strictEqual(ctx.req.on.firstCall[0], 'data')
assert.strictEqual(ctx.req.on.secondCall[0], 'end')
assert.strictEqual(finished, false)
ctx.req.on.firstCall[1](Buffer.from(parsed.slice(0, parsed.length / 2)))
assert.strictEqual(finished, false)
ctx.req.on.firstCall[1](Buffer.from(parsed.slice(parsed.length / 2)))
assert.strictEqual(finished, false)
ctx.req.on.secondCall[1]()
await setTimeout(10)
assert.strictEqual(finished, true)
assert.strictEqual(err, null)
assert.notStrictEqual(ctx.req.body, assertBody)
assert.deepStrictEqual(ctx.req.body, assertBody)
})
t.test('should throw if buffer grows too large', async function() {
let defaultLimit = 10 * 1024
let segmentSize = 100
let finished = false
let err = null
jsonHandler(ctx).catch(function(error) {
err = error
}).then(function() {
finished = true
})
for (let i = 0; i < defaultLimit; i += segmentSize) {
ctx.req.on.firstCall[1](Buffer.alloc(segmentSize, 'a'))
}
await setTimeout(10)
assert.strictEqual(finished, true)
assert.notStrictEqual(err, null)
assert.ok(err instanceof HttpError)
assert.strictEqual(err.status, 413)
assert.match(err.message, new RegExp(100 * 103))
assert.match(err.message, new RegExp(defaultLimit))
})
t.test('should throw if buffer is not valid json', async function() {
let finished = false
let err = null
jsonHandler(ctx).catch(function(error) {
err = error
}).then(function() {
finished = true
})
ctx.req.on.firstCall[1](Buffer.alloc(10, 'a'))
ctx.req.on.firstCall[1](Buffer.alloc(10, 'a'))
ctx.req.on.secondCall[1]()
await setTimeout(10)
assert.strictEqual(finished, true)
assert.notStrictEqual(err, null)
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.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')
})
t.test('should not throw if body is empty', async function() {
let finished = false
let err = null
jsonHandler(ctx).catch(function(error) {
err = error
}).then(function() {
finished = true
})
assert.ok(ctx.req.on.called)
assert.strictEqual(ctx.req.on.firstCall[0], 'data')
assert.strictEqual(ctx.req.on.secondCall[0], 'end')
assert.strictEqual(finished, false)
ctx.req.on.secondCall[1]()
await setTimeout(10)
assert.strictEqual(finished, true)
assert.strictEqual(err, null)
assert.deepStrictEqual(ctx.req.body, {})
})
})
t.describe('#FormidableHandler()', function() {
let formidable
let incomingForm
let ctx
t.beforeEach(function() {
ctx = createCtx()
formidable = {
IncomingForm: stub(),
fsRename: stub().resolves(),
}
incomingForm = {
parse: stub().returnWith(function(req, cb) {
cb(null, {}, { file: { name: 'asdf.png' } })
})
}
formidable.IncomingForm.returns(incomingForm)
})
t.test('should call formidable with correct defaults', async function() {
let handler = FormidableHandler(formidable)
await handler(ctx)
assert.strictEqual(incomingForm.uploadDir, os.tmpdir())
assert.strictEqual(incomingForm.maxFileSize, 8 * 1024 * 1024)
assert.strictEqual(incomingForm.maxFieldsSize, 10 * 1024)
assert.strictEqual(incomingForm.maxFields, 50)
assert.strictEqual(incomingForm.parse.firstCall[0], ctx.req)
})
t.test('should apply fields and rename file before returning', async function() {
const assertFilename = 'Lets love.png'
const assertOriginalPath = 'Hitoshi/Fujima/Yuigi.png'
const assertFile = { a: 1, name: assertFilename, path: assertOriginalPath }
const assertFields = { b: 2, c: 3 }
let handler = FormidableHandler(formidable)
incomingForm.parse.returnWith(function(req, cb) {
cb(null, assertFields, { file: assertFile })
})
assert.notOk(ctx.req.body)
assert.notOk(ctx.req.file)
let prefix = new Date().toISOString().replace(/-/g, '').replace('T', '_').replace(/:/g, '').split('.')[0]
await handler(ctx)
assert.strictEqual(ctx.req.body, assertFields)
assert.strictEqual(ctx.req.file, assertFile)
assert.strictEqual(ctx.req.file.path, path.join(os.tmpdir(), ctx.req.file.filename))
assert.match(ctx.req.file.filename, new RegExp(prefix))
assert.match(ctx.req.file.filename, new RegExp(assertFilename))
assert.ok(formidable.fsRename.called)
assert.strictEqual(formidable.fsRename.firstCall[0], assertOriginalPath)
assert.strictEqual(formidable.fsRename.firstCall[1], ctx.req.file.path)
})
t.test('should throw parse error if parse fails', async function() {
const assertError = new Error('Aozora')
let handler = FormidableHandler(formidable)
incomingForm.parse.returnWith(function(req, cb) {
cb(assertError)
})
let err = await assert.isRejected(handler(ctx))
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() {
const assertError = new Error('Aozora')
formidable.fsRename.rejects(assertError)
let handler = FormidableHandler(formidable)
let err = await assert.isRejected(handler(ctx))
assert.strictEqual(err, assertError)
})
t.test('should not call rename if no file is present', async function() {
const assertNotError = new Error('Aozora')
const assertFields = { a: 1 }
formidable.fsRename.rejects(assertNotError)
let handler = FormidableHandler(formidable)
incomingForm.parse.returnWith(function(req, cb) {
cb(null, assertFields, null)
})
await handler(ctx)
assert.strictEqual(ctx.req.body, assertFields)
assert.strictEqual(ctx.req.file, null)
incomingForm.parse.returnWith(function(req, cb) {
cb(null, assertFields, { file: null })
})
await handler(ctx)
assert.strictEqual(ctx.req.body, assertFields)
assert.strictEqual(ctx.req.file, null)
})
t.test('should throw filename error if filename fails', async function() {
const assertError = new Error('Dallaglio Piano')
let handler = FormidableHandler(formidable, {
filename: function() {
throw assertError
}
})
let err = await assert.isRejected(handler(ctx))
assert.strictEqual(err, assertError)
})
t.test('should default to original name of filename returns null', async function() {
const assertFilename = 'Herrscher.png'
let handler = FormidableHandler(formidable, {
filename: function() {
return null
}
})
incomingForm.parse.returnWith(function(req, cb) {
cb(null, { }, { file: { name: assertFilename } })
})
await handler(ctx)
assert.strictEqual(ctx.req.file.filename, assertFilename)
})
t.test('should support multiple filename calls in same second', async function() {
const assertFilename = 'Herrscher.png'
let handler = FormidableHandler(formidable)
await handler(ctx)
let file1 = ctx.req.file
await handler(ctx)
let file2 = ctx.req.file
assert.notStrictEqual(file1, file2)
assert.notStrictEqual(file1.filename, file2.filename)
})
t.test('should support parsing fields as json', async function() {
const assertFields = { b: '2', c: '3', e: 'asdf', f: '{"a": 1}' }
let handler = FormidableHandler(formidable, {
parseFields: true,
})
incomingForm.parse.returnWith(function(req, cb) {
cb(null, assertFields, { file: { name: 'test.png' } })
})
await handler(ctx)
assert.strictEqual(ctx.req.body, assertFields)
assert.strictEqual(ctx.req.body.b, 2)
assert.strictEqual(ctx.req.body.c, 3)
assert.strictEqual(ctx.req.body.e, 'asdf')
assert.deepStrictEqual(ctx.req.body.f, {a: 1})
})
})