@@ -164,6 +164,124 @@ describe('Parse.Query Aggregate testing', () => {
164164 } ) ;
165165 } ) ;
166166
167+ it ( 'group by date object transform' , ( done ) => {
168+ const obj1 = new TestObject ( ) ;
169+ const obj2 = new TestObject ( ) ;
170+ const obj3 = new TestObject ( ) ;
171+ const pipeline = [ {
172+ group : {
173+ objectId : { day : { $dayOfMonth : "$updatedAt" } , month : { $month : "$createdAt" } , year : { $year : "$createdAt" } } ,
174+ count : { $sum : 1 }
175+ }
176+ } ] ;
177+ Parse . Object . saveAll ( [ obj1 , obj2 , obj3 ] ) . then ( ( ) => {
178+ const query = new Parse . Query ( TestObject ) ;
179+ return query . aggregate ( pipeline ) ;
180+ } ) . then ( ( results ) => {
181+ const createdAt = new Date ( obj1 . createdAt ) ;
182+ expect ( results [ 0 ] . objectId . day ) . toEqual ( createdAt . getUTCDate ( ) ) ;
183+ expect ( results [ 0 ] . objectId . month ) . toEqual ( createdAt . getMonth ( ) + 1 ) ;
184+ expect ( results [ 0 ] . objectId . year ) . toEqual ( createdAt . getUTCFullYear ( ) ) ;
185+ done ( ) ;
186+ } ) ;
187+ } ) ;
188+
189+ it_exclude_dbs ( [ 'postgres' ] ) ( 'group and multiply transform' , ( done ) => {
190+ const obj1 = new TestObject ( { name : 'item a' , quantity : 2 , price : 10 } ) ;
191+ const obj2 = new TestObject ( { name : 'item b' , quantity : 5 , price : 5 } ) ;
192+ const pipeline = [ {
193+ group : {
194+ objectId : null ,
195+ total : { $sum : { $multiply : [ '$quantity' , '$price' ] } }
196+ }
197+ } ] ;
198+ Parse . Object . saveAll ( [ obj1 , obj2 ] ) . then ( ( ) => {
199+ const query = new Parse . Query ( TestObject ) ;
200+ return query . aggregate ( pipeline ) ;
201+ } ) . then ( ( results ) => {
202+ expect ( results . length ) . toEqual ( 1 ) ;
203+ expect ( results [ 0 ] . total ) . toEqual ( 45 ) ;
204+ done ( ) ;
205+ } ) ;
206+ } ) ;
207+
208+ it_exclude_dbs ( [ 'postgres' ] ) ( 'project and multiply transform' , ( done ) => {
209+ const obj1 = new TestObject ( { name : 'item a' , quantity : 2 , price : 10 } ) ;
210+ const obj2 = new TestObject ( { name : 'item b' , quantity : 5 , price : 5 } ) ;
211+ const pipeline = [
212+ {
213+ match : { quantity : { $exists : true } }
214+ } ,
215+ {
216+ project : {
217+ name : 1 ,
218+ total : { $multiply : [ '$quantity' , '$price' ] }
219+ }
220+ }
221+ ] ;
222+ Parse . Object . saveAll ( [ obj1 , obj2 ] ) . then ( ( ) => {
223+ const query = new Parse . Query ( TestObject ) ;
224+ return query . aggregate ( pipeline ) ;
225+ } ) . then ( ( results ) => {
226+ expect ( results . length ) . toEqual ( 2 ) ;
227+ if ( results [ 0 ] . name === 'item a' ) {
228+ expect ( results [ 0 ] . total ) . toEqual ( 20 ) ;
229+ expect ( results [ 1 ] . total ) . toEqual ( 25 ) ;
230+ }
231+ else {
232+ expect ( results [ 0 ] . total ) . toEqual ( 25 ) ;
233+ expect ( results [ 1 ] . total ) . toEqual ( 20 ) ;
234+ }
235+ done ( ) ;
236+ } ) ;
237+ } ) ;
238+
239+ it_exclude_dbs ( [ 'postgres' ] ) ( 'project without objectId transform' , ( done ) => {
240+ const obj1 = new TestObject ( { name : 'item a' , quantity : 2 , price : 10 } ) ;
241+ const obj2 = new TestObject ( { name : 'item b' , quantity : 5 , price : 5 } ) ;
242+ const pipeline = [
243+ {
244+ match : { quantity : { $exists : true } }
245+ } ,
246+ {
247+ project : {
248+ objectId : 0 ,
249+ total : { $multiply : [ '$quantity' , '$price' ] }
250+ }
251+ } ,
252+ {
253+ sort : { total : 1 }
254+ }
255+ ] ;
256+ Parse . Object . saveAll ( [ obj1 , obj2 ] ) . then ( ( ) => {
257+ const query = new Parse . Query ( TestObject ) ;
258+ return query . aggregate ( pipeline ) ;
259+ } ) . then ( ( results ) => {
260+ expect ( results . length ) . toEqual ( 2 ) ;
261+ expect ( results [ 0 ] . total ) . toEqual ( 20 ) ;
262+ expect ( results [ 0 ] . objectId ) . toEqual ( undefined ) ;
263+ expect ( results [ 1 ] . total ) . toEqual ( 25 ) ;
264+ expect ( results [ 1 ] . objectId ) . toEqual ( undefined ) ;
265+ done ( ) ;
266+ } ) ;
267+ } ) ;
268+
269+ it_exclude_dbs ( [ 'postgres' ] ) ( 'project updatedAt only transform' , ( done ) => {
270+ const pipeline = [ {
271+ project : { objectId : 0 , updatedAt : 1 }
272+ } ] ;
273+ const query = new Parse . Query ( TestObject ) ;
274+ query . aggregate ( pipeline ) . then ( ( results ) => {
275+ expect ( results . length ) . toEqual ( 4 ) ;
276+ for ( let i = 0 ; i < results . length ; i ++ ) {
277+ const item = results [ i ] ;
278+ expect ( item . hasOwnProperty ( 'updatedAt' ) ) . toEqual ( true ) ;
279+ expect ( item . hasOwnProperty ( 'objectId' ) ) . toEqual ( false ) ;
280+ }
281+ done ( ) ;
282+ } ) ;
283+ } ) ;
284+
167285 it_exclude_dbs ( [ 'postgres' ] ) ( 'cannot group by date field (excluding createdAt and updatedAt)' , ( done ) => {
168286 const obj1 = new TestObject ( { dateField : new Date ( 1990 , 11 , 1 ) } ) ;
169287 const obj2 = new TestObject ( { dateField : new Date ( 1990 , 5 , 1 ) } ) ;
@@ -339,6 +457,27 @@ describe('Parse.Query Aggregate testing', () => {
339457 } ) . catch ( done . fail ) ;
340458 } ) ;
341459
460+ it ( 'match comparison date query' , ( done ) => {
461+ const today = new Date ( ) ;
462+ const yesterday = new Date ( ) ;
463+ const tomorrow = new Date ( ) ;
464+ yesterday . setDate ( today . getDate ( ) - 1 ) ;
465+ tomorrow . setDate ( today . getDate ( ) + 1 ) ;
466+ const obj1 = new TestObject ( { dateField : yesterday } ) ;
467+ const obj2 = new TestObject ( { dateField : today } ) ;
468+ const obj3 = new TestObject ( { dateField : tomorrow } ) ;
469+ const pipeline = [
470+ { match : { dateField : { $lt : tomorrow } } }
471+ ] ;
472+ Parse . Object . saveAll ( [ obj1 , obj2 , obj3 ] ) . then ( ( ) => {
473+ const query = new Parse . Query ( TestObject ) ;
474+ return query . aggregate ( pipeline ) ;
475+ } ) . then ( ( results ) => {
476+ expect ( results . length ) . toBe ( 2 ) ;
477+ done ( ) ;
478+ } ) ;
479+ } ) ;
480+
342481 it ( 'match comparison query' , ( done ) => {
343482 const options = Object . assign ( { } , masterKeyOptions , {
344483 body : {
@@ -474,6 +613,96 @@ describe('Parse.Query Aggregate testing', () => {
474613 } ) ;
475614 } ) ;
476615
616+ it_exclude_dbs ( [ 'postgres' ] ) ( 'match exists query' , ( done ) => {
617+ const pipeline = [
618+ { match : { score : { $exists : true } } }
619+ ] ;
620+ const query = new Parse . Query ( TestObject ) ;
621+ query . aggregate ( pipeline ) . then ( ( results ) => {
622+ expect ( results . length ) . toEqual ( 4 ) ;
623+ done ( ) ;
624+ } ) ;
625+ } ) ;
626+
627+ it ( 'match date query - createdAt' , ( done ) => {
628+ const obj1 = new TestObject ( ) ;
629+ const obj2 = new TestObject ( ) ;
630+
631+ Parse . Object . saveAll ( [ obj1 , obj2 ] ) . then ( ( ) => {
632+ const now = new Date ( ) ;
633+ const today = new Date ( now . getFullYear ( ) , now . getMonth ( ) , now . getDate ( ) ) ;
634+ const pipeline = [
635+ { match : { 'createdAt' : { $gte : today } } }
636+ ] ;
637+ const query = new Parse . Query ( TestObject ) ;
638+ return query . aggregate ( pipeline ) ;
639+ } ) . then ( ( results ) => {
640+ // Four objects were created initially, we added two more.
641+ expect ( results . length ) . toEqual ( 6 ) ;
642+ done ( ) ;
643+ } ) ;
644+ } ) ;
645+
646+ it ( 'match date query - updatedAt' , ( done ) => {
647+ const obj1 = new TestObject ( ) ;
648+ const obj2 = new TestObject ( ) ;
649+
650+ Parse . Object . saveAll ( [ obj1 , obj2 ] ) . then ( ( ) => {
651+ const now = new Date ( ) ;
652+ const today = new Date ( now . getFullYear ( ) , now . getMonth ( ) , now . getDate ( ) ) ;
653+ const pipeline = [
654+ { match : { 'updatedAt' : { $gte : today } } }
655+ ] ;
656+ const query = new Parse . Query ( TestObject ) ;
657+ return query . aggregate ( pipeline ) ;
658+ } ) . then ( ( results ) => {
659+ // Four objects were added initially, we added two more.
660+ expect ( results . length ) . toEqual ( 6 ) ;
661+ done ( ) ;
662+ } ) ;
663+ } ) ;
664+
665+ it ( 'match date query - empty' , ( done ) => {
666+ const obj1 = new TestObject ( ) ;
667+ const obj2 = new TestObject ( ) ;
668+
669+ Parse . Object . saveAll ( [ obj1 , obj2 ] ) . then ( ( ) => {
670+ const now = new Date ( ) ;
671+ const future = new Date ( now . getFullYear ( ) , now . getMonth ( ) + 1 , now . getDate ( ) ) ;
672+ const pipeline = [
673+ { match : { 'createdAt' : future } }
674+ ] ;
675+ const query = new Parse . Query ( TestObject ) ;
676+ return query . aggregate ( pipeline ) ;
677+ } ) . then ( ( results ) => {
678+ expect ( results . length ) . toEqual ( 0 ) ;
679+ done ( ) ;
680+ } ) ;
681+ } ) ;
682+
683+ it_exclude_dbs ( [ 'postgres' ] ) ( 'match pointer with operator query' , ( done ) => {
684+ const pointer = new PointerObject ( ) ;
685+
686+ const obj1 = new TestObject ( { pointer } ) ;
687+ const obj2 = new TestObject ( { pointer } ) ;
688+ const obj3 = new TestObject ( ) ;
689+
690+ Parse . Object . saveAll ( [ pointer , obj1 , obj2 , obj3 ] ) . then ( ( ) => {
691+ const pipeline = [
692+ { match : { pointer : { $exists : true } } }
693+ ] ;
694+ const query = new Parse . Query ( TestObject ) ;
695+ return query . aggregate ( pipeline ) ;
696+ } ) . then ( ( results ) => {
697+ expect ( results . length ) . toEqual ( 2 ) ;
698+ expect ( results [ 0 ] . pointer . objectId ) . toEqual ( pointer . id ) ;
699+ expect ( results [ 1 ] . pointer . objectId ) . toEqual ( pointer . id ) ;
700+ expect ( results . some ( result => result . objectId === obj1 . id ) ) . toEqual ( true ) ;
701+ expect ( results . some ( result => result . objectId === obj2 . id ) ) . toEqual ( true ) ;
702+ done ( ) ;
703+ } ) ;
704+ } ) ;
705+
477706 it ( 'project query' , ( done ) => {
478707 const options = Object . assign ( { } , masterKeyOptions , {
479708 body : {
@@ -512,6 +741,26 @@ describe('Parse.Query Aggregate testing', () => {
512741 } ) . catch ( done . fail ) ;
513742 } ) ;
514743
744+ it ( 'project pointer query' , ( done ) => {
745+ const pointer = new PointerObject ( ) ;
746+ const obj = new TestObject ( { pointer, name : 'hello' } ) ;
747+
748+ obj . save ( ) . then ( ( ) => {
749+ const pipeline = [
750+ { match : { objectId : obj . id } } ,
751+ { project : { pointer : 1 , name : 1 , createdAt : 1 } }
752+ ] ;
753+ const query = new Parse . Query ( TestObject ) ;
754+ return query . aggregate ( pipeline ) ;
755+ } ) . then ( ( results ) => {
756+ expect ( results . length ) . toEqual ( 1 ) ;
757+ expect ( results [ 0 ] . name ) . toEqual ( 'hello' ) ;
758+ expect ( results [ 0 ] . createdAt ) . not . toBe ( undefined ) ;
759+ expect ( results [ 0 ] . pointer . objectId ) . toEqual ( pointer . id ) ;
760+ done ( ) ;
761+ } ) ;
762+ } ) ;
763+
515764 it ( 'project with group query' , ( done ) => {
516765 const options = Object . assign ( { } , masterKeyOptions , {
517766 body : {
0 commit comments