@loopback/example-lb3-application 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierignore +2 -0
- package/.prettierrc +7 -0
- package/.vscode/settings.json +20 -0
- package/.vscode/tasks.json +29 -0
- package/CHANGELOG.md +626 -0
- package/LICENSE +25 -0
- package/README.md +560 -0
- package/dist/__tests__/acceptance/home-page.acceptance.d.ts +1 -0
- package/dist/__tests__/acceptance/home-page.acceptance.js +38 -0
- package/dist/__tests__/acceptance/home-page.acceptance.js.map +1 -0
- package/dist/__tests__/acceptance/lb3app.acceptance.d.ts +1 -0
- package/dist/__tests__/acceptance/lb3app.acceptance.js +200 -0
- package/dist/__tests__/acceptance/lb3app.acceptance.js.map +1 -0
- package/dist/__tests__/acceptance/test-helper.d.ts +11 -0
- package/dist/__tests__/acceptance/test-helper.js +33 -0
- package/dist/__tests__/acceptance/test-helper.js.map +1 -0
- package/dist/application.d.ts +187 -0
- package/dist/application.js +41 -0
- package/dist/application.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/migrate.d.ts +1 -0
- package/dist/migrate.js +25 -0
- package/dist/migrate.js.map +1 -0
- package/dist/openapi-spec.d.ts +1 -0
- package/dist/openapi-spec.js +28 -0
- package/dist/openapi-spec.js.map +1 -0
- package/dist/sequence.d.ts +3 -0
- package/dist/sequence.js +12 -0
- package/dist/sequence.js.map +1 -0
- package/dist/server.d.ts +15 -0
- package/dist/server.js +58 -0
- package/dist/server.js.map +1 -0
- package/lb3app/common/models/coffee-shop.js +44 -0
- package/lb3app/common/models/coffee-shop.json +30 -0
- package/lb3app/server/boot/authentication.js +11 -0
- package/lb3app/server/boot/create-sample-models.js +28 -0
- package/lb3app/server/config.json +21 -0
- package/lb3app/server/datasources.json +6 -0
- package/lb3app/server/middleware.json +9 -0
- package/lb3app/server/model-config.json +39 -0
- package/lb3app/server/server.js +17 -0
- package/lb3app/test/acceptance.js +107 -0
- package/lb3app/test/authentication.js +135 -0
- package/lb3app/test/integration.js +75 -0
- package/package.json +78 -0
- package/public/index.html +74 -0
- package/public/lb3-index.html +5 -0
- package/src/__tests__/acceptance/home-page.acceptance.ts +44 -0
- package/src/__tests__/acceptance/lb3app.acceptance.ts +244 -0
- package/src/__tests__/acceptance/test-helper.ts +40 -0
- package/src/application.ts +44 -0
- package/src/index.ts +35 -0
- package/src/migrate.ts +25 -0
- package/src/openapi-spec.ts +28 -0
- package/src/sequence.ts +8 -0
- package/src/server.ts +71 -0
- package/tsconfig.json +36 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
Copyright (c) IBM Corp. 2019.
|
|
2
|
+
Node module: @loopback/example-lb3-application
|
|
3
|
+
This project is licensed under the MIT License, full text below.
|
|
4
|
+
|
|
5
|
+
--------
|
|
6
|
+
|
|
7
|
+
MIT license
|
|
8
|
+
|
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
11
|
+
in the Software without restriction, including without limitation the rights
|
|
12
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
14
|
+
furnished to do so, subject to the following conditions:
|
|
15
|
+
|
|
16
|
+
The above copyright notice and this permission notice shall be included in
|
|
17
|
+
all copies or substantial portions of the Software.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
22
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
23
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
25
|
+
THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
# @loopback/example-lb3-application
|
|
2
|
+
|
|
3
|
+
This example demonstrates how to mount your existing LoopBack 3 (LB3)
|
|
4
|
+
application on a new LoopBack 4 (LB4) project and how to move the middleware
|
|
5
|
+
from the LB3 application to a common location so that both the LB3 and LB4
|
|
6
|
+
applications can use them.
|
|
7
|
+
|
|
8
|
+
## Mounting LB3 app on LB4 app
|
|
9
|
+
|
|
10
|
+
1. Create a new LoopBack 4 project using `lb4 app`.
|
|
11
|
+
|
|
12
|
+
```
|
|
13
|
+
$ lb4 app
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Fill out the prompts as they fit your project and leave all features enabled.
|
|
17
|
+
|
|
18
|
+
2. Create a new directory `lb3app` from the root of your LoopBack 4 application
|
|
19
|
+
and copy your existing LoopBack 3 application there. You should end up with
|
|
20
|
+
the following directory layout:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
lb3app/
|
|
24
|
+
# LoopBack 3 application in JavaScript
|
|
25
|
+
common/
|
|
26
|
+
models/
|
|
27
|
+
# LB3 model files
|
|
28
|
+
server/
|
|
29
|
+
boot/
|
|
30
|
+
# LB3 boot scripts
|
|
31
|
+
public/
|
|
32
|
+
# front-end assets (LB4 way)
|
|
33
|
+
src/
|
|
34
|
+
# LoopBack 4 application in TypeScript
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
3. Move LB3 dependencies to the main package.json file and remove
|
|
38
|
+
`lb3app/package.json`, `lb3app/node_modules/`, and`lb3app/package-lock.json`,
|
|
39
|
+
if it exists. Typically you will need to add the following entries, plus any
|
|
40
|
+
connectors or components you are using in your LB3 application.
|
|
41
|
+
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"compression": "^1.7.4",
|
|
45
|
+
"cors": "^2.8.5",
|
|
46
|
+
"helmet": "^3.16.0",
|
|
47
|
+
"loopback": "^3.25.1",
|
|
48
|
+
"loopback-boot": "^3.3.0"
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Note: make sure to use `loopback-boot@3.2.1` or higher.
|
|
53
|
+
|
|
54
|
+
Run `npm install` from the root of your LB4 project to install the LB3
|
|
55
|
+
dependencies.
|
|
56
|
+
|
|
57
|
+
4. Disable error handling in your LB3 app, leave it for the new LB4 app.
|
|
58
|
+
|
|
59
|
+
- Remove `lb3app/server/middleware.development.json`
|
|
60
|
+
- Edit `lb3app/server/middleware.json` and remove the following two entries:
|
|
61
|
+
- `final` >> `loopback#urlNotFound`
|
|
62
|
+
- `final:after` >> `strong-error-handler`
|
|
63
|
+
- Remove `strong-error-handler` from `package.json` dependencies.
|
|
64
|
+
- In `lb3app/server/config.json`, if `"handleErrors": false` is in
|
|
65
|
+
`remoting`, move it to `rest`.
|
|
66
|
+
|
|
67
|
+
5. Move your front-end files from `lb3app/client` to `public/` directory and
|
|
68
|
+
disable static assets in your LB3 app by removing the following entry in
|
|
69
|
+
`lb3app/server/middleware.json`:
|
|
70
|
+
|
|
71
|
+
- `files` >> `loopback#static`
|
|
72
|
+
|
|
73
|
+
Also remove `lb3app/server/boot/root.js`, since the main page will be served
|
|
74
|
+
by the LoopBack 4 project.
|
|
75
|
+
|
|
76
|
+
6. Remove `lb3app/server/component-config.json` to disable LoopBack 3's
|
|
77
|
+
explorer. The LoopBack 4 explorer will be used instead.
|
|
78
|
+
|
|
79
|
+
7. Install and configure `@loopback/booter-lb3app` to boot and mount the LB3
|
|
80
|
+
application:
|
|
81
|
+
|
|
82
|
+
1. `npm install --save @loopback/booter-lb3app`
|
|
83
|
+
|
|
84
|
+
2. Import the component at the top of your `src/application.ts` file.
|
|
85
|
+
|
|
86
|
+
```ts
|
|
87
|
+
import {Lb3AppBooterComponent} from '@loopback/booter-lb3app';
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
3. Register the component in Application's constructor:
|
|
91
|
+
|
|
92
|
+
```ts
|
|
93
|
+
this.component(Lb3AppBooterComponent);
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Start the new LB4 application
|
|
97
|
+
|
|
98
|
+
```sh
|
|
99
|
+
$ npm start
|
|
100
|
+
Server is running at http://127.0.0.1:3000
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Open the URL printed to console to view your front-end served from `public`
|
|
104
|
+
directory or go to `http://127.0.0.1:3000/explorer` to explore the REST API.
|
|
105
|
+
|
|
106
|
+
The LB3 application is now successfully mounted on a LB4 application, but we can
|
|
107
|
+
further optimize the setup so that only the bare neccessary artifacts from the
|
|
108
|
+
LoopBack 3 application remain. This includes moving almost all of the middleware
|
|
109
|
+
to a common location so that they are shared by both the LoopBack 3 and the
|
|
110
|
+
LoopBack 4 apps.
|
|
111
|
+
|
|
112
|
+
## Migrating Express middleware from LB3 app
|
|
113
|
+
|
|
114
|
+
1. Update config.json
|
|
115
|
+
|
|
116
|
+
First off, edit the LB3 app's `config.json` file.
|
|
117
|
+
|
|
118
|
+
Remove these properties, as they are not required anymore:
|
|
119
|
+
|
|
120
|
+
```json
|
|
121
|
+
"host": "0.0.0.0",
|
|
122
|
+
"port": 3000,
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Change `restApiRoot` to `/` or any path where you would like the LB3 app to
|
|
126
|
+
be mounted; that's relative to the LB4 app's REST API path, which defaults to
|
|
127
|
+
`/api`.
|
|
128
|
+
|
|
129
|
+
And then add `"handleUnknownPaths": false` to the `rest` property, this will
|
|
130
|
+
prevent the LB3 REST api from sending a 404 response for requests it cannot
|
|
131
|
+
handle.
|
|
132
|
+
|
|
133
|
+
The `config.json` file should now look like this:
|
|
134
|
+
|
|
135
|
+
```json
|
|
136
|
+
{
|
|
137
|
+
"restApiRoot": "/",
|
|
138
|
+
"remoting": {
|
|
139
|
+
"context": false,
|
|
140
|
+
"rest": {
|
|
141
|
+
"handleErrors": false,
|
|
142
|
+
"handleUnknownPaths": false,
|
|
143
|
+
"normalizeHttpPath": false,
|
|
144
|
+
"xml": false
|
|
145
|
+
},
|
|
146
|
+
"json": {
|
|
147
|
+
"strict": false,
|
|
148
|
+
"limit": "100kb"
|
|
149
|
+
},
|
|
150
|
+
"urlencoded": {
|
|
151
|
+
"extended": true,
|
|
152
|
+
"limit": "100kb"
|
|
153
|
+
},
|
|
154
|
+
"cors": false
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
2. Configure the base Express app
|
|
160
|
+
|
|
161
|
+
We will be using a base Express app (`src/server.ts`) for mounting the LB4
|
|
162
|
+
app as described in
|
|
163
|
+
"[Creating an Express Application with LoopBack REST API](https://loopback.io/doc/en/lb4/express-with-lb4-rest-tutorial.html)"
|
|
164
|
+
guide.
|
|
165
|
+
|
|
166
|
+
Migrate the LB3 app's middleware from its `middleware.json` file to this
|
|
167
|
+
Express app, except the one from the `routes` phase (there is a
|
|
168
|
+
[pending task](https://github.com/loopbackio/loopback-next/issues/4181) to
|
|
169
|
+
complete the support for this middleware).
|
|
170
|
+
|
|
171
|
+
Each root property in the `middleware.json` object represents a middleware
|
|
172
|
+
phase, extract the relevant middleware and load them in the Express app in
|
|
173
|
+
order.
|
|
174
|
+
|
|
175
|
+
An entry like `"compression": {}` translates to `compression()`, and
|
|
176
|
+
`loopback#favicon` translates to `loopback.favicon()` in TypeScript. For more
|
|
177
|
+
details about `middleware.json`, refer to
|
|
178
|
+
[its documentation](https://loopback.io/doc/en/lb3/middleware.json.html).
|
|
179
|
+
|
|
180
|
+
The `middleware.json` file should look like this now:
|
|
181
|
+
|
|
182
|
+
```js
|
|
183
|
+
{
|
|
184
|
+
"routes": {
|
|
185
|
+
"loopback#rest": {
|
|
186
|
+
"paths": [
|
|
187
|
+
"${restApiRoot}"
|
|
188
|
+
]
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
The middleware mounted in the Express app will be shared by both LB3 and LB4
|
|
195
|
+
apps.
|
|
196
|
+
|
|
197
|
+
Move any static files from the LB3 app to the `public` directory of the
|
|
198
|
+
Express app. Move any non-REST routes defined anywhere in the LB3 app to the
|
|
199
|
+
Express app.
|
|
200
|
+
|
|
201
|
+
This is what the `src/server.ts` file will look like:
|
|
202
|
+
|
|
203
|
+
```ts
|
|
204
|
+
import {ApplicationConfig} from '@loopback/core';
|
|
205
|
+
import {once} from 'events';
|
|
206
|
+
import express, {Request, Response} from 'express';
|
|
207
|
+
import * as http from 'http';
|
|
208
|
+
import {AddressInfo} from 'net';
|
|
209
|
+
import * as path from 'path';
|
|
210
|
+
// Replace CoffeeShopApplication with the name of your application
|
|
211
|
+
import {CoffeeShopApplication} from './application';
|
|
212
|
+
|
|
213
|
+
const loopback = require('loopback');
|
|
214
|
+
const compression = require('compression');
|
|
215
|
+
const cors = require('cors');
|
|
216
|
+
const helmet = require('helmet');
|
|
217
|
+
|
|
218
|
+
export class ExpressServer {
|
|
219
|
+
private app: express.Application;
|
|
220
|
+
public readonly lbApp: CoffeeShopApplication;
|
|
221
|
+
public server?: http.Server;
|
|
222
|
+
public url: String;
|
|
223
|
+
|
|
224
|
+
constructor(options: ApplicationConfig = {}) {
|
|
225
|
+
this.app = express();
|
|
226
|
+
this.lbApp = new CoffeeShopApplication(options);
|
|
227
|
+
|
|
228
|
+
// Middleware migrated from LoopBack 3
|
|
229
|
+
this.app.use(loopback.favicon());
|
|
230
|
+
this.app.use(compression());
|
|
231
|
+
this.app.use(cors());
|
|
232
|
+
this.app.use(helmet());
|
|
233
|
+
|
|
234
|
+
// Mount the LB4 REST API
|
|
235
|
+
this.app.use('/api', this.lbApp.requestHandler);
|
|
236
|
+
|
|
237
|
+
// Custom Express routes
|
|
238
|
+
this.app.get('/ping', function (_req: Request, res: Response) {
|
|
239
|
+
res.send('pong');
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
// Serve static files in the public folder
|
|
243
|
+
this.app.use(express.static(path.join(__dirname, '../public')));
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
public async boot() {
|
|
247
|
+
await this.lbApp.boot();
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
public async start() {
|
|
251
|
+
await this.lbApp.start();
|
|
252
|
+
const port = this.lbApp.restServer.config.port || 3000;
|
|
253
|
+
const host = this.lbApp.restServer.config.host || '127.0.0.1';
|
|
254
|
+
this.server = this.app.listen(port, host);
|
|
255
|
+
await once(this.server, 'listening');
|
|
256
|
+
const add = <AddressInfo>this.server.address();
|
|
257
|
+
this.url = `http://${add.address}:${add.port}`;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
public async stop() {
|
|
261
|
+
if (!this.server) return;
|
|
262
|
+
await this.lbApp.stop();
|
|
263
|
+
this.server.close();
|
|
264
|
+
await once(this.server, 'close');
|
|
265
|
+
this.server = undefined;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
3. Update `src/index.ts`
|
|
271
|
+
|
|
272
|
+
The Express app will replace the `CoffeeShopApplication` as the entry point
|
|
273
|
+
for the program, modify the `src/index.ts` file accordingly.
|
|
274
|
+
|
|
275
|
+
```ts
|
|
276
|
+
import {ApplicationConfig} from '@loopback/core';
|
|
277
|
+
import {ExpressServer} from './server';
|
|
278
|
+
|
|
279
|
+
export {ApplicationConfig, ExpressServer};
|
|
280
|
+
|
|
281
|
+
export async function main(options: ApplicationConfig = {}) {
|
|
282
|
+
const server = new ExpressServer(options);
|
|
283
|
+
await server.boot();
|
|
284
|
+
await server.start();
|
|
285
|
+
console.log(`Server is running at ${server.url}`);
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
4. Next, modify the application config in `src/index.ts` file to prevent the LB4
|
|
290
|
+
app from listening, by adding `listenOnStart: false` in `config.rest` object.
|
|
291
|
+
The `config` object should now look like this:
|
|
292
|
+
|
|
293
|
+
```ts
|
|
294
|
+
const config = {
|
|
295
|
+
rest: {
|
|
296
|
+
port: +(process.env.PORT ?? 3000),
|
|
297
|
+
host: process.env.HOST ?? 'localhost',
|
|
298
|
+
openApiSpec: {
|
|
299
|
+
// useful when used with OpenAPI-to-GraphQL to locate your application
|
|
300
|
+
setServersFromRequest: true,
|
|
301
|
+
},
|
|
302
|
+
listenOnStart: false,
|
|
303
|
+
},
|
|
304
|
+
};
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
Then, in the `bootOptions` of the `CoffeeShopApplication` class, add the
|
|
308
|
+
`lb3app` to configure the path of the LB3 APIs.
|
|
309
|
+
|
|
310
|
+
```js
|
|
311
|
+
lb3app: {
|
|
312
|
+
mode: 'fullApp';
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
`this.bootOptions` should now look like this:
|
|
317
|
+
|
|
318
|
+
```ts
|
|
319
|
+
this.bootOptions = {
|
|
320
|
+
controllers: {
|
|
321
|
+
// Customize ControllerBooter Conventions here
|
|
322
|
+
dirs: ['controllers'],
|
|
323
|
+
extensions: ['.controller.js'],
|
|
324
|
+
nested: true,
|
|
325
|
+
},
|
|
326
|
+
lb3app: {
|
|
327
|
+
mode: 'fullApp',
|
|
328
|
+
},
|
|
329
|
+
};
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
Start the app:
|
|
333
|
+
|
|
334
|
+
```sh
|
|
335
|
+
$ npm start
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
Load [http://localhost:3000/](http://localhost:3000/) on your browser. This will
|
|
339
|
+
load the Express app, with mounted LB3 and LB4 applications.
|
|
340
|
+
|
|
341
|
+
## Running LB3 tests from LB4
|
|
342
|
+
|
|
343
|
+
You can run tests in an LoopBack 3 application from the LoopBack 4 application
|
|
344
|
+
it mounted on with command `npm test`.
|
|
345
|
+
|
|
346
|
+
We want the LoopBack 3 tests to use the LoopBack 4 server rather than the
|
|
347
|
+
LoopBack 3 application. The following guide shows how to run
|
|
348
|
+
|
|
349
|
+
- acceptance-level tests making HTTP calls to invoke application logic. e.g.
|
|
350
|
+
`POST /users/login`
|
|
351
|
+
- integration-level tests that are using JS API to call application logic. e.g.
|
|
352
|
+
`MyModel.create()`
|
|
353
|
+
|
|
354
|
+
### Adding LB3 Test Path in Command
|
|
355
|
+
|
|
356
|
+
In order to run LoopBack 3's tests from their current folder, add LB3 tests'
|
|
357
|
+
path to `test` entry in package.json:
|
|
358
|
+
|
|
359
|
+
- `"test": "lb-mocha \"dist/**tests**/*_/_.js\" \"lb3app/test/*.js\""`
|
|
360
|
+
|
|
361
|
+
In this case, the test folder is
|
|
362
|
+
[`/lb3app/test`](https://github.com/loopbackio/loopback-next/tree/spike/lb3test/examples/lb3-application/lb3app/test)
|
|
363
|
+
from the root of the LoopBack 4 project.
|
|
364
|
+
|
|
365
|
+
This will run LoopBack 4 tests first then LoopBack 3 tests.
|
|
366
|
+
|
|
367
|
+
_To emphasize the setup steps and separate them from the test case details, all
|
|
368
|
+
the comprehensive test code are extracted into function `runTests`._
|
|
369
|
+
|
|
370
|
+
### Running Acceptance Tests
|
|
371
|
+
|
|
372
|
+
First, move any LoopBack 3 test dependencies to `package.json`'s devDependencies
|
|
373
|
+
and run:
|
|
374
|
+
|
|
375
|
+
```sh
|
|
376
|
+
npm install
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
In your test file:
|
|
380
|
+
|
|
381
|
+
1. When launch the Express server
|
|
382
|
+
|
|
383
|
+
- 1.1 Update to use the Express server when doing requests:
|
|
384
|
+
|
|
385
|
+
```ts
|
|
386
|
+
// can use lb4's testlab's supertest as the dependency is already installed
|
|
387
|
+
const {supertest} = require('@loopback/testlab');
|
|
388
|
+
const assert = require('assert');
|
|
389
|
+
const should = require('should');
|
|
390
|
+
const {ExpressServer} = require('../../dist/server');
|
|
391
|
+
|
|
392
|
+
let app;
|
|
393
|
+
|
|
394
|
+
function jsonForExpressApp(verb, url) {
|
|
395
|
+
// use the express server, it mounts LoopBack 3 apis to
|
|
396
|
+
// base path '/api'
|
|
397
|
+
return supertest(app.server)
|
|
398
|
+
[verb]('/api' + url)
|
|
399
|
+
.set('Content-Type', 'application/json')
|
|
400
|
+
.set('Accept', 'application/json')
|
|
401
|
+
.expect('Content-Type', /json/);
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
- 1.2 Boot and start the Express app in your before hook, and stop the app in
|
|
406
|
+
the after hook:
|
|
407
|
+
|
|
408
|
+
```ts
|
|
409
|
+
describe('LoopBack 3 style tests - Launch Express server', function () {
|
|
410
|
+
before(async function () {
|
|
411
|
+
app = new ExpressServer();
|
|
412
|
+
await app.boot();
|
|
413
|
+
await app.start();
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
after(async () => {
|
|
417
|
+
await app.stop();
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
// your tests here
|
|
421
|
+
runTests();
|
|
422
|
+
});
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
2. When launch the LoopBack 4 application
|
|
426
|
+
|
|
427
|
+
- 2.1 Update to use the LoopBack 4 server when doing requests:
|
|
428
|
+
|
|
429
|
+
```ts
|
|
430
|
+
// can use lb4's testlab's supertest as the dependency is already installed
|
|
431
|
+
const {supertest} = require('@loopback/testlab');
|
|
432
|
+
const assert = require('assert');
|
|
433
|
+
const should = require('should');
|
|
434
|
+
const {CoffeeShopApplication} = require('../../dist/application');
|
|
435
|
+
|
|
436
|
+
let app;
|
|
437
|
+
|
|
438
|
+
function jsonForLB4(verb, url) {
|
|
439
|
+
// use the lb4 app's rest server
|
|
440
|
+
return supertest(app.restServer.url)
|
|
441
|
+
[verb](url)
|
|
442
|
+
.set('Content-Type', 'application/json')
|
|
443
|
+
.set('Accept', 'application/json')
|
|
444
|
+
.expect('Content-Type', /json/);
|
|
445
|
+
}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
- 2.2 Boot and start the LoopBack 4 app in your before hook, and stop the app in
|
|
449
|
+
the after hook:
|
|
450
|
+
|
|
451
|
+
```ts
|
|
452
|
+
describe('LoopBack 3 style tests - launch LB4 app', function () {
|
|
453
|
+
before(async function () {
|
|
454
|
+
app = new CoffeeShopApplication();
|
|
455
|
+
await app.boot();
|
|
456
|
+
await app.start();
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
after(async () => {
|
|
460
|
+
await app.stop();
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
// your tests here
|
|
464
|
+
runTests();
|
|
465
|
+
});
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
Example of this use can be seen in
|
|
469
|
+
[`test/acceptance.js`](https://github.com/loopbackio/loopback-next/tree/master/examples/lb3-application/lb3app/test/acceptance.js)
|
|
470
|
+
which has the same tests as
|
|
471
|
+
[`src/__tests__/acceptance/lb3app.acceptance.ts`](https://github.com/loopbackio/loopback-next/blob/spike/lb3test/examples/lb3-application/src/__tests__/acceptance/lb3app.acceptance.ts),
|
|
472
|
+
but in LB3 style. And
|
|
473
|
+
[`test/authentication.js`](https://github.com/loopbackio/loopback-next/tree/master/examples/lb3-application/lb3app/test/authentication.js)
|
|
474
|
+
|
|
475
|
+
Now when you run `npm test` your LoopBack 3 tests should be run along with any
|
|
476
|
+
LoopBack 4 tests you have.
|
|
477
|
+
|
|
478
|
+
Optional: Another option is to migrate your tests to use LoopBack 4 style of
|
|
479
|
+
testing, similar to `src/__tests__/acceptance/lb3app.acceptance.ts`.
|
|
480
|
+
Documentation for LoopBack testing can be found in
|
|
481
|
+
https://loopback.io/doc/en/lb4/Testing-your-application.html.
|
|
482
|
+
|
|
483
|
+
## Running Integration Tests
|
|
484
|
+
|
|
485
|
+
For the integration tests, LoopBack 3 models were bound to the LoopBack 4
|
|
486
|
+
application in order to allow JavaScript API to call application logic such as
|
|
487
|
+
`Model.create()`. This can be seen in
|
|
488
|
+
[`packages/booter-lb3app/src/lb3app.booter.ts`](https://github.com/loopbackio/loopback-next/blob/spike/lb3test/packages/booter-lb3app/src/lb3app.booter.ts#L76-L85).
|
|
489
|
+
|
|
490
|
+
In order to retrieve the model from the application's context, `get()` can be
|
|
491
|
+
used as follows:
|
|
492
|
+
|
|
493
|
+
```ts
|
|
494
|
+
describe('LoopBack 3 style integration tests', function () {
|
|
495
|
+
let app;
|
|
496
|
+
let CoffeeShop;
|
|
497
|
+
|
|
498
|
+
before(async function () {
|
|
499
|
+
// If launch the LoopBack 4 application
|
|
500
|
+
// app = new CoffeeShopApplication();
|
|
501
|
+
app = new ExpressServer();
|
|
502
|
+
await app.boot();
|
|
503
|
+
await app.start();
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
before(() => {
|
|
507
|
+
// follow the syntax: lb3-models.{ModelName}
|
|
508
|
+
// If launch the LoopBack 4 application
|
|
509
|
+
// CoffeeShop = await app.get('lb3-models.CoffeeShop');
|
|
510
|
+
CoffeeShop = await app.lbApp.get('lb3-models.CoffeeShop');
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
after(async () => {
|
|
514
|
+
await app.stop();
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
// your tests here
|
|
518
|
+
runTests();
|
|
519
|
+
});
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
The syntax for LB3 model's binding key is `lb3-models.{model name}`.
|
|
523
|
+
|
|
524
|
+
Additionally, LB3 datasources are also bound to the LB4 application's context
|
|
525
|
+
and can be retrieved with a key in the syntax `lb3-datasources.{ds name}`.
|
|
526
|
+
|
|
527
|
+
Example integration tests can be found in
|
|
528
|
+
[`examples/lb3-application/lb3app/test/integration.js`](https://github.com/loopbackio/loopback-next/tree/master/examples/lb3-application/lb3app/test/integration.js).
|
|
529
|
+
|
|
530
|
+
Example authentication tests can be found in
|
|
531
|
+
[`examples/lb3-application/lb3app/test/authentication.js`](https://github.com/loopbackio/loopback-next/tree/master/examples/lb3-application/lb3app/test/authentication.js).
|
|
532
|
+
|
|
533
|
+
## Need help?
|
|
534
|
+
|
|
535
|
+
Check out our
|
|
536
|
+
[Slack](https://join.slack.com/t/loopbackio/shared_invite/zt-8lbow73r-SKAKz61Vdao~_rGf91pcsw)
|
|
537
|
+
and ask for help with this tutorial.
|
|
538
|
+
|
|
539
|
+
## Bugs/Feedback
|
|
540
|
+
|
|
541
|
+
Open an issue in [loopback-next](https://github.com/loopbackio/loopback-next)
|
|
542
|
+
and we'll take a look.
|
|
543
|
+
|
|
544
|
+
## Contributions
|
|
545
|
+
|
|
546
|
+
- [Guidelines](https://github.com/loopbackio/loopback-next/blob/master/docs/CONTRIBUTING.md)
|
|
547
|
+
- [Join the team](https://github.com/loopbackio/loopback-next/issues/110)
|
|
548
|
+
|
|
549
|
+
## Tests
|
|
550
|
+
|
|
551
|
+
Run `npm test` from the root folder.
|
|
552
|
+
|
|
553
|
+
## Contributors
|
|
554
|
+
|
|
555
|
+
See
|
|
556
|
+
[all contributors](https://github.com/loopbackio/loopback-next/graphs/contributors).
|
|
557
|
+
|
|
558
|
+
## License
|
|
559
|
+
|
|
560
|
+
MIT
|