Skip to content

Commit

Permalink
fixup! apply most feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
nabdelgadir committed May 4, 2019
1 parent 8e865a8 commit 3802d72
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 79 deletions.
21 changes: 10 additions & 11 deletions examples/lb3-application/lb3app/common/models/coffee-shop.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@
const debug = require('debug')('loopback:example:lb3application');

module.exports = function(CoffeeShop) {
CoffeeShop.status = function(cb) {
var currentDate = new Date();
var currentHour = currentDate.getHours();
var OPEN_HOUR = 6;
var CLOSE_HOUR = 20;
CoffeeShop.status = async function() {
const currentDate = new Date();
const currentHour = currentDate.getHours();
const OPEN_HOUR = 6;
const CLOSE_HOUR = 20;
debug('Current hour is %d', currentHour);
var response;
let response;
if (currentHour > OPEN_HOUR && currentHour < CLOSE_HOUR) {
response = 'We are open for business.';
} else {
response = 'Sorry, we are closed. Open daily from 6am to 8pm.';
}
cb(null, response);
return response;
};
CoffeeShop.remoteMethod('status', {
http: {
Expand All @@ -27,10 +27,9 @@ module.exports = function(CoffeeShop) {
type: 'string',
},
});
CoffeeShop.greet = function(cb) {
process.nextTick(function() {
cb(null, 'Hello from this Coffee Shop');
});

CoffeeShop.greet = async function() {
return 'Hello from this Coffee Shop';
};
CoffeeShop.remoteMethod('greet', {
http: {path: '/greet', verb: 'get'},
Expand Down
42 changes: 17 additions & 25 deletions examples/lb3-application/lb3app/server/boot/create-sample-models.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,22 @@

const debug = require('debug')('loopback:example:lb3application');

module.exports = function(app, cb) {
app.dataSources.db.automigrate('CoffeeShop', function(err) {
if (err) cb(err);
module.exports = async function(app) {
await app.dataSources.db.automigrate('CoffeeShop');

app.models.CoffeeShop.create(
[
{
name: 'Bel Cafe',
city: 'Vancouver',
},
{
name: 'Three Bees Coffee House',
city: 'San Mateo',
},
{
name: 'Caffe Artigiano',
city: 'Vancouver',
},
],
function(err, coffeeShops) {
if (err) return cb(err);
debug('Models created: \n', coffeeShops);
cb();
},
);
});
const coffeeShops = app.models.CoffeeShop.create([
{
name: 'Bel Cafe',
city: 'Vancouver',
},
{
name: 'Three Bees Coffee House',
city: 'San Mateo',
},
{
name: 'Caffe Artigiano',
city: 'Vancouver',
},
]);
debug('Models created: \n', coffeeShops);
};
6 changes: 3 additions & 3 deletions examples/lb3-application/lb3app/server/server.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
'use strict';

var loopback = require('loopback');
var boot = require('loopback-boot');
const loopback = require('loopback');
const boot = require('loopback-boot');

var app = (module.exports = loopback());
const app = (module.exports = loopback());

// Bootstrap the application, configure models, datasources and middleware.
// Sub-apps like REST API are mounted via boot scripts.
Expand Down
2 changes: 0 additions & 2 deletions examples/lb3-application/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@
"@types/lodash": "^4.14.123",
"@types/node": "^10.11.2",
"lodash": "^4.17.11",
"loopback-swagger": "^5.7.3",
"swagger2openapi": "^5.3.0",
"tslint": "^5.16.0",
"typescript": "^3.4.5"
},
Expand Down
1 change: 1 addition & 0 deletions examples/lb3-application/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ <h1>@loopback/example-lb3-application</h1>

<h3>OpenAPI spec: <a href="/openapi.json">/openapi.json</a></h3>
<h3>API Explorer: <a href="/explorer">/explorer</a></h3>
<h3><a href="/lb3-index.html">Home page from the LB3 app</a></h3>
</div>

<footer class="power">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,12 @@ describe('HomePage', () => {
.expect('Content-Type', /text\/html/)
.expect(/<title>LoopBack API Explorer/);
});

it('exposes LoopBack 3 home page', async () => {
await client
.get('/lb3-index.html')
.expect(200)
.expect('Content-Type', /text\/html/)
.expect(/<h1>LoopBack Rocks!/);
});
});
104 changes: 66 additions & 38 deletions examples/lb3-application/src/__tests__/acceptance/lb3app.acceptance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@ import * as _ from 'lodash';
import {CoffeeShopApplication} from '../../application';
import {givenCoffeeShop, setupApplication} from './test-helper';

const {generateSwaggerSpec} = require('loopback-swagger');
const swagger2openapi = require('swagger2openapi');

const lb3App = require('../../../lb3app/server/server');

describe('CoffeeShopApplication', () => {
Expand Down Expand Up @@ -43,17 +40,12 @@ describe('CoffeeShopApplication', () => {
});

it("gets the CoffeeShop's status", async () => {
const currentDate = new Date();
const currentHour = currentDate.getHours();
const response = await client.get('/api/CoffeeShops/status').expect(200);

if (currentHour >= 6 && currentHour < 20) {
expect(response.body.status).to.eql('We are open for business.');
} else {
expect(response.body.status).to.eql(
'Sorry, we are closed. Open daily from 6am to 8pm.',
);
}
expect(response.body.status).to.be.equalOneOf(
'We are open for business.',
'Sorry, we are closed. Open daily from 6am to 8pm.',
);
});

it('gets external route in application', async () => {
Expand Down Expand Up @@ -89,8 +81,6 @@ describe('CoffeeShopApplication', () => {
password: 'L00pBack!',
});

// await client.get('/api/CoffeeShops/greet').expect(401);

const token = await User.login({
email: 'sample@email.com',
password: 'L00pBack!',
Expand All @@ -103,10 +93,14 @@ describe('CoffeeShopApplication', () => {
expect(response.body.undefined).to.eql('Hello from this Coffee Shop');
});

it.skip('rejects anonymous requests to protected endpoints', async () => {
await client.get('/api/CoffeeShops/greet').expect(401);
});

it.skip("denies request made by another user's access token", async () => {
const users = await User.create([
{
email: 'sample@email.com',
email: 'original@email.com',
password: 'L00pBack!',
},
{
Expand Down Expand Up @@ -142,49 +136,83 @@ describe('CoffeeShopApplication', () => {

context('OpenAPI spec', () => {
let apiSpec: OpenApiSpec;
let swaggerSpec: OpenApiSpec;
let lb3Spec: OpenApiSpec;

before(async () => {
apiSpec = app.restServer.getApiSpec();
swaggerSpec = await generateSwaggerSpec(lb3App);
const result = await swagger2openapi.convertObj(swaggerSpec, {});
lb3Spec = result.openapi;
});

it('has the same properties in both the LB3 and LB4 specs', () => {
const lb4SpecProperties = Object.keys(apiSpec).sort();
const lb3SpecProperties = Object.keys(lb3Spec).sort();

expect(lb4SpecProperties).to.eql(lb3SpecProperties);
const lb4SpecProperties = Object.keys(apiSpec);

expect(lb4SpecProperties).to.eql([
'openapi',
'info',
'paths',
'servers',
'components',
'tags',
]);
});

it('uses OpenApi version 3', () => {
expect(apiSpec.openapi).to.eql('3.0.0');
});

it('transfers the tags from the LB3 spec to the LB4 spec', () => {
expect(apiSpec.tags).to.eql(swaggerSpec.tags);
expect(apiSpec.tags).to.containDeep([
{name: 'User', description: undefined, externalDocs: undefined},
{name: 'CoffeeShop', description: undefined, externalDocs: undefined},
]);
});

it('transfers the components from the LB3 spec to the LB4 spec', () => {
if (apiSpec.components && lb3Spec.components) {
expect(apiSpec.components.schemas).to.eql(lb3Spec.components.schemas);
}
});
it.skip('transfers the components from the LB3 spec to the LB4 spec', () => {});

it('appends the basePath and transfers the paths from the LB3 spec to the LB4 spec', () => {
const lb3Paths = Object.keys(lb3Spec.paths).map(
path => swaggerSpec.basePath + path,
);
const lb4SpecPaths = Object.keys(apiSpec.paths);
const paths = Object.keys(apiSpec.paths);
expect(paths).to.have.length(32);

// some of the expected paths
expect(paths).to.containDeep([
'/api/Users/{id}/accessTokens/{fk}',
'/api/Users',
'/api/Users/{id}/exists',
'/api/Users/login',
'/api/CoffeeShops',
'/api/CoffeeShops/{id}',
'/api/CoffeeShops/greet',
]);
});

expect(lb4SpecPaths).to.eql(lb3Paths);
it('transfers the paths details', () => {
const CoffeeShopsEndpoint = apiSpec.paths['/api/CoffeeShops'];

const lb4SpecPathsInfo = Object.values(apiSpec.paths);
const lb3SpecPathsInfo = Object.values(lb3Spec.paths);
expect(CoffeeShopsEndpoint).to.have.properties([
'post',
'patch',
'put',
'get',
]);

expect(lb4SpecPathsInfo).to.deepEqual(lb3SpecPathsInfo);
expect(CoffeeShopsEndpoint['post']).to.containDeep({
tags: ['CoffeeShop'],
summary:
'Create a new instance of the model and persist it into the data source.',
operationId: 'CoffeeShop.create',
requestBody: {$ref: '#/components/requestBodies/CoffeeShop'},
responses: {
'200': {
description: 'Request was successful',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/CoffeeShop',
},
},
},
},
},
deprecated: false,
});
});
});
});
4 changes: 4 additions & 0 deletions examples/lb3-application/src/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ export async function migrate(args: string[]) {

const app = new CoffeeShopApplication();
await app.boot();
console.warn(
'Skipping migration of models from LB3 application (not supported yet).',
);
console.warn('See https://github.com/strongloop/loopback-next/issues/2825');
await app.migrateSchema({existingSchema});

// Connectors usually keep a pool of opened connections,
Expand Down

0 comments on commit 3802d72

Please sign in to comment.