diff --git a/src/driver/koa/KoaDriver.ts b/src/driver/koa/KoaDriver.ts index b856a321..154bf51d 100644 --- a/src/driver/koa/KoaDriver.ts +++ b/src/driver/koa/KoaDriver.ts @@ -247,11 +247,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) { @@ -401,4 +403,32 @@ export class KoaDriver extends BaseDriver { throw new Error('@koa/multer package was not found installed. Try to install it: npm install @koa/multer --save'); } } + + + /** + * This middleware fixes a bug on koa-multer implementation. + * + * This bug should be fixed by koa-multer PR #15: https://github.com/koa-modules/multer/pull/15 + */ + private async fixMulterRequestAssignment(ctx: any, next: Function) { + if ('request' in ctx) { + if (ctx.req.body) ctx.request.body = ctx.req.body; + if (ctx.req.file) ctx.request.file = ctx.req.file; + if (ctx.req.files) { + ctx.request.files = ctx.req.files; + ctx.files = ctx.req.files; + } + } + + 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 efa49c7c..88bff297 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'); @@ -52,27 +96,52 @@ describe(``, () => { 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() }); });