FIRIndexingTests.mm 8.3 KB

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