| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137 |
- /*
- * Copyright 2023 Google LLC
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #import <FirebaseFirestore/FIRAggregateField.h>
- #import <FirebaseFirestore/FIRFieldPath.h>
- #import <FirebaseFirestore/FirebaseFirestore.h>
- #import <XCTest/XCTest.h>
- #import "Firestore/Example/Tests/Util/FSTIntegrationTestCase.h"
- #import "Firestore/core/src/util/exception.h"
- @interface FIRAggregateTests : FSTIntegrationTestCase
- @end
- @implementation FIRAggregateTests
- - (void)testCountAggregateFieldQueryEquals {
- FIRCollectionReference* coll1 = [self collectionRefWithDocuments:@{}];
- FIRCollectionReference* coll1Same = [[coll1 firestore] collectionWithPath:[coll1 path]];
- FIRAggregateQuery* query1 = [coll1 aggregate:@[ [FIRAggregateField aggregateFieldForCount] ]];
- FIRAggregateQuery* query1Same =
- [coll1Same aggregate:@[ [FIRAggregateField aggregateFieldForCount] ]];
- FIRAggregateQuery* query1DiffAgg =
- [coll1Same aggregate:@[ [FIRAggregateField aggregateFieldForSumOfField:@"baz"] ]];
- FIRCollectionReference* sub = [[coll1 documentWithPath:@"bar"] collectionWithPath:@"baz"];
- FIRAggregateQuery* query2 = [[[sub queryWhereField:@"a" isEqualTo:@1] queryLimitedTo:100]
- aggregate:@[ [FIRAggregateField aggregateFieldForCount] ]];
- FIRAggregateQuery* query2Same = [[[sub queryWhereField:@"a"
- isEqualTo:@1] queryLimitedTo:100] count];
- FIRAggregateQuery* query3 = [[[sub queryWhereField:@"b" isEqualTo:@1] queryOrderedByField:@"c"]
- aggregate:@[ [FIRAggregateField aggregateFieldForCount] ]];
- FIRAggregateQuery* query3Same = [[[sub queryWhereField:@"b"
- isEqualTo:@1] queryOrderedByField:@"c"] count];
- XCTAssertEqualObjects(query1, query1Same);
- XCTAssertEqualObjects(query2, query2Same);
- XCTAssertEqualObjects(query3, query3Same);
- XCTAssertEqual([query1 hash], [query1Same hash]);
- XCTAssertEqual([query2 hash], [query2Same hash]);
- XCTAssertEqual([query3 hash], [query3Same hash]);
- XCTAssertFalse([query1 isEqual:nil]);
- XCTAssertFalse([query1 isEqual:@"string"]);
- XCTAssertFalse([query1 isEqual:query2]);
- XCTAssertFalse([query2 isEqual:query3]);
- XCTAssertNotEqual([query1 hash], [query1DiffAgg hash]);
- XCTAssertNotEqual([query1 hash], [query2 hash]);
- XCTAssertNotEqual([query2 hash], [query3 hash]);
- }
- - (void)testSumAggregateFieldQueryEquals {
- FIRCollectionReference* coll1 = [self collectionRefWithDocuments:@{}];
- FIRCollectionReference* coll1Same = [[coll1 firestore] collectionWithPath:[coll1 path]];
- FIRAggregateQuery* query1 =
- [coll1 aggregate:@[ [FIRAggregateField aggregateFieldForSumOfField:@"baz"] ]];
- FIRAggregateQuery* query1Same =
- [coll1Same aggregate:@[ [FIRAggregateField aggregateFieldForSumOfField:@"baz"] ]];
- FIRAggregateQuery* query1WithFieldPath =
- [coll1Same aggregate:@[ [FIRAggregateField
- aggregateFieldForSumOfFieldPath:[[FIRFieldPath alloc]
- initWithFields:@[ @"baz" ]]] ]];
- FIRAggregateQuery* query1DiffAgg =
- [coll1Same aggregate:@[ [FIRAggregateField aggregateFieldForCount] ]];
- FIRCollectionReference* sub = [[coll1 documentWithPath:@"bar"] collectionWithPath:@"baz"];
- FIRAggregateQuery* query2 = [[[sub queryWhereField:@"a" isEqualTo:@1] queryLimitedTo:100]
- aggregate:@[ [FIRAggregateField aggregateFieldForSumOfField:@"baz"] ]];
- FIRAggregateQuery* query2Same = [[[sub queryWhereField:@"a" isEqualTo:@1] queryLimitedTo:100]
- aggregate:@[ [FIRAggregateField aggregateFieldForSumOfField:@"baz"] ]];
- FIRAggregateQuery* query3 = [[[sub queryWhereField:@"b" isEqualTo:@1] queryOrderedByField:@"c"]
- aggregate:@[ [FIRAggregateField aggregateFieldForSumOfField:@"baz"] ]];
- FIRAggregateQuery* query3Same = [[[sub queryWhereField:@"b"
- isEqualTo:@1] queryOrderedByField:@"c"]
- aggregate:@[ [FIRAggregateField aggregateFieldForSumOfField:@"baz"] ]];
- XCTAssertEqualObjects(query1, query1Same);
- XCTAssertEqualObjects(query1, query1WithFieldPath);
- XCTAssertEqualObjects(query2, query2Same);
- XCTAssertEqualObjects(query3, query3Same);
- XCTAssertEqual([query1 hash], [query1Same hash]);
- XCTAssertEqual([query1 hash], [query1WithFieldPath hash]);
- XCTAssertEqual([query2 hash], [query2Same hash]);
- XCTAssertEqual([query3 hash], [query3Same hash]);
- XCTAssertFalse([query1 isEqual:nil]);
- XCTAssertFalse([query1 isEqual:@"string"]);
- XCTAssertFalse([query1 isEqual:query2]);
- XCTAssertFalse([query2 isEqual:query3]);
- XCTAssertNotEqual([query1 hash], [query1DiffAgg hash]);
- XCTAssertNotEqual([query1 hash], [query2 hash]);
- XCTAssertNotEqual([query2 hash], [query3 hash]);
- }
- - (void)testAverageAggregateFieldQueryEquals {
- FIRCollectionReference* coll1 = [self collectionRefWithDocuments:@{}];
- FIRCollectionReference* coll1Same = [[coll1 firestore] collectionWithPath:[coll1 path]];
- FIRAggregateQuery* query1 =
- [coll1 aggregate:@[ [FIRAggregateField aggregateFieldForAverageOfField:@"baz"] ]];
- FIRAggregateQuery* query1Same =
- [coll1Same aggregate:@[ [FIRAggregateField aggregateFieldForAverageOfField:@"baz"] ]];
- FIRAggregateQuery* query1WithFieldPath = [coll1Same aggregate:@[
- [FIRAggregateField
- aggregateFieldForAverageOfFieldPath:[[FIRFieldPath alloc] initWithFields:@[ @"baz" ]]]
- ]];
- FIRAggregateQuery* query1DiffAgg =
- [coll1Same aggregate:@[ [FIRAggregateField aggregateFieldForCount] ]];
- FIRCollectionReference* sub = [[coll1 documentWithPath:@"bar"] collectionWithPath:@"baz"];
- FIRAggregateQuery* query2 = [[[sub queryWhereField:@"a" isEqualTo:@1] queryLimitedTo:100]
- aggregate:@[ [FIRAggregateField aggregateFieldForAverageOfField:@"baz"] ]];
- FIRAggregateQuery* query2Same = [[[sub queryWhereField:@"a" isEqualTo:@1] queryLimitedTo:100]
- aggregate:@[ [FIRAggregateField aggregateFieldForAverageOfField:@"baz"] ]];
- FIRAggregateQuery* query3 = [[[sub queryWhereField:@"b" isEqualTo:@1] queryOrderedByField:@"c"]
- aggregate:@[ [FIRAggregateField aggregateFieldForAverageOfField:@"baz"] ]];
- FIRAggregateQuery* query3Same = [[[sub queryWhereField:@"b"
- isEqualTo:@1] queryOrderedByField:@"c"]
- aggregate:@[ [FIRAggregateField aggregateFieldForAverageOfField:@"baz"] ]];
- XCTAssertEqualObjects(query1, query1Same);
- XCTAssertEqualObjects(query1, query1WithFieldPath);
- XCTAssertEqualObjects(query2, query2Same);
- XCTAssertEqualObjects(query3, query3Same);
- XCTAssertEqual([query1 hash], [query1Same hash]);
- XCTAssertEqual([query1 hash], [query1WithFieldPath hash]);
- XCTAssertEqual([query2 hash], [query2Same hash]);
- XCTAssertEqual([query3 hash], [query3Same hash]);
- XCTAssertFalse([query1 isEqual:nil]);
- XCTAssertFalse([query1 isEqual:@"string"]);
- XCTAssertFalse([query1 isEqual:query2]);
- XCTAssertFalse([query2 isEqual:query3]);
- XCTAssertNotEqual([query1 hash], [query1DiffAgg hash]);
- XCTAssertNotEqual([query1 hash], [query2 hash]);
- XCTAssertNotEqual([query2 hash], [query3 hash]);
- }
- - (void)testAggregateFieldQueryNotEquals {
- FIRCollectionReference* coll = [self collectionRefWithDocuments:@{}];
- FIRAggregateQuery* query1 = [coll aggregate:@[ [FIRAggregateField aggregateFieldForCount] ]];
- FIRAggregateQuery* query2 =
- [coll aggregate:@[ [FIRAggregateField aggregateFieldForSumOfField:@"baz"] ]];
- FIRAggregateQuery* query3 =
- [coll aggregate:@[ [FIRAggregateField aggregateFieldForAverageOfField:@"baz"] ]];
- XCTAssertNotEqualObjects(query1, query2);
- XCTAssertNotEqualObjects(query2, query3);
- XCTAssertNotEqualObjects(query3, query1);
- XCTAssertNotEqual([query1 hash], [query2 hash]);
- XCTAssertNotEqual([query2 hash], [query3 hash]);
- XCTAssertNotEqual([query3 hash], [query1 hash]);
- FIRQuery* baseQuery = [[[[coll documentWithPath:@"bar"] collectionWithPath:@"baz"]
- queryWhereField:@"a"
- isEqualTo:@1] queryLimitedTo:100];
- FIRAggregateQuery* query4 = [baseQuery aggregate:@[ [FIRAggregateField aggregateFieldForCount] ]];
- FIRAggregateQuery* query5 =
- [baseQuery aggregate:@[ [FIRAggregateField aggregateFieldForSumOfField:@"baz"] ]];
- FIRAggregateQuery* query6 =
- [baseQuery aggregate:@[ [FIRAggregateField aggregateFieldForAverageOfField:@"baz"] ]];
- XCTAssertNotEqualObjects(query4, query5);
- XCTAssertNotEqualObjects(query5, query6);
- XCTAssertNotEqualObjects(query6, query4);
- XCTAssertNotEqual([query4 hash], [query5 hash]);
- XCTAssertNotEqual([query5 hash], [query6 hash]);
- XCTAssertNotEqual([query6 hash], [query4 hash]);
- }
- - (void)testCanRunAggregateQuery {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{
- @"author" : @"authorA",
- @"title" : @"titleA",
- @"pages" : @100,
- @"height" : @24.5,
- @"weight" : @24.1,
- @"foo" : @1,
- @"bar" : @2,
- @"baz" : @3
- },
- @"b" : @{
- @"author" : @"authorB",
- @"title" : @"titleB",
- @"pages" : @50,
- @"height" : @25.5,
- @"weight" : @75.5,
- @"foo" : @1,
- @"bar" : @2,
- @"baz" : @3
- }
- }];
- FIRAggregateQuerySnapshot* snapshot =
- [self readSnapshotForAggregate:[testCollection aggregate:@[
- [FIRAggregateField aggregateFieldForCount],
- [FIRAggregateField aggregateFieldForSumOfField:@"pages"],
- [FIRAggregateField aggregateFieldForAverageOfField:@"pages"]
- ]]];
- // Count
- XCTAssertEqual([snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForCount]],
- [NSNumber numberWithLong:2L]);
- XCTAssertEqual([snapshot count], [NSNumber numberWithLong:2L]);
- // Sum
- XCTAssertEqual(
- [snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:@"pages"]],
- [NSNumber numberWithLong:150L], );
- // Average
- XCTAssertEqual([snapshot valueForAggregateField:[FIRAggregateField
- aggregateFieldForAverageOfField:@"pages"]],
- [NSNumber numberWithDouble:75.0]);
- }
- - (void)testCanRunEmptyAggregateQuery {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{
- @"author" : @"authorA",
- @"title" : @"titleA",
- @"pages" : @100,
- @"height" : @24.5,
- @"weight" : @24.1,
- @"foo" : @1,
- @"bar" : @2,
- @"baz" : @3
- },
- @"b" : @{
- @"author" : @"authorB",
- @"title" : @"titleB",
- @"pages" : @50,
- @"height" : @25.5,
- @"weight" : @75.5,
- @"foo" : @1,
- @"bar" : @2,
- @"baz" : @3
- }
- }];
- FIRAggregateQuery* emptyQuery = [testCollection aggregate:@[]];
- __block NSError* result;
- XCTestExpectation* expectation = [self expectationWithDescription:@"aggregate result"];
- [emptyQuery aggregationWithSource:FIRAggregateSourceServer
- completion:^(FIRAggregateQuerySnapshot* snapshot, NSError* error) {
- XCTAssertNil(snapshot);
- result = error;
- [expectation fulfill];
- }];
- [self awaitExpectation:expectation];
- XCTAssertNotNil(result);
- XCTAssertTrue([[result localizedDescription] containsString:@"Aggregations can not be empty"]);
- }
- // (TODO:b/283101111): Try thread sanitizer to see if timeout on Github Actions is gone.
- #if !defined(THREAD_SANITIZER)
- - (void)testAggregateFieldQuerySnapshotEquality {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{
- @"author" : @"authorA",
- @"title" : @"titleA",
- @"pages" : @100,
- @"height" : @24.5,
- @"weight" : @24.1,
- @"foo" : @1,
- @"bar" : @2,
- @"baz" : @3
- },
- @"b" : @{
- @"author" : @"authorB",
- @"title" : @"titleB",
- @"pages" : @50,
- @"height" : @25.5,
- @"weight" : @75.5,
- @"foo" : @1,
- @"bar" : @2,
- @"baz" : @3
- }
- }];
- FIRAggregateQuerySnapshot* snapshot1 =
- [self readSnapshotForAggregate:[testCollection aggregate:@[
- [FIRAggregateField aggregateFieldForCount],
- [FIRAggregateField aggregateFieldForSumOfField:@"pages"],
- [FIRAggregateField aggregateFieldForAverageOfField:@"pages"]
- ]]];
- FIRAggregateQuerySnapshot* snapshot2 =
- [self readSnapshotForAggregate:[testCollection aggregate:@[
- [FIRAggregateField aggregateFieldForCount],
- [FIRAggregateField aggregateFieldForSumOfField:@"pages"],
- [FIRAggregateField aggregateFieldForAverageOfField:@"pages"]
- ]]];
- // different aggregates
- FIRAggregateQuerySnapshot* snapshot3 =
- [self readSnapshotForAggregate:[testCollection aggregate:@[
- [FIRAggregateField aggregateFieldForCount],
- [FIRAggregateField aggregateFieldForSumOfField:@"weight"],
- [FIRAggregateField aggregateFieldForAverageOfField:@"weight"]
- ]]];
- // different data set
- FIRAggregateQuerySnapshot* snapshot4 =
- [self readSnapshotForAggregate:[[testCollection queryWhereField:@"pages" isGreaterThan:@50]
- aggregate:@[
- [FIRAggregateField aggregateFieldForCount],
- [FIRAggregateField aggregateFieldForSumOfField:@"pages"],
- [FIRAggregateField
- aggregateFieldForAverageOfField:@"pages"]
- ]]];
- XCTAssertEqualObjects(snapshot1, snapshot2);
- XCTAssertNotEqualObjects(snapshot1, snapshot3);
- XCTAssertNotEqualObjects(snapshot1, snapshot4);
- XCTAssertNotEqualObjects(snapshot3, snapshot4);
- XCTAssertEqual([snapshot1 hash], [snapshot2 hash]);
- XCTAssertNotEqual([snapshot1 hash], [snapshot3 hash]);
- XCTAssertNotEqual([snapshot1 hash], [snapshot4 hash]);
- XCTAssertNotEqual([snapshot3 hash], [snapshot4 hash]);
- }
- #endif // #if !defined(THREAD_SANITIZER)
- - (void)testAggregateOnFieldNameWithMaxLength {
- // The longest field name and alias allowed is 1500 bytes or 1499 characters.
- NSString* longField = [@"" stringByPaddingToLength:1499
- withString:@"0123456789"
- startingAtIndex:0];
- FIRCollectionReference* testCollection =
- [self collectionRefWithDocuments:@{@"a" : @{longField : @1}, @"b" : @{longField : @2}}];
- FIRAggregateQuerySnapshot* snapshot =
- [self readSnapshotForAggregate:[testCollection
- aggregate:@[ [FIRAggregateField
- aggregateFieldForSumOfField:longField] ]]];
- // Sum
- XCTAssertEqual(
- [snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:longField]],
- [NSNumber numberWithLong:3], );
- }
- - (void)testCanGetDuplicateAggregations {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{
- @"author" : @"authorA",
- @"title" : @"titleA",
- @"pages" : @100,
- @"height" : @24.5,
- @"weight" : @24.1,
- @"foo" : @1,
- @"bar" : @2,
- @"baz" : @3
- },
- @"b" : @{
- @"author" : @"authorB",
- @"title" : @"titleB",
- @"pages" : @50,
- @"height" : @25.5,
- @"weight" : @75.5,
- @"foo" : @1,
- @"bar" : @2,
- @"baz" : @3
- }
- }];
- FIRAggregateQuerySnapshot* snapshot =
- [self readSnapshotForAggregate:[testCollection aggregate:@[
- [FIRAggregateField aggregateFieldForCount],
- [FIRAggregateField aggregateFieldForSumOfField:@"pages"],
- [FIRAggregateField aggregateFieldForSumOfField:@"pages"]
- ]]];
- // Count
- XCTAssertEqual([snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForCount]],
- [NSNumber numberWithLong:2L]);
- // Sum
- XCTAssertEqual(
- [snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:@"pages"]],
- [NSNumber numberWithLong:150L], );
- }
- - (void)testTerminateDoesNotCrashWithFlyingAggregateQuery {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{
- @"author" : @"authorA",
- @"title" : @"titleA",
- @"pages" : @100,
- @"height" : @24.5,
- @"weight" : @24.1,
- @"foo" : @1,
- @"bar" : @2,
- @"baz" : @3
- },
- @"b" : @{
- @"author" : @"authorB",
- @"title" : @"titleB",
- @"pages" : @50,
- @"height" : @25.5,
- @"weight" : @75.5,
- @"foo" : @1,
- @"bar" : @2,
- @"baz" : @3
- }
- }];
- FIRAggregateQuery* aggQuery = [testCollection aggregate:@[
- [FIRAggregateField aggregateFieldForCount],
- [FIRAggregateField aggregateFieldForSumOfField:@"pages"],
- [FIRAggregateField aggregateFieldForAverageOfField:@"pages"]
- ]];
- __block FIRAggregateQuerySnapshot* result;
- XCTestExpectation* expectation = [self expectationWithDescription:@"aggregate result"];
- [aggQuery aggregationWithSource:FIRAggregateSourceServer
- completion:^(FIRAggregateQuerySnapshot* snapshot, NSError* error) {
- XCTAssertNil(error);
- result = snapshot;
- [expectation fulfill];
- }];
- [self awaitExpectation:expectation];
- // Count
- XCTAssertEqual([result valueForAggregateField:[FIRAggregateField aggregateFieldForCount]],
- [NSNumber numberWithLong:2L]);
- // Sum
- XCTAssertEqual(
- [result valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:@"pages"]],
- [NSNumber numberWithLong:150L], );
- }
- - (void)testCannotPerformMoreThanMaxAggregations {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{
- @"author" : @"authorA",
- @"title" : @"titleA",
- @"pages" : @100,
- @"height" : @24.5,
- @"weight" : @24.1,
- @"foo" : @1,
- @"bar" : @2,
- @"baz" : @3
- },
- @"b" : @{
- @"author" : @"authorB",
- @"title" : @"titleB",
- @"pages" : @50,
- @"height" : @25.5,
- @"weight" : @75.5,
- @"foo" : @1,
- @"bar" : @2,
- @"baz" : @3
- }
- }];
- // Max is 5, we're attempting 6. I also like to live dangerously.
- FIRAggregateQuery* query = [testCollection aggregate:@[
- [FIRAggregateField aggregateFieldForCount],
- [FIRAggregateField aggregateFieldForSumOfField:@"pages"],
- [FIRAggregateField aggregateFieldForSumOfField:@"weight"],
- [FIRAggregateField aggregateFieldForAverageOfField:@"pages"],
- [FIRAggregateField aggregateFieldForAverageOfField:@"weight"],
- [FIRAggregateField aggregateFieldForAverageOfField:@"foo"]
- ]];
- __block NSError* result;
- XCTestExpectation* expectation = [self expectationWithDescription:@"aggregate result"];
- [query aggregationWithSource:FIRAggregateSourceServer
- completion:^(FIRAggregateQuerySnapshot* snapshot, NSError* error) {
- XCTAssertNil(snapshot);
- result = error;
- [expectation fulfill];
- }];
- [self awaitExpectation:expectation];
- XCTAssertNotNil(result);
- XCTAssertTrue([[result localizedDescription] containsString:@"maximum number of aggregations"]);
- }
- - (void)testThrowsAnErrorWhenGettingTheResultOfAnUnrequestedAggregation {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{
- @"author" : @"authorA",
- @"title" : @"titleA",
- @"pages" : @100,
- @"height" : @24.5,
- @"weight" : @24.1,
- @"foo" : @1,
- @"bar" : @2,
- @"baz" : @3
- },
- @"b" : @{
- @"author" : @"authorB",
- @"title" : @"titleB",
- @"pages" : @50,
- @"height" : @25.5,
- @"weight" : @75.5,
- @"foo" : @1,
- @"bar" : @2,
- @"baz" : @3
- }
- }];
- FIRAggregateQuerySnapshot* snapshot =
- [self readSnapshotForAggregate:[testCollection
- aggregate:@[ [FIRAggregateField
- aggregateFieldForSumOfField:@"pages"] ]]];
- @try {
- [snapshot count];
- XCTAssertTrue(false, "Exception expected");
- } @catch (NSException* exception) {
- XCTAssertEqualObjects(exception.name, @"FIRInvalidArgumentException");
- XCTAssertEqualObjects(exception.reason,
- @"'count()' was not requested in the aggregation query.");
- }
- @
- try {
- [snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:@"foo"]];
- XCTAssertTrue(false, "Exception expected");
- } @catch (NSException* exception) {
- XCTAssertEqualObjects(exception.name, @"FIRInvalidArgumentException");
- XCTAssertEqualObjects(exception.reason,
- @"'sum(foo)' was not requested in the aggregation query.");
- }
- @
- try {
- [snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForAverageOfField:@"pages"]];
- XCTAssertTrue(false, "Exception expected");
- } @catch (NSException* exception) {
- XCTAssertEqualObjects(exception.name, @"FIRInvalidArgumentException");
- XCTAssertEqualObjects(exception.reason,
- @"'avg(pages)' was not requested in the aggregation query.");
- }
- }
- - (void)testPerformsAggregationWhenUsingInOperator {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{
- @"author" : @"authorA",
- @"title" : @"titleA",
- @"pages" : @100,
- @"year" : @1980,
- @"rating" : @5
- },
- @"b" : @{
- @"author" : @"authorB",
- @"title" : @"titleB",
- @"pages" : @50,
- @"year" : @2020,
- @"rating" : @4
- },
- @"c" : @{
- @"author" : @"authorC",
- @"title" : @"titleC",
- @"pages" : @100,
- @"year" : @1980,
- @"rating" : @3
- },
- @"d" : @{
- @"author" : @"authorD",
- @"title" : @"titleD",
- @"pages" : @50,
- @"year" : @2020,
- @"rating" : @0
- }
- }];
- FIRAggregateQuerySnapshot* snapshot = [self
- readSnapshotForAggregate:[[testCollection queryWhereField:@"rating" in:@[ @5, @3 ]]
- aggregate:@[
- [FIRAggregateField aggregateFieldForSumOfField:@"rating"],
- [FIRAggregateField aggregateFieldForAverageOfField:@"rating"],
- [FIRAggregateField aggregateFieldForCount]
- ]]];
- // Count
- XCTAssertEqual(
- [[snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForCount]] longValue], 2L);
- // Sum
- XCTAssertEqual(
- [[snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:@"rating"]]
- longValue],
- 8L);
- // Average
- XCTAssertEqual([[snapshot valueForAggregateField:[FIRAggregateField
- aggregateFieldForAverageOfField:@"rating"]]
- doubleValue],
- 4.0);
- }
- - (void)testPerformsAggregationsOnNestedMapValues {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{
- @"author" : @"authorA",
- @"title" : @"titleA",
- @"metadata" : @{@"pages" : @100, @"rating" : @{@"critic" : @2, @"user" : @5}}
- },
- @"b" : @{
- @"author" : @"authorB",
- @"title" : @"titleB",
- @"metadata" : @{@"pages" : @50, @"rating" : @{@"critic" : @4, @"user" : @4}}
- },
- }];
- FIRAggregateQuerySnapshot* snapshot =
- [self readSnapshotForAggregate:[testCollection aggregate:@[
- [FIRAggregateField aggregateFieldForSumOfField:@"metadata.pages"],
- [FIRAggregateField aggregateFieldForAverageOfField:@"metadata.pages"],
- [FIRAggregateField aggregateFieldForCount]
- ]]];
- // Count
- XCTAssertEqual(
- [[snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForCount]] longValue], 2L);
- // Sum
- XCTAssertEqual(
- [[snapshot
- valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:@"metadata.pages"]]
- longValue],
- 150L);
- // Average
- XCTAssertEqual(
- [[snapshot valueForAggregateField:[FIRAggregateField
- aggregateFieldForAverageOfField:@"metadata.pages"]]
- doubleValue],
- 75.0);
- }
- - (void)testPerformsSumThatOverflowsMaxLong {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{
- @"author" : @"authorA",
- @"title" : @"titleA",
- @"rating" : [NSNumber numberWithLong:LLONG_MAX]
- },
- @"b" : @{
- @"author" : @"authorB",
- @"title" : @"titleB",
- @"rating" : [NSNumber numberWithLong:LLONG_MAX]
- },
- }];
- FIRAggregateQuerySnapshot* snapshot =
- [self readSnapshotForAggregate:[testCollection
- aggregate:@[ [FIRAggregateField
- aggregateFieldForSumOfField:@"rating"] ]]];
- // Sum
- XCTAssertEqual(
- [[snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:@"rating"]]
- doubleValue],
- [[NSNumber numberWithLong:LLONG_MAX] doubleValue] +
- [[NSNumber numberWithLong:LLONG_MAX] doubleValue]);
- }
- - (void)testPerformsSumThatCanOverflowLongValuesDuringAccumulation {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{
- @"author" : @"authorA",
- @"title" : @"titleA",
- @"rating" : [NSNumber numberWithLong:LLONG_MAX]
- },
- @"b" : @{@"author" : @"authorB", @"title" : @"titleB", @"rating" : [NSNumber numberWithLong:1]},
- @"c" :
- @{@"author" : @"authorC", @"title" : @"titleC", @"rating" : [NSNumber numberWithLong:-101]}
- }];
- FIRAggregateQuerySnapshot* snapshot =
- [self readSnapshotForAggregate:[testCollection
- aggregate:@[ [FIRAggregateField
- aggregateFieldForSumOfField:@"rating"] ]]];
- // Sum
- XCTAssertEqual(
- [[snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:@"rating"]]
- longLongValue],
- [[NSNumber numberWithLong:LLONG_MAX - 100] longLongValue]);
- }
- - (void)testPerformsSumThatIsNegative {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{
- @"author" : @"authorA",
- @"title" : @"titleA",
- @"rating" : [NSNumber numberWithLong:LLONG_MAX]
- },
- @"b" : @{
- @"author" : @"authorB",
- @"title" : @"titleB",
- @"rating" : [NSNumber numberWithLong:-LLONG_MAX]
- },
- @"c" :
- @{@"author" : @"authorC", @"title" : @"titleC", @"rating" : [NSNumber numberWithLong:-101]},
- @"d" : @{
- @"author" : @"authorD",
- @"title" : @"titleD",
- @"rating" : [NSNumber numberWithLong:-10000]
- }
- }];
- FIRAggregateQuerySnapshot* snapshot =
- [self readSnapshotForAggregate:[testCollection
- aggregate:@[ [FIRAggregateField
- aggregateFieldForSumOfField:@"rating"] ]]];
- // Sum
- XCTAssertEqual(
- [[snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:@"rating"]]
- longLongValue],
- [[NSNumber numberWithLong:-10101] longLongValue]);
- }
- - (void)testPerformsSumThatIsPositiveInfinity {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{
- @"author" : @"authorA",
- @"title" : @"titleA",
- @"rating" : [NSNumber numberWithDouble:DBL_MAX]
- },
- @"b" : @{
- @"author" : @"authorB",
- @"title" : @"titleB",
- @"rating" : [NSNumber numberWithDouble:DBL_MAX]
- }
- }];
- FIRAggregateQuerySnapshot* snapshot =
- [self readSnapshotForAggregate:[testCollection
- aggregate:@[ [FIRAggregateField
- aggregateFieldForSumOfField:@"rating"] ]]];
- // Sum
- XCTAssertEqual(
- [snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:@"rating"]],
- [NSNumber numberWithDouble:INFINITY]);
- }
- - (void)testPerformsSumThatIsNegativeInfinity {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{
- @"author" : @"authorA",
- @"title" : @"titleA",
- @"rating" : [NSNumber numberWithDouble:-DBL_MAX]
- },
- @"b" : @{
- @"author" : @"authorB",
- @"title" : @"titleB",
- @"rating" : [NSNumber numberWithDouble:-DBL_MAX]
- }
- }];
- FIRAggregateQuerySnapshot* snapshot =
- [self readSnapshotForAggregate:[testCollection
- aggregate:@[ [FIRAggregateField
- aggregateFieldForSumOfField:@"rating"] ]]];
- // Sum
- XCTAssertEqual(
- [snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:@"rating"]],
- [NSNumber numberWithDouble:-INFINITY]);
- }
- - (void)testPerformsSumThatIsValidButCouldOverflowDuringAggregation {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{@"rating" : [NSNumber numberWithDouble:DBL_MAX]},
- @"b" : @{@"rating" : [NSNumber numberWithDouble:DBL_MAX]},
- @"c" : @{@"rating" : [NSNumber numberWithDouble:-DBL_MAX]},
- @"d" : @{@"rating" : [NSNumber numberWithDouble:-DBL_MAX]}
- }];
- FIRAggregateQuerySnapshot* snapshot =
- [self readSnapshotForAggregate:[testCollection
- aggregate:@[ [FIRAggregateField
- aggregateFieldForSumOfField:@"rating"] ]]];
- // Sum
- long long ratingL =
- [[snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:@"rating"]]
- longLongValue];
- XCTAssertTrue(ratingL == [[NSNumber numberWithDouble:-INFINITY] longLongValue] || ratingL == 0 ||
- ratingL == [[NSNumber numberWithDouble:INFINITY] longLongValue]);
- double ratingD =
- [[snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:@"rating"]]
- doubleValue];
- XCTAssertTrue(ratingD == -INFINITY || ratingD == 0 || ratingD == INFINITY);
- }
- - (void)testPerformsSumOverResultSetOfZeroDocuments {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{
- @"author" : @"authorA",
- @"title" : @"titleA",
- @"pages" : @100,
- @"height" : @24.5,
- @"weight" : @24.1,
- @"foo" : @1,
- @"bar" : @2,
- @"baz" : @3
- },
- @"b" : @{
- @"author" : @"authorB",
- @"title" : @"titleB",
- @"pages" : @50,
- @"height" : @25.5,
- @"weight" : @75.5,
- @"foo" : @1,
- @"bar" : @2,
- @"baz" : @3
- }
- }];
- FIRAggregateQuerySnapshot* snapshot =
- [self readSnapshotForAggregate:[[testCollection queryWhereField:@"pages" isGreaterThan:@200]
- aggregate:@[ [FIRAggregateField
- aggregateFieldForSumOfField:@"pages"] ]]];
- // Sum
- XCTAssertEqual(
- [snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:@"pages"]],
- [NSNumber numberWithLong:0L]);
- }
- - (void)testPerformsSumOnlyOnNumericFields {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{@"rating" : [NSNumber numberWithLong:5]},
- @"b" : @{@"rating" : [NSNumber numberWithLong:4]},
- @"c" : @{@"rating" : @"3"},
- @"d" : @{@"rating" : [NSNumber numberWithLong:1]}
- }];
- FIRAggregateQuerySnapshot* snapshot =
- [self readSnapshotForAggregate:[testCollection aggregate:@[
- [FIRAggregateField aggregateFieldForCount],
- [FIRAggregateField aggregateFieldForSumOfField:@"rating"]
- ]]];
- // Count
- XCTAssertEqual(
- [[snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForCount]] longValue], 4L);
- // Sum
- XCTAssertEqual(
- [[snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:@"rating"]]
- longLongValue],
- [[NSNumber numberWithLong:10] longLongValue]);
- }
- - (void)testPerformsSumOfMinIEEE754 {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{@"rating" : [NSNumber numberWithDouble:__DBL_DENORM_MIN__]}
- }];
- FIRAggregateQuerySnapshot* snapshot =
- [self readSnapshotForAggregate:[testCollection
- aggregate:@[ [FIRAggregateField
- aggregateFieldForSumOfField:@"rating"] ]]];
- // Sum
- XCTAssertEqual(
- [[snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForSumOfField:@"rating"]]
- doubleValue],
- [[NSNumber numberWithDouble:__DBL_DENORM_MIN__] doubleValue]);
- }
- - (void)testPerformsAverageOfVariousNumericTypes {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{
- @"x" : @1,
- @"intToInt" : [NSNumber numberWithLong:10],
- @"floatToInt" : [NSNumber numberWithDouble:10.5],
- @"mixedToInt" : [NSNumber numberWithLong:10],
- @"floatToFloat" : [NSNumber numberWithDouble:5.5],
- @"mixedToFloat" : [NSNumber numberWithDouble:8.6],
- @"intToFloat" : [NSNumber numberWithLong:10]
- },
- @"b" : @{
- @"intToInt" : [NSNumber numberWithLong:5],
- @"floatToInt" : [NSNumber numberWithDouble:9.5],
- @"mixedToInt" : [NSNumber numberWithDouble:9.5],
- @"floatToFloat" : [NSNumber numberWithDouble:4.5],
- @"mixedToFloat" : [NSNumber numberWithLong:9],
- @"intToFloat" : [NSNumber numberWithLong:9]
- },
- @"c" : @{
- @"intToInt" : [NSNumber numberWithLong:0],
- @"floatToInt" : @"ignore",
- @"mixedToInt" : [NSNumber numberWithDouble:10.5],
- @"floatToFloat" : [NSNumber numberWithDouble:3.5],
- @"mixedToFloat" : [NSNumber numberWithLong:10],
- @"intToFloat" : @"ignore"
- }
- }];
- NSArray* testCases = @[
- @{
- @"agg" : [FIRAggregateField aggregateFieldForAverageOfField:@"intToInt"],
- @"expected" : [NSNumber numberWithLong:5]
- },
- @{
- @"agg" : [FIRAggregateField aggregateFieldForAverageOfField:@"floatToInt"],
- @"expected" : [NSNumber numberWithLong:10]
- },
- @{
- @"agg" : [FIRAggregateField aggregateFieldForAverageOfField:@"mixedToInt"],
- @"expected" : [NSNumber numberWithLong:10]
- },
- @{
- @"agg" : [FIRAggregateField aggregateFieldForAverageOfField:@"floatToFloat"],
- @"expected" : [NSNumber numberWithDouble:4.5]
- },
- @{
- @"agg" : [FIRAggregateField aggregateFieldForAverageOfField:@"mixedToFloat"],
- @"expected" : [NSNumber numberWithDouble:9.2]
- },
- @{
- @"agg" : [FIRAggregateField aggregateFieldForAverageOfField:@"intToFloat"],
- @"expected" : [NSNumber numberWithDouble:9.5]
- }
- ];
- for (NSDictionary* testCase in testCases) {
- FIRAggregateQuerySnapshot* snapshot =
- [self readSnapshotForAggregate:[testCollection aggregate:@[ testCase[@"agg"] ]]];
- // Average
- XCTAssertEqual([[snapshot valueForAggregateField:testCase[@"agg"]] longValue],
- [testCase[@"expected"] longLongValue]);
- XCTAssertEqualWithAccuracy([[snapshot valueForAggregateField:testCase[@"agg"]] doubleValue],
- [testCase[@"expected"] doubleValue], 0.00000000000001);
- }
- }
- - (void)testPerformsAverageCausingUnderflow {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{@"rating" : [NSNumber numberWithDouble:__DBL_DENORM_MIN__]},
- @"b" : @{@"rating" : [NSNumber numberWithDouble:0]}
- }];
- FIRAggregateQuerySnapshot* snapshot =
- [self readSnapshotForAggregate:[testCollection aggregate:@[
- [FIRAggregateField aggregateFieldForAverageOfField:@"rating"]
- ]]];
- // Average
- XCTAssertEqual([[snapshot valueForAggregateField:[FIRAggregateField
- aggregateFieldForAverageOfField:@"rating"]]
- doubleValue],
- [[NSNumber numberWithDouble:0] doubleValue]);
- }
- - (void)testPerformsAverageOfMinIEEE754 {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{@"rating" : [NSNumber numberWithDouble:__DBL_DENORM_MIN__]}
- }];
- FIRAggregateQuerySnapshot* snapshot =
- [self readSnapshotForAggregate:[testCollection aggregate:@[
- [FIRAggregateField aggregateFieldForAverageOfField:@"rating"]
- ]]];
- // Average
- XCTAssertEqual([[snapshot valueForAggregateField:[FIRAggregateField
- aggregateFieldForAverageOfField:@"rating"]]
- doubleValue],
- [[NSNumber numberWithDouble:__DBL_DENORM_MIN__] doubleValue]);
- }
- - (void)testPerformsAverageOverflowIEEE754DuringAccumulation {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{@"rating" : [NSNumber numberWithDouble:DBL_MAX]},
- @"b" : @{@"rating" : [NSNumber numberWithDouble:DBL_MAX]}
- }];
- FIRAggregateQuerySnapshot* snapshot =
- [self readSnapshotForAggregate:[testCollection aggregate:@[
- [FIRAggregateField aggregateFieldForAverageOfField:@"rating"]
- ]]];
- // Average
- XCTAssertEqual([[snapshot valueForAggregateField:[FIRAggregateField
- aggregateFieldForAverageOfField:@"rating"]]
- doubleValue],
- [[NSNumber numberWithDouble:INFINITY] doubleValue]);
- }
- - (void)testPerformsAverageOverResultSetOfZeroDocuments {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{
- @"author" : @"authorA",
- @"title" : @"titleA",
- @"pages" : @100,
- @"height" : @24.5,
- @"weight" : @24.1,
- @"foo" : @1,
- @"bar" : @2,
- @"baz" : @3
- },
- @"b" : @{
- @"author" : @"authorB",
- @"title" : @"titleB",
- @"pages" : @50,
- @"height" : @25.5,
- @"weight" : @75.5,
- @"foo" : @1,
- @"bar" : @2,
- @"baz" : @3
- }
- }];
- FIRAggregateQuerySnapshot* snapshot = [self
- readSnapshotForAggregate:[[testCollection queryWhereField:@"pages" isGreaterThan:@200]
- aggregate:@[ [FIRAggregateField
- aggregateFieldForAverageOfField:@"pages"] ]]];
- // Average
- XCTAssertEqual([snapshot valueForAggregateField:[FIRAggregateField
- aggregateFieldForAverageOfField:@"pages"]],
- [NSNull null]);
- }
- - (void)testPerformsAverageOnlyOnNumericFields {
- FIRCollectionReference* testCollection = [self collectionRefWithDocuments:@{
- @"a" : @{@"rating" : [NSNumber numberWithLong:5]},
- @"b" : @{@"rating" : [NSNumber numberWithLong:4]},
- @"c" : @{@"rating" : @"3"},
- @"d" : @{@"rating" : [NSNumber numberWithLong:6]}
- }];
- FIRAggregateQuerySnapshot* snapshot =
- [self readSnapshotForAggregate:[testCollection aggregate:@[
- [FIRAggregateField aggregateFieldForCount],
- [FIRAggregateField aggregateFieldForAverageOfField:@"rating"]
- ]]];
- // Count
- XCTAssertEqual(
- [[snapshot valueForAggregateField:[FIRAggregateField aggregateFieldForCount]] longValue], 4L);
- // Average
- XCTAssertEqual([[snapshot valueForAggregateField:[FIRAggregateField
- aggregateFieldForAverageOfField:@"rating"]]
- doubleValue],
- [[NSNumber numberWithDouble:5] doubleValue]);
- }
- - (void)testFailWithMessageWithConsoleLinkIfMissingIndex {
- XCTSkipIf([FSTIntegrationTestCase isRunningAgainstEmulator],
- "Skip this test when running against the Firestore emulator because the Firestore "
- "emulator does not use indexes and never fails with a 'missing index' error.");
- FIRCollectionReference* testCollection = [self collectionRef];
- FIRQuery* compositeIndexQuery = [[testCollection queryWhereField:@"field1"
- isEqualTo:@42] queryWhereField:@"field2"
- isLessThan:@99];
- FIRAggregateQuery* compositeIndexAggregateQuery = [compositeIndexQuery aggregate:@[
- [FIRAggregateField aggregateFieldForCount],
- [FIRAggregateField aggregateFieldForSumOfField:@"pages"],
- [FIRAggregateField aggregateFieldForAverageOfField:@"pages"]
- ]];
- XCTestExpectation* queryCompletion = [self expectationWithDescription:@"query"];
- [compositeIndexAggregateQuery
- aggregationWithSource:FIRAggregateSourceServer
- completion:^(FIRAggregateQuerySnapshot* snapshot, NSError* error) {
- XCTAssertNotNil(error);
- if (error) {
- NSString* errorDescription = [error localizedDescription];
- XCTAssertTrue([errorDescription.lowercaseString containsString:@"index"],
- "The NSError should have contained the word 'index' "
- "(case-insensitive), but got: %@",
- errorDescription);
- // TODO(b/316359394) Remove this check for the default databases once
- // cl/582465034 is rolled out to production.
- if ([[FSTIntegrationTestCase databaseID] isEqualToString:@"(default)"]) {
- XCTAssertTrue(
- [errorDescription containsString:@"https://console.firebase.google.com"],
- "The NSError should have contained the string "
- "'https://console.firebase.google.com', but got: %@",
- errorDescription);
- }
- }
- XCTAssertNil(snapshot);
- [queryCompletion fulfill];
- }];
- [self awaitExpectations];
- }
- @end
|