Skip to content

Commit f4be330

Browse files
committed
feat(cli): add code template for default home page controller
1 parent c146366 commit f4be330

File tree

7 files changed

+177
-22
lines changed

7 files changed

+177
-22
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<title><%= project.description %></title>
6+
7+
<meta charset="utf-8">
8+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
9+
<meta name="viewport" content="width=device-width, initial-scale=1">
10+
<link rel="shortcut icon" type="image/x-icon" href="//v4.loopback.io/favicon.ico">
11+
12+
<style>
13+
h3 {
14+
margin-left: 25px;
15+
text-align: center;
16+
}
17+
18+
a, a:visited {
19+
color: #3f5dff;
20+
}
21+
22+
h3 a {
23+
margin-left: 10px;
24+
}
25+
26+
a:hover, a:focus, a:active {
27+
color: #001956;
28+
}
29+
30+
.power {
31+
position: absolute;
32+
bottom: 25px;
33+
left: 50%;
34+
transform: translateX(-50%);
35+
}
36+
37+
.info {
38+
position: absolute;
39+
top: 50%;
40+
left: 50%;
41+
transform: translate(-50%, -50%)
42+
}
43+
44+
.info h1 {
45+
text-align: center;
46+
margin-bottom: 0px;
47+
}
48+
49+
.info p {
50+
text-align: center;
51+
margin-bottom: 3em;
52+
margin-top: 1em;
53+
}
54+
</style>
55+
</head>
56+
57+
<body>
58+
<div class="info">
59+
<h1><%= project.name %></h1>
60+
<p>Version <%= project.version || '1.0.0' %></p>
61+
62+
<h3>OpenAPI spec: <a href="/openapi.json">/openapi.json</a></h4>
63+
<h3>API Explorer: <a href="/explorer">/explorer</a></h4>
64+
</div>
65+
66+
<footer class="power">
67+
<a href="https://v4.loopback.io" target="_blank">
68+
<img src="https://loopback.io/images/branding/powered-by-loopback/blue/powered-by-loopback-sm.png" />
69+
</a>
70+
</footer>
71+
</body>
72+
73+
</html>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import {get} from '@loopback/openapi-v3';
2+
import * as fs from 'fs';
3+
import * as path from 'path';
4+
import {inject} from '@loopback/context';
5+
import {RestBindings, Response} from '@loopback/rest';
6+
7+
export class HomePageController {
8+
private html: string;
9+
constructor(@inject(RestBindings.Http.RESPONSE) private response: Response) {
10+
this.html = fs.readFileSync(
11+
path.join(__dirname, '../../../public/index.html'),
12+
'utf-8',
13+
);
14+
}
15+
16+
@get('/', {
17+
responses: {
18+
'200': {
19+
description: 'Home Page',
20+
content: {'text/html': {schema: {type: 'string'}}},
21+
},
22+
},
23+
})
24+
homePage() {
25+
this.response
26+
.status(200)
27+
.contentType('html')
28+
.send(this.html);
29+
return this.response;
30+
}
31+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright IBM Corp. 2018. All Rights Reserved.
2+
// Node module: @loopback/example-shopping
3+
// This file is licensed under the MIT License.
4+
// License text available at https://opensource.org/licenses/MIT
5+
6+
import {Client} from '@loopback/testlab';
7+
import {<%= project.applicationName %>} from '../..';
8+
import {setupApplication} from './test-helper';
9+
10+
describe('HomePageController', () => {
11+
let app: <%= project.applicationName %>;
12+
let client: Client;
13+
14+
before('setupApplication', async () => {
15+
({app, client} = await setupApplication());
16+
});
17+
18+
after(async () => {
19+
await app.stop();
20+
});
21+
22+
it('exposes a default home page', async () => {
23+
await client
24+
.get('/')
25+
.expect(200)
26+
.expect('Content-Type', /text\/html/);
27+
});
28+
});
Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,13 @@
1-
import {
2-
Client,
3-
createRestAppClient,
4-
givenHttpServerConfig,
5-
expect,
6-
} from '@loopback/testlab';
1+
import {Client, expect} from '@loopback/testlab';
72
import {<%= project.applicationName %>} from '../..';
3+
import {setupApplication} from './test-helper';
84

95
describe('PingController', () => {
106
let app: <%= project.applicationName %>;
117
let client: Client;
128

13-
before(givenAnApplication);
14-
15-
before(async () => {
16-
await app.boot();
17-
await app.start();
18-
});
19-
20-
before(() => {
21-
client = createRestAppClient(app);
9+
before('setupApplication', async () => {
10+
({app, client} = await setupApplication());
2211
});
2312

2413
after(async () => {
@@ -29,10 +18,4 @@ describe('PingController', () => {
2918
const res = await client.get('/ping?msg=world').expect(200);
3019
expect(res.body).to.containEql({greeting: 'Hello from LoopBack'});
3120
});
32-
33-
function givenAnApplication() {
34-
app = new <%= project.applicationName %>({
35-
rest: givenHttpServerConfig(),
36-
});
37-
}
3821
});
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import {<%= project.applicationName %>} from '../..';
2+
import {
3+
createRestAppClient,
4+
givenHttpServerConfig,
5+
Client,
6+
} from '@loopback/testlab';
7+
8+
export async function setupApplication(): Promise<AppWithClient> {
9+
const app = new <%= project.applicationName %>({
10+
rest: givenHttpServerConfig(),
11+
});
12+
13+
await app.boot();
14+
await app.start();
15+
16+
const client = createRestAppClient(app);
17+
18+
return {app, client};
19+
}
20+
21+
export interface AppWithClient {
22+
app: <%= project.applicationName %>;
23+
client: Client;
24+
}

packages/cli/lib/utils.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ exports.renameEJS = function() {
259259

260260
// extname already contains a leading '.'
261261
const fileName = `${basename}${extname}`;
262-
const result = fileName.match(/(.+)(.ts|.json|.js|.md)\.ejs$/);
262+
const result = fileName.match(/(.+)(.ts|.json|.js|.md|.html)\.ejs$/);
263263
if (result) {
264264
extname = result[2];
265265
basename = result[1];

packages/cli/test/integration/generators/app.integration.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,22 @@ describe('app-generator specific files', () => {
6363
'test/acceptance/ping.controller.acceptance.ts',
6464
/describe\('PingController'/,
6565
);
66+
assert.fileContent(
67+
'src/controllers/home-page.controller.ts',
68+
/export class HomePageController/,
69+
);
70+
assert.fileContent(
71+
'src/controllers/home-page.controller.ts',
72+
/homePage\(\)/,
73+
);
74+
assert.fileContent(
75+
'test/acceptance/home-page.controller.acceptance.ts',
76+
/describe\('HomePageController'/,
77+
);
78+
assert.fileContent(
79+
'test/acceptance/test-helper.ts',
80+
/export async function setupApplication/,
81+
);
6682
});
6783
});
6884

0 commit comments

Comments
 (0)