From ebb18d33ffa4ebd990a558aec630fff4f5fc5735 Mon Sep 17 00:00:00 2001 From: Ethan Smith Date: Tue, 2 Apr 2019 14:04:36 -0400 Subject: [PATCH] feat: Add plain text body for redirects (#44) --- src/Response.ts | 18 +++++++++++++++++- tests/Response.test.ts | 40 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/src/Response.ts b/src/Response.ts index e336e2e..a8697e3 100644 --- a/src/Response.ts +++ b/src/Response.ts @@ -523,7 +523,23 @@ export default class Response { path = args[0]; } - return this.status(code).location(path).end(); + // NOTE: We must set the status and location before creating the response body. The + // status and location functions contain logic needed to properly create the body. + // (e.g. status message creation and 'back' handling) + this.status(code).location(path); + + const target = _.first(this.getHeaders().Location); + + // TODO: Once Request supports parsing the accept headers, add support for returning + // an HTML response (assuming the request accepts HTML back). See: + // https://github.com/expressjs/express/blob/3d10279826f59bf68e28995ce423f7bc4d2f11cf/lib/response.js#L930-L933 + const body = this.getStatus().message + '. Redirecting to ' + target; + + if (this._request.method !== 'HEAD') { + this._body = body; + } + + return this.end(); } /** diff --git a/tests/Response.test.ts b/tests/Response.test.ts index afc03ad..55d4b82 100644 --- a/tests/Response.test.ts +++ b/tests/Response.test.ts @@ -856,6 +856,24 @@ describe('Response', () => { }); describe('redirect', () => { + it('returns a redirect for the given path', () => { + const evt = albMultiValHeadersRequest(), + req = new Request(app, evt, handlerContext()), + target = 'https://en.wikipedia.org/wiki/HTTP_referer'; + + resp = new Response(app, req, cb); + + const output = makeOutput(302, 'Found', 'Found. Redirecting to ' + target, { + 'Location': [ target ], + }); + + resp.redirect(target); + + addHeadersFromMultiValueHeaders(resp, output); + assert.calledOnce(cb); + expect(cb.firstCall.args).to.eql([ undefined, output ]); + }); + const testWithBack = (referer: string | null | false, expectation: string, code?: number, msg?: string): void => { it(`redirects - special value 'back', status ${code}, referer '${referer}'`, () => { let evt; @@ -880,7 +898,9 @@ describe('Response', () => { resp = new Response(app, req, cb); - const output = makeOutput(code ? code : 302, msg ? msg : 'Found', '', { + const expectedBody = (msg ? msg : 'Found') + '. Redirecting to ' + expectation; + + const output = makeOutput(code ? code : 302, msg ? msg : 'Found', expectedBody, { 'Location': [ expectation ], }); @@ -920,6 +940,24 @@ describe('Response', () => { testWithBack(false, '/', code, msg); }); + it('doesn\'t return a body for HEAD requests', () => { + const evt = _.extend(albMultiValHeadersRequest(), { httpMethod: 'HEAD' }), + req = new Request(app, evt, handlerContext()), + target = 'https://en.wikipedia.org/wiki/HTTP_referer'; + + resp = new Response(app, req, cb); + + const output = makeOutput(302, 'Found', '', { + 'Location': [ target ], + }); + + resp.redirect(target); + + addHeadersFromMultiValueHeaders(resp, output); + assert.calledOnce(cb); + expect(cb.firstCall.args).to.eql([ undefined, output ]); + }); + }); describe('send', () => {