diff --git a/integration/test/ParseLocalDatastoreTest.js b/integration/test/ParseLocalDatastoreTest.js index 19d224582..2c13c2423 100644 --- a/integration/test/ParseLocalDatastoreTest.js +++ b/integration/test/ParseLocalDatastoreTest.js @@ -1227,6 +1227,66 @@ function runTest(controller) { assert.equal(results[0].id, parent3.id); }); + it(`${controller.name} can handle containsAll query on array`, async () => { + const obj1 = new TestObject({ arrayField: [1, 2, 3, 4] }); + const obj2 = new TestObject({ arrayField: [0, 2] }); + const obj3 = new TestObject({ arrayField: [1, 2, 3] }); + await Parse.Object.saveAll([obj1, obj2, obj3]); + await Parse.Object.pinAll([obj1, obj2, obj3]); + + let query = new Parse.Query(TestObject); + query.containsAll('arrayField', [1, 2]); + query.fromPin(); + let results = await query.find(); + expect(results.length).toBe(2); + + query = new Parse.Query(TestObject); + query.containsAll('arrayField', [5, 6]); + query.fromPin(); + results = await query.find(); + expect(results.length).toBe(0); + }); + + it(`${controller.name} can handle containedIn query on array`, async () => { + const obj1 = new TestObject({ arrayField: [1, 2, 3, 4] }); + const obj2 = new TestObject({ arrayField: [0, 2] }); + const obj3 = new TestObject({ arrayField: [1, 2, 3] }); + await Parse.Object.saveAll([obj1, obj2, obj3]); + await Parse.Object.pinAll([obj1, obj2, obj3]); + + let query = new Parse.Query(TestObject); + query.containedIn('arrayField', [3]); + query.fromPin(); + let results = await query.find(); + expect(results.length).toEqual(2); + + query = new Parse.Query(TestObject); + query.containedIn('arrayField', [5]); + query.fromPin(); + results = await query.find(); + expect(results.length).toEqual(0); + }); + + it(`${controller.name} can handle notContainedIn query on array`, async () => { + const obj1 = new TestObject({ arrayField: [1, 2, 3, 4] }); + const obj2 = new TestObject({ arrayField: [0, 2] }); + const obj3 = new TestObject({ arrayField: [1, 2, 3] }); + await Parse.Object.saveAll([obj1, obj2, obj3]); + await Parse.Object.pinAll([obj1, obj2, obj3]); + + let query = new Parse.Query(TestObject); + query.notContainedIn('arrayField', [3]); + query.fromPin(); + let results = await query.find(); + expect(results.length).toEqual(1); + + query = new Parse.Query(TestObject); + query.notContainedIn('arrayField', [5]); + query.fromPin(); + results = await query.find(); + expect(results.length).toEqual(3); + }); + it(`${controller.name} can test equality with undefined`, async () => { const query = new Parse.Query('BoxedNumber'); query.equalTo('number', undefined); diff --git a/src/OfflineQuery.js b/src/OfflineQuery.js index f76cfa061..aac8b15e2 100644 --- a/src/OfflineQuery.js +++ b/src/OfflineQuery.js @@ -24,6 +24,13 @@ function contains(haystack, needle) { } return false; } + if (Array.isArray(needle)) { + for (const need of needle) { + if (contains(haystack, need)) { + return true; + } + } + } return haystack.indexOf(needle) > -1; } diff --git a/src/__tests__/OfflineQuery-test.js b/src/__tests__/OfflineQuery-test.js index ae67a8494..1a24bc011 100644 --- a/src/__tests__/OfflineQuery-test.js +++ b/src/__tests__/OfflineQuery-test.js @@ -610,6 +610,33 @@ describe('OfflineQuery', () => { expect(matchesQuery(q.className, message, [], q)).toBe(false); }); + it('should support containedIn with array of pointers', () => { + const profile1 = new ParseObject('Profile'); + profile1.id = 'yeahaw'; + const profile2 = new ParseObject('Profile'); + profile2.id = 'yes'; + + const message = new ParseObject('Message'); + message.id = 'O2'; + message.set('profiles', [profile1, profile2]); + + let q = new ParseQuery('Message'); + q.containedIn('profiles', [ + ParseObject.fromJSON({ className: 'Profile', objectId: 'no' }), + ParseObject.fromJSON({ className: 'Profile', objectId: 'yes' }), + ]); + + expect(matchesQuery(q.className, message, [], q)).toBe(true); + + q = new ParseQuery('Message'); + q.containedIn('profiles', [ + ParseObject.fromJSON({ className: 'Profile', objectId: 'no' }), + ParseObject.fromJSON({ className: 'Profile', objectId: 'nope' }), + ]); + + expect(matchesQuery(q.className, message, [], q)).toBe(false); + }); + it('should support notContainedIn with pointers', () => { const profile = new ParseObject('Profile'); profile.id = 'abc';