Skip to content

Commit 10fa73c

Browse files
authored
Merge pull request #369 from leeyeh/feat-query-param-check
feat(Query): throw Errors when undefined is specified as key/value
2 parents ad0595d + e09a117 commit 10fa73c

File tree

3 files changed

+53
-33
lines changed

3 files changed

+53
-33
lines changed

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ node_js:
66

77
sudo: false
88

9+
before_install:
10+
- if [[ `npm -v` != 3* ]]; then npm i -g npm; fi
911
install:
1012
- npm install -g codecov
1113
- npm install

src/query.js

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
const _ = require('underscore');
22
const AVError = require('./error');
33
const AVRequest = require('./request').request;
4+
const { ensureArray } = require('./utils');
5+
6+
const requires = (value, message) => {
7+
if (value === undefined) {
8+
throw new Error(message);
9+
}
10+
};
411

512
// AV.Query is a way to create a list of AV.Objects.
613
module.exports = function(AV) {
@@ -58,6 +65,7 @@ module.exports = function(AV) {
5865

5966
this._where = {};
6067
this._include = [];
68+
this._select = [];
6169
this._limit = -1; // negative limit means, do not send a limit
6270
this._skip = 0;
6371
this._extraOptions = {};
@@ -203,7 +211,7 @@ module.exports = function(AV) {
203211
if (this._include.length > 0) {
204212
params.include = this._include.join(",");
205213
}
206-
if (this._select) {
214+
if (this._select.length > 0) {
207215
params.keys = this._select.join(",");
208216
}
209217
if (this._limit >= 0) {
@@ -275,8 +283,6 @@ module.exports = function(AV) {
275283

276284
/**
277285
* Counts the number of objects that match this query.
278-
* Either options.success or options.error is called when the count
279-
* completes.
280286
*
281287
* @param {AuthOptions} options
282288
* @return {Promise} A promise that is resolved with the count when
@@ -326,6 +332,7 @@ module.exports = function(AV) {
326332
* @return {AV.Query} Returns the query, so you can chain this call.
327333
*/
328334
skip: function(n) {
335+
requires(n, 'undefined is not a valid skip value');
329336
this._skip = n;
330337
return this;
331338
},
@@ -337,6 +344,7 @@ module.exports = function(AV) {
337344
* @return {AV.Query} Returns the query, so you can chain this call.
338345
*/
339346
limit: function(n) {
347+
requires(n, 'undefined is not a valid limit value');
340348
this._limit = n;
341349
return this;
342350
},
@@ -349,6 +357,8 @@ module.exports = function(AV) {
349357
* @return {AV.Query} Returns the query, so you can chain this call.
350358
*/
351359
equalTo: function(key, value) {
360+
requires(key, 'undefined is not a valid key');
361+
requires(value, 'undefined is not a valid value');
352362
this._where[key] = AV._encode(value);
353363
return this;
354364
},
@@ -358,6 +368,10 @@ module.exports = function(AV) {
358368
* @private
359369
*/
360370
_addCondition: function(key, condition, value) {
371+
requires(key, 'undefined is not a valid condition key');
372+
requires(condition, 'undefined is not a valid condition');
373+
requires(value, 'undefined is not a valid condition value');
374+
361375
// Check if we already have a condition
362376
if (!this._where[key]) {
363377
this._where[key] = {};
@@ -669,6 +683,7 @@ module.exports = function(AV) {
669683
* @return {AV.Query} Returns the query, so you can chain this call.
670684
*/
671685
ascending: function(key) {
686+
requires(key, 'undefined is not a valid key');
672687
this._order = key;
673688
return this;
674689
},
@@ -681,6 +696,7 @@ module.exports = function(AV) {
681696
* @return {AV.Query} Returns the query so you can chain this call.
682697
*/
683698
addAscending: function(key){
699+
requires(key, 'undefined is not a valid key');
684700
if(this._order)
685701
this._order += ',' + key;
686702
else
@@ -695,6 +711,7 @@ module.exports = function(AV) {
695711
* @return {AV.Query} Returns the query, so you can chain this call.
696712
*/
697713
descending: function(key) {
714+
requires(key, 'undefined is not a valid key');
698715
this._order = "-" + key;
699716
return this;
700717
},
@@ -707,6 +724,7 @@ module.exports = function(AV) {
707724
* @return {AV.Query} Returns the query so you can chain this call.
708725
*/
709726
addDescending: function(key){
727+
requires(key, 'undefined is not a valid key');
710728
if(this._order)
711729
this._order += ',-' + key;
712730
else
@@ -797,38 +815,25 @@ module.exports = function(AV) {
797815
/**
798816
* Include nested AV.Objects for the provided key. You can use dot
799817
* notation to specify which fields in the included object are also fetch.
800-
* @param {String} key The name of the key to include.
818+
* @param {String[]} keys The name of the key to include.
801819
* @return {AV.Query} Returns the query, so you can chain this call.
802820
*/
803-
include: function() {
804-
var self = this;
805-
AV._arrayEach(arguments, function(key) {
806-
if (_.isArray(key)) {
807-
self._include = self._include.concat(key);
808-
} else {
809-
self._include.push(key);
810-
}
811-
});
821+
include: function(keys) {
822+
requires(keys, 'undefined is not a valid key');
823+
this._include = this._include.concat(ensureArray(keys));
812824
return this;
813825
},
814826

815827
/**
816828
* Restrict the fields of the returned AV.Objects to include only the
817829
* provided keys. If this is called multiple times, then all of the keys
818830
* specified in each of the calls will be included.
819-
* @param {Array} keys The names of the keys to include.
831+
* @param {String[]} keys The names of the keys to include.
820832
* @return {AV.Query} Returns the query, so you can chain this call.
821833
*/
822-
select: function() {
823-
var self = this;
824-
this._select = this._select || [];
825-
AV._arrayEach(arguments, function(key) {
826-
if (_.isArray(key)) {
827-
self._select = self._select.concat(key);
828-
} else {
829-
self._select.push(key);
830-
}
831-
});
834+
select: function(keys) {
835+
requires(keys, 'undefined is not a valid key');
836+
this._select = this._select.concat(ensureArray(keys));
832837
return this;
833838
},
834839

test/query.js

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,10 @@ describe('Queries', function () {
3434

3535
query = new AV.Query(GameScore);
3636
expect(function() {
37-
query.get(null, {
38-
success: function () {},
39-
error: function () {}
40-
});
37+
query.get(null);
4138
}).to.throwError();
4239
expect(function() {
43-
query.get(undefined, {
44-
success: function () {},
45-
error: function () {}
46-
});
40+
query.get(undefined);
4741
}).to.throwError();
4842

4943
});
@@ -120,11 +114,30 @@ describe('Queries', function () {
120114
});
121115

122116
describe('Query Constraints', function () {
117+
before(function() {
118+
return new GameScore({
119+
playerName: 'testname',
120+
}).save().then(gameScore => this.gameScore = gameScore);
121+
});
122+
123+
after(function() {
124+
return this.gameScore.destroy();
125+
});
123126

124127
it('basic', function () {
125128
query = new AV.Query(GameScore);
126129
query.equalTo('playerName', 'testname');
127-
return query.first();
130+
return query.first().then(gameScore => {
131+
expect(gameScore.get('playerName')).to.be('testname');
132+
});
133+
});
134+
135+
it('param check', () => {
136+
const query = new AV.Query(GameScore);
137+
expect(() => query.equalTo('playerName', undefined)).to.throwError();
138+
expect(() => query.contains('playerName', undefined)).to.throwError();
139+
expect(() => query.limit(undefined)).to.throwError();
140+
expect(() => query.addAscending(undefined)).to.throwError();
128141
});
129142

130143
it('sizeEqualTo', function () {

0 commit comments

Comments
 (0)