diff --git a/src/koa.test.ts b/src/koa.test.ts index 5a3bbb9..996ed2e 100644 --- a/src/koa.test.ts +++ b/src/koa.test.ts @@ -1,3 +1,6 @@ +import axios from 'axios'; +import Koa = require('koa'); +import bodyParser = require('koa-bodyparser'); import Router = require('koa-router'); import { implementSchema } from '.'; import { withAssumptions } from './meta-schema'; @@ -25,3 +28,56 @@ test('using unsupported methods throws immediately', () => { ); }).toThrowError('Unsupported method detected: OPTIONS /post'); }); + +test('setting a 200-level response code overrides the response', async () => { + const router = new Router(); + implementSchema( + withAssumptions({ + Endpoints: { + 'DELETE /post/:id': { + Name: 'deletePost', + Response: {}, + }, + 'POST /posts': { + Name: 'createPost', + Response: {}, + }, + }, + }), + { + on: router, + parse: () => null as any, + implementation: { + 'DELETE /post/:id': (ctx) => { + ctx.response.status = 204; + return {}; + }, + 'POST /posts': (ctx) => { + ctx.response.status = 301; + return {}; + }, + }, + }, + ); + + const server = new Koa() + .use(bodyParser()) + .use(router.routes()) + .use(router.allowedMethods()) + .listen(); + + const { port } = server.address() as any; + + const client = axios.create({ + baseURL: `http://localhost:${port}`, + validateStatus: () => true, + }); + + const deleteRes = await client.delete('/post/bogus'); + expect(deleteRes.status).toStrictEqual(204); + + const createRes = await client.post('/posts'); + expect(createRes.status).toStrictEqual(200); + + server.close(); +}); diff --git a/src/koa.ts b/src/koa.ts index 56ad0f4..5786817 100644 --- a/src/koa.ts +++ b/src/koa.ts @@ -126,7 +126,11 @@ export const implementSchema = >( // 3. Return the result and call the next middleware. ctx.response.body = response; - ctx.response.status = 200; + // If the response status is already set to a 200-level code, don't override it. + // This is the mechanism for allowing consumers to customize response codes. + if (ctx.response.status < 200 || ctx.response.status >= 300) { + ctx.response.status = 200; + } return next(); };