FIRIndexingTests.mm 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  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/Source/API/FIRFirestore+Internal.h"
  19. #import "Firestore/Source/API/FIRPersistentCacheSettings+Internal.h"
  20. #import "Firestore/Example/Tests/Util/FSTHelpers.h"
  21. #import "Firestore/Example/Tests/Util/FSTIntegrationTestCase.h"
  22. @interface FIRIndexingTests : FSTIntegrationTestCase
  23. @end
  24. @implementation FIRIndexingTests
  25. // Clears persistence for each test method to have a clean start.
  26. - (void)setUp {
  27. [super setUp];
  28. self.db = [self firestore];
  29. XCTestExpectation *exp = [self expectationWithDescription:@"clear persistence"];
  30. [self.db clearPersistenceWithCompletion:^(NSError *) {
  31. [exp fulfill];
  32. }];
  33. [self awaitExpectation:exp];
  34. }
  35. - (void)testCanConfigureIndexes {
  36. NSString *json = @"{\n"
  37. "\t\"indexes\": [{\n"
  38. "\t\t\t\"collectionGroup\": \"restaurants\",\n"
  39. "\t\t\t\"queryScope\": \"COLLECTION\",\n"
  40. "\t\t\t\"fields\": [{\n"
  41. "\t\t\t\t\t\"fieldPath\": \"price\",\n"
  42. "\t\t\t\t\t\"order\": \"ASCENDING\"\n"
  43. "\t\t\t\t},\n"
  44. "\t\t\t\t{\n"
  45. "\t\t\t\t\t\"fieldPath\": \"avgRating\",\n"
  46. "\t\t\t\t\t\"order\": \"DESCENDING\"\n"
  47. "\t\t\t\t}\n"
  48. "\t\t\t]\n"
  49. "\t\t},\n"
  50. "\t\t{\n"
  51. "\t\t\t\"collectionGroup\": \"restaurants\",\n"
  52. "\t\t\t\"queryScope\": \"COLLECTION\",\n"
  53. "\t\t\t\"fields\": [{\n"
  54. "\t\t\t\t\"fieldPath\": \"price\",\n"
  55. "\t\t\t\t\"order\": \"ASCENDING\"\n"
  56. "\t\t\t}]\n"
  57. "\t\t}\n"
  58. "\t],\n"
  59. "\t\"fieldOverrides\": []\n"
  60. "}";
  61. [self.db setIndexConfigurationFromJSON:json
  62. completion:^(NSError *error) {
  63. XCTAssertNil(error);
  64. }];
  65. }
  66. - (void)testBadJsonDoesNotCrashClient {
  67. [self.db setIndexConfigurationFromJSON:@"{,"
  68. completion:^(NSError *error) {
  69. XCTAssertNotNil(error);
  70. XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
  71. XCTAssertEqual(error.code, FIRFirestoreErrorCodeInvalidArgument);
  72. }];
  73. }
  74. - (void)testBadIndexDoesNotCrashClient {
  75. NSString *json = @"{\n"
  76. "\t\"indexes\": [{\n"
  77. "\t\t\"collectionGroup\": \"restaurants\",\n"
  78. "\t\t\"queryScope\": \"COLLECTION\",\n"
  79. "\t\t\"fields\": [{\n"
  80. "\t\t\t\"fieldPath\": \"price\",\n"
  81. "\t\t\t\"order\": \"ASCENDING\",\n"
  82. "\t\t]}\n"
  83. "\t}],\n"
  84. "\t\"fieldOverrides\": []\n"
  85. "}";
  86. [self.db setIndexConfigurationFromJSON:json
  87. completion:^(NSError *error) {
  88. XCTAssertNotNil(error);
  89. XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
  90. XCTAssertEqual(error.code, FIRFirestoreErrorCodeInvalidArgument);
  91. }];
  92. }
  93. /**
  94. * After Auto Index Creation is enabled, through public API there is no way to see the indexes
  95. * sitting inside SDK. So this test only checks the API of auto index creation.
  96. */
  97. - (void)testAutoIndexCreationSetSuccessfully {
  98. // Use persistent disk cache (explict)
  99. FIRFirestoreSettings *settings = [self.db settings];
  100. [settings setCacheSettings:[[FIRPersistentCacheSettings alloc] init]];
  101. [self.db setSettings:settings];
  102. FIRCollectionReference *coll = [self collectionRef];
  103. NSDictionary *testDocs = @{
  104. @"a" : @{@"match" : @YES},
  105. @"b" : @{@"match" : @NO},
  106. @"c" : @{@"match" : @NO},
  107. };
  108. [self writeAllDocuments:testDocs toCollection:coll];
  109. FIRQuery *query = [coll queryWhereField:@"match" isEqualTo:@YES];
  110. [query getDocumentsWithSource:FIRFirestoreSourceCache
  111. completion:^(FIRQuerySnapshot *results, NSError *error) {
  112. XCTAssertNil(error);
  113. XCTAssertEqual(results.count, 1);
  114. }];
  115. XCTAssertNoThrow([self.db.persistentCacheIndexManager enableIndexAutoCreation]);
  116. [query getDocumentsWithSource:FIRFirestoreSourceCache
  117. completion:^(FIRQuerySnapshot *results, NSError *error) {
  118. XCTAssertNil(error);
  119. XCTAssertEqual(results.count, 1);
  120. }];
  121. XCTAssertNoThrow([self.db.persistentCacheIndexManager disableIndexAutoCreation]);
  122. [query getDocumentsWithSource:FIRFirestoreSourceCache
  123. completion:^(FIRQuerySnapshot *results, NSError *error) {
  124. XCTAssertNil(error);
  125. XCTAssertEqual(results.count, 1);
  126. }];
  127. XCTAssertNoThrow([self.db.persistentCacheIndexManager deleteAllIndexes]);
  128. [query getDocumentsWithSource:FIRFirestoreSourceCache
  129. completion:^(FIRQuerySnapshot *results, NSError *error) {
  130. XCTAssertNil(error);
  131. XCTAssertEqual(results.count, 1);
  132. }];
  133. }
  134. - (void)testAutoIndexCreationSetSuccessfullyUsingDefault {
  135. // Use persistent disk cache (default)
  136. FIRCollectionReference *coll = [self collectionRef];
  137. NSDictionary *testDocs = @{
  138. @"a" : @{@"match" : @YES},
  139. @"b" : @{@"match" : @NO},
  140. @"c" : @{@"match" : @NO},
  141. };
  142. [self writeAllDocuments:testDocs toCollection:coll];
  143. FIRQuery *query = [coll queryWhereField:@"match" isEqualTo:@YES];
  144. [query getDocumentsWithSource:FIRFirestoreSourceCache
  145. completion:^(FIRQuerySnapshot *results, NSError *error) {
  146. XCTAssertNil(error);
  147. XCTAssertEqual(results.count, 1);
  148. }];
  149. XCTAssertNoThrow([self.db.persistentCacheIndexManager enableIndexAutoCreation]);
  150. [query getDocumentsWithSource:FIRFirestoreSourceCache
  151. completion:^(FIRQuerySnapshot *results, NSError *error) {
  152. XCTAssertNil(error);
  153. XCTAssertEqual(results.count, 1);
  154. }];
  155. XCTAssertNoThrow([self.db.persistentCacheIndexManager disableIndexAutoCreation]);
  156. [query getDocumentsWithSource:FIRFirestoreSourceCache
  157. completion:^(FIRQuerySnapshot *results, NSError *error) {
  158. XCTAssertNil(error);
  159. XCTAssertEqual(results.count, 1);
  160. }];
  161. XCTAssertNoThrow([self.db.persistentCacheIndexManager deleteAllIndexes]);
  162. [query getDocumentsWithSource:FIRFirestoreSourceCache
  163. completion:^(FIRQuerySnapshot *results, NSError *error) {
  164. XCTAssertNil(error);
  165. XCTAssertEqual(results.count, 1);
  166. }];
  167. }
  168. - (void)testAutoIndexCreationAfterFailsTermination {
  169. [self terminateFirestore:self.db];
  170. FSTAssertThrows([self.db.persistentCacheIndexManager enableIndexAutoCreation],
  171. @"The client has already been terminated.");
  172. FSTAssertThrows([self.db.persistentCacheIndexManager disableIndexAutoCreation],
  173. @"The client has already been terminated.");
  174. FSTAssertThrows([self.db.persistentCacheIndexManager deleteAllIndexes],
  175. @"The client has already been terminated.");
  176. }
  177. // TODO(b/296100693) Add testing hooks to verify indexes are created as expected.
  178. @end