Tidy up extended operator check

This commit is contained in:
Raymond Feng 2018-10-14 09:27:46 -07:00
parent 71f1259e72
commit bae60d1c08
2 changed files with 55 additions and 29 deletions

View File

@ -1477,6 +1477,7 @@ DataAccessObject._getSetting = function(key) {
};
var operators = {
eq: '=',
gt: '>',
gte: '>=',
lt: '<',
@ -1818,6 +1819,7 @@ DataAccessObject._coerce = function(where, options) {
// NOOP when not coercable into an array.
}
var allowExtendedOperators = self._allowExtendedOperators(options);
// Coerce the array items
if (Array.isArray(val)) {
for (var i = 0; i < val.length; i++) {
@ -1829,7 +1831,6 @@ DataAccessObject._coerce = function(where, options) {
}
} else {
if (val != null) {
var allowExtendedOperators = self._allowExtendedOperators(options);
if (operator === null && val instanceof RegExp) {
// Normalize {name: /A/} to {name: {regexp: /A/}}
operator = 'regexp';
@ -1841,12 +1842,28 @@ DataAccessObject._coerce = function(where, options) {
} else if (allowExtendedOperators && typeof val === 'object') {
// Do not coerce object values when extended operators are allowed
} else {
if (!allowExtendedOperators) {
var extendedOperators = Object.keys(val).filter(function(k) {
return k[0] === '$';
});
if (extendedOperators.length) {
const msg = g.f('Operators "' + extendedOperators.join(', ') + '" are not allowed in query');
const err = new Error(msg);
err.code = 'OPERATOR_NOT_ALLOWED_IN_QUERY';
err.statusCode = 400;
err.details = {
operators: extendedOperators,
where: where,
};
throw err;
}
}
val = DataType(val);
}
}
}
// Rebuild {property: {operator: value}}
if (operator) {
if (operator && operator !== 'eq') {
var value = {};
value[operator] = val;
if (exp.options) {

View File

@ -67,50 +67,59 @@ describe('allowExtendedOperators', () => {
}
}
function assertOperatorNotAllowed(err) {
should.exist(err);
err.message.should.match(/Operators "\$exists" are not allowed in query/);
err.code.should.equal('OPERATOR_NOT_ALLOWED_IN_QUERY');
err.statusCode.should.equal(400);
err.details.should.have.property('operators');
err.details.should.have.property('where');
}
describe('dataSource.settings.allowExtendedOperators', () => {
context('DAO.find()', () => {
it('converts extended operators to string value by default', () => {
it('reports invalid operator by default', () => {
const TestModel = createTestModel();
return TestModel.find(extendedQuery()).then((results) => {
should(results[0].value).eql('[object Object]');
return TestModel.find(extendedQuery()).catch(err => {
assertOperatorNotAllowed(err);
});
});
it('preserves extended operators with allowExtendedOperators set', () => {
const TestModel = createTestModel({allowExtendedOperators: true});
return TestModel.find(extendedQuery()).then((results) => {
return TestModel.find(extendedQuery()).then(results => {
should(results[0].value).eql({$exists: true});
});
});
it('`Model.settings.allowExtendedOperators` override data source settings - ' +
'converts extended operators', () => {
'reports invalid operator', () => {
const TestModel = createTestModel({allowExtendedOperators: true}, {allowExtendedOperators: false});
return TestModel.find(extendedQuery()).then((results) => {
should(results[0].value).eql('[object Object]');
return TestModel.find(extendedQuery()).catch(err => {
assertOperatorNotAllowed(err);
});
});
it('`Model.settings.allowExtendedOperators` override data source settings - ' +
'preserves extended operators', () => {
const TestModel = createTestModel({allowExtendedOperators: false}, {allowExtendedOperators: true});
return TestModel.find(extendedQuery()).then((results) => {
return TestModel.find(extendedQuery()).then(results => {
should(results[0].value).eql({$exists: true});
});
});
it('`options.allowExtendedOperators` override data source settings - ' +
'converts extended operators', () => {
'reports invalid operator', () => {
const TestModel = createTestModel({allowExtendedOperators: true});
return TestModel.find(extendedQuery(), {allowExtendedOperators: false}).then((results) => {
should(results[0].value).eql('[object Object]');
return TestModel.find(extendedQuery(), {allowExtendedOperators: false}).catch(err => {
assertOperatorNotAllowed(err);
});
});
it('`options.allowExtendedOperators` override data source settings - ' +
'preserves extended operators', () => {
const TestModel = createTestModel({allowExtendedOperators: false});
return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then((results) => {
return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then(results => {
should(results[0].value).eql({$exists: true});
});
});
@ -168,37 +177,37 @@ describe('allowExtendedOperators', () => {
context('DAO.find()', () => {
it('preserves extended operators with allowExtendedOperators set', () => {
const TestModel = createTestModel({}, {allowExtendedOperators: true});
return TestModel.find(extendedQuery()).then((results) => {
return TestModel.find(extendedQuery()).then(results => {
should(results[0].value).eql({$exists: true});
});
});
it('`dataSource.settings.allowExtendedOperators` honor Model settings - ' +
'converts extended operators', () => {
'reports invalid operator', () => {
const TestModel = createTestModel({allowExtendedOperators: true}, {allowExtendedOperators: false});
return TestModel.find(extendedQuery()).then((results) => {
should(results[0].value).eql('[object Object]');
return TestModel.find(extendedQuery()).catch(err => {
assertOperatorNotAllowed(err);
});
});
it('`dataSource.settings.allowExtendedOperators` honor Model settings - ' +
'preserves extended operators', () => {
const TestModel = createTestModel({allowExtendedOperators: false}, {allowExtendedOperators: true});
return TestModel.find(extendedQuery()).then((results) => {
return TestModel.find(extendedQuery()).then(results => {
should(results[0].value).eql({$exists: true});
});
});
it('`options.allowExtendedOperators` override Model settings - converts extended operators', () => {
const TestModel = createTestModel({allowExtendedOperators: true});
return TestModel.find(extendedQuery(), {allowExtendedOperators: false}).then((results) => {
should(results[0].value).eql('[object Object]');
return TestModel.find(extendedQuery(), {allowExtendedOperators: false}).catch(err => {
assertOperatorNotAllowed(err);
});
});
it('`options.allowExtendedOperators` Model settings - preserves extended operators', () => {
const TestModel = createTestModel({allowExtendedOperators: false});
return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then((results) => {
return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then(results => {
should(results[0].value).eql({$exists: true});
});
});
@ -255,7 +264,7 @@ describe('allowExtendedOperators', () => {
context('DAO.find()', () => {
it('preserves extended operators with allowExtendedOperators set', () => {
const TestModel = createTestModel();
return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then((results) => {
return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then(results => {
should(results[0].value).eql({$exists: true});
});
});
@ -263,15 +272,15 @@ describe('allowExtendedOperators', () => {
it('`dataSource.settings.allowExtendedOperators` honor options settings - ' +
'converts extended operators', () => {
const TestModel = createTestModel({allowExtendedOperators: true});
return TestModel.find(extendedQuery(), {allowExtendedOperators: false}).then((results) => {
should(results[0].value).eql('[object Object]');
return TestModel.find(extendedQuery(), {allowExtendedOperators: false}).catch(err => {
assertOperatorNotAllowed(err);
});
});
it('`dataSource.settings.allowExtendedOperators` honor options settings - ' +
'preserves extended operators', () => {
const TestModel = createTestModel({allowExtendedOperators: false});
return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then((results) => {
return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then(results => {
should(results[0].value).eql({$exists: true});
});
});
@ -279,15 +288,15 @@ describe('allowExtendedOperators', () => {
it('`Model.settings.allowExtendedOperators` honor options settings - ' +
'converts extended operators', () => {
const TestModel = createTestModel({}, {allowExtendedOperators: true});
return TestModel.find(extendedQuery(), {allowExtendedOperators: false}).then((results) => {
should(results[0].value).eql('[object Object]');
return TestModel.find(extendedQuery(), {allowExtendedOperators: false}).catch(err => {
assertOperatorNotAllowed(err);
});
});
it('`Model.settings.allowExtendedOperators` honor options settings - ' +
'preserves extended operators', () => {
const TestModel = createTestModel({}, {allowExtendedOperators: false});
return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then((results) => {
return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then(results => {
should(results[0].value).eql({$exists: true});
});
});