Update nestRemoting to pass optionsFromContext

Fix the code invoking relation getter to correctly pass through
the "options" argument.
This commit is contained in:
bmatson 2017-10-19 16:25:58 -04:00 committed by Miroslav Bajtoš
parent fdb453943a
commit 317e00d92c
No known key found for this signature in database
GPG Key ID: 6F2304BA9361C7E3
3 changed files with 43 additions and 16 deletions

View File

@ -947,38 +947,45 @@ module.exports = function(registry) {
}
});
const lastArg = opts.accepts[opts.accepts.length - 1] || {};
const hasOptionsFromContext =
(lastArg.arg || lastArg.name) === 'options' &&
lastArg.type === 'object' && lastArg.http;
if (relation.multiple) {
sharedClass.defineMethod(methodName, opts, function(fkId) {
var args = Array.prototype.slice.call(arguments, 1);
var last = args[args.length - 1];
var cb = typeof last === 'function' ? last : null;
this[getterName](fkId, function(err, inst) {
if (err && cb) return cb(err);
const args = Array.prototype.slice.call(arguments, 1);
const cb = args[args.length - 1];
const contextOptions =
hasOptionsFromContext && args[args.length - 2] || {};
this[getterName](fkId, contextOptions, function(err, inst) {
if (err) return cb(err);
if (inst instanceof relation.modelTo) {
try {
nestedFn.apply(inst, args);
} catch (err) {
if (cb) return cb(err);
return cb(err);
}
} else if (cb) {
} else {
cb(err, null);
}
});
}, method.isStatic);
} else {
sharedClass.defineMethod(methodName, opts, function() {
var args = Array.prototype.slice.call(arguments);
var last = args[args.length - 1];
var cb = typeof last === 'function' ? last : null;
this[getterName](function(err, inst) {
if (err && cb) return cb(err);
const args = Array.prototype.slice.call(arguments);
const cb = args[args.length - 1];
const contextOptions =
hasOptionsFromContext && args[args.length - 2] || {};
this[getterName](contextOptions, function(err, inst) {
if (err) return cb(err);
if (inst instanceof relation.modelTo) {
try {
nestedFn.apply(inst, args);
} catch (err) {
if (cb) return cb(err);
return cb(err);
}
} else if (cb) {
} else {
cb(err, null);
}
});

View File

@ -695,7 +695,6 @@ describe('Multiple users with custom principalType', function() {
});
it('fails when the access token belongs to a different user mode', () => {
debugger;
logServerErrorsOtherThan(403, app);
return supertest(app)
.post('/AnotherUsers/change-password')

View File

@ -1439,6 +1439,8 @@ describe('relations - integration', function() {
});
describe('nested relations', function() {
let accessOptions;
before(function defineModels() {
var Book = app.registry.createModel(
'Book',
@ -1486,7 +1488,8 @@ describe('relations - integration', function() {
throw new Error('This should not crash the app');
};
Page.remoteMethod('__throw__errors', {isStatic: false, http: {path: '/throws', verb: 'get'}});
Page.remoteMethod('__throw__errors', {isStatic: false, http: {path: '/throws', verb: 'get'},
accepts: [{arg: 'options', type: 'object', http: 'optionsFromRequest'}]});
// Now `pages` has nestRemoting set to true and no need to call nestRemoting()
// Book.nestRemoting('pages');
@ -1507,6 +1510,15 @@ describe('relations - integration', function() {
next();
});
Page.observe('access', function(ctx, next) {
accessOptions = ctx.options;
next();
});
});
beforeEach(function resetAccessOptions() {
accessOptions = 'access hook not triggered';
});
before(function createBook(done) {
@ -1619,6 +1631,7 @@ describe('relations - integration', function() {
it('enables nested relationship routes - belongsTo findById', function(done) {
var test = this;
this.get('/api/images/' + test.image.id + '/book/pages/' + test.page.id)
.expect(200)
.end(function(err, res) {
if (err) return done(err);
@ -1658,6 +1671,14 @@ describe('relations - integration', function() {
});
});
it('passes options to nested relationship routes', function() {
return this.get(`/api/books/${this.book.id}/pages/${this.page.id}/notes/${this.note.id}`)
.expect(200)
.then(res => {
expect(accessOptions).to.have.property('accessToken');
});
});
it('should nest remote hooks of ModelTo - hasMany findById', function(done) {
var test = this;
this.get('/api/books/' + test.book.id + '/chapters/' + test.chapter.id + '/notes/' + test.cnote.id)