@@ -18,6 +18,7 @@ import kotlinx.coroutines.flow.filter
18
18
import kotlinx.coroutines.flow.first
19
19
import kotlinx.coroutines.test.TestResult
20
20
import kotlinx.coroutines.withContext
21
+ import kotlinx.serialization.KSerializer
21
22
import kotlinx.serialization.Serializable
22
23
import kotlinx.serialization.builtins.nullable
23
24
import kotlin.random.Random
@@ -43,6 +44,7 @@ class FirebaseFirestoreTest {
43
44
val time : Double = 0.0 ,
44
45
val count : Int = 0 ,
45
46
val list : List <String > = emptyList(),
47
+ val optional : String? = null ,
46
48
)
47
49
48
50
@Serializable
@@ -51,6 +53,29 @@ class FirebaseFirestoreTest {
51
53
val time : BaseTimestamp ?
52
54
)
53
55
56
+ companion object {
57
+ val testOne = FirestoreTest (
58
+ " aaa" ,
59
+ 0.0 ,
60
+ 1 ,
61
+ listOf (" a" , " aa" , " aaa" ),
62
+ " notNull" ,
63
+ )
64
+ val testTwo = FirestoreTest (
65
+ " bbb" ,
66
+ 0.0 ,
67
+ 2 ,
68
+ listOf (" b" , " bb" , " ccc" )
69
+ )
70
+ val testThree = FirestoreTest (
71
+ " ccc" ,
72
+ 1.0 ,
73
+ 3 ,
74
+ listOf (" c" , " cc" , " ccc" ),
75
+ " notNull" ,
76
+ )
77
+ }
78
+
54
79
lateinit var firestore: FirebaseFirestore
55
80
56
81
@BeforeTest
@@ -523,18 +548,241 @@ class FirebaseFirestoreTest {
523
548
assertEquals(setOf (DocumentWithTimestamp (futureTimestamp)), gtQueryResult)
524
549
}
525
550
526
- private suspend fun setupFirestoreData () {
551
+ @Test
552
+ fun testQueryEqualTo () = runTest {
553
+ setupFirestoreData()
554
+
555
+ val fieldQuery = firestore
556
+ .collection(" testFirestoreQuerying" )
557
+ .where { " prop1" equalTo testOne.prop1 }
558
+
559
+ fieldQuery.assertDocuments(FirestoreTest .serializer(), testOne)
560
+
561
+ val pathQuery = firestore
562
+ .collection(" testFirestoreQuerying" )
563
+ .where { FieldPath (FirestoreTest ::prop1.name) equalTo testTwo.prop1 }
564
+
565
+ pathQuery.assertDocuments(FirestoreTest .serializer(), testTwo)
566
+
567
+ val nullableQuery = firestore
568
+ .collection(" testFirestoreQuerying" )
569
+ .where { FieldPath (FirestoreTest ::optional.name) equalTo null }
570
+
571
+ nullableQuery.assertDocuments(FirestoreTest .serializer(), testTwo)
572
+ }
573
+
574
+ @Test
575
+ fun testQueryNotEqualTo () = runTest {
576
+ setupFirestoreData()
577
+
578
+ val fieldQuery = firestore
579
+ .collection(" testFirestoreQuerying" )
580
+ .where { " prop1" notEqualTo testOne.prop1 }
581
+
582
+ fieldQuery.assertDocuments(FirestoreTest .serializer(), testTwo, testThree)
583
+
584
+ val pathQuery = firestore
585
+ .collection(" testFirestoreQuerying" )
586
+ .where { FieldPath (FirestoreTest ::prop1.name) notEqualTo testTwo.prop1 }
587
+
588
+ pathQuery.assertDocuments(FirestoreTest .serializer(), testOne, testThree)
589
+
590
+ val nullableQuery = firestore
591
+ .collection(" testFirestoreQuerying" )
592
+ .where { FieldPath (FirestoreTest ::optional.name) notEqualTo null }
593
+
594
+ nullableQuery.assertDocuments(FirestoreTest .serializer(), testOne, testThree)
595
+ }
596
+
597
+ @Test
598
+ fun testQueryLessThan () = runTest {
599
+ setupFirestoreData()
600
+
601
+ val fieldQuery = firestore
602
+ .collection(" testFirestoreQuerying" )
603
+ .where { " count" lessThan testThree.count }
604
+
605
+ fieldQuery.assertDocuments(FirestoreTest .serializer(), testOne, testTwo)
606
+
607
+ val pathQuery = firestore
608
+ .collection(" testFirestoreQuerying" )
609
+ .where { FieldPath (FirestoreTest ::count.name) lessThan testTwo.count }
610
+
611
+ pathQuery.assertDocuments(FirestoreTest .serializer(), testOne)
612
+ }
613
+
614
+ @Test
615
+ fun testQueryGreaterThan () = runTest {
616
+ setupFirestoreData()
617
+
618
+ val fieldQuery = firestore
619
+ .collection(" testFirestoreQuerying" )
620
+ .where { " count" greaterThan testOne.count }
621
+
622
+ fieldQuery.assertDocuments(FirestoreTest .serializer(), testTwo, testThree)
623
+
624
+ val pathQuery = firestore
625
+ .collection(" testFirestoreQuerying" )
626
+ .where { FieldPath (FirestoreTest ::count.name) greaterThan testTwo.count }
627
+
628
+ pathQuery.assertDocuments(FirestoreTest .serializer(), testThree)
629
+ }
630
+
631
+ @Test
632
+ fun testQueryLessThanOrEqualTo () = runTest {
633
+ setupFirestoreData()
634
+
635
+ val fieldQuery = firestore
636
+ .collection(" testFirestoreQuerying" )
637
+ .where { " count" lessThanOrEqualTo testOne.count }
638
+
639
+ fieldQuery.assertDocuments(FirestoreTest .serializer(), testOne)
640
+
641
+ val pathQuery = firestore
642
+ .collection(" testFirestoreQuerying" )
643
+ .where { FieldPath (FirestoreTest ::count.name) lessThanOrEqualTo testTwo.count }
644
+
645
+ pathQuery.assertDocuments(FirestoreTest .serializer(), testOne, testTwo)
646
+ }
647
+
648
+ @Test
649
+ fun testQueryGreaterThanOrEqualTo () = runTest {
650
+ setupFirestoreData()
651
+
652
+ val fieldQuery = firestore
653
+ .collection(" testFirestoreQuerying" )
654
+ .where { " count" greaterThanOrEqualTo testThree.count }
655
+
656
+ fieldQuery.assertDocuments(FirestoreTest .serializer(), testThree)
657
+
658
+ val pathQuery = firestore
659
+ .collection(" testFirestoreQuerying" )
660
+ .where { FieldPath (FirestoreTest ::count.name) greaterThanOrEqualTo testTwo.count }
661
+
662
+ pathQuery.assertDocuments(FirestoreTest .serializer(), testTwo, testThree)
663
+ }
664
+
665
+ @Test
666
+ fun testQueryArrayContains () = runTest {
667
+ setupFirestoreData()
668
+
669
+ val fieldQuery = firestore
670
+ .collection(" testFirestoreQuerying" )
671
+ .where { " list" contains " a" }
672
+
673
+ fieldQuery.assertDocuments(FirestoreTest .serializer(), testOne)
674
+
675
+ val pathQuery = firestore
676
+ .collection(" testFirestoreQuerying" )
677
+ .where { FieldPath (FirestoreTest ::list.name) contains " ccc" }
678
+
679
+ pathQuery.assertDocuments(FirestoreTest .serializer(), testThree, testTwo)
680
+ }
681
+
682
+ @Test
683
+ fun testQueryArrayContainsAny () = runTest {
684
+ setupFirestoreData()
685
+
686
+ val fieldQuery = firestore
687
+ .collection(" testFirestoreQuerying" )
688
+ .where { " list" containsAny listOf (" a" , " b" ) }
689
+
690
+ fieldQuery.assertDocuments(FirestoreTest .serializer(), testOne, testTwo)
691
+
692
+ val pathQuery = firestore
693
+ .collection(" testFirestoreQuerying" )
694
+ .where { FieldPath (FirestoreTest ::list.name) containsAny listOf (" c" , " d" ) }
695
+
696
+ pathQuery.assertDocuments(FirestoreTest .serializer(), testThree)
697
+ }
698
+
699
+ @Test
700
+ fun testQueryInArray () = runTest {
701
+ setupFirestoreData()
702
+
703
+ val fieldQuery = firestore
704
+ .collection(" testFirestoreQuerying" )
705
+ .where { " prop1" `in ` listOf (" aaa" , " bbb" ) }
706
+
707
+ fieldQuery.assertDocuments(FirestoreTest .serializer(), testOne, testTwo)
708
+
709
+ val pathQuery = firestore
710
+ .collection(" testFirestoreQuerying" )
711
+ .where { FieldPath (FirestoreTest ::prop1.name) `in ` listOf (" ccc" , " ddd" ) }
712
+
713
+ pathQuery.assertDocuments(FirestoreTest .serializer(), testThree)
714
+ }
715
+
716
+ @Test
717
+ fun testQueryNotInArray () = runTest {
718
+ setupFirestoreData()
719
+
720
+ val fieldQuery = firestore
721
+ .collection(" testFirestoreQuerying" )
722
+ .where { " prop1" notIn listOf (" aaa" , " bbb" ) }
723
+
724
+ fieldQuery.assertDocuments(FirestoreTest .serializer(), testThree)
725
+
726
+ val pathQuery = firestore
727
+ .collection(" testFirestoreQuerying" )
728
+ .where { FieldPath (FirestoreTest ::prop1.name) notIn listOf (" ccc" , " ddd" ) }
729
+
730
+ pathQuery.assertDocuments(FirestoreTest .serializer(), testOne, testTwo)
731
+ }
732
+
733
+ @Test
734
+ fun testCompoundQuery () = runTest {
735
+ setupFirestoreData()
736
+
737
+ val andQuery = firestore
738
+ .collection(" testFirestoreQuerying" )
739
+ .where {
740
+ FieldPath (FirestoreTest ::prop1.name) `in ` listOf (" aaa" , " bbb" ) and (FieldPath (FirestoreTest ::count.name) equalTo 1 )
741
+ }
742
+ andQuery.assertDocuments(FirestoreTest .serializer(), testOne)
743
+
744
+ val orQuery = firestore
745
+ .collection(" testFirestoreQuerying" )
746
+ .where {
747
+ FieldPath (FirestoreTest ::prop1.name) equalTo " aaa" or (FieldPath (FirestoreTest ::count.name) equalTo 2 )
748
+ }
749
+ orQuery.assertDocuments(FirestoreTest .serializer(), testOne, testTwo)
750
+
751
+ val andOrQuery = firestore
752
+ .collection(" testFirestoreQuerying" )
753
+ .where {
754
+ (
755
+ FieldPath (FirestoreTest ::prop1.name) equalTo " aaa" or
756
+ (FieldPath (FirestoreTest ::count.name) equalTo 2 )
757
+ ) and (FieldPath (FirestoreTest ::list.name) contains " a" )
758
+ }
759
+ andOrQuery.assertDocuments(FirestoreTest .serializer(), testOne)
760
+ }
761
+
762
+ private suspend fun setupFirestoreData (
763
+ documentOne : FirestoreTest = testOne,
764
+ documentTwo : FirestoreTest = testTwo,
765
+ documentThree : FirestoreTest = testThree
766
+ ) {
527
767
firestore.collection(" testFirestoreQuerying" )
528
768
.document(" one" )
529
- .set(FirestoreTest .serializer(), FirestoreTest ( " aaa " ) )
769
+ .set(FirestoreTest .serializer(), documentOne )
530
770
firestore.collection(" testFirestoreQuerying" )
531
771
.document(" two" )
532
- .set(FirestoreTest .serializer(), FirestoreTest ( " bbb " ) )
772
+ .set(FirestoreTest .serializer(), documentTwo )
533
773
firestore.collection(" testFirestoreQuerying" )
534
774
.document(" three" )
535
- .set(FirestoreTest .serializer(), FirestoreTest ( " ccc " ) )
775
+ .set(FirestoreTest .serializer(), documentThree )
536
776
}
537
-
777
+
778
+ private suspend fun <T > Query.assertDocuments (serializer : KSerializer <T >, vararg expected : T ) {
779
+ val documents = get().documents
780
+ assertEquals(expected.size, documents.size)
781
+ documents.forEachIndexed { index, documentSnapshot ->
782
+ assertEquals(expected[index], documentSnapshot.data(serializer))
783
+ }
784
+ }
785
+
538
786
private suspend fun nonSkippedDelay (timeout : Long ) = withContext(Dispatchers .Default ) {
539
787
delay(timeout)
540
788
}
0 commit comments