21
21
#include < limits>
22
22
23
23
#import " Firestore/Source/API/FIRFieldValue+Internal.h"
24
+ #import " Firestore/Source/API/FIRQuery+Internal.h"
24
25
25
26
#import " Firestore/Example/Tests/Util/FSTHelpers.h"
26
27
#import " Firestore/Example/Tests/Util/FSTIntegrationTestCase.h"
@@ -399,6 +400,10 @@ - (void)testNonEqualityQueriesOnNullOrNaNFail {
399
400
@" Invalid Query. Null supports only equality comparisons." );
400
401
FSTAssertThrows ([[self collectionRef ] queryWhereField: @" a" arrayContains: [NSNull null ]],
401
402
@" Invalid Query. Null supports only equality comparisons." );
403
+ FSTAssertThrows ([[self collectionRef ] queryWhereField: @" a" arrayContainsAny: [NSNull null ]],
404
+ @" Invalid Query. A non-empty array is required for 'arrayContainsAny' filters." );
405
+ FSTAssertThrows ([[self collectionRef ] queryWhereField: @" a" arrayContainsAny: [NSNull null ]],
406
+ @" Invalid Query. A non-empty array is required for 'arrayContainsAny' filters." );
402
407
403
408
FSTAssertThrows ([[self collectionRef ] queryWhereField: @" a" isGreaterThan: @(NAN)],
404
409
@" Invalid Query. NaN supports only equality comparisons." );
@@ -511,7 +516,7 @@ - (void)testQueryMustNotSpecifyStartingOrEndingPointAfterOrder {
511
516
FSTAssertThrows ([[query queryEndingBeforeValues: @[ @1 ]] queryOrderedByField: @" bar" ], reason);
512
517
}
513
518
514
- - (void )testQueriesFilteredByDocumentIDMustUseStringsOrDocumentReferences {
519
+ - (void )testQueriesFilteredByDocumentIdMustUseStringsOrDocumentReferences {
515
520
FIRCollectionReference *collection = [self collectionRef ];
516
521
NSString *reason = @" Invalid query. When querying by document ID you must provide a valid "
517
522
" document ID, but it was an empty string." ;
@@ -539,6 +544,37 @@ - (void)testQueriesFilteredByDocumentIDMustUseStringsOrDocumentReferences {
539
544
" are not arrays." ;
540
545
FSTAssertThrows ([collection queryWhereFieldPath: [FIRFieldPath documentID ] arrayContains: @1 ],
541
546
reason);
547
+
548
+ reason = @" Invalid query. You can't perform arrayContainsAny queries on document ID since "
549
+ @" document IDs "
550
+ " are not arrays." ;
551
+ FSTAssertThrows ([collection queryWhereFieldPath: [FIRFieldPath documentID ] arrayContainsAny: @1 ],
552
+ reason);
553
+ }
554
+
555
+ - (void )testQueriesUsingInAndDocumentIdMustHaveProperDocumentReferencesInArray {
556
+ FIRCollectionReference *collection = [self collectionRef ];
557
+ NSString *reason = @" Invalid query. When querying by document ID you must provide a valid "
558
+ " document ID, but it was an empty string." ;
559
+ FSTAssertThrows ([collection queryWhereFieldPath: [FIRFieldPath documentID ] in: @[ @" " ]], reason);
560
+
561
+ reason = @" Invalid query. When querying a collection by document ID you must provide a "
562
+ " plain document ID, but 'foo/bar/baz' contains a '/' character." ;
563
+ FSTAssertThrows ([collection queryWhereFieldPath: [FIRFieldPath documentID ] in: @[ @" foo/bar/baz" ]],
564
+ reason);
565
+
566
+ reason = @" Invalid query. When querying by document ID you must provide a valid string or "
567
+ " DocumentReference, but it was of type: __NSArrayI" ;
568
+ NSArray *value = @[ @1 , @2 ];
569
+ FSTAssertThrows ([collection queryWhereFieldPath: [FIRFieldPath documentID ] in: value], reason);
570
+
571
+ reason = @" Invalid query. When querying a collection group by document ID, the value "
572
+ " provided must result in a valid document path, but 'foo' is not because it "
573
+ " has an odd number of segments." ;
574
+ FSTAssertThrows (
575
+ [[self .db collectionGroupWithID: @" collection" ] queryWhereFieldPath: [FIRFieldPath documentID ]
576
+ in: @[ @" foo" ]],
577
+ reason);
542
578
}
543
579
544
580
- (void )testQueryInequalityFieldMustMatchFirstOrderByField {
@@ -569,6 +605,9 @@ - (void)testQueryInequalityFieldMustMatchFirstOrderByField {
569
605
@" Inequality and equality on different fields works" );
570
606
XCTAssertNoThrow ([base queryWhereField: @" y" arrayContains: @" cat" ],
571
607
@" Inequality and array_contains on different fields works" );
608
+ XCTAssertNoThrow ([base queryWhereField: @" y" arrayContainsAny: @[ @" cat" ]],
609
+ @" array-contains-any on different fields works" );
610
+ XCTAssertNoThrow ([base queryWhereField: @" y" in: @[ @" cat" ]], @" IN on different fields works" );
572
611
573
612
XCTAssertNoThrow ([base queryOrderedByField: @" x" ], @" inequality same as order by works" );
574
613
XCTAssertNoThrow ([[coll queryOrderedByField: @" x" ] queryWhereField: @" x" isGreaterThan: @32 ],
@@ -585,11 +624,108 @@ - (void)testQueryInequalityFieldMustMatchFirstOrderByField {
585
624
@" array_contains different than orderBy works." );
586
625
}
587
626
588
- - (void )testQueryMustNotHaveMultipleArrayContainsFilters {
627
+ - (void )testQueriesWithMultipleArrayFiltersFail {
589
628
FIRCollectionReference *coll = [self .db collectionWithPath: @" collection" ];
590
629
FSTAssertThrows ([[coll queryWhereField: @" foo" arrayContains: @1 ] queryWhereField: @" foo"
591
630
arrayContains: @2 ],
592
- @" Invalid Query. Queries only support a single arrayContains filter." );
631
+ @" Invalid Query. You cannot use more than one 'arrayContains' filter." );
632
+
633
+ FSTAssertThrows (
634
+ [[coll queryWhereField: @" foo" arrayContains: @1 ] queryWhereField: @" foo"
635
+ arrayContainsAny: @[ @2 ]],
636
+ @" Invalid Query. You cannot use 'arrayContainsAny' filters with 'arrayContains' filters." );
637
+
638
+ FSTAssertThrows (
639
+ [[coll queryWhereField: @" foo" arrayContainsAny: @[ @1 ]] queryWhereField: @" foo"
640
+ arrayContains: @2 ],
641
+ @" Invalid Query. You cannot use 'arrayContains' filters with 'arrayContainsAny' filters." );
642
+ }
643
+
644
+ - (void )testQueriesWithMultipleDisjunctiveFiltersFail {
645
+ FIRCollectionReference *coll = [self .db collectionWithPath: @" collection" ];
646
+ FSTAssertThrows ([[coll queryWhereField: @" foo" in: @[ @1 ]] queryWhereField: @" foo" in: @[ @2 ]],
647
+ @" Invalid Query. You cannot use more than one 'in' filter." );
648
+
649
+ FSTAssertThrows ([[coll queryWhereField: @" foo" arrayContainsAny: @[ @1 ]] queryWhereField: @" foo"
650
+ arrayContainsAny: @[ @2 ]],
651
+ @" Invalid Query. You cannot use more than one 'arrayContainsAny' filter." );
652
+
653
+ FSTAssertThrows ([[coll queryWhereField: @" foo" arrayContainsAny: @[ @1 ]] queryWhereField: @" foo"
654
+ in: @[ @2 ]],
655
+ @" Invalid Query. You cannot use 'in' filters with 'arrayContainsAny' filters." );
656
+
657
+ FSTAssertThrows ([[coll queryWhereField: @" foo" in: @[ @1 ]] queryWhereField: @" foo"
658
+ arrayContainsAny: @[ @2 ]],
659
+ @" Invalid Query. You cannot use 'arrayContainsAny' filters with 'in' filters." );
660
+
661
+ // This is redundant with the above tests, but makes sure our validation doesn't get confused.
662
+ FSTAssertThrows ([[[coll queryWhereField: @" foo"
663
+ in: @[ @1 ]] queryWhereField: @" foo"
664
+ arrayContains: @2 ] queryWhereField: @" foo"
665
+ arrayContainsAny: @[ @2 ]],
666
+ @" Invalid Query. You cannot use 'arrayContainsAny' filters with 'in' filters." );
667
+
668
+ FSTAssertThrows ([[[coll queryWhereField: @" foo"
669
+ arrayContains: @1 ] queryWhereField: @" foo"
670
+ in: @[ @2 ]] queryWhereField: @" foo"
671
+ arrayContainsAny: @[ @2 ]],
672
+ @" Invalid Query. You cannot use 'arrayContainsAny' filters with 'in' filters." );
673
+ }
674
+
675
+ - (void )testQueriesCanUseInWithArrayContain {
676
+ FIRCollectionReference *coll = [self .db collectionWithPath: @" collection" ];
677
+ XCTAssertNoThrow ([[coll queryWhereField: @" foo" arrayContains: @1 ] queryWhereField: @" foo"
678
+ in: @[ @2 ]],
679
+ @" arrayContains with IN works." );
680
+
681
+ XCTAssertNoThrow ([[coll queryWhereField: @" foo" in: @[ @1 ]] queryWhereField: @" foo"
682
+ arrayContains: @2 ],
683
+ @" IN with arrayContains works." );
684
+
685
+ FSTAssertThrows ([[[coll queryWhereField: @" foo"
686
+ in: @[ @1 ]] queryWhereField: @" foo"
687
+ arrayContains: @2 ] queryWhereField: @" foo"
688
+ arrayContains: @3 ],
689
+ @" Invalid Query. You cannot use more than one 'arrayContains' filter." );
690
+
691
+ FSTAssertThrows ([[[coll queryWhereField: @" foo"
692
+ arrayContains: @1 ] queryWhereField: @" foo"
693
+ in: @[ @2 ]] queryWhereField: @" foo"
694
+ in: @[ @3 ]],
695
+ @" Invalid Query. You cannot use more than one 'in' filter." );
696
+ }
697
+
698
+ - (void )testQueriesInAndArrayContainsAnyArrayRules {
699
+ FIRCollectionReference *coll = [self .db collectionWithPath: @" collection" ];
700
+
701
+ FSTAssertThrows ([coll queryWhereField: @" foo" in: @[]],
702
+ @" Invalid Query. A non-empty array is required for 'in' filters." );
703
+
704
+ FSTAssertThrows ([coll queryWhereField: @" foo" arrayContainsAny: @[]],
705
+ @" Invalid Query. A non-empty array is required for 'arrayContainsAny' filters." );
706
+
707
+ // The 10 element max includes duplicates.
708
+ NSArray *values = @[ @1 , @2 , @3 , @4 , @5 , @6 , @7 , @8 , @9 , @9 , @9 ];
709
+ FSTAssertThrows (
710
+ [coll queryWhereField: @" foo" in: values],
711
+ @" Invalid Query. 'in' filters support a maximum of 10 elements in the value array." );
712
+ FSTAssertThrows ([coll queryWhereField: @" foo" arrayContainsAny: values],
713
+ @" Invalid Query. 'arrayContainsAny' filters support a maximum of 10 elements"
714
+ " in the value array." );
715
+
716
+ NSArray *withNullValues = @[ @1 , [NSNull null ] ];
717
+ FSTAssertThrows ([coll queryWhereField: @" foo" in: withNullValues],
718
+ @" Invalid Query. 'in' filters cannot contain 'null' in the value array." );
719
+ FSTAssertThrows (
720
+ [coll queryWhereField: @" foo" arrayContainsAny: withNullValues],
721
+ @" Invalid Query. 'arrayContainsAny' filters cannot contain 'null' in the value array." );
722
+
723
+ NSArray *withNaNValues = @[ @2 , @(NAN) ];
724
+ FSTAssertThrows ([coll queryWhereField: @" foo" in: withNaNValues],
725
+ @" Invalid Query. 'in' filters cannot contain 'NaN' in the value array." );
726
+ FSTAssertThrows (
727
+ [coll queryWhereField: @" foo" arrayContainsAny: withNaNValues],
728
+ @" Invalid Query. 'arrayContainsAny' filters cannot contain 'NaN' in the value array." );
593
729
}
594
730
595
731
#pragma mark - GeoPoint Validation
0 commit comments