diff --git a/packages/cli/generators/app/templates/public/index.html.ejs b/packages/cli/generators/app/templates/public/index.html.ejs
new file mode 100644
index 000000000000..88759a7be6ac
--- /dev/null
+++ b/packages/cli/generators/app/templates/public/index.html.ejs
@@ -0,0 +1,73 @@
+
+
+
+
+ <%= project.description %>
+
+
+
+
+
+
+
+
+
+
+
+
<%= project.name %>
+
Version <%= project.version || '1.0.0' %>
+
+
+
+
+
+
+
diff --git a/packages/cli/generators/app/templates/src/controllers/home-page.controller.ts.ejs b/packages/cli/generators/app/templates/src/controllers/home-page.controller.ts.ejs
new file mode 100644
index 000000000000..f78f989e4632
--- /dev/null
+++ b/packages/cli/generators/app/templates/src/controllers/home-page.controller.ts.ejs
@@ -0,0 +1,31 @@
+import {get} from '@loopback/openapi-v3';
+import * as fs from 'fs';
+import * as path from 'path';
+import {inject} from '@loopback/context';
+import {RestBindings, Response} from '@loopback/rest';
+
+export class HomePageController {
+ private html: string;
+ constructor(@inject(RestBindings.Http.RESPONSE) private response: Response) {
+ this.html = fs.readFileSync(
+ path.join(__dirname, '../../../public/index.html'),
+ 'utf-8',
+ );
+ }
+
+ @get('/', {
+ responses: {
+ '200': {
+ description: 'Home Page',
+ content: {'text/html': {schema: {type: 'string'}}},
+ },
+ },
+ })
+ homePage() {
+ this.response
+ .status(200)
+ .contentType('html')
+ .send(this.html);
+ return this.response;
+ }
+}
diff --git a/packages/cli/generators/app/templates/test/acceptance/home-page.controller.acceptance.ts.ejs b/packages/cli/generators/app/templates/test/acceptance/home-page.controller.acceptance.ts.ejs
new file mode 100644
index 000000000000..913261ec8fa5
--- /dev/null
+++ b/packages/cli/generators/app/templates/test/acceptance/home-page.controller.acceptance.ts.ejs
@@ -0,0 +1,28 @@
+// Copyright IBM Corp. 2018. All Rights Reserved.
+// Node module: @loopback/example-shopping
+// This file is licensed under the MIT License.
+// License text available at https://opensource.org/licenses/MIT
+
+import {Client} from '@loopback/testlab';
+import {<%= project.applicationName %>} from '../..';
+import {setupApplication} from './test-helper';
+
+describe('HomePageController', () => {
+ let app: <%= project.applicationName %>;
+ let client: Client;
+
+ before('setupApplication', async () => {
+ ({app, client} = await setupApplication());
+ });
+
+ after(async () => {
+ await app.stop();
+ });
+
+ it('exposes a default home page', async () => {
+ await client
+ .get('/')
+ .expect(200)
+ .expect('Content-Type', /text\/html/);
+ });
+});
diff --git a/packages/cli/generators/app/templates/test/acceptance/ping.controller.acceptance.ts.ejs b/packages/cli/generators/app/templates/test/acceptance/ping.controller.acceptance.ts.ejs
index aaaf55d20d00..9aab5cb41fe3 100644
--- a/packages/cli/generators/app/templates/test/acceptance/ping.controller.acceptance.ts.ejs
+++ b/packages/cli/generators/app/templates/test/acceptance/ping.controller.acceptance.ts.ejs
@@ -1,24 +1,13 @@
-import {
- Client,
- createRestAppClient,
- givenHttpServerConfig,
- expect,
-} from '@loopback/testlab';
+import {Client, expect} from '@loopback/testlab';
import {<%= project.applicationName %>} from '../..';
+import {setupApplication} from './test-helper';
describe('PingController', () => {
let app: <%= project.applicationName %>;
let client: Client;
- before(givenAnApplication);
-
- before(async () => {
- await app.boot();
- await app.start();
- });
-
- before(() => {
- client = createRestAppClient(app);
+ before('setupApplication', async () => {
+ ({app, client} = await setupApplication());
});
after(async () => {
@@ -29,10 +18,4 @@ describe('PingController', () => {
const res = await client.get('/ping?msg=world').expect(200);
expect(res.body).to.containEql({greeting: 'Hello from LoopBack'});
});
-
- function givenAnApplication() {
- app = new <%= project.applicationName %>({
- rest: givenHttpServerConfig(),
- });
- }
});
diff --git a/packages/cli/generators/app/templates/test/acceptance/test-helper.ts.ejs b/packages/cli/generators/app/templates/test/acceptance/test-helper.ts.ejs
new file mode 100644
index 000000000000..e5176aed740f
--- /dev/null
+++ b/packages/cli/generators/app/templates/test/acceptance/test-helper.ts.ejs
@@ -0,0 +1,24 @@
+import {<%= project.applicationName %>} from '../..';
+import {
+ createRestAppClient,
+ givenHttpServerConfig,
+ Client,
+} from '@loopback/testlab';
+
+export async function setupApplication(): Promise {
+ const app = new <%= project.applicationName %>({
+ rest: givenHttpServerConfig(),
+ });
+
+ await app.boot();
+ await app.start();
+
+ const client = createRestAppClient(app);
+
+ return {app, client};
+}
+
+export interface AppWithClient {
+ app: <%= project.applicationName %>;
+ client: Client;
+}
diff --git a/packages/cli/lib/utils.js b/packages/cli/lib/utils.js
index 2b34f2a14a7a..6ffa0d030020 100644
--- a/packages/cli/lib/utils.js
+++ b/packages/cli/lib/utils.js
@@ -257,7 +257,7 @@ exports.renameEJS = function() {
// extname already contains a leading '.'
const fileName = `${basename}${extname}`;
- const result = fileName.match(/(.+)(.ts|.json|.js|.md)\.ejs$/);
+ const result = fileName.match(/(.+)(.ts|.json|.js|.md|.html)\.ejs$/);
if (result) {
extname = result[2];
basename = result[1];
diff --git a/packages/cli/test/integration/generators/app.integration.js b/packages/cli/test/integration/generators/app.integration.js
index d8e549f01b22..ca2f34e859a7 100644
--- a/packages/cli/test/integration/generators/app.integration.js
+++ b/packages/cli/test/integration/generators/app.integration.js
@@ -63,6 +63,22 @@ describe('app-generator specific files', () => {
'test/acceptance/ping.controller.acceptance.ts',
/describe\('PingController'/,
);
+ assert.fileContent(
+ 'src/controllers/home-page.controller.ts',
+ /export class HomePageController/,
+ );
+ assert.fileContent(
+ 'src/controllers/home-page.controller.ts',
+ /homePage\(\)/,
+ );
+ assert.fileContent(
+ 'test/acceptance/home-page.controller.acceptance.ts',
+ /describe\('HomePageController'/,
+ );
+ assert.fileContent(
+ 'test/acceptance/test-helper.ts',
+ /export async function setupApplication/,
+ );
});
});