From c3d0ec5dc54d708bb2ab2bffc98a11033069f9a9 Mon Sep 17 00:00:00 2001 From: Swain Molster Date: Tue, 31 May 2022 16:25:06 -0400 Subject: [PATCH 1/2] feat: allow customizing success status codes --- src/koa.test.ts | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ src/koa.ts | 6 +++++- 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/src/koa.test.ts b/src/koa.test.ts index 5a3bbb9..e90f266 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,54 @@ 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); +}); 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(); }; From 19320c7080ec1b80111998585b5f7e1693733f1c Mon Sep 17 00:00:00 2001 From: Swain Molster Date: Tue, 31 May 2022 16:47:46 -0400 Subject: [PATCH 2/2] close server on exit --- src/koa.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/koa.test.ts b/src/koa.test.ts index e90f266..996ed2e 100644 --- a/src/koa.test.ts +++ b/src/koa.test.ts @@ -78,4 +78,6 @@ test('setting a 200-level response code overrides the response', async () => { const createRes = await client.post('/posts'); expect(createRes.status).toStrictEqual(200); + + server.close(); });