aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firestore/Example/Tests
diff options
context:
space:
mode:
Diffstat (limited to 'Firestore/Example/Tests')
-rw-r--r--Firestore/Example/Tests/Integration/API/FIRFirestoreSourceTests.mm648
-rw-r--r--Firestore/Example/Tests/Util/FSTIntegrationTestCase.h11
-rw-r--r--Firestore/Example/Tests/Util/FSTIntegrationTestCase.mm43
3 files changed, 692 insertions, 10 deletions
diff --git a/Firestore/Example/Tests/Integration/API/FIRFirestoreSourceTests.mm b/Firestore/Example/Tests/Integration/API/FIRFirestoreSourceTests.mm
new file mode 100644
index 0000000..0f844c6
--- /dev/null
+++ b/Firestore/Example/Tests/Integration/API/FIRFirestoreSourceTests.mm
@@ -0,0 +1,648 @@
+/*
+ * Copyright 2018 Google
+ *
+ * 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/FirebaseFirestore.h>
+
+#import <XCTest/XCTest.h>
+
+#import "Firestore/Example/Tests/Util/FSTIntegrationTestCase.h"
+#import "Firestore/Source/API/FIRFirestore+Internal.h"
+#import "Firestore/Source/Core/FSTFirestoreClient.h"
+
+@interface FIRFirestoreSourceTests : FSTIntegrationTestCase
+@end
+
+@implementation FIRFirestoreSourceTests
+
+- (void)testGetDocumentWhileOnlineWithDefaultSource {
+ FIRDocumentReference *doc = [self documentRef];
+
+ // set document to a known value
+ NSDictionary<NSString *, id> *initialData = @{@"key" : @"value"};
+ [self writeDocumentRef:doc data:initialData];
+
+ // get doc and ensure that it exists, is *not* from the cache, and matches
+ // the initialData.
+ FIRDocumentSnapshot *result = [self readDocumentForRef:doc];
+ XCTAssertTrue(result.exists);
+ XCTAssertFalse(result.metadata.fromCache);
+ XCTAssertFalse(result.metadata.hasPendingWrites);
+ XCTAssertEqualObjects(result.data, initialData);
+}
+
+- (void)testGetCollectionWhileOnlineWithDefaultSource {
+ FIRCollectionReference *col = [self collectionRef];
+
+ // set a few documents to known values
+ NSDictionary<NSString *, NSDictionary<NSString *, id> *> *initialDocs = @{
+ @"doc1" : @{@"key1" : @"value1"},
+ @"doc2" : @{@"key2" : @"value2"},
+ @"doc3" : @{@"key3" : @"value3"}
+ };
+ [self writeAllDocuments:initialDocs toCollection:col];
+
+ // get docs and ensure they are *not* from the cache, and match the
+ // initialDocs.
+ FIRQuerySnapshot *result = [self readDocumentSetForRef:col];
+ XCTAssertFalse(result.metadata.fromCache);
+ XCTAssertFalse(result.metadata.hasPendingWrites);
+ XCTAssertEqualObjects(
+ FIRQuerySnapshotGetData(result),
+ (@[ @{@"key1" : @"value1"}, @{@"key2" : @"value2"}, @{@"key3" : @"value3"} ]));
+ XCTAssertEqualObjects(FIRQuerySnapshotGetDocChangesData(result), (@[
+ @[ @(FIRDocumentChangeTypeAdded), @"doc1", @{@"key1" : @"value1"} ],
+ @[ @(FIRDocumentChangeTypeAdded), @"doc2", @{@"key2" : @"value2"} ],
+ @[ @(FIRDocumentChangeTypeAdded), @"doc3", @{@"key3" : @"value3"} ]
+ ]));
+}
+
+- (void)testGetDocumentWhileOfflineWithDefaultSource {
+ FIRDocumentReference *doc = [self documentRef];
+
+ // set document to a known value
+ NSDictionary<NSString *, id> *initialData = @{@"key1" : @"value1"};
+ [self writeDocumentRef:doc data:initialData];
+
+ // go offline for the rest of this test
+ [self disableNetwork];
+
+ // update the doc (though don't wait for a server response. We're offline; so
+ // that ain't happening!). This allows us to further distinguished cached vs
+ // server responses below.
+ NSDictionary<NSString *, id> *newData = @{@"key2" : @"value2"};
+ [doc setData:newData
+ completion:^(NSError *_Nullable error) {
+ XCTAssertTrue(false, "Because we're offline, this should never occur.");
+ }];
+
+ // get doc and ensure it exists, *is* from the cache, and matches the
+ // newData.
+ FIRDocumentSnapshot *result = [self readDocumentForRef:doc];
+ XCTAssertTrue(result.exists);
+ XCTAssertTrue(result.metadata.fromCache);
+ XCTAssertTrue(result.metadata.hasPendingWrites);
+ XCTAssertEqualObjects(result.data, newData);
+}
+
+- (void)testGetCollectionWhileOfflineWithDefaultSource {
+ FIRCollectionReference *col = [self collectionRef];
+
+ // set a few documents to known values
+ NSDictionary<NSString *, NSDictionary<NSString *, id> *> *initialDocs = @{
+ @"doc1" : @{@"key1" : @"value1"},
+ @"doc2" : @{@"key2" : @"value2"},
+ @"doc3" : @{@"key3" : @"value3"}
+ };
+ [self writeAllDocuments:initialDocs toCollection:col];
+
+ // go offline for the rest of this test
+ [self disableNetwork];
+
+ // update the docs (though don't wait for a server response. We're offline; so
+ // that ain't happening!). This allows us to further distinguished cached vs
+ // server responses below.
+ [[col documentWithPath:@"doc2"] setData:@{@"key2b" : @"value2b"} options:FIRSetOptions.merge];
+ [[col documentWithPath:@"doc3"] setData:@{@"key3b" : @"value3b"}];
+ [[col documentWithPath:@"doc4"] setData:@{@"key4" : @"value4"}];
+
+ // get docs and ensure they *are* from the cache, and matches the updated data.
+ FIRQuerySnapshot *result = [self readDocumentSetForRef:col];
+ XCTAssertTrue(result.metadata.fromCache);
+ XCTAssertTrue(result.metadata.hasPendingWrites);
+ XCTAssertEqualObjects(FIRQuerySnapshotGetData(result), (@[
+ @{@"key1" : @"value1"}, @{@"key2" : @"value2", @"key2b" : @"value2b"},
+ @{@"key3b" : @"value3b"}, @{@"key4" : @"value4"}
+ ]));
+ XCTAssertEqualObjects(
+ FIRQuerySnapshotGetDocChangesData(result), (@[
+ @[ @(FIRDocumentChangeTypeAdded), @"doc1", @{@"key1" : @"value1"} ],
+ @[ @(FIRDocumentChangeTypeAdded), @"doc2", @{@"key2" : @"value2", @"key2b" : @"value2b"} ],
+ @[ @(FIRDocumentChangeTypeAdded), @"doc3", @{@"key3b" : @"value3b"} ],
+ @[ @(FIRDocumentChangeTypeAdded), @"doc4", @{@"key4" : @"value4"} ]
+ ]));
+}
+
+- (void)testGetDocumentWhileOnlineCacheOnly {
+ FIRDocumentReference *doc = [self documentRef];
+
+ // set document to a known value
+ NSDictionary<NSString *, id> *initialData = @{@"key" : @"value"};
+ [self writeDocumentRef:doc data:initialData];
+
+ // get doc and ensure that it exists, *is* from the cache, and matches
+ // the initialData.
+ FIRDocumentSnapshot *result = [self readDocumentForRef:doc source:FIRFirestoreSourceCache];
+ XCTAssertTrue(result.exists);
+ XCTAssertTrue(result.metadata.fromCache);
+ XCTAssertFalse(result.metadata.hasPendingWrites);
+ XCTAssertEqualObjects(result.data, initialData);
+}
+
+- (void)testGetCollectionWhileOnlineCacheOnly {
+ FIRCollectionReference *col = [self collectionRef];
+
+ // set a few documents to a known value
+ NSDictionary<NSString *, NSDictionary<NSString *, id> *> *initialDocs = @{
+ @"doc1" : @{@"key1" : @"value1"},
+ @"doc2" : @{@"key2" : @"value2"},
+ @"doc3" : @{@"key3" : @"value3"},
+ };
+ [self writeAllDocuments:initialDocs toCollection:col];
+
+ // get docs and ensure they *are* from the cache, and matches the
+ // initialDocs.
+ FIRQuerySnapshot *result = [self readDocumentSetForRef:col source:FIRFirestoreSourceCache];
+ XCTAssertTrue(result.metadata.fromCache);
+ XCTAssertFalse(result.metadata.hasPendingWrites);
+ XCTAssertEqualObjects(FIRQuerySnapshotGetData(result), (@[
+ @{@"key1" : @"value1"},
+ @{@"key2" : @"value2"},
+ @{@"key3" : @"value3"},
+ ]));
+ XCTAssertEqualObjects(FIRQuerySnapshotGetDocChangesData(result), (@[
+ @[ @(FIRDocumentChangeTypeAdded), @"doc1", @{@"key1" : @"value1"} ],
+ @[ @(FIRDocumentChangeTypeAdded), @"doc2", @{@"key2" : @"value2"} ],
+ @[ @(FIRDocumentChangeTypeAdded), @"doc3", @{@"key3" : @"value3"} ]
+ ]));
+}
+
+- (void)testGetDocumentWhileOfflineCacheOnly {
+ FIRDocumentReference *doc = [self documentRef];
+
+ // set document to a known value
+ NSDictionary<NSString *, id> *initialData = @{@"key1" : @"value1"};
+ [self writeDocumentRef:doc data:initialData];
+
+ // go offline for the rest of this test
+ [self disableNetwork];
+
+ // update the doc (though don't wait for a server response. We're offline; so
+ // that ain't happening!). This allows us to further distinguished cached vs
+ // server responses below.
+ NSDictionary<NSString *, id> *newData = @{@"key2" : @"value2"};
+ [doc setData:newData
+ completion:^(NSError *_Nullable error) {
+ XCTFail("Because we're offline, this should never occur.");
+ }];
+
+ // get doc and ensure it exists, *is* from the cache, and matches the
+ // newData.
+ FIRDocumentSnapshot *result = [self readDocumentForRef:doc source:FIRFirestoreSourceCache];
+ XCTAssertTrue(result.exists);
+ XCTAssertTrue(result.metadata.fromCache);
+ XCTAssertTrue(result.metadata.hasPendingWrites);
+ XCTAssertEqualObjects(result.data, newData);
+}
+
+- (void)testGetCollectionWhileOfflineCacheOnly {
+ FIRCollectionReference *col = [self collectionRef];
+
+ // set a few documents to a known value
+ NSDictionary<NSString *, NSDictionary<NSString *, id> *> *initialDocs = @{
+ @"doc1" : @{@"key1" : @"value1"},
+ @"doc2" : @{@"key2" : @"value2"},
+ @"doc3" : @{@"key3" : @"value3"},
+ };
+ [self writeAllDocuments:initialDocs toCollection:col];
+
+ // go offline for the rest of this test
+ [self disableNetwork];
+
+ // update the docs (though don't wait for a server response. We're offline; so
+ // that ain't happening!). This allows us to further distinguished cached vs
+ // server responses below.
+ [[col documentWithPath:@"doc2"] setData:@{@"key2b" : @"value2b"} options:FIRSetOptions.merge];
+ [[col documentWithPath:@"doc3"] setData:@{@"key3b" : @"value3b"}];
+ [[col documentWithPath:@"doc4"] setData:@{@"key4" : @"value4"}];
+
+ // get docs and ensure they *are* from the cache, and matches the updated
+ // data.
+ FIRQuerySnapshot *result = [self readDocumentSetForRef:col source:FIRFirestoreSourceCache];
+ XCTAssertTrue(result.metadata.fromCache);
+ XCTAssertTrue(result.metadata.hasPendingWrites);
+ XCTAssertEqualObjects(FIRQuerySnapshotGetData(result), (@[
+ @{@"key1" : @"value1"}, @{@"key2" : @"value2", @"key2b" : @"value2b"},
+ @{@"key3b" : @"value3b"}, @{@"key4" : @"value4"}
+ ]));
+ XCTAssertEqualObjects(
+ FIRQuerySnapshotGetDocChangesData(result), (@[
+ @[ @(FIRDocumentChangeTypeAdded), @"doc1", @{@"key1" : @"value1"} ],
+ @[ @(FIRDocumentChangeTypeAdded), @"doc2", @{@"key2" : @"value2", @"key2b" : @"value2b"} ],
+ @[ @(FIRDocumentChangeTypeAdded), @"doc3", @{@"key3b" : @"value3b"} ],
+ @[ @(FIRDocumentChangeTypeAdded), @"doc4", @{@"key4" : @"value4"} ]
+ ]));
+}
+
+- (void)testGetDocumentWhileOnlineServerOnly {
+ FIRDocumentReference *doc = [self documentRef];
+
+ // set document to a known value
+ NSDictionary<NSString *, id> *initialData = @{@"key" : @"value"};
+ [self writeDocumentRef:doc data:initialData];
+
+ // get doc and ensure that it exists, is *not* from the cache, and matches
+ // the initialData.
+ FIRDocumentSnapshot *result = [self readDocumentForRef:doc source:FIRFirestoreSourceServer];
+ XCTAssertTrue(result.exists);
+ XCTAssertFalse(result.metadata.fromCache);
+ XCTAssertFalse(result.metadata.hasPendingWrites);
+ XCTAssertEqualObjects(result.data, initialData);
+}
+
+- (void)testGetCollectionWhileOnlineServerOnly {
+ FIRCollectionReference *col = [self collectionRef];
+
+ // set a few documents to a known value
+ NSDictionary<NSString *, NSDictionary<NSString *, id> *> *initialDocs = @{
+ @"doc1" : @{@"key1" : @"value1"},
+ @"doc2" : @{@"key2" : @"value2"},
+ @"doc3" : @{@"key3" : @"value3"},
+ };
+ [self writeAllDocuments:initialDocs toCollection:col];
+
+ // get docs and ensure they are *not* from the cache, and matches the
+ // initialData.
+ FIRQuerySnapshot *result = [self readDocumentSetForRef:col source:FIRFirestoreSourceServer];
+ XCTAssertFalse(result.metadata.fromCache);
+ XCTAssertFalse(result.metadata.hasPendingWrites);
+ XCTAssertEqualObjects(FIRQuerySnapshotGetData(result), (@[
+ @{@"key1" : @"value1"},
+ @{@"key2" : @"value2"},
+ @{@"key3" : @"value3"},
+ ]));
+ XCTAssertEqualObjects(FIRQuerySnapshotGetDocChangesData(result), (@[
+ @[ @(FIRDocumentChangeTypeAdded), @"doc1", @{@"key1" : @"value1"} ],
+ @[ @(FIRDocumentChangeTypeAdded), @"doc2", @{@"key2" : @"value2"} ],
+ @[ @(FIRDocumentChangeTypeAdded), @"doc3", @{@"key3" : @"value3"} ]
+ ]));
+}
+
+- (void)testGetDocumentWhileOfflineServerOnly {
+ FIRDocumentReference *doc = [self documentRef];
+
+ // set document to a known value
+ NSDictionary<NSString *, id> *initialData = @{@"key1" : @"value1"};
+ [self writeDocumentRef:doc data:initialData];
+
+ // go offline for the rest of this test
+ [self disableNetwork];
+
+ // attempt to get doc and ensure it cannot be retreived
+ XCTestExpectation *failedGetDocCompletion = [self expectationWithDescription:@"failedGetDoc"];
+ [doc getDocumentWithSource:FIRFirestoreSourceServer
+ completion:^(FIRDocumentSnapshot *snapshot, NSError *error) {
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
+ XCTAssertEqual(error.code, FIRFirestoreErrorCodeUnavailable);
+ [failedGetDocCompletion fulfill];
+ }];
+ [self awaitExpectations];
+}
+
+- (void)testGetCollectionWhileOfflineServerOnly {
+ FIRCollectionReference *col = [self collectionRef];
+
+ // set a few documents to a known value
+ NSDictionary<NSString *, NSDictionary<NSString *, id> *> *initialDocs = @{
+ @"doc1" : @{@"key1" : @"value1"},
+ @"doc2" : @{@"key2" : @"value2"},
+ @"doc3" : @{@"key3" : @"value3"},
+ };
+ [self writeAllDocuments:initialDocs toCollection:col];
+
+ // go offline for the rest of this test
+ [self disableNetwork];
+
+ // attempt to get docs and ensure they cannot be retreived
+ XCTestExpectation *failedGetDocsCompletion = [self expectationWithDescription:@"failedGetDocs"];
+ [col getDocumentsWithSource:FIRFirestoreSourceServer
+ completion:^(FIRQuerySnapshot *snapshot, NSError *error) {
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
+ XCTAssertEqual(error.code, FIRFirestoreErrorCodeUnavailable);
+ [failedGetDocsCompletion fulfill];
+ }];
+ [self awaitExpectations];
+}
+
+- (void)testGetDocumentWhileOfflineWithDifferentSource {
+ FIRDocumentReference *doc = [self documentRef];
+
+ // set document to a known value
+ NSDictionary<NSString *, id> *initialData = @{@"key1" : @"value1"};
+ [self writeDocumentRef:doc data:initialData];
+
+ // go offline for the rest of this test
+ [self disableNetwork];
+
+ // update the doc (though don't wait for a server response. We're offline; so
+ // that ain't happening!). This allows us to further distinguished cached vs
+ // server responses below.
+ NSDictionary<NSString *, id> *newData = @{@"key2" : @"value2"};
+ [doc setData:newData
+ completion:^(NSError *_Nullable error) {
+ XCTAssertTrue(false, "Because we're offline, this should never occur.");
+ }];
+
+ // Create an initial listener for this query (to attempt to disrupt the gets below) and wait for
+ // the listener to deliver its initial snapshot before continuing.
+ XCTestExpectation *listenerReady = [self expectationWithDescription:@"listenerReady"];
+ [doc addSnapshotListener:^(FIRDocumentSnapshot *snapshot, NSError *error) {
+ [listenerReady fulfill];
+ }];
+ [self awaitExpectations];
+
+ // get doc (from cache) and ensure it exists, *is* from the cache, and
+ // matches the newData.
+ FIRDocumentSnapshot *result = [self readDocumentForRef:doc source:FIRFirestoreSourceCache];
+ XCTAssertTrue(result.exists);
+ XCTAssertTrue(result.metadata.fromCache);
+ XCTAssertTrue(result.metadata.hasPendingWrites);
+ XCTAssertEqualObjects(result.data, newData);
+
+ // attempt to get doc (with default get source)
+ result = [self readDocumentForRef:doc source:FIRFirestoreSourceDefault];
+ XCTAssertTrue(result.exists);
+ XCTAssertTrue(result.metadata.fromCache);
+ XCTAssertTrue(result.metadata.hasPendingWrites);
+ XCTAssertEqualObjects(result.data, newData);
+
+ // attempt to get doc (from the server) and ensure it cannot be retreived
+ XCTestExpectation *failedGetDocCompletion = [self expectationWithDescription:@"failedGetDoc"];
+ [doc getDocumentWithSource:FIRFirestoreSourceServer
+ completion:^(FIRDocumentSnapshot *snapshot, NSError *error) {
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
+ XCTAssertEqual(error.code, FIRFirestoreErrorCodeUnavailable);
+ [failedGetDocCompletion fulfill];
+ }];
+ [self awaitExpectations];
+}
+
+- (void)testGetCollectionWhileOfflineWithDifferentSource {
+ FIRCollectionReference *col = [self collectionRef];
+
+ // set a few documents to a known value
+ NSDictionary<NSString *, NSDictionary<NSString *, id> *> *initialDocs = @{
+ @"doc1" : @{@"key1" : @"value1"},
+ @"doc2" : @{@"key2" : @"value2"},
+ @"doc3" : @{@"key3" : @"value3"},
+ };
+ [self writeAllDocuments:initialDocs toCollection:col];
+
+ // go offline for the rest of this test
+ [self disableNetwork];
+
+ // update the docs (though don't wait for a server response. We're offline; so
+ // that ain't happening!). This allows us to further distinguished cached vs
+ // server responses below.
+ [[col documentWithPath:@"doc2"] setData:@{@"key2b" : @"value2b"} options:FIRSetOptions.merge];
+ [[col documentWithPath:@"doc3"] setData:@{@"key3b" : @"value3b"}];
+ [[col documentWithPath:@"doc4"] setData:@{@"key4" : @"value4"}];
+
+ // Create an initial listener for this query (to attempt to disrupt the gets
+ // below) and wait for the listener to deliver its initial snapshot before
+ // continuing.
+ XCTestExpectation *listenerReady = [self expectationWithDescription:@"listenerReady"];
+ [col addSnapshotListener:^(FIRQuerySnapshot *snapshot, NSError *error) {
+ [listenerReady fulfill];
+ }];
+ [self awaitExpectations];
+
+ // get docs (from cache) and ensure they *are* from the cache, and
+ // matches the updated data.
+ FIRQuerySnapshot *result = [self readDocumentSetForRef:col source:FIRFirestoreSourceCache];
+ XCTAssertTrue(result.metadata.fromCache);
+ XCTAssertTrue(result.metadata.hasPendingWrites);
+ XCTAssertEqualObjects(FIRQuerySnapshotGetData(result), (@[
+ @{@"key1" : @"value1"}, @{@"key2" : @"value2", @"key2b" : @"value2b"},
+ @{@"key3b" : @"value3b"}, @{@"key4" : @"value4"}
+ ]));
+ XCTAssertEqualObjects(
+ FIRQuerySnapshotGetDocChangesData(result), (@[
+ @[ @(FIRDocumentChangeTypeAdded), @"doc1", @{@"key1" : @"value1"} ],
+ @[ @(FIRDocumentChangeTypeAdded), @"doc2", @{@"key2" : @"value2", @"key2b" : @"value2b"} ],
+ @[ @(FIRDocumentChangeTypeAdded), @"doc3", @{@"key3b" : @"value3b"} ],
+ @[ @(FIRDocumentChangeTypeAdded), @"doc4", @{@"key4" : @"value4"} ]
+ ]));
+
+ // attempt to get docs (with default get source)
+ result = [self readDocumentSetForRef:col source:FIRFirestoreSourceDefault];
+ XCTAssertTrue(result.metadata.fromCache);
+ XCTAssertEqualObjects(FIRQuerySnapshotGetData(result), (@[
+ @{@"key1" : @"value1"}, @{@"key2" : @"value2", @"key2b" : @"value2b"},
+ @{@"key3b" : @"value3b"}, @{@"key4" : @"value4"}
+ ]));
+ XCTAssertEqualObjects(
+ FIRQuerySnapshotGetDocChangesData(result), (@[
+ @[ @(FIRDocumentChangeTypeAdded), @"doc1", @{@"key1" : @"value1"} ],
+ @[ @(FIRDocumentChangeTypeAdded), @"doc2", @{@"key2" : @"value2", @"key2b" : @"value2b"} ],
+ @[ @(FIRDocumentChangeTypeAdded), @"doc3", @{@"key3b" : @"value3b"} ],
+ @[ @(FIRDocumentChangeTypeAdded), @"doc4", @{@"key4" : @"value4"} ]
+ ]));
+
+ // attempt to get docs (from the server) and ensure they cannot be retreived
+ XCTestExpectation *failedGetDocsCompletion = [self expectationWithDescription:@"failedGetDocs"];
+ [col getDocumentsWithSource:FIRFirestoreSourceServer
+ completion:^(FIRQuerySnapshot *snapshot, NSError *error) {
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
+ XCTAssertEqual(error.code, FIRFirestoreErrorCodeUnavailable);
+ [failedGetDocsCompletion fulfill];
+ }];
+ [self awaitExpectations];
+}
+
+- (void)testGetNonExistingDocWhileOnlineWithDefaultSource {
+ FIRDocumentReference *doc = [self documentRef];
+
+ // get doc and ensure that it does not exist and is *not* from the cache.
+ FIRDocumentSnapshot *snapshot = [self readDocumentForRef:doc];
+ XCTAssertFalse(snapshot.exists);
+ XCTAssertFalse(snapshot.metadata.fromCache);
+ XCTAssertFalse(snapshot.metadata.hasPendingWrites);
+}
+
+- (void)testGetNonExistingCollectionWhileOnlineWithDefaultSource {
+ FIRCollectionReference *col = [self collectionRef];
+
+ // get collection and ensure it's empty and that it's *not* from the cache.
+ FIRQuerySnapshot *snapshot = [self readDocumentSetForRef:col];
+ XCTAssertEqual(snapshot.count, 0);
+ XCTAssertEqual(snapshot.documentChanges.count, 0);
+ XCTAssertFalse(snapshot.metadata.fromCache);
+ XCTAssertFalse(snapshot.metadata.hasPendingWrites);
+}
+
+- (void)testGetNonExistingDocWhileOfflineWithDefaultSource {
+ FIRDocumentReference *doc = [self documentRef];
+
+ // go offline for the rest of this test
+ [self disableNetwork];
+
+ // attempt to get doc. Currently, this is expected to fail. In the future, we
+ // might consider adding support for negative cache hits so that we know
+ // certain documents *don't* exist.
+ XCTestExpectation *getNonExistingDocCompletion =
+ [self expectationWithDescription:@"getNonExistingDoc"];
+ [doc getDocumentWithCompletion:^(FIRDocumentSnapshot *snapshot, NSError *error) {
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
+ XCTAssertEqual(error.code, FIRFirestoreErrorCodeUnavailable);
+ [getNonExistingDocCompletion fulfill];
+ }];
+ [self awaitExpectations];
+}
+
+- (void)testGetNonExistingCollectionWhileOfflineWithDefaultSource {
+ FIRCollectionReference *col = [self collectionRef];
+
+ // go offline for the rest of this test
+ [self disableNetwork];
+
+ // get collection and ensure it's empty and that it *is* from the cache.
+ FIRQuerySnapshot *snapshot = [self readDocumentSetForRef:col];
+ XCTAssertEqual(snapshot.count, 0);
+ XCTAssertEqual(snapshot.documentChanges.count, 0);
+ XCTAssertTrue(snapshot.metadata.fromCache);
+ XCTAssertFalse(snapshot.metadata.hasPendingWrites);
+}
+
+- (void)testGetNonExistingDocWhileOnlineCacheOnly {
+ FIRDocumentReference *doc = [self documentRef];
+
+ // attempt to get doc. Currently, this is expected to fail. In the future, we
+ // might consider adding support for negative cache hits so that we know
+ // certain documents *don't* exist.
+ XCTestExpectation *getNonExistingDocCompletion =
+ [self expectationWithDescription:@"getNonExistingDoc"];
+ [doc getDocumentWithSource:FIRFirestoreSourceCache
+ completion:^(FIRDocumentSnapshot *snapshot, NSError *error) {
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
+ XCTAssertEqual(error.code, FIRFirestoreErrorCodeUnavailable);
+ [getNonExistingDocCompletion fulfill];
+ }];
+ [self awaitExpectations];
+}
+
+- (void)testGetNonExistingCollectionWhileOnlineCacheOnly {
+ FIRCollectionReference *col = [self collectionRef];
+
+ // get collection and ensure it's empty and that it *is* from the cache.
+ FIRQuerySnapshot *snapshot = [self readDocumentSetForRef:col source:FIRFirestoreSourceCache];
+ XCTAssertEqual(snapshot.count, 0);
+ XCTAssertEqual(snapshot.documentChanges.count, 0);
+ XCTAssertTrue(snapshot.metadata.fromCache);
+ XCTAssertFalse(snapshot.metadata.hasPendingWrites);
+}
+
+- (void)testGetNonExistingDocWhileOfflineCacheOnly {
+ FIRDocumentReference *doc = [self documentRef];
+
+ // go offline for the rest of this test
+ [self disableNetwork];
+
+ // attempt to get doc. Currently, this is expected to fail. In the future, we
+ // might consider adding support for negative cache hits so that we know
+ // certain documents *don't* exist.
+ XCTestExpectation *getNonExistingDocCompletion =
+ [self expectationWithDescription:@"getNonExistingDoc"];
+ [doc getDocumentWithSource:FIRFirestoreSourceCache
+ completion:^(FIRDocumentSnapshot *snapshot, NSError *error) {
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
+ XCTAssertEqual(error.code, FIRFirestoreErrorCodeUnavailable);
+ [getNonExistingDocCompletion fulfill];
+ }];
+ [self awaitExpectations];
+}
+
+- (void)testGetNonExistingCollectionWhileOfflineCacheOnly {
+ FIRCollectionReference *col = [self collectionRef];
+
+ // go offline for the rest of this test
+ [self disableNetwork];
+
+ // get collection and ensure it's empty and that it *is* from the cache.
+ FIRQuerySnapshot *snapshot = [self readDocumentSetForRef:col source:FIRFirestoreSourceCache];
+ XCTAssertEqual(snapshot.count, 0);
+ XCTAssertEqual(snapshot.documentChanges.count, 0);
+ XCTAssertTrue(snapshot.metadata.fromCache);
+ XCTAssertFalse(snapshot.metadata.hasPendingWrites);
+}
+
+- (void)testGetNonExistingDocWhileOnlineServerOnly {
+ FIRDocumentReference *doc = [self documentRef];
+
+ // get doc and ensure that it does not exist and is *not* from the cache.
+ FIRDocumentSnapshot *snapshot = [self readDocumentForRef:doc source:FIRFirestoreSourceServer];
+ XCTAssertFalse(snapshot.exists);
+ XCTAssertFalse(snapshot.metadata.fromCache);
+ XCTAssertFalse(snapshot.metadata.hasPendingWrites);
+}
+
+- (void)testGetNonExistingCollectionWhileOnlineServerOnly {
+ FIRCollectionReference *col = [self collectionRef];
+
+ // get collection and ensure that it's empty and that it's *not* from the cache.
+ FIRQuerySnapshot *snapshot = [self readDocumentSetForRef:col source:FIRFirestoreSourceServer];
+ XCTAssertEqual(snapshot.count, 0);
+ XCTAssertEqual(snapshot.documentChanges.count, 0);
+ XCTAssertFalse(snapshot.metadata.fromCache);
+ XCTAssertFalse(snapshot.metadata.hasPendingWrites);
+}
+
+- (void)testGetNonExistingDocWhileOfflineServerOnly {
+ FIRDocumentReference *doc = [self documentRef];
+
+ // go offline for the rest of this test
+ [self disableNetwork];
+
+ // attempt to get doc. Currently, this is expected to fail. In the future, we
+ // might consider adding support for negative cache hits so that we know
+ // certain documents *don't* exist.
+ XCTestExpectation *getNonExistingDocCompletion =
+ [self expectationWithDescription:@"getNonExistingDoc"];
+ [doc getDocumentWithSource:FIRFirestoreSourceServer
+ completion:^(FIRDocumentSnapshot *snapshot, NSError *error) {
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
+ XCTAssertEqual(error.code, FIRFirestoreErrorCodeUnavailable);
+ [getNonExistingDocCompletion fulfill];
+ }];
+ [self awaitExpectations];
+}
+
+- (void)testGetNonExistingCollectionWhileOfflineServerOnly {
+ FIRCollectionReference *col = [self collectionRef];
+
+ // go offline for the rest of this test
+ [self disableNetwork];
+
+ // attempt to get collection and ensure that it cannot be retreived
+ XCTestExpectation *failedGetDocsCompletion = [self expectationWithDescription:@"failedGetDocs"];
+ [col getDocumentsWithSource:FIRFirestoreSourceServer
+ completion:^(FIRQuerySnapshot *snapshot, NSError *error) {
+ XCTAssertNotNil(error);
+ XCTAssertEqualObjects(error.domain, FIRFirestoreErrorDomain);
+ XCTAssertEqual(error.code, FIRFirestoreErrorCodeUnavailable);
+ [failedGetDocsCompletion fulfill];
+ }];
+ [self awaitExpectations];
+}
+
+@end
diff --git a/Firestore/Example/Tests/Util/FSTIntegrationTestCase.h b/Firestore/Example/Tests/Util/FSTIntegrationTestCase.h
index e27491b..585d99a 100644
--- a/Firestore/Example/Tests/Util/FSTIntegrationTestCase.h
+++ b/Firestore/Example/Tests/Util/FSTIntegrationTestCase.h
@@ -20,6 +20,8 @@
#import "Firestore/Example/Tests/Util/XCTestCase+Await.h"
#import "Firestore/Source/Core/FSTTypes.h"
+#import "FIRFirestoreSource.h"
+
@class FIRCollectionReference;
@class FIRDocumentSnapshot;
@class FIRDocumentReference;
@@ -71,8 +73,13 @@ extern "C" {
- (FIRDocumentSnapshot *)readDocumentForRef:(FIRDocumentReference *)ref;
+- (FIRDocumentSnapshot *)readDocumentForRef:(FIRDocumentReference *)ref
+ source:(FIRFirestoreSource)source;
+
- (FIRQuerySnapshot *)readDocumentSetForRef:(FIRQuery *)query;
+- (FIRQuerySnapshot *)readDocumentSetForRef:(FIRQuery *)query source:(FIRFirestoreSource)source;
+
- (FIRDocumentSnapshot *)readSnapshotForRef:(FIRDocumentReference *)query
requireOnline:(BOOL)online;
@@ -108,6 +115,10 @@ NSArray<NSDictionary<NSString *, id> *> *FIRQuerySnapshotGetData(FIRQuerySnapsho
/** Converts the FIRQuerySnapshot to an NSArray containing the document IDs in order. */
NSArray<NSString *> *FIRQuerySnapshotGetIDs(FIRQuerySnapshot *docs);
+/** Converts the FIRQuerySnapshot to an NSArray containing an NSArray containing the doc change data
+ * in order of { type, doc title, doc data }. */
+NSArray<NSArray<id> *> *FIRQuerySnapshotGetDocChangesData(FIRQuerySnapshot *docs);
+
#if __cplusplus
} // extern "C"
#endif
diff --git a/Firestore/Example/Tests/Util/FSTIntegrationTestCase.mm b/Firestore/Example/Tests/Util/FSTIntegrationTestCase.mm
index 9bfdb3b..1817015 100644
--- a/Firestore/Example/Tests/Util/FSTIntegrationTestCase.mm
+++ b/Firestore/Example/Tests/Util/FSTIntegrationTestCase.mm
@@ -212,28 +212,39 @@ NS_ASSUME_NONNULL_BEGIN
}
- (FIRDocumentSnapshot *)readDocumentForRef:(FIRDocumentReference *)ref {
+ return [self readDocumentForRef:ref source:FIRFirestoreSourceDefault];
+}
+
+- (FIRDocumentSnapshot *)readDocumentForRef:(FIRDocumentReference *)ref
+ source:(FIRFirestoreSource)source {
__block FIRDocumentSnapshot *result;
XCTestExpectation *expectation = [self expectationWithDescription:@"getData"];
- [ref getDocumentWithCompletion:^(FIRDocumentSnapshot *doc, NSError *_Nullable error) {
- XCTAssertNil(error);
- result = doc;
- [expectation fulfill];
- }];
+ [ref getDocumentWithSource:source
+ completion:^(FIRDocumentSnapshot *doc, NSError *_Nullable error) {
+ XCTAssertNil(error);
+ result = doc;
+ [expectation fulfill];
+ }];
[self awaitExpectations];
return result;
}
- (FIRQuerySnapshot *)readDocumentSetForRef:(FIRQuery *)query {
+ return [self readDocumentSetForRef:query source:FIRFirestoreSourceDefault];
+}
+
+- (FIRQuerySnapshot *)readDocumentSetForRef:(FIRQuery *)query source:(FIRFirestoreSource)source {
__block FIRQuerySnapshot *result;
XCTestExpectation *expectation = [self expectationWithDescription:@"getData"];
- [query getDocumentsWithCompletion:^(FIRQuerySnapshot *documentSet, NSError *error) {
- XCTAssertNil(error);
- result = documentSet;
- [expectation fulfill];
- }];
+ [query getDocumentsWithSource:source
+ completion:^(FIRQuerySnapshot *documentSet, NSError *error) {
+ XCTAssertNil(error);
+ result = documentSet;
+ [expectation fulfill];
+ }];
[self awaitExpectations];
return result;
@@ -329,6 +340,18 @@ extern "C" NSArray<NSString *> *FIRQuerySnapshotGetIDs(FIRQuerySnapshot *docs) {
return result;
}
+extern "C" NSArray<NSArray<id> *> *FIRQuerySnapshotGetDocChangesData(FIRQuerySnapshot *docs) {
+ NSMutableArray<NSMutableArray<id> *> *result = [NSMutableArray array];
+ for (FIRDocumentChange *docChange in docs.documentChanges) {
+ NSMutableArray<id> *docChangeData = [NSMutableArray array];
+ [docChangeData addObject:@(docChange.type)];
+ [docChangeData addObject:docChange.document.documentID];
+ [docChangeData addObject:docChange.document.data];
+ [result addObject:docChangeData];
+ }
+ return result;
+}
+
@end
NS_ASSUME_NONNULL_END