2016-12-05 15:04:54 +00:00
|
|
|
// Copyright IBM Corp. 2015,2016. All Rights Reserved.
|
|
|
|
// Node module: loopback-datasource-juggler
|
|
|
|
// This file is licensed under the MIT License.
|
|
|
|
// License text available at https://opensource.org/licenses/MIT
|
|
|
|
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
const DataSource = require('..').DataSource;
|
|
|
|
const should = require('should');
|
|
|
|
|
2016-06-16 14:34:38 +00:00
|
|
|
describe('allowExtendedOperators', () => {
|
|
|
|
function createTestModel(connectorSettings, modelSettings) {
|
|
|
|
const ds = createTestDataSource(connectorSettings);
|
|
|
|
const TestModel = ds.createModel('TestModel', {value: String}, modelSettings);
|
2016-12-05 15:04:54 +00:00
|
|
|
|
2016-06-16 14:34:38 +00:00
|
|
|
TestModel.observe('persist', function(ctx, next) {
|
|
|
|
ctx.Model.lastPersistedData = ctx.data;
|
|
|
|
next();
|
2016-12-05 15:04:54 +00:00
|
|
|
});
|
|
|
|
|
2016-06-16 14:34:38 +00:00
|
|
|
return TestModel;
|
2016-12-05 15:04:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function createTestDataSource(connectorSettings) {
|
|
|
|
connectorSettings = connectorSettings || {};
|
|
|
|
connectorSettings.connector = {
|
|
|
|
initialize: (dataSource, cb) => {
|
|
|
|
dataSource.connector = new TestConnector(dataSource);
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
return new DataSource(connectorSettings);
|
|
|
|
}
|
|
|
|
|
2016-06-16 14:34:38 +00:00
|
|
|
function extendedQuery() {
|
|
|
|
// datasource modifies the query,
|
|
|
|
// we have to build a new object for each test
|
|
|
|
return {where: {value: {$exists: true}}};
|
|
|
|
}
|
|
|
|
|
|
|
|
function setCustomData() {
|
|
|
|
return {$set: {value: 'changed'}};
|
|
|
|
}
|
|
|
|
|
|
|
|
function updateShouldHaveFailed() {
|
|
|
|
throw new Error('updateAttributes() should have failed.');
|
|
|
|
}
|
|
|
|
|
2016-12-05 15:04:54 +00:00
|
|
|
class TestConnector {
|
|
|
|
constructor(dataSource) {
|
|
|
|
}
|
|
|
|
|
2016-06-16 14:34:38 +00:00
|
|
|
create(model, data, options, callback) {
|
|
|
|
callback();
|
|
|
|
}
|
|
|
|
|
|
|
|
updateAttributes(model, id, data, options, callback) {
|
|
|
|
callback();
|
|
|
|
}
|
|
|
|
|
2016-12-05 15:04:54 +00:00
|
|
|
all(model, filter, options, callback) {
|
|
|
|
// return the raw "value" query
|
2018-12-07 16:13:48 +00:00
|
|
|
const instanceFound = {
|
2016-12-05 15:04:54 +00:00
|
|
|
value: filter.where.value,
|
|
|
|
};
|
|
|
|
callback(null, [instanceFound]);
|
|
|
|
}
|
|
|
|
}
|
2016-06-16 14:34:38 +00:00
|
|
|
|
2018-10-14 16:27:46 +00:00
|
|
|
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');
|
|
|
|
}
|
|
|
|
|
2016-06-16 14:34:38 +00:00
|
|
|
describe('dataSource.settings.allowExtendedOperators', () => {
|
|
|
|
context('DAO.find()', () => {
|
2018-10-14 16:27:46 +00:00
|
|
|
it('reports invalid operator by default', () => {
|
2016-06-16 14:34:38 +00:00
|
|
|
const TestModel = createTestModel();
|
2018-10-14 16:27:46 +00:00
|
|
|
return TestModel.find(extendedQuery()).catch(err => {
|
|
|
|
assertOperatorNotAllowed(err);
|
2016-06-16 14:34:38 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('preserves extended operators with allowExtendedOperators set', () => {
|
|
|
|
const TestModel = createTestModel({allowExtendedOperators: true});
|
2018-10-14 16:27:46 +00:00
|
|
|
return TestModel.find(extendedQuery()).then(results => {
|
2016-06-16 14:34:38 +00:00
|
|
|
should(results[0].value).eql({$exists: true});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`Model.settings.allowExtendedOperators` override data source settings - ' +
|
2018-10-14 16:27:46 +00:00
|
|
|
'reports invalid operator', () => {
|
2016-06-16 14:34:38 +00:00
|
|
|
const TestModel = createTestModel({allowExtendedOperators: true}, {allowExtendedOperators: false});
|
2018-10-14 16:27:46 +00:00
|
|
|
return TestModel.find(extendedQuery()).catch(err => {
|
|
|
|
assertOperatorNotAllowed(err);
|
2016-06-16 14:34:38 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`Model.settings.allowExtendedOperators` override data source settings - ' +
|
|
|
|
'preserves extended operators', () => {
|
|
|
|
const TestModel = createTestModel({allowExtendedOperators: false}, {allowExtendedOperators: true});
|
2018-10-14 16:27:46 +00:00
|
|
|
return TestModel.find(extendedQuery()).then(results => {
|
2016-06-16 14:34:38 +00:00
|
|
|
should(results[0].value).eql({$exists: true});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`options.allowExtendedOperators` override data source settings - ' +
|
2018-10-14 16:27:46 +00:00
|
|
|
'reports invalid operator', () => {
|
2016-06-16 14:34:38 +00:00
|
|
|
const TestModel = createTestModel({allowExtendedOperators: true});
|
2018-10-14 16:27:46 +00:00
|
|
|
return TestModel.find(extendedQuery(), {allowExtendedOperators: false}).catch(err => {
|
|
|
|
assertOperatorNotAllowed(err);
|
2016-06-16 14:34:38 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`options.allowExtendedOperators` override data source settings - ' +
|
|
|
|
'preserves extended operators', () => {
|
|
|
|
const TestModel = createTestModel({allowExtendedOperators: false});
|
2018-10-14 16:27:46 +00:00
|
|
|
return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then(results => {
|
2016-06-16 14:34:38 +00:00
|
|
|
should(results[0].value).eql({$exists: true});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
context('DAO.updateAttributes()', () => {
|
|
|
|
it('`options.allowExtendedOperators` override data source settings - disable strict check', () => {
|
|
|
|
const TestModel = createTestModel({allowExtendedOperators: false}, {strict: true});
|
|
|
|
return TestModel.create({value: 'test'}).then((instance) => {
|
|
|
|
return instance.updateAttributes(setCustomData(), {allowExtendedOperators: true})
|
|
|
|
.then(() => {
|
|
|
|
should(TestModel.lastPersistedData).eql(setCustomData());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`options.allowExtendedOperators` override data source settings - enable strict check', () => {
|
|
|
|
const TestModel = createTestModel({allowExtendedOperators: true}, {strict: true});
|
|
|
|
return TestModel.create({value: 'test'}).then((inst) => {
|
|
|
|
return inst.updateAttributes(setCustomData(), {allowExtendedOperators: false})
|
|
|
|
.then(updateShouldHaveFailed, function onError(err) {
|
|
|
|
should.exist(err);
|
|
|
|
should(err.name).equal('ValidationError');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`Model.settings.allowExtendedOperators` override data source settings - ' +
|
|
|
|
'disable strict check', () => {
|
|
|
|
const TestModel = createTestModel({allowExtendedOperators: false},
|
|
|
|
{strict: true, allowExtendedOperators: true});
|
|
|
|
return TestModel.create({value: 'test'}).then((instance) => {
|
|
|
|
return instance.updateAttributes(setCustomData()).then(() => {
|
|
|
|
should(TestModel.lastPersistedData).eql(setCustomData());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`Model.settings.allowExtendedOperators` override data source settings - ' +
|
|
|
|
'enable strict check', () => {
|
|
|
|
const TestModel = createTestModel({allowExtendedOperators: true},
|
|
|
|
{strict: true, allowExtendedOperators: false});
|
|
|
|
return TestModel.create({value: 'test'}).then((inst) => {
|
|
|
|
return inst.updateAttributes(setCustomData())
|
|
|
|
.then(updateShouldHaveFailed, function onError(err) {
|
|
|
|
should.exist(err);
|
|
|
|
should(err.name).equal('ValidationError');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('Model.settings.allowExtendedOperators', () => {
|
|
|
|
context('DAO.find()', () => {
|
|
|
|
it('preserves extended operators with allowExtendedOperators set', () => {
|
|
|
|
const TestModel = createTestModel({}, {allowExtendedOperators: true});
|
2018-10-14 16:27:46 +00:00
|
|
|
return TestModel.find(extendedQuery()).then(results => {
|
2016-06-16 14:34:38 +00:00
|
|
|
should(results[0].value).eql({$exists: true});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`dataSource.settings.allowExtendedOperators` honor Model settings - ' +
|
2018-10-14 16:27:46 +00:00
|
|
|
'reports invalid operator', () => {
|
2016-06-16 14:34:38 +00:00
|
|
|
const TestModel = createTestModel({allowExtendedOperators: true}, {allowExtendedOperators: false});
|
2018-10-14 16:27:46 +00:00
|
|
|
return TestModel.find(extendedQuery()).catch(err => {
|
|
|
|
assertOperatorNotAllowed(err);
|
2016-06-16 14:34:38 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`dataSource.settings.allowExtendedOperators` honor Model settings - ' +
|
|
|
|
'preserves extended operators', () => {
|
|
|
|
const TestModel = createTestModel({allowExtendedOperators: false}, {allowExtendedOperators: true});
|
2018-10-14 16:27:46 +00:00
|
|
|
return TestModel.find(extendedQuery()).then(results => {
|
2016-06-16 14:34:38 +00:00
|
|
|
should(results[0].value).eql({$exists: true});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`options.allowExtendedOperators` override Model settings - converts extended operators', () => {
|
|
|
|
const TestModel = createTestModel({allowExtendedOperators: true});
|
2018-10-14 16:27:46 +00:00
|
|
|
return TestModel.find(extendedQuery(), {allowExtendedOperators: false}).catch(err => {
|
|
|
|
assertOperatorNotAllowed(err);
|
2016-06-16 14:34:38 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`options.allowExtendedOperators` Model settings - preserves extended operators', () => {
|
|
|
|
const TestModel = createTestModel({allowExtendedOperators: false});
|
2018-10-14 16:27:46 +00:00
|
|
|
return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then(results => {
|
2016-06-16 14:34:38 +00:00
|
|
|
should(results[0].value).eql({$exists: true});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
context('DAO.updateAttributes()', () => {
|
|
|
|
it('`options.allowExtendedOperators` override Model settings - disable strict check', () => {
|
|
|
|
const TestModel = createTestModel({}, {strict: true, allowExtendedOperators: false});
|
|
|
|
return TestModel.create({value: 'test'}).then((instance) => {
|
|
|
|
return instance.updateAttributes(setCustomData(), {allowExtendedOperators: true})
|
|
|
|
.then(() => {
|
|
|
|
should(TestModel.lastPersistedData).eql(setCustomData());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`options.allowExtendedOperators` override Model settings - enabled strict check', () => {
|
|
|
|
const TestModel = createTestModel({}, {strict: true, allowExtendedOperators: true});
|
|
|
|
return TestModel.create({value: 'test'}).then((inst) => {
|
|
|
|
return inst.updateAttributes(setCustomData(), {allowExtendedOperators: false})
|
|
|
|
.then(updateShouldHaveFailed, function onError(err) {
|
|
|
|
should.exist(err);
|
|
|
|
should(err.name).equal('ValidationError');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`dataSource.settings.allowExtendedOperators` honor Model settings - disable strict check', () => {
|
|
|
|
const TestModel = createTestModel({allowExtendedOperators: false},
|
|
|
|
{strict: true, allowExtendedOperators: true});
|
|
|
|
return TestModel.create({value: 'test'}).then((instance) => {
|
|
|
|
return instance.updateAttributes(setCustomData()).then(() => {
|
|
|
|
should(TestModel.lastPersistedData).eql(setCustomData());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`dataSource.settings.allowExtendedOperators` honor Model settings - ' +
|
|
|
|
'enable strict check', () => {
|
|
|
|
const TestModel = createTestModel({allowExtendedOperators: true},
|
|
|
|
{strict: true, allowExtendedOperators: false});
|
|
|
|
return TestModel.create({value: 'test'}).then((inst) => {
|
|
|
|
return inst.updateAttributes(setCustomData())
|
|
|
|
.then(updateShouldHaveFailed, function onError(err) {
|
|
|
|
should.exist(err);
|
|
|
|
should(err.name).equal('ValidationError');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('options.allowExtendedOperators', () => {
|
|
|
|
context('DAO.find()', () => {
|
|
|
|
it('preserves extended operators with allowExtendedOperators set', () => {
|
|
|
|
const TestModel = createTestModel();
|
2018-10-14 16:27:46 +00:00
|
|
|
return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then(results => {
|
2016-06-16 14:34:38 +00:00
|
|
|
should(results[0].value).eql({$exists: true});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`dataSource.settings.allowExtendedOperators` honor options settings - ' +
|
|
|
|
'converts extended operators', () => {
|
|
|
|
const TestModel = createTestModel({allowExtendedOperators: true});
|
2018-10-14 16:27:46 +00:00
|
|
|
return TestModel.find(extendedQuery(), {allowExtendedOperators: false}).catch(err => {
|
|
|
|
assertOperatorNotAllowed(err);
|
2016-06-16 14:34:38 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`dataSource.settings.allowExtendedOperators` honor options settings - ' +
|
|
|
|
'preserves extended operators', () => {
|
|
|
|
const TestModel = createTestModel({allowExtendedOperators: false});
|
2018-10-14 16:27:46 +00:00
|
|
|
return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then(results => {
|
2016-06-16 14:34:38 +00:00
|
|
|
should(results[0].value).eql({$exists: true});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`Model.settings.allowExtendedOperators` honor options settings - ' +
|
|
|
|
'converts extended operators', () => {
|
|
|
|
const TestModel = createTestModel({}, {allowExtendedOperators: true});
|
2018-10-14 16:27:46 +00:00
|
|
|
return TestModel.find(extendedQuery(), {allowExtendedOperators: false}).catch(err => {
|
|
|
|
assertOperatorNotAllowed(err);
|
2016-06-16 14:34:38 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`Model.settings.allowExtendedOperators` honor options settings - ' +
|
|
|
|
'preserves extended operators', () => {
|
|
|
|
const TestModel = createTestModel({}, {allowExtendedOperators: false});
|
2018-10-14 16:27:46 +00:00
|
|
|
return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then(results => {
|
2016-06-16 14:34:38 +00:00
|
|
|
should(results[0].value).eql({$exists: true});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
context('DAO.updateAttributes()', () => {
|
|
|
|
it('`Model.settings.allowExtendedOperators` honor options settings - disable strict check', () => {
|
|
|
|
const TestModel = createTestModel({}, {strict: true, allowExtendedOperators: false});
|
|
|
|
return TestModel.create({value: 'test'}).then((instance) => {
|
|
|
|
return instance.updateAttributes(setCustomData(), {allowExtendedOperators: true})
|
|
|
|
.then(() => {
|
|
|
|
should(TestModel.lastPersistedData).eql(setCustomData());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`Model.settings.allowExtendedOperators` honor options settings - enable strict check', () => {
|
|
|
|
const TestModel = createTestModel({}, {strict: true, allowExtendedOperators: true});
|
|
|
|
return TestModel.create({value: 'test'}).then((inst) => {
|
|
|
|
return inst.updateAttributes(setCustomData(), {allowExtendedOperators: false})
|
|
|
|
.then(updateShouldHaveFailed, function onError(err) {
|
|
|
|
should.exist(err);
|
|
|
|
should(err.name).equal('ValidationError');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`dataSource.settings.allowExtendedOperators` honor options settings - disable strict check', () => {
|
|
|
|
const TestModel = createTestModel({}, {strict: true});
|
|
|
|
return TestModel.create({value: 'test'}).then((instance) => {
|
|
|
|
return instance.updateAttributes(setCustomData(), {allowExtendedOperators: true})
|
|
|
|
.then(() => {
|
|
|
|
should(TestModel.lastPersistedData).eql(setCustomData());
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('`dataSource.settings.allowExtendedOperators` honor options settings - enable strict check', () => {
|
|
|
|
const TestModel = createTestModel({allowExtendedOperators: true}, {strict: true});
|
|
|
|
return TestModel.create({value: 'test'}).then((inst) => {
|
|
|
|
return inst.updateAttributes(setCustomData(), {allowExtendedOperators: false})
|
|
|
|
.then(updateShouldHaveFailed, function onError(err) {
|
|
|
|
should.exist(err);
|
|
|
|
should(err.name).equal('ValidationError');
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
2016-12-05 15:04:54 +00:00
|
|
|
});
|