From cdfeb055bcf978a2bd8144848831668f7e2d0853 Mon Sep 17 00:00:00 2001 From: gongyanyu Date: Thu, 30 Sep 2021 11:23:57 +0800 Subject: [PATCH] fix: After the first rendering of html, all request results return the first rendered html --- src/driver/koa/KoaDriver.ts | 18 +++- test/functional/render-decorator.spec.ts | 113 ++++++++++++++++++----- 2 files changed, 105 insertions(+), 26 deletions(-) diff --git a/src/driver/koa/KoaDriver.ts b/src/driver/koa/KoaDriver.ts index d0159095..d628f0e0 100644 --- a/src/driver/koa/KoaDriver.ts +++ b/src/driver/koa/KoaDriver.ts @@ -244,11 +244,13 @@ export class KoaDriver extends BaseDriver { } } else if (action.renderedTemplate) { // if template is set then render it // TODO: not working in koa - const renderOptions = result && result instanceof Object ? result : {}; + options.context.renderOptions = { + page : action.renderedTemplate, + locals : result && result instanceof Object ? result : {}, + } + // eslint-disable-next-line @typescript-eslint/unbound-method + if(this.koa.middleware.indexOf(this.loadKoaViews) === -1) this.koa.use(this.loadKoaViews) - this.koa.use(async function (ctx: any, next: any) { - await ctx.render(action.renderedTemplate, renderOptions); - }); } else if (result === undefined) { // throw NotFoundError on undefined response if (action.undefinedResultCode instanceof Function) { @@ -416,4 +418,12 @@ export class KoaDriver extends BaseDriver { return await next(); } + + private async loadKoaViews(ctx: any, next: Function) { + if('renderOptions' in ctx){ + return await ctx.render(ctx.renderOptions.page, ctx.renderOptions.locals) + } + + return await next() + } } diff --git a/test/functional/render-decorator.spec.ts b/test/functional/render-decorator.spec.ts index f248a388..80e0a189 100644 --- a/test/functional/render-decorator.spec.ts +++ b/test/functional/render-decorator.spec.ts @@ -2,19 +2,55 @@ import express, { Application as ExpressApplication } from 'express'; import { Server as HttpServer } from 'http'; import HttpStatusCodes from 'http-status-codes'; import mustacheExpress from 'mustache-express'; +import koaViews from 'koa-views'; import path from 'path'; import { Controller } from '../../src/decorator/Controller'; import { Get } from '../../src/decorator/Get'; import { Render } from '../../src/decorator/Render'; import { Res } from '../../src/decorator/Res'; -import { createExpressServer, getMetadataArgsStorage } from '../../src/index'; +import { createExpressServer, createKoaServer, getMetadataArgsStorage } from '../../src/index'; import { axios } from '../utilities/axios'; import DoneCallback = jest.DoneCallback; describe(``, () => { - let expressServer: HttpServer; + + function cases(){ + + it('should render a template and use given variables', async () => { + expect.assertions(6); + const response = await axios.get('/index'); + expect(response.status).toEqual(HttpStatusCodes.OK); + expect(response.data).toContain(''); + expect(response.data).toContain(''); + expect(response.data).toContain('Routing-controllers'); + expect(response.data).toContain(''); + expect(response.data).toContain(''); + }); + + it('should render a template with given variables and locals variables', async () => { + expect.assertions(7); + const response = await axios.get('/locals'); + expect(response.status).toEqual(HttpStatusCodes.OK); + expect(response.data).toContain(''); + expect(response.data).toContain(''); + expect(response.data).toContain('Routing-controllers'); + expect(response.data).toContain('my-variable'); + expect(response.data).toContain(''); + expect(response.data).toContain(''); + }); + + it('should render to different html by random variables', async () => { + expect.assertions(2); + const response = await axios.get('/random'); + expect(response.status).toEqual(HttpStatusCodes.OK); + const response2 = await axios.get('/random'); + expect(response.data).not.toEqual(response2.data) + }); + } describe('template rendering', () => { + let expressServer: HttpServer; + beforeAll((done: DoneCallback) => { getMetadataArgsStorage().reset(); @@ -37,6 +73,14 @@ describe(``, () => { name: 'Routing-controllers', }; } + + @Get('/random') + @Render('render-test-spec.html') + random(): any { + return { + name: Math.random(), + }; + } } const resourcePath: string = path.resolve(__dirname, '../resources'); @@ -50,27 +94,52 @@ describe(``, () => { afterAll((done: DoneCallback) => expressServer.close(done)); - it('should render a template and use given variables', async () => { - expect.assertions(6); - const response = await axios.get('/index'); - expect(response.status).toEqual(HttpStatusCodes.OK); - expect(response.data).toContain(''); - expect(response.data).toContain(''); - expect(response.data).toContain('Routing-controllers'); - expect(response.data).toContain(''); - expect(response.data).toContain(''); - }); + cases() + }); - it('should render a template with given variables and locals variables', async () => { - expect.assertions(7); - const response = await axios.get('/locals'); - expect(response.status).toEqual(HttpStatusCodes.OK); - expect(response.data).toContain(''); - expect(response.data).toContain(''); - expect(response.data).toContain('Routing-controllers'); - expect(response.data).toContain('my-variable'); - expect(response.data).toContain(''); - expect(response.data).toContain(''); + describe('template rendering in koa', () => { + let koaServer: HttpServer; + + beforeAll((done: DoneCallback) => { + getMetadataArgsStorage().reset(); + + @Controller() + class RenderController { + @Get('/index') + @Render('render-test-spec.html') + index(): any { + return { + name: 'Routing-controllers', + }; + } + + @Get('/locals') + @Render('render-test-locals-spec.html') + locals(@Res() res: any): any { + + return { + name: 'Routing-controllers', + myVariable: 'my-variable' + }; + } + + @Get('/random') + @Render('render-test-spec.html') + random(): any { + return { + name: Math.random(), + }; + } + } + + const resourcePath: string = path.resolve(__dirname, '../resources'); + const app = createKoaServer(); + app.use(koaViews(resourcePath, { map: { html: "handlebars" }})); + koaServer = app.listen(3001, done); }); + + afterAll((done: DoneCallback) => koaServer.close(done)); + + cases() }); });