Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(rest): make sure basePath is included in RestServer.url #2560

Merged
merged 1 commit into from Mar 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
88 changes: 72 additions & 16 deletions packages/rest/src/__tests__/integration/rest.server.integration.ts
Expand Up @@ -6,12 +6,12 @@
import {Application} from '@loopback/core';
import {
createClientForHandler,
createRestAppClient,
expect,
givenHttpServerConfig,
httpsGetAsync,
itSkippedOnTravis,
supertest,
createRestAppClient,
} from '@loopback/testlab';
import * as fs from 'fs';
import {IncomingMessage, ServerResponse} from 'http';
Expand All @@ -26,32 +26,88 @@ import {
Request,
requestBody,
RequestContext,
RestApplication,
RestBindings,
RestComponent,
RestServer,
RestServerConfig,
RestApplication,
} from '../..';
const readFileAsync = util.promisify(fs.readFile);

const FIXTURES = path.resolve(__dirname, '../../../fixtures');
const ASSETS = path.resolve(FIXTURES, 'assets');

describe('RestServer (integration)', () => {
it('exports url property', async () => {
const server = await givenAServer();
server.handler(dummyRequestHandler);
expect(server.url).to.be.undefined();
await server.start();
expect(server)
.to.have.property('url')
.which.is.a.String()
.match(/http|https\:\/\//);
await supertest(server.url)
.get('/')
.expect(200, 'Hello');
await server.stop();
expect(server.url).to.be.undefined();
describe('url/rootUrl properties', () => {
let server: RestServer;

afterEach('shuts down server', async () => {
if (!server) return;
await server.stop();
raymondfeng marked this conversation as resolved.
Show resolved Hide resolved
expect(server.url).to.be.undefined();
expect(server.rootUrl).to.be.undefined();
});

describe('url', () => {
it('exports url property', async () => {
server = await givenAServer();
server.handler(dummyRequestHandler);
expect(server.url).to.be.undefined();
await server.start();
expect(server)
.to.have.property('url')
.which.is.a.String()
.match(/http|https\:\/\//);
await supertest(server.url)
.get('/')
.expect(200, 'Hello');
});

it('includes basePath in the url property', async () => {
server = await givenAServer({rest: {basePath: '/api'}});
server.handler(dummyRequestHandler);
expect(server.url).to.be.undefined();
await server.start();
expect(server)
.to.have.property('url')
.which.is.a.String()
.match(/http|https\:\/\//);
expect(server.url).to.match(/api$/);
await supertest(server.url)
.get('/')
.expect(200, 'Hello');
});
});

describe('rootUrl', () => {
it('exports rootUrl property', async () => {
server = await givenAServer();
server.handler(dummyRequestHandler);
expect(server.rootUrl).to.be.undefined();
await server.start();
expect(server)
.to.have.property('rootUrl')
.which.is.a.String()
.match(/http|https\:\/\//);
await supertest(server.rootUrl)
.get('/api')
.expect(200, 'Hello');
});

it('does not include basePath in rootUrl', async () => {
server = await givenAServer({rest: {basePath: '/api'}});
server.handler(dummyRequestHandler);
expect(server.rootUrl).to.be.undefined();
await server.start();
expect(server)
.to.have.property('rootUrl')
.which.is.a.String()
.match(/http|https\:\/\//);
await supertest(server.rootUrl)
.get('/api')
.expect(200, 'Hello');
});
});
});

it('parses query without decorated rest query params', async () => {
Expand Down
16 changes: 16 additions & 0 deletions packages/rest/src/rest.server.ts
Expand Up @@ -151,7 +151,23 @@ export class RestServer extends Context implements Server, HttpServerLike {
return this._httpServer ? this._httpServer.listening : false;
}

/**
* The base url for the server, including the basePath if set. For example,
* the value will be 'http://localhost:3000/api' if `basePath` is set to
* '/api'.
*/
get url(): string | undefined {
raymondfeng marked this conversation as resolved.
Show resolved Hide resolved
let serverUrl = this.rootUrl;
if (!serverUrl) return serverUrl;
serverUrl = serverUrl + (this._basePath || '');
raymondfeng marked this conversation as resolved.
Show resolved Hide resolved
return serverUrl;
}

/**
* The root url for the server without the basePath. For example, the value
* will be 'http://localhost:3000' regardless of the `basePath`.
*/
get rootUrl(): string | undefined {
raymondfeng marked this conversation as resolved.
Show resolved Hide resolved
return this._httpServer && this._httpServer.url;
}

Expand Down
3 changes: 2 additions & 1 deletion packages/testlab/src/client.ts
Expand Up @@ -33,7 +33,7 @@ export function createClientForHandler(
* @param app A running (listening) instance of a RestApplication.
*/
export function createRestAppClient(app: RestApplicationLike) {
const url = app.restServer.url;
const url = app.restServer.rootUrl || app.restServer.url;
if (!url) {
throw new Error(
`Cannot create client for ${app.constructor.name}, it is not listening.`,
Expand All @@ -53,4 +53,5 @@ export interface RestApplicationLike {

export interface RestServerLike {
url?: string;
rootUrl?: string;
}