Fix duplicate definition of a remote model type

Before this commit, when a remote model had relations, the model was
registered an additional time per each relation. As a result,
the following warnings were printed to the console

   Warning: overriding remoting type $MODEL_NAME

This commit fixes registration of models with strong-remoting to avoid
those warnings.
This commit is contained in:
maxim.sharai 2018-01-07 23:34:59 +03:00 committed by Miroslav Bajtoš
parent 906979a960
commit af125c50cc
No known key found for this signature in database
GPG Key ID: 6F2304BA9361C7E3
3 changed files with 84 additions and 3 deletions

View File

@ -62,8 +62,8 @@ RemoteConnector.initialize = function(dataSource, callback) {
}; };
RemoteConnector.prototype.define = function(definition) { RemoteConnector.prototype.define = function(definition) {
var Model = definition.model; const Model = definition.model;
var remotes = this.remotes; const remotes = this.remotes;
assert(Model.sharedClass, assert(Model.sharedClass,
'cannot attach ' + 'cannot attach ' +
@ -73,17 +73,23 @@ RemoteConnector.prototype.define = function(definition) {
jutil.mixin(Model, RelationMixin); jutil.mixin(Model, RelationMixin);
jutil.mixin(Model, InclusionMixin); jutil.mixin(Model, InclusionMixin);
remotes.addClass(Model.sharedClass); remotes.addClass(Model.sharedClass);
this.resolve(Model); this.resolve(Model);
this.setupRemotingTypeFor(Model);
}; };
RemoteConnector.prototype.resolve = function(Model) { RemoteConnector.prototype.resolve = function(Model) {
var remotes = this.remotes; const remotes = this.remotes;
Model.sharedClass.methods().forEach(function(remoteMethod) { Model.sharedClass.methods().forEach(function(remoteMethod) {
if (remoteMethod.name !== 'Change' && remoteMethod.name !== 'Checkpoint') { if (remoteMethod.name !== 'Change' && remoteMethod.name !== 'Checkpoint') {
createProxyMethod(Model, remotes, remoteMethod); createProxyMethod(Model, remotes, remoteMethod);
} }
}); });
};
RemoteConnector.prototype.setupRemotingTypeFor = function(Model) {
const remotes = this.remotes;
// setup a remoting type converter for this model // setup a remoting type converter for this model
remotes.defineObjectType(Model.modelName, function(data) { remotes.defineObjectType(Model.modelName, function(data) {

View File

@ -44,6 +44,7 @@
"grunt-mocha-test": "^0.12.7", "grunt-mocha-test": "^0.12.7",
"loopback": "^3.0.0", "loopback": "^3.0.0",
"mocha": "^3.0.2", "mocha": "^3.0.2",
"sinon": "^4.1.3",
"strong-task-emitter": "^0.0.7" "strong-task-emitter": "^0.0.7"
}, },
"optionalDependencies": {} "optionalDependencies": {}

View File

@ -0,0 +1,74 @@
// Copyright IBM Corp. 2016. All Rights Reserved.
// Node module: loopback-connector-remote
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
'use strict';
const helper = require('./helper');
const loopback = require('loopback');
const sinon = require('sinon');
const relation = require('loopback-datasource-juggler/lib/relation-definition');
const RelationTypes = relation.RelationTypes;
describe('Models Define Type Tests', function() {
let serverApp, clientApp, remoteDs, defineObjectTypeSpy, ChildModel;
beforeEach('create remote datasource', () => {
serverApp = helper.createRestAppAndListen();
clientApp = loopback({localRegistry: true});
remoteDs = helper.createRemoteDataSource(clientApp, serverApp);
});
beforeEach('spy remote connector', () => {
defineObjectTypeSpy = sinon.spy(remoteDs.connector.remotes,
'defineObjectType');
});
afterEach('restore remote connector', () => {
defineObjectTypeSpy.restore();
});
it('should define a type of a remote model only once (no relations)', () => {
const RemoteModel = clientApp.registry.createModel({
name: 'RemoteModel',
});
clientApp.model(RemoteModel, {dataSource: remoteDs});
sinon.assert.calledOnce(defineObjectTypeSpy.withArgs(
RemoteModel.modelName));
});
describe('when a child model is created', () => {
beforeEach('create a child model', () => {
ChildModel = clientApp.registry.createModel({
name: 'ChildModel',
});
clientApp.model(ChildModel, {dataSource: remoteDs});
});
Object.getOwnPropertyNames(RelationTypes).forEach((relationKey) => {
const relation = RelationTypes[relationKey];
it('should define a type of a remote model only once (' + relation + ')',
() => {
const RemoteModel = clientApp.registry.createModel({
name: 'RemoteModel' + relation,
relations: {
children: {
type: relation,
model: 'ChildModel',
},
},
});
clientApp.model(RemoteModel, {dataSource: remoteDs});
sinon.assert.calledOnce(defineObjectTypeSpy.withArgs(
RemoteModel.modelName));
sinon.assert.calledOnce(defineObjectTypeSpy.withArgs(
ChildModel.modelName));
});
});
});
});