UNPKG

14.5 kBJavaScriptView Raw
1// Copyright IBM Corp. 2016,2019. All Rights Reserved.
2// Node module: loopback-datasource-juggler
3// This file is licensed under the MIT License.
4// License text available at https://opensource.org/licenses/MIT
5
6'use strict';
7
8const DataSource = require('..').DataSource;
9const should = require('should');
10
11describe('allowExtendedOperators', () => {
12 function createTestModel(connectorSettings, modelSettings) {
13 const ds = createTestDataSource(connectorSettings);
14 const TestModel = ds.createModel('TestModel', {value: String}, modelSettings);
15
16 TestModel.observe('persist', function(ctx, next) {
17 ctx.Model.lastPersistedData = ctx.data;
18 next();
19 });
20
21 return TestModel;
22 }
23
24 function createTestDataSource(connectorSettings) {
25 connectorSettings = connectorSettings || {};
26 connectorSettings.connector = {
27 initialize: (dataSource, cb) => {
28 dataSource.connector = new TestConnector(dataSource);
29 },
30 };
31
32 return new DataSource(connectorSettings);
33 }
34
35 function extendedQuery() {
36 // datasource modifies the query,
37 // we have to build a new object for each test
38 return {where: {value: {$exists: true}}};
39 }
40
41 function setCustomData() {
42 return {$set: {value: 'changed'}};
43 }
44
45 function updateShouldHaveFailed() {
46 throw new Error('updateAttributes() should have failed.');
47 }
48
49 class TestConnector {
50 constructor(dataSource) {
51 }
52
53 create(model, data, options, callback) {
54 callback();
55 }
56
57 updateAttributes(model, id, data, options, callback) {
58 callback();
59 }
60
61 all(model, filter, options, callback) {
62 // return the raw "value" query
63 const instanceFound = {
64 value: filter.where.value,
65 };
66 callback(null, [instanceFound]);
67 }
68 }
69
70 function assertOperatorNotAllowed(err) {
71 should.exist(err);
72 err.message.should.match(/Operators "\$exists" are not allowed in query/);
73 err.code.should.equal('OPERATOR_NOT_ALLOWED_IN_QUERY');
74 err.statusCode.should.equal(400);
75 err.details.should.have.property('operators');
76 err.details.should.have.property('where');
77 }
78
79 describe('dataSource.settings.allowExtendedOperators', () => {
80 context('DAO.find()', () => {
81 it('reports invalid operator by default', () => {
82 const TestModel = createTestModel();
83 return TestModel.find(extendedQuery()).catch(err => {
84 assertOperatorNotAllowed(err);
85 });
86 });
87
88 it('preserves extended operators with allowExtendedOperators set', () => {
89 const TestModel = createTestModel({allowExtendedOperators: true});
90 return TestModel.find(extendedQuery()).then(results => {
91 should(results[0].value).eql({$exists: true});
92 });
93 });
94
95 it('`Model.settings.allowExtendedOperators` override data source settings - ' +
96 'reports invalid operator', () => {
97 const TestModel = createTestModel({allowExtendedOperators: true}, {allowExtendedOperators: false});
98 return TestModel.find(extendedQuery()).catch(err => {
99 assertOperatorNotAllowed(err);
100 });
101 });
102
103 it('`Model.settings.allowExtendedOperators` override data source settings - ' +
104 'preserves extended operators', () => {
105 const TestModel = createTestModel({allowExtendedOperators: false}, {allowExtendedOperators: true});
106 return TestModel.find(extendedQuery()).then(results => {
107 should(results[0].value).eql({$exists: true});
108 });
109 });
110
111 it('`options.allowExtendedOperators` override data source settings - ' +
112 'reports invalid operator', () => {
113 const TestModel = createTestModel({allowExtendedOperators: true});
114 return TestModel.find(extendedQuery(), {allowExtendedOperators: false}).catch(err => {
115 assertOperatorNotAllowed(err);
116 });
117 });
118
119 it('`options.allowExtendedOperators` override data source settings - ' +
120 'preserves extended operators', () => {
121 const TestModel = createTestModel({allowExtendedOperators: false});
122 return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then(results => {
123 should(results[0].value).eql({$exists: true});
124 });
125 });
126 });
127
128 context('DAO.updateAttributes()', () => {
129 it('`options.allowExtendedOperators` override data source settings - disable strict check', () => {
130 const TestModel = createTestModel({allowExtendedOperators: false}, {strict: true});
131 return TestModel.create({value: 'test'}).then((instance) => {
132 return instance.updateAttributes(setCustomData(), {allowExtendedOperators: true})
133 .then(() => {
134 should(TestModel.lastPersistedData).eql(setCustomData());
135 });
136 });
137 });
138
139 it('`options.allowExtendedOperators` override data source settings - enable strict check', () => {
140 const TestModel = createTestModel({allowExtendedOperators: true}, {strict: true});
141 return TestModel.create({value: 'test'}).then((inst) => {
142 return inst.updateAttributes(setCustomData(), {allowExtendedOperators: false})
143 .then(updateShouldHaveFailed, function onError(err) {
144 should.exist(err);
145 should(err.name).equal('ValidationError');
146 });
147 });
148 });
149
150 it('`Model.settings.allowExtendedOperators` override data source settings - ' +
151 'disable strict check', () => {
152 const TestModel = createTestModel({allowExtendedOperators: false},
153 {strict: true, allowExtendedOperators: true});
154 return TestModel.create({value: 'test'}).then((instance) => {
155 return instance.updateAttributes(setCustomData()).then(() => {
156 should(TestModel.lastPersistedData).eql(setCustomData());
157 });
158 });
159 });
160
161 it('`Model.settings.allowExtendedOperators` override data source settings - ' +
162 'enable strict check', () => {
163 const TestModel = createTestModel({allowExtendedOperators: true},
164 {strict: true, allowExtendedOperators: false});
165 return TestModel.create({value: 'test'}).then((inst) => {
166 return inst.updateAttributes(setCustomData())
167 .then(updateShouldHaveFailed, function onError(err) {
168 should.exist(err);
169 should(err.name).equal('ValidationError');
170 });
171 });
172 });
173 });
174 });
175
176 describe('Model.settings.allowExtendedOperators', () => {
177 context('DAO.find()', () => {
178 it('preserves extended operators with allowExtendedOperators set', () => {
179 const TestModel = createTestModel({}, {allowExtendedOperators: true});
180 return TestModel.find(extendedQuery()).then(results => {
181 should(results[0].value).eql({$exists: true});
182 });
183 });
184
185 it('`dataSource.settings.allowExtendedOperators` honor Model settings - ' +
186 'reports invalid operator', () => {
187 const TestModel = createTestModel({allowExtendedOperators: true}, {allowExtendedOperators: false});
188 return TestModel.find(extendedQuery()).catch(err => {
189 assertOperatorNotAllowed(err);
190 });
191 });
192
193 it('`dataSource.settings.allowExtendedOperators` honor Model settings - ' +
194 'preserves extended operators', () => {
195 const TestModel = createTestModel({allowExtendedOperators: false}, {allowExtendedOperators: true});
196 return TestModel.find(extendedQuery()).then(results => {
197 should(results[0].value).eql({$exists: true});
198 });
199 });
200
201 it('`options.allowExtendedOperators` override Model settings - converts extended operators', () => {
202 const TestModel = createTestModel({allowExtendedOperators: true});
203 return TestModel.find(extendedQuery(), {allowExtendedOperators: false}).catch(err => {
204 assertOperatorNotAllowed(err);
205 });
206 });
207
208 it('`options.allowExtendedOperators` Model settings - preserves extended operators', () => {
209 const TestModel = createTestModel({allowExtendedOperators: false});
210 return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then(results => {
211 should(results[0].value).eql({$exists: true});
212 });
213 });
214 });
215
216 context('DAO.updateAttributes()', () => {
217 it('`options.allowExtendedOperators` override Model settings - disable strict check', () => {
218 const TestModel = createTestModel({}, {strict: true, allowExtendedOperators: false});
219 return TestModel.create({value: 'test'}).then((instance) => {
220 return instance.updateAttributes(setCustomData(), {allowExtendedOperators: true})
221 .then(() => {
222 should(TestModel.lastPersistedData).eql(setCustomData());
223 });
224 });
225 });
226
227 it('`options.allowExtendedOperators` override Model settings - enabled strict check', () => {
228 const TestModel = createTestModel({}, {strict: true, allowExtendedOperators: true});
229 return TestModel.create({value: 'test'}).then((inst) => {
230 return inst.updateAttributes(setCustomData(), {allowExtendedOperators: false})
231 .then(updateShouldHaveFailed, function onError(err) {
232 should.exist(err);
233 should(err.name).equal('ValidationError');
234 });
235 });
236 });
237
238 it('`dataSource.settings.allowExtendedOperators` honor Model settings - disable strict check', () => {
239 const TestModel = createTestModel({allowExtendedOperators: false},
240 {strict: true, allowExtendedOperators: true});
241 return TestModel.create({value: 'test'}).then((instance) => {
242 return instance.updateAttributes(setCustomData()).then(() => {
243 should(TestModel.lastPersistedData).eql(setCustomData());
244 });
245 });
246 });
247
248 it('`dataSource.settings.allowExtendedOperators` honor Model settings - ' +
249 'enable strict check', () => {
250 const TestModel = createTestModel({allowExtendedOperators: true},
251 {strict: true, allowExtendedOperators: false});
252 return TestModel.create({value: 'test'}).then((inst) => {
253 return inst.updateAttributes(setCustomData())
254 .then(updateShouldHaveFailed, function onError(err) {
255 should.exist(err);
256 should(err.name).equal('ValidationError');
257 });
258 });
259 });
260 });
261 });
262
263 describe('options.allowExtendedOperators', () => {
264 context('DAO.find()', () => {
265 it('preserves extended operators with allowExtendedOperators set', () => {
266 const TestModel = createTestModel();
267 return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then(results => {
268 should(results[0].value).eql({$exists: true});
269 });
270 });
271
272 it('`dataSource.settings.allowExtendedOperators` honor options settings - ' +
273 'converts extended operators', () => {
274 const TestModel = createTestModel({allowExtendedOperators: true});
275 return TestModel.find(extendedQuery(), {allowExtendedOperators: false}).catch(err => {
276 assertOperatorNotAllowed(err);
277 });
278 });
279
280 it('`dataSource.settings.allowExtendedOperators` honor options settings - ' +
281 'preserves extended operators', () => {
282 const TestModel = createTestModel({allowExtendedOperators: false});
283 return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then(results => {
284 should(results[0].value).eql({$exists: true});
285 });
286 });
287
288 it('`Model.settings.allowExtendedOperators` honor options settings - ' +
289 'converts extended operators', () => {
290 const TestModel = createTestModel({}, {allowExtendedOperators: true});
291 return TestModel.find(extendedQuery(), {allowExtendedOperators: false}).catch(err => {
292 assertOperatorNotAllowed(err);
293 });
294 });
295
296 it('`Model.settings.allowExtendedOperators` honor options settings - ' +
297 'preserves extended operators', () => {
298 const TestModel = createTestModel({}, {allowExtendedOperators: false});
299 return TestModel.find(extendedQuery(), {allowExtendedOperators: true}).then(results => {
300 should(results[0].value).eql({$exists: true});
301 });
302 });
303 });
304
305 context('DAO.updateAttributes()', () => {
306 it('`Model.settings.allowExtendedOperators` honor options settings - disable strict check', () => {
307 const TestModel = createTestModel({}, {strict: true, allowExtendedOperators: false});
308 return TestModel.create({value: 'test'}).then((instance) => {
309 return instance.updateAttributes(setCustomData(), {allowExtendedOperators: true})
310 .then(() => {
311 should(TestModel.lastPersistedData).eql(setCustomData());
312 });
313 });
314 });
315
316 it('`Model.settings.allowExtendedOperators` honor options settings - enable strict check', () => {
317 const TestModel = createTestModel({}, {strict: true, allowExtendedOperators: true});
318 return TestModel.create({value: 'test'}).then((inst) => {
319 return inst.updateAttributes(setCustomData(), {allowExtendedOperators: false})
320 .then(updateShouldHaveFailed, function onError(err) {
321 should.exist(err);
322 should(err.name).equal('ValidationError');
323 });
324 });
325 });
326
327 it('`dataSource.settings.allowExtendedOperators` honor options settings - disable strict check', () => {
328 const TestModel = createTestModel({}, {strict: true});
329 return TestModel.create({value: 'test'}).then((instance) => {
330 return instance.updateAttributes(setCustomData(), {allowExtendedOperators: true})
331 .then(() => {
332 should(TestModel.lastPersistedData).eql(setCustomData());
333 });
334 });
335 });
336
337 it('`dataSource.settings.allowExtendedOperators` honor options settings - enable strict check', () => {
338 const TestModel = createTestModel({allowExtendedOperators: true}, {strict: true});
339 return TestModel.create({value: 'test'}).then((inst) => {
340 return inst.updateAttributes(setCustomData(), {allowExtendedOperators: false})
341 .then(updateShouldHaveFailed, function onError(err) {
342 should.exist(err);
343 should(err.name).equal('ValidationError');
344 });
345 });
346 });
347 });
348 });
349});