FIRCountTests.mm 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. /*
  2. * Copyright 2022 Google LLC
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #import <FirebaseFirestore/FirebaseFirestore.h>
  17. #import <XCTest/XCTest.h>
  18. #import "Firestore/Example/Tests/Util/FSTIntegrationTestCase.h"
  19. #import "Firestore/Source/Public/FirebaseFirestore/FIRAggregateQuery.h"
  20. #import "Firestore/Source/Public/FirebaseFirestore/FIRAggregateQuerySnapshot.h"
  21. #import "Firestore/Source/Public/FirebaseFirestore/FIRAggregateSource.h"
  22. @interface FIRCountTests : FSTIntegrationTestCase
  23. @end
  24. @implementation FIRCountTests
  25. - (void)testAggregateQueryEquals {
  26. FIRCollectionReference* coll1 = [self collectionRefWithDocuments:@{}];
  27. FIRCollectionReference* coll1Same = [[coll1 firestore] collectionWithPath:[coll1 path]];
  28. FIRAggregateQuery* query1 = [coll1 count];
  29. FIRAggregateQuery* query1Same = [coll1Same count];
  30. FIRCollectionReference* sub = [[coll1 documentWithPath:@"bar"] collectionWithPath:@"baz"];
  31. FIRAggregateQuery* query2 = [[[sub queryWhereField:@"a" isEqualTo:@1] queryLimitedTo:100] count];
  32. FIRAggregateQuery* query2Same = [[[sub queryWhereField:@"a"
  33. isEqualTo:@1] queryLimitedTo:100] count];
  34. FIRAggregateQuery* query3 = [[[sub queryWhereField:@"b"
  35. isEqualTo:@1] queryOrderedByField:@"c"] count];
  36. FIRAggregateQuery* query3Same = [[[sub queryWhereField:@"b"
  37. isEqualTo:@1] queryOrderedByField:@"c"] count];
  38. XCTAssertEqualObjects(query1, query1Same);
  39. XCTAssertEqualObjects(query2, query2Same);
  40. XCTAssertEqualObjects(query3, query3Same);
  41. XCTAssertEqual([query1 hash], [query1Same hash]);
  42. XCTAssertEqual([query2 hash], [query2Same hash]);
  43. XCTAssertEqual([query3 hash], [query3Same hash]);
  44. XCTAssertFalse([query1 isEqual:nil]);
  45. XCTAssertFalse([query1 isEqual:@"string"]);
  46. XCTAssertFalse([query1 isEqual:query2]);
  47. XCTAssertFalse([query2 isEqual:query3]);
  48. XCTAssertNotEqual([query1 hash], [query2 hash]);
  49. XCTAssertNotEqual([query2 hash], [query3 hash]);
  50. }
  51. - (void)testCanRunCountQuery {
  52. // TODO(b/246758022): Remove this (and below) once COUNT is release for the backend.
  53. if (![FSTIntegrationTestCase isRunningAgainstEmulator]) {
  54. return;
  55. }
  56. FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
  57. @"a" : @{@"k" : @"a"},
  58. @"b" : @{@"k" : @"b"},
  59. @"c" : @{@"k" : @"c"}
  60. }];
  61. FIRAggregateQuerySnapshot* snapshot = [self readSnapshotForAggregate:[testCollection count]];
  62. XCTAssertEqual(snapshot.count, [NSNumber numberWithLong:3L]);
  63. }
  64. - (void)testCanRunCountWithFilters {
  65. if (![FSTIntegrationTestCase isRunningAgainstEmulator]) {
  66. return;
  67. }
  68. FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
  69. @"a" : @{@"k" : @"a"},
  70. @"b" : @{@"k" : @"b"},
  71. @"c" : @{@"k" : @"c"}
  72. }];
  73. FIRAggregateQuerySnapshot* snapshot =
  74. [self readSnapshotForAggregate:[[testCollection queryWhereField:@"k" isEqualTo:@"b"] count]];
  75. XCTAssertEqual(snapshot.count, [NSNumber numberWithLong:1L]);
  76. }
  77. - (void)testCanRunCountWithOrderBys {
  78. if (![FSTIntegrationTestCase isRunningAgainstEmulator]) {
  79. return;
  80. }
  81. FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
  82. @"a" : @{@"k" : @"a"},
  83. @"b" : @{@"k" : @"b"},
  84. @"c" : @{@"k" : @"c"},
  85. @"d" : @{@"absent" : @"d"},
  86. }];
  87. FIRAggregateQuerySnapshot* snapshot =
  88. [self readSnapshotForAggregate:[[testCollection queryOrderedByField:@"k"] count]];
  89. XCTAssertEqual(snapshot.count, [NSNumber numberWithLong:3L]);
  90. }
  91. - (void)testSnapshotEquals {
  92. if (![FSTIntegrationTestCase isRunningAgainstEmulator]) {
  93. return;
  94. }
  95. FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
  96. @"a" : @{@"k" : @"a"},
  97. @"b" : @{@"k" : @"b"},
  98. @"c" : @{@"k" : @"c"}
  99. }];
  100. FIRAggregateQuerySnapshot* snapshot1 =
  101. [self readSnapshotForAggregate:[[testCollection queryWhereField:@"k" isEqualTo:@"b"] count]];
  102. FIRAggregateQuerySnapshot* snapshot1Same =
  103. [self readSnapshotForAggregate:[[testCollection queryWhereField:@"k" isEqualTo:@"b"] count]];
  104. FIRAggregateQuerySnapshot* snapshot2 =
  105. [self readSnapshotForAggregate:[[testCollection queryWhereField:@"k" isEqualTo:@"a"] count]];
  106. [self writeDocumentRef:[testCollection documentWithPath:@"d"] data:@{@"k" : @"a"}];
  107. FIRAggregateQuerySnapshot* snapshot2Different =
  108. [self readSnapshotForAggregate:[[testCollection queryWhereField:@"k" isEqualTo:@"a"] count]];
  109. FIRAggregateQuerySnapshot* snapshot3 =
  110. [self readSnapshotForAggregate:[[testCollection queryWhereField:@"k" isEqualTo:@"b"] count]];
  111. FIRAggregateQuerySnapshot* snapshot3Different =
  112. [self readSnapshotForAggregate:[[testCollection queryWhereField:@"k" isEqualTo:@"c"] count]];
  113. XCTAssertEqualObjects(snapshot1, snapshot1Same);
  114. XCTAssertEqual([snapshot1 hash], [snapshot1Same hash]);
  115. XCTAssertEqualObjects([snapshot1 query], [[testCollection queryWhereField:@"k"
  116. isEqualTo:@"b"] count]);
  117. XCTAssertNotEqualObjects(snapshot1, nil);
  118. XCTAssertNotEqualObjects(snapshot1, @"string");
  119. XCTAssertNotEqualObjects(snapshot1, snapshot2);
  120. XCTAssertNotEqual([snapshot1 hash], [snapshot2 hash]);
  121. XCTAssertNotEqualObjects(snapshot2, snapshot2Different);
  122. XCTAssertNotEqual([snapshot2 hash], [snapshot2Different hash]);
  123. XCTAssertNotEqualObjects(snapshot3, snapshot3Different);
  124. XCTAssertNotEqual([snapshot3 hash], [snapshot3Different hash]);
  125. }
  126. - (void)testTerminateDoesNotCrashWithFlyingCountQuery {
  127. if (![FSTIntegrationTestCase isRunningAgainstEmulator]) {
  128. return;
  129. }
  130. FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
  131. @"a" : @{@"k" : @"a"},
  132. @"b" : @{@"k" : @"b"},
  133. @"c" : @{@"k" : @"c"},
  134. }];
  135. [[testCollection count]
  136. aggregationWithSource:FIRAggregateSourceServer
  137. completion:^(FIRAggregateQuerySnapshot* snapshot, NSError* error) {
  138. (void)snapshot;
  139. (void)error;
  140. }];
  141. [self terminateFirestore:testCollection.firestore];
  142. }
  143. - (void)testCanRunCollectionGroupCountQuery {
  144. if (![FSTIntegrationTestCase isRunningAgainstEmulator]) {
  145. return;
  146. }
  147. NSString* collectionGroup =
  148. [NSString stringWithFormat:@"%@%@", @"b",
  149. [self.db collectionWithPath:@"foo"].documentWithAutoID.documentID];
  150. NSArray* docPathFormats = @[
  151. @"abc/123/%@/cg-doc1", @"abc/123/%@/cg-doc2", @"%@/cg-doc3", @"%@/cg-doc4",
  152. @"def/456/%@/cg-doc5", @"%@/virtual-doc/nested-coll/not-cg-doc", @"x%@/not-cg-doc",
  153. @"%@x/not-cg-doc", @"abc/123/%@x/not-cg-doc", @"abc/123/x%@/not-cg-doc", @"abc/%@"
  154. ];
  155. FIRWriteBatch* batch = self.db.batch;
  156. for (NSString* format in docPathFormats) {
  157. NSString* path = [NSString stringWithFormat:format, collectionGroup];
  158. [batch setData:@{@"x" : @"a"} forDocument:[self.db documentWithPath:path]];
  159. }
  160. XCTestExpectation* expectation = [self expectationWithDescription:@"commit"];
  161. [batch commitWithCompletion:^(NSError* error) {
  162. XCTAssertNil(error);
  163. [expectation fulfill];
  164. }];
  165. [self awaitExpectation:expectation];
  166. FIRAggregateQuerySnapshot* snapshot =
  167. [self readSnapshotForAggregate:[[self.db collectionGroupWithID:collectionGroup] count]];
  168. // "cg-doc1", "cg-doc2", "cg-doc3", "cg-doc4", "cg-doc5",
  169. XCTAssertEqual(snapshot.count, [NSNumber numberWithLong:5L]);
  170. }
  171. - (void)testCanRunCountWithFiltersAndLimits {
  172. if (![FSTIntegrationTestCase isRunningAgainstEmulator]) {
  173. return;
  174. }
  175. FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
  176. @"a" : @{@"k" : @"a"},
  177. @"b" : @{@"k" : @"a"},
  178. @"c" : @{@"k" : @"a"},
  179. @"d" : @{@"k" : @"d"},
  180. }];
  181. FIRAggregateQuerySnapshot* snapshot = [self
  182. readSnapshotForAggregate:[[[testCollection queryLimitedTo:2] queryWhereField:@"k"
  183. isEqualTo:@"a"] count]];
  184. XCTAssertEqual(snapshot.count, [NSNumber numberWithLong:2L]);
  185. snapshot = [self readSnapshotForAggregate:[[[testCollection queryLimitedToLast:2]
  186. queryWhereField:@"k"
  187. isEqualTo:@"a"] count]];
  188. XCTAssertEqual(snapshot.count, [NSNumber numberWithLong:2L]);
  189. snapshot = [self readSnapshotForAggregate:[[[testCollection queryLimitedToLast:1000]
  190. queryWhereField:@"k"
  191. isEqualTo:@"d"] count]];
  192. XCTAssertEqual(snapshot.count, [NSNumber numberWithLong:1L]);
  193. }
  194. - (void)testCanRunCountOnNonExistentCollection {
  195. if (![FSTIntegrationTestCase isRunningAgainstEmulator]) {
  196. return;
  197. }
  198. FIRCollectionReference* testCollection = [self collectionRef];
  199. FIRAggregateQuerySnapshot* snapshot = [self readSnapshotForAggregate:[testCollection count]];
  200. XCTAssertEqual(snapshot.count, [NSNumber numberWithLong:0L]);
  201. snapshot = [self readSnapshotForAggregate:[[testCollection queryWhereField:@"k"
  202. isEqualTo:@"a"] count]];
  203. XCTAssertEqual(snapshot.count, [NSNumber numberWithLong:0L]);
  204. }
  205. - (void)testFailWithoutNetwork {
  206. if (![FSTIntegrationTestCase isRunningAgainstEmulator]) {
  207. return;
  208. }
  209. FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
  210. @"a" : @{@"k" : @"a"},
  211. @"b" : @{@"k" : @"b"},
  212. @"c" : @{@"k" : @"c"}
  213. }];
  214. [self disableNetwork];
  215. [[testCollection count]
  216. aggregationWithSource:FIRAggregateSourceServer
  217. completion:^(FIRAggregateQuerySnapshot* snapshot, NSError* error) {
  218. (void)snapshot;
  219. XCTAssertNotNil(error);
  220. }];
  221. [self enableNetwork];
  222. FIRAggregateQuerySnapshot* snapshot = [self readSnapshotForAggregate:[testCollection count]];
  223. XCTAssertEqual(snapshot.count, [NSNumber numberWithLong:3L]);
  224. }
  225. @end