diff --git a/packages/rest-explorer/package.json b/packages/rest-explorer/package.json index 6098845b9b86..551f07aaa34e 100644 --- a/packages/rest-explorer/package.json +++ b/packages/rest-explorer/package.json @@ -28,7 +28,9 @@ "@loopback/testlab": "^1.0.7", "@loopback/tslint-config": "^2.0.1", "@types/ejs": "^2.6.0", - "@types/node": "^10.1.1" + "@types/express": "^4.16.1", + "@types/node": "^10.1.1", + "express": "^4.16.4" }, "keywords": [ "LoopBack", diff --git a/packages/rest-explorer/src/__tests__/acceptance/rest-explorer.express.acceptance.ts b/packages/rest-explorer/src/__tests__/acceptance/rest-explorer.express.acceptance.ts new file mode 100644 index 000000000000..df575b420bae --- /dev/null +++ b/packages/rest-explorer/src/__tests__/acceptance/rest-explorer.express.acceptance.ts @@ -0,0 +1,65 @@ +// Copyright IBM Corp. 2017,2018. All Rights Reserved. +// Node module: @loopback/rest +// This file is licensed under the MIT License. +// License text available at https://opensource.org/licenses/MIT + +import { + HttpRequestListener, + RestApplication, + RestServer, + RestServerConfig, +} from '@loopback/rest'; +import { + Client, + createClientForHandler, + givenHttpServerConfig, +} from '@loopback/testlab'; +import * as express from 'express'; +import {RestExplorerComponent} from '../..'; + +describe('REST Explorer mounted as an express router', () => { + let client: Client; + let expressApp: express.Application; + let server: RestServer; + let handler: HttpRequestListener; + beforeEach(givenLoopBackApp); + beforeEach(givenExpressApp); + beforeEach(givenClient); + + it('exposes API Explorer at "/api/explorer/"', async () => { + await client + .get('/api/explorer/') + .expect(200) + .expect('content-type', /html/) + .expect(/url\: '\/api\/openapi\.json'\,/); + }); + + it('redirects from "/api/explorer" to "/api/explorer/"', async () => { + await client + .get('/api/explorer') + .expect(301) + .expect('location', '/api/explorer/'); + }); + + async function givenLoopBackApp( + options: {rest: RestServerConfig} = {rest: {port: 0}}, + ) { + options.rest = givenHttpServerConfig(options.rest); + const app = new RestApplication(options); + app.component(RestExplorerComponent); + server = await app.getServer(RestServer); + handler = server.requestHandler; + } + + /** + * Create an express app that mounts the LoopBack routes to `/api` + */ + function givenExpressApp() { + expressApp = express(); + expressApp.use('/api', handler); + } + + function givenClient() { + client = createClientForHandler(expressApp); + } +}); diff --git a/packages/rest-explorer/src/rest-explorer.controller.ts b/packages/rest-explorer/src/rest-explorer.controller.ts index 85dac4796852..6bc24099141c 100644 --- a/packages/rest-explorer/src/rest-explorer.controller.ts +++ b/packages/rest-explorer/src/rest-explorer.controller.ts @@ -33,12 +33,20 @@ export class ExplorerController { } indexRedirect() { - this.response.redirect(301, this.request.url + '/'); + let url = this.request.url + '/'; + if (this.request.baseUrl && this.request.baseUrl !== '/') { + url = this.request.baseUrl + url; + } + this.response.redirect(301, url); } index() { + let openApiSpecUrl = this.openApiSpecUrl; + if (this.request.baseUrl && this.request.baseUrl !== '/') { + openApiSpecUrl = this.request.baseUrl + openApiSpecUrl; + } const data = { - openApiSpecUrl: this.openApiSpecUrl, + openApiSpecUrl, }; const homePage = templateFn(data);