Skip to content

Commit

Permalink
Merge 2fdc30f into 6b794a5
Browse files Browse the repository at this point in the history
  • Loading branch information
bajtos committed May 13, 2019
2 parents 6b794a5 + 2fdc30f commit 8edc720
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 13 deletions.
Expand Up @@ -20,6 +20,11 @@ describe('API Explorer (acceptance)', () => {
let app: RestApplication;
let request: Client;

afterEach(async () => {
if (app) await app.stop();
(app as unknown) = undefined;
});

context('with default config', () => {
beforeEach(async () => {
app = givenRestApplication();
Expand Down Expand Up @@ -109,6 +114,26 @@ describe('API Explorer (acceptance)', () => {
}
});

context('with custom basePath', () => {
beforeEach(async () => {
app = givenRestApplication();
app.basePath('/api');
app.component(RestExplorerComponent);
await app.start();
request = createRestAppClient(app);
});

it('uses correct URLs', async () => {
// static assets (including swagger-ui) honor basePath
await request
.get('/api/explorer/')
.expect(200)
.expect('content-type', /html/)
// OpenAPI endpoints DO NOT honor basePath
.expect(/url\: '\/openapi\.json'\,/);
});
});

function givenRestApplication(config?: RestServerConfig) {
const rest = Object.assign({}, givenHttpServerConfig(), config);
return new RestApplication({rest});
Expand Down
Expand Up @@ -3,12 +3,7 @@
// 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 {RestApplication, RestServer, RestServerConfig} from '@loopback/rest';
import {
Client,
createClientForHandler,
Expand All @@ -21,7 +16,6 @@ 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);
Expand All @@ -41,22 +35,35 @@ describe('REST Explorer mounted as an express router', () => {
.expect('location', '/api/explorer/');
});

it('honors basePath config', async () => {
server.basePath('/v1');
await client
// static assets (including swagger-ui) honor basePath
.get('/api/v1/explorer/')
.expect(200)
.expect('content-type', /html/)
// OpenAPI endpoints DO NOT honor basePath
.expect(/url\: '\/api\/openapi\.json'\,/);
});

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);
expressApp.use('/api', (req, res, _next) => {
// defer calling of `server.requestHandler` until a request arrives
server.requestHandler(req, res);
});
}

function givenClient() {
Expand Down
21 changes: 17 additions & 4 deletions packages/rest-explorer/src/rest-explorer.controller.ts
Expand Up @@ -5,11 +5,11 @@

import {inject} from '@loopback/context';
import {
RestBindings,
RestServerConfig,
OpenApiSpecForm,
Request,
Response,
RestBindings,
RestServerConfig,
} from '@loopback/rest';
import * as ejs from 'ejs';
import * as fs from 'fs';
Expand All @@ -26,6 +26,7 @@ export class ExplorerController {
constructor(
@inject(RestBindings.CONFIG, {optional: true})
restConfig: RestServerConfig = {},
@inject(RestBindings.BASE_PATH) private serverBasePath: string,
@inject(RestBindings.Http.REQUEST) private request: Request,
@inject(RestBindings.Http.RESPONSE) private response: Response,
) {
Expand All @@ -39,8 +40,20 @@ export class ExplorerController {

index() {
let openApiSpecUrl = this.openApiSpecUrl;
if (this.request.baseUrl && this.request.baseUrl !== '/') {
openApiSpecUrl = this.request.baseUrl + openApiSpecUrl;

// baseURL is composed from mountPath and basePath
// OpenAPI endpoints ignore basePath but do honor mountPath
let rootPath = this.request.baseUrl;
if (
this.serverBasePath &&
this.serverBasePath !== '/' &&
rootPath.endsWith(this.serverBasePath)
) {
rootPath = rootPath.slice(0, -this.serverBasePath.length);
}

if (rootPath && rootPath !== '/') {
openApiSpecUrl = rootPath + openApiSpecUrl;
}
const data = {
openApiSpecUrl,
Expand Down

0 comments on commit 8edc720

Please sign in to comment.