-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(cli): add code template for default home page controller #1763
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
|
||
<head> | ||
<title><%= project.description %></title> | ||
|
||
<meta charset="utf-8"> | ||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1"> | ||
<link rel="shortcut icon" type="image/x-icon" href="//v4.loopback.io/favicon.ico"> | ||
|
||
<style> | ||
h3 { | ||
margin-left: 25px; | ||
text-align: center; | ||
} | ||
|
||
a, a:visited { | ||
color: #3f5dff; | ||
} | ||
|
||
h3 a { | ||
margin-left: 10px; | ||
} | ||
|
||
a:hover, a:focus, a:active { | ||
color: #001956; | ||
} | ||
|
||
.power { | ||
position: absolute; | ||
bottom: 25px; | ||
left: 50%; | ||
transform: translateX(-50%); | ||
} | ||
|
||
.info { | ||
position: absolute; | ||
top: 50%; | ||
left: 50%; | ||
transform: translate(-50%, -50%) | ||
} | ||
|
||
.info h1 { | ||
text-align: center; | ||
margin-bottom: 0px; | ||
} | ||
|
||
.info p { | ||
text-align: center; | ||
margin-bottom: 3em; | ||
margin-top: 1em; | ||
} | ||
</style> | ||
</head> | ||
|
||
<body> | ||
<div class="info"> | ||
<h1><%= project.name %></h1> | ||
<p>Version <%= project.version || '1.0.0' %></p> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIUC, we are hard-coding project name and version to @raymondfeng @virkt25 Is this intentional? I thought our intention was to render the home pages from an EJS template at runtime, that's what I see in loopbackio/loopback4-example-shopping#16. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was intentional as the first step: We wanted to keep the HomePageController implementation simple and easy to understand.
That's been said, I'm fine to upgrade it to an EJS view once #1764 is landed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we remove the Version from the static page then? Application name is unlikely to change, but the version is going to change often. |
||
|
||
<h3>OpenAPI spec: <a href="/openapi.json">/openapi.json</a></h4> | ||
<h3>API Explorer: <a href="/explorer">/explorer</a></h4> | ||
</div> | ||
|
||
<footer class="power"> | ||
<a href="https://v4.loopback.io" target="_blank"> | ||
<img src="https://loopback.io/images/branding/powered-by-loopback/blue/powered-by-loopback-sm.png" /> | ||
</a> | ||
</footer> | ||
</body> | ||
|
||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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/); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import {<%= project.applicationName %>} from '../..'; | ||
import { | ||
createRestAppClient, | ||
givenHttpServerConfig, | ||
Client, | ||
} from '@loopback/testlab'; | ||
|
||
export async function setupApplication(): Promise<AppWithClient> { | ||
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; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we also assert |
||
'test/acceptance/home-page.controller.acceptance.ts', | ||
/describe\('HomePageController'/, | ||
); | ||
assert.fileContent( | ||
'test/acceptance/test-helper.ts', | ||
/export async function setupApplication/, | ||
); | ||
}); | ||
}); | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update to the newest design so we have a favicon (otherwise loading this throws a console error in the browser (if someone was to check)).