Files
firebase-ios-sdk/Firestore/Example/Tests/Core/FSTViewTests.mm
T

736 lines
34 KiB
Plaintext
Raw Normal View History

2017-10-03 08:55:22 -07:00
/*
* Copyright 2017 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 "Firestore/Source/Core/FSTView.h"
2017-10-03 08:55:22 -07:00
#import <XCTest/XCTest.h>
2019-03-25 11:04:21 -07:00
#include <initializer_list>
2019-03-01 14:16:41 -05:00
#include <utility>
#include <vector>
#import "Firestore/Source/API/FIRFirestore+Internal.h"
#import "Firestore/Source/Core/FSTQuery.h"
#import "Firestore/Source/Model/FSTDocument.h"
#import "Firestore/Source/Model/FSTFieldValue.h"
2017-10-03 08:55:22 -07:00
#import "Firestore/Example/Tests/Util/FSTHelpers.h"
2017-10-03 08:55:22 -07:00
#include "Firestore/core/src/firebase/firestore/core/filter.h"
2019-03-01 14:16:41 -05:00
#include "Firestore/core/src/firebase/firestore/core/view_snapshot.h"
2019-03-25 11:04:21 -07:00
#include "Firestore/core/src/firebase/firestore/model/document_set.h"
#include "Firestore/core/src/firebase/firestore/model/resource_path.h"
#include "Firestore/core/test/firebase/firestore/testutil/testutil.h"
2019-03-21 14:48:55 -07:00
#include "Firestore/core/test/firebase/firestore/testutil/xcgmock.h"
2019-01-29 15:10:18 -05:00
#include "absl/types/optional.h"
namespace testutil = firebase::firestore::testutil;
using firebase::firestore::core::DocumentViewChange;
using firebase::firestore::core::Filter;
2019-03-01 14:16:41 -05:00
using firebase::firestore::core::ViewSnapshot;
using firebase::firestore::model::ResourcePath;
using firebase::firestore::model::DocumentKeySet;
2019-03-25 11:04:21 -07:00
using firebase::firestore::model::DocumentSet;
using firebase::firestore::model::FieldValue;
2019-03-21 14:48:55 -07:00
using testing::ElementsAre;
2017-10-03 08:55:22 -07:00
NS_ASSUME_NONNULL_BEGIN
2019-03-25 11:04:21 -07:00
/**
* A custom matcher that verifies that the subject has the same keys as the given documents without
* verifying that the contents are the same.
*/
MATCHER_P(ContainsDocs, expected, "") {
if (expected.size() != arg.size()) {
return false;
}
for (FSTDocument *doc : expected) {
if (!arg.ContainsKey(doc.key)) {
return false;
}
}
return true;
}
/** Constructs `ContainsDocs` instances with an initializer list. */
inline ContainsDocsMatcherP<std::vector<FSTDocument *>> ContainsDocs(
std::vector<FSTDocument *> docs) {
return ContainsDocsMatcherP<std::vector<FSTDocument *>>(docs);
}
2017-10-03 08:55:22 -07:00
@interface FSTViewTests : XCTestCase
@end
@implementation FSTViewTests
/** Returns a new empty query to use for testing. */
- (FSTQuery *)queryForMessages {
return [FSTQuery queryWithPath:ResourcePath{"rooms", "eros", "messages"}];
2017-10-03 08:55:22 -07:00
}
- (void)testAddsDocumentsBasedOnQuery {
FSTQuery *query = [self queryForMessages];
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
2017-10-03 08:55:22 -07:00
2018-11-01 09:44:30 -07:00
FSTDocument *doc1 =
FSTTestDoc("rooms/eros/messages/1", 0, @{@"text" : @"msg1"}, FSTDocumentStateSynced);
FSTDocument *doc2 =
FSTTestDoc("rooms/eros/messages/2", 0, @{@"text" : @"msg2"}, FSTDocumentStateSynced);
FSTDocument *doc3 =
FSTTestDoc("rooms/other/messages/1", 0, @{@"text" : @"msg3"}, FSTDocumentStateSynced);
2017-10-03 08:55:22 -07:00
2019-03-01 14:16:41 -05:00
absl::optional<ViewSnapshot> maybe_snapshot = FSTTestApplyChanges(
2018-06-12 10:58:35 -07:00
view, @[ doc1, doc2, doc3 ], FSTTestTargetChangeAckDocuments({doc1.key, doc2.key, doc3.key}));
2019-03-01 14:16:41 -05:00
XCTAssertTrue(maybe_snapshot.has_value());
ViewSnapshot snapshot = std::move(maybe_snapshot).value();
2017-10-03 08:55:22 -07:00
2019-03-01 14:16:41 -05:00
XCTAssertEqual(snapshot.query(), query);
2017-10-03 08:55:22 -07:00
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(snapshot.documents(), ElementsAre(doc1, doc2));
2017-10-03 08:55:22 -07:00
XCTAssertTrue((
2019-03-01 14:16:41 -05:00
snapshot.document_changes() ==
std::vector<DocumentViewChange>{DocumentViewChange{doc1, DocumentViewChange::Type::kAdded},
DocumentViewChange{doc2, DocumentViewChange::Type::kAdded}}));
2017-10-03 08:55:22 -07:00
2019-03-01 14:16:41 -05:00
XCTAssertFalse(snapshot.from_cache());
XCTAssertFalse(snapshot.has_pending_writes());
XCTAssertTrue(snapshot.sync_state_changed());
2017-10-03 08:55:22 -07:00
}
- (void)testRemovesDocuments {
FSTQuery *query = [self queryForMessages];
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
2017-10-03 08:55:22 -07:00
2018-11-01 09:44:30 -07:00
FSTDocument *doc1 =
FSTTestDoc("rooms/eros/messages/1", 0, @{@"text" : @"msg1"}, FSTDocumentStateSynced);
FSTDocument *doc2 =
FSTTestDoc("rooms/eros/messages/2", 0, @{@"text" : @"msg2"}, FSTDocumentStateSynced);
FSTDocument *doc3 =
FSTTestDoc("rooms/eros/messages/3", 0, @{@"text" : @"msg3"}, FSTDocumentStateSynced);
2017-10-03 08:55:22 -07:00
// initial state
2019-01-29 15:10:18 -05:00
FSTTestApplyChanges(view, @[ doc1, doc2 ], absl::nullopt);
2017-10-03 08:55:22 -07:00
// delete doc2, add doc3
2019-03-01 14:16:41 -05:00
absl::optional<ViewSnapshot> maybe_snapshot =
2018-11-01 09:44:30 -07:00
FSTTestApplyChanges(view, @[ FSTTestDeletedDoc("rooms/eros/messages/2", 0, NO), doc3 ],
2018-06-12 10:58:35 -07:00
FSTTestTargetChangeAckDocuments({doc1.key, doc3.key}));
2019-03-01 14:16:41 -05:00
XCTAssertTrue(maybe_snapshot.has_value());
ViewSnapshot snapshot = std::move(maybe_snapshot).value();
2017-10-03 08:55:22 -07:00
2019-03-01 14:16:41 -05:00
XCTAssertEqual(snapshot.query(), query);
2017-10-03 08:55:22 -07:00
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(snapshot.documents(), ElementsAre(doc1, doc3));
2017-10-03 08:55:22 -07:00
XCTAssertTrue((
2019-03-01 14:16:41 -05:00
snapshot.document_changes() ==
std::vector<DocumentViewChange>{DocumentViewChange{doc2, DocumentViewChange::Type::kRemoved},
DocumentViewChange{doc3, DocumentViewChange::Type::kAdded}}));
2017-10-03 08:55:22 -07:00
2019-03-01 14:16:41 -05:00
XCTAssertFalse(snapshot.from_cache());
XCTAssertTrue(snapshot.sync_state_changed());
2017-10-03 08:55:22 -07:00
}
- (void)testReturnsNilIfThereAreNoChanges {
FSTQuery *query = [self queryForMessages];
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
2017-10-03 08:55:22 -07:00
2018-11-01 09:44:30 -07:00
FSTDocument *doc1 =
FSTTestDoc("rooms/eros/messages/1", 0, @{@"text" : @"msg1"}, FSTDocumentStateSynced);
FSTDocument *doc2 =
FSTTestDoc("rooms/eros/messages/2", 0, @{@"text" : @"msg2"}, FSTDocumentStateSynced);
2017-10-03 08:55:22 -07:00
// initial state
2019-01-29 15:10:18 -05:00
FSTTestApplyChanges(view, @[ doc1, doc2 ], absl::nullopt);
2017-10-03 08:55:22 -07:00
// reapply same docs, no changes
2019-03-01 14:16:41 -05:00
absl::optional<ViewSnapshot> snapshot = FSTTestApplyChanges(view, @[ doc1, doc2 ], absl::nullopt);
XCTAssertFalse(snapshot.has_value());
2017-10-03 08:55:22 -07:00
}
- (void)testDoesNotReturnNilForFirstChanges {
FSTQuery *query = [self queryForMessages];
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
2017-10-03 08:55:22 -07:00
2019-03-01 14:16:41 -05:00
absl::optional<ViewSnapshot> snapshot = FSTTestApplyChanges(view, @[], absl::nullopt);
XCTAssertTrue(snapshot.has_value());
2017-10-03 08:55:22 -07:00
}
- (void)testFiltersDocumentsBasedOnQueryWithFilter {
FSTQuery *query = [self queryForMessages];
FSTRelationFilter *filter = [FSTRelationFilter filterWithField:testutil::Field("sort")
filterOperator:Filter::Operator::LessThanOrEqual
value:FieldValue::FromDouble(2).Wrap()];
2017-10-03 08:55:22 -07:00
query = [query queryByAddingFilter:filter];
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
FSTDocument *doc1 =
FSTTestDoc("rooms/eros/messages/1", 0, @{@"sort" : @1}, FSTDocumentStateSynced);
FSTDocument *doc2 =
FSTTestDoc("rooms/eros/messages/2", 0, @{@"sort" : @2}, FSTDocumentStateSynced);
FSTDocument *doc3 =
FSTTestDoc("rooms/eros/messages/3", 0, @{@"sort" : @3}, FSTDocumentStateSynced);
2018-11-01 09:44:30 -07:00
FSTDocument *doc4 =
FSTTestDoc("rooms/eros/messages/4", 0, @{}, FSTDocumentStateSynced); // no sort, no match
FSTDocument *doc5 =
FSTTestDoc("rooms/eros/messages/5", 0, @{@"sort" : @1}, FSTDocumentStateSynced);
2017-10-03 08:55:22 -07:00
2019-03-01 14:16:41 -05:00
absl::optional<ViewSnapshot> maybe_snapshot =
2019-01-29 15:10:18 -05:00
FSTTestApplyChanges(view, @[ doc1, doc2, doc3, doc4, doc5 ], absl::nullopt);
2019-03-01 14:16:41 -05:00
XCTAssertTrue(maybe_snapshot.has_value());
ViewSnapshot snapshot = std::move(maybe_snapshot).value();
2017-10-03 08:55:22 -07:00
2019-03-01 14:16:41 -05:00
XCTAssertEqual(snapshot.query(), query);
2017-10-03 08:55:22 -07:00
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(snapshot.documents(), ElementsAre(doc1, doc5, doc2));
2017-10-03 08:55:22 -07:00
XCTAssertTrue((
2019-03-01 14:16:41 -05:00
snapshot.document_changes() ==
std::vector<DocumentViewChange>{DocumentViewChange{doc1, DocumentViewChange::Type::kAdded},
DocumentViewChange{doc5, DocumentViewChange::Type::kAdded},
DocumentViewChange{doc2, DocumentViewChange::Type::kAdded}}));
2017-10-03 08:55:22 -07:00
2019-03-01 14:16:41 -05:00
XCTAssertTrue(snapshot.from_cache());
XCTAssertTrue(snapshot.sync_state_changed());
2017-10-03 08:55:22 -07:00
}
- (void)testUpdatesDocumentsBasedOnQueryWithFilter {
FSTQuery *query = [self queryForMessages];
FSTRelationFilter *filter = [FSTRelationFilter filterWithField:testutil::Field("sort")
filterOperator:Filter::Operator::LessThanOrEqual
value:FieldValue::FromDouble(2).Wrap()];
2017-10-03 08:55:22 -07:00
query = [query queryByAddingFilter:filter];
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
FSTDocument *doc1 =
FSTTestDoc("rooms/eros/messages/1", 0, @{@"sort" : @1}, FSTDocumentStateSynced);
FSTDocument *doc2 =
FSTTestDoc("rooms/eros/messages/2", 0, @{@"sort" : @3}, FSTDocumentStateSynced);
FSTDocument *doc3 =
FSTTestDoc("rooms/eros/messages/3", 0, @{@"sort" : @2}, FSTDocumentStateSynced);
2018-11-01 09:44:30 -07:00
FSTDocument *doc4 = FSTTestDoc("rooms/eros/messages/4", 0, @{}, FSTDocumentStateSynced);
2017-10-03 08:55:22 -07:00
2019-03-01 14:16:41 -05:00
ViewSnapshot snapshot =
FSTTestApplyChanges(view, @[ doc1, doc2, doc3, doc4 ], absl::nullopt).value();
2017-10-03 08:55:22 -07:00
2019-03-01 14:16:41 -05:00
XCTAssertEqual(snapshot.query(), query);
2017-10-03 08:55:22 -07:00
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(snapshot.documents(), ElementsAre(doc1, doc3));
2017-10-03 08:55:22 -07:00
FSTDocument *newDoc2 =
FSTTestDoc("rooms/eros/messages/2", 1, @{@"sort" : @2}, FSTDocumentStateSynced);
FSTDocument *newDoc3 =
FSTTestDoc("rooms/eros/messages/3", 1, @{@"sort" : @3}, FSTDocumentStateSynced);
FSTDocument *newDoc4 =
FSTTestDoc("rooms/eros/messages/4", 1, @{@"sort" : @0}, FSTDocumentStateSynced);
2017-10-03 08:55:22 -07:00
2019-03-01 14:16:41 -05:00
snapshot = FSTTestApplyChanges(view, @[ newDoc2, newDoc3, newDoc4 ], absl::nullopt).value();
2017-10-03 08:55:22 -07:00
2019-03-01 14:16:41 -05:00
XCTAssertEqual(snapshot.query(), query);
2017-10-03 08:55:22 -07:00
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(snapshot.documents(), ElementsAre(newDoc4, doc1, newDoc2));
2017-10-03 08:55:22 -07:00
2019-03-21 14:48:55 -07:00
XC_ASSERT_THAT(snapshot.document_changes(),
ElementsAre(DocumentViewChange{doc3, DocumentViewChange::Type::kRemoved},
DocumentViewChange{newDoc4, DocumentViewChange::Type::kAdded},
DocumentViewChange{newDoc2, DocumentViewChange::Type::kAdded}));
2017-10-03 08:55:22 -07:00
2019-03-01 14:16:41 -05:00
XCTAssertTrue(snapshot.from_cache());
XCTAssertFalse(snapshot.sync_state_changed());
2017-10-03 08:55:22 -07:00
}
- (void)testRemovesDocumentsForQueryWithLimit {
FSTQuery *query = [self queryForMessages];
query = [query queryBySettingLimit:2];
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
2017-10-03 08:55:22 -07:00
2018-11-01 09:44:30 -07:00
FSTDocument *doc1 =
FSTTestDoc("rooms/eros/messages/1", 0, @{@"text" : @"msg1"}, FSTDocumentStateSynced);
FSTDocument *doc2 =
FSTTestDoc("rooms/eros/messages/2", 0, @{@"text" : @"msg2"}, FSTDocumentStateSynced);
FSTDocument *doc3 =
FSTTestDoc("rooms/eros/messages/3", 0, @{@"text" : @"msg3"}, FSTDocumentStateSynced);
2017-10-03 08:55:22 -07:00
// initial state
2019-01-29 15:10:18 -05:00
FSTTestApplyChanges(view, @[ doc1, doc3 ], absl::nullopt);
2017-10-03 08:55:22 -07:00
// add doc2, which should push out doc3
2019-03-01 14:16:41 -05:00
ViewSnapshot snapshot =
FSTTestApplyChanges(view, @[ doc2 ],
FSTTestTargetChangeAckDocuments({doc1.key, doc2.key, doc3.key}))
.value();
2017-10-03 08:55:22 -07:00
2019-03-01 14:16:41 -05:00
XCTAssertEqual(snapshot.query(), query);
2017-10-03 08:55:22 -07:00
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(snapshot.documents(), ElementsAre(doc1, doc2));
2017-10-03 08:55:22 -07:00
XCTAssertTrue((
2019-03-01 14:16:41 -05:00
snapshot.document_changes() ==
std::vector<DocumentViewChange>{DocumentViewChange{doc3, DocumentViewChange::Type::kRemoved},
DocumentViewChange{doc2, DocumentViewChange::Type::kAdded}}));
2017-10-03 08:55:22 -07:00
2019-03-01 14:16:41 -05:00
XCTAssertFalse(snapshot.from_cache());
XCTAssertTrue(snapshot.sync_state_changed());
2017-10-03 08:55:22 -07:00
}
- (void)testDoesntReportChangesForDocumentBeyondLimitOfQuery {
FSTQuery *query = [self queryForMessages];
query = [query queryByAddingSortOrder:[FSTSortOrder sortOrderWithFieldPath:testutil::Field("num")
ascending:YES]];
2017-10-03 08:55:22 -07:00
query = [query queryBySettingLimit:2];
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
2017-10-03 08:55:22 -07:00
FSTDocument *doc1 =
FSTTestDoc("rooms/eros/messages/1", 0, @{@"num" : @1}, FSTDocumentStateSynced);
FSTDocument *doc2 =
FSTTestDoc("rooms/eros/messages/2", 0, @{@"num" : @2}, FSTDocumentStateSynced);
FSTDocument *doc3 =
FSTTestDoc("rooms/eros/messages/3", 0, @{@"num" : @3}, FSTDocumentStateSynced);
FSTDocument *doc4 =
FSTTestDoc("rooms/eros/messages/4", 0, @{@"num" : @4}, FSTDocumentStateSynced);
2017-10-03 08:55:22 -07:00
// initial state
2019-01-29 15:10:18 -05:00
FSTTestApplyChanges(view, @[ doc1, doc2 ], absl::nullopt);
2017-10-03 08:55:22 -07:00
// change doc2 to 5, and add doc3 and doc4.
// doc2 will be modified + removed = removed
// doc3 will be added
// doc4 will be added + removed = nothing
2018-11-01 09:44:30 -07:00
doc2 = FSTTestDoc("rooms/eros/messages/2", 1, @{@"num" : @5}, FSTDocumentStateSynced);
2017-10-03 08:55:22 -07:00
FSTViewDocumentChanges *viewDocChanges =
[view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc2, doc3, doc4 ])];
XCTAssertTrue(viewDocChanges.needsRefill);
// Verify that all the docs still match.
viewDocChanges = [view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1, doc2, doc3, doc4 ])
previousChanges:viewDocChanges];
2019-03-01 14:16:41 -05:00
absl::optional<ViewSnapshot> maybe_snapshot =
2017-10-03 08:55:22 -07:00
[view applyChangesToDocuments:viewDocChanges
2018-06-12 10:58:35 -07:00
targetChange:FSTTestTargetChangeAckDocuments(
{doc1.key, doc2.key, doc3.key, doc4.key})]
2017-10-03 08:55:22 -07:00
.snapshot;
2019-03-01 14:16:41 -05:00
XCTAssertTrue(maybe_snapshot.has_value());
ViewSnapshot snapshot = std::move(maybe_snapshot).value();
2017-10-03 08:55:22 -07:00
2019-03-01 14:16:41 -05:00
XCTAssertEqual(snapshot.query(), query);
2017-10-03 08:55:22 -07:00
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(snapshot.documents(), ElementsAre(doc1, doc3));
2017-10-03 08:55:22 -07:00
2019-03-21 14:48:55 -07:00
XC_ASSERT_THAT(snapshot.document_changes(),
ElementsAre(DocumentViewChange{doc2, DocumentViewChange::Type::kRemoved},
DocumentViewChange{doc3, DocumentViewChange::Type::kAdded}));
2017-10-03 08:55:22 -07:00
2019-03-01 14:16:41 -05:00
XCTAssertFalse(snapshot.from_cache());
XCTAssertTrue(snapshot.sync_state_changed());
2017-10-03 08:55:22 -07:00
}
- (void)testKeepsTrackOfLimboDocuments {
FSTQuery *query = [self queryForMessages];
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
2017-10-03 08:55:22 -07:00
2018-11-01 09:44:30 -07:00
FSTDocument *doc1 = FSTTestDoc("rooms/eros/messages/0", 0, @{}, FSTDocumentStateSynced);
FSTDocument *doc2 = FSTTestDoc("rooms/eros/messages/1", 0, @{}, FSTDocumentStateSynced);
FSTDocument *doc3 = FSTTestDoc("rooms/eros/messages/2", 0, @{}, FSTDocumentStateSynced);
2017-10-03 08:55:22 -07:00
FSTViewChange *change = [view
applyChangesToDocuments:[view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1 ])]];
XCTAssertEqualObjects(change.limboChanges, @[]);
2018-06-12 10:58:35 -07:00
change = [view applyChangesToDocuments:[view computeChangesWithDocuments:FSTTestDocUpdates(@[])]
targetChange:FSTTestTargetChangeMarkCurrent()];
XCTAssertEqualObjects(change.limboChanges,
@[ [FSTLimboDocumentChange changeWithType:FSTLimboDocumentChangeTypeAdded
key:doc1.key] ]);
2017-10-03 08:55:22 -07:00
2018-06-12 10:58:35 -07:00
change = [view applyChangesToDocuments:[view computeChangesWithDocuments:FSTTestDocUpdates(@[])]
targetChange:FSTTestTargetChangeAckDocuments({doc1.key})];
XCTAssertEqualObjects(change.limboChanges,
@[ [FSTLimboDocumentChange changeWithType:FSTLimboDocumentChangeTypeRemoved
key:doc1.key] ]);
2017-10-03 08:55:22 -07:00
2018-06-12 10:58:35 -07:00
change =
[view applyChangesToDocuments:[view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc2 ])]
targetChange:FSTTestTargetChangeAckDocuments({doc2.key})];
2017-10-03 08:55:22 -07:00
XCTAssertEqualObjects(change.limboChanges, @[]);
change = [view
applyChangesToDocuments:[view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc3 ])]];
XCTAssertEqualObjects(change.limboChanges,
@[ [FSTLimboDocumentChange changeWithType:FSTLimboDocumentChangeTypeAdded
key:doc3.key] ]);
2017-10-03 08:55:22 -07:00
change = [view applyChangesToDocuments:[view computeChangesWithDocuments:FSTTestDocUpdates(@[
2018-11-01 09:44:30 -07:00
FSTTestDeletedDoc("rooms/eros/messages/2", 1, NO)
2017-10-03 08:55:22 -07:00
])]]; // remove
XCTAssertEqualObjects(change.limboChanges,
@[ [FSTLimboDocumentChange changeWithType:FSTLimboDocumentChangeTypeRemoved
key:doc3.key] ]);
2017-10-03 08:55:22 -07:00
}
- (void)testResumingQueryCreatesNoLimbos {
FSTQuery *query = [self queryForMessages];
2018-11-01 09:44:30 -07:00
FSTDocument *doc1 = FSTTestDoc("rooms/eros/messages/0", 0, @{}, FSTDocumentStateSynced);
FSTDocument *doc2 = FSTTestDoc("rooms/eros/messages/1", 0, @{}, FSTDocumentStateSynced);
2017-10-03 08:55:22 -07:00
// Unlike other cases, here the view is initialized with a set of previously synced documents
// which happens when listening to a previously listened-to query.
FSTView *view = [[FSTView alloc] initWithQuery:query
remoteDocuments:DocumentKeySet{doc1.key, doc2.key}];
2017-10-03 08:55:22 -07:00
FSTViewDocumentChanges *changes = [view computeChangesWithDocuments:FSTTestDocUpdates(@[])];
FSTViewChange *change = [view applyChangesToDocuments:changes
targetChange:FSTTestTargetChangeMarkCurrent()];
2017-10-03 08:55:22 -07:00
XCTAssertEqualObjects(change.limboChanges, @[]);
}
- (void)testReturnsNeedsRefillOnDeleteInLimitQuery {
FSTQuery *query = [[self queryForMessages] queryBySettingLimit:2];
2018-11-01 09:44:30 -07:00
FSTDocument *doc1 = FSTTestDoc("rooms/eros/messages/0", 0, @{}, FSTDocumentStateSynced);
FSTDocument *doc2 = FSTTestDoc("rooms/eros/messages/1", 0, @{}, FSTDocumentStateSynced);
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
2017-10-03 08:55:22 -07:00
// Start with a full view.
FSTViewDocumentChanges *changes =
[view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1, doc2 ])];
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(changes.documentSet, ContainsDocs({doc1, doc2}));
2017-10-03 08:55:22 -07:00
XCTAssertFalse(changes.needsRefill);
XCTAssertEqual(2, changes.changeSet.GetChanges().size());
2017-10-03 08:55:22 -07:00
[view applyChangesToDocuments:changes];
// Remove one of the docs.
changes = [view computeChangesWithDocuments:FSTTestDocUpdates(@[ FSTTestDeletedDoc(
2018-11-01 09:44:30 -07:00
"rooms/eros/messages/0", 0, NO) ])];
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(changes.documentSet, ContainsDocs({doc2}));
2017-10-03 08:55:22 -07:00
XCTAssertTrue(changes.needsRefill);
XCTAssertEqual(1, changes.changeSet.GetChanges().size());
2017-10-03 08:55:22 -07:00
// Refill it with just the one doc remaining.
changes = [view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc2 ]) previousChanges:changes];
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(changes.documentSet, ContainsDocs({doc2}));
2017-10-03 08:55:22 -07:00
XCTAssertFalse(changes.needsRefill);
XCTAssertEqual(1, changes.changeSet.GetChanges().size());
2017-10-03 08:55:22 -07:00
[view applyChangesToDocuments:changes];
}
- (void)testReturnsNeedsRefillOnReorderInLimitQuery {
FSTQuery *query = [self queryForMessages];
query =
[query queryByAddingSortOrder:[FSTSortOrder sortOrderWithFieldPath:testutil::Field("order")
2017-10-03 08:55:22 -07:00
ascending:YES]];
query = [query queryBySettingLimit:2];
FSTDocument *doc1 =
FSTTestDoc("rooms/eros/messages/0", 0, @{@"order" : @1}, FSTDocumentStateSynced);
FSTDocument *doc2 =
FSTTestDoc("rooms/eros/messages/1", 0, @{@"order" : @2}, FSTDocumentStateSynced);
FSTDocument *doc3 =
FSTTestDoc("rooms/eros/messages/2", 0, @{@"order" : @3}, FSTDocumentStateSynced);
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
2017-10-03 08:55:22 -07:00
// Start with a full view.
FSTViewDocumentChanges *changes =
[view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1, doc2, doc3 ])];
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(changes.documentSet, ContainsDocs({doc1, doc2}));
2017-10-03 08:55:22 -07:00
XCTAssertFalse(changes.needsRefill);
XCTAssertEqual(2, changes.changeSet.GetChanges().size());
2017-10-03 08:55:22 -07:00
[view applyChangesToDocuments:changes];
// Move one of the docs.
2018-11-01 09:44:30 -07:00
doc2 = FSTTestDoc("rooms/eros/messages/1", 1, @{@"order" : @2000}, FSTDocumentStateSynced);
2017-10-03 08:55:22 -07:00
changes = [view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc2 ])];
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(changes.documentSet, ContainsDocs({doc1, doc2}));
2017-10-03 08:55:22 -07:00
XCTAssertTrue(changes.needsRefill);
XCTAssertEqual(1, changes.changeSet.GetChanges().size());
2017-10-03 08:55:22 -07:00
// Refill it with all three current docs.
changes = [view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1, doc2, doc3 ])
previousChanges:changes];
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(changes.documentSet, ContainsDocs({doc1, doc3}));
2017-10-03 08:55:22 -07:00
XCTAssertFalse(changes.needsRefill);
XCTAssertEqual(2, changes.changeSet.GetChanges().size());
2017-10-03 08:55:22 -07:00
[view applyChangesToDocuments:changes];
}
- (void)testDoesntNeedRefillOnReorderWithinLimit {
FSTQuery *query = [self queryForMessages];
query =
[query queryByAddingSortOrder:[FSTSortOrder sortOrderWithFieldPath:testutil::Field("order")
2017-10-03 08:55:22 -07:00
ascending:YES]];
query = [query queryBySettingLimit:3];
FSTDocument *doc1 =
FSTTestDoc("rooms/eros/messages/0", 0, @{@"order" : @1}, FSTDocumentStateSynced);
FSTDocument *doc2 =
FSTTestDoc("rooms/eros/messages/1", 0, @{@"order" : @2}, FSTDocumentStateSynced);
FSTDocument *doc3 =
FSTTestDoc("rooms/eros/messages/2", 0, @{@"order" : @3}, FSTDocumentStateSynced);
FSTDocument *doc4 =
FSTTestDoc("rooms/eros/messages/3", 0, @{@"order" : @4}, FSTDocumentStateSynced);
FSTDocument *doc5 =
FSTTestDoc("rooms/eros/messages/4", 0, @{@"order" : @5}, FSTDocumentStateSynced);
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
2017-10-03 08:55:22 -07:00
// Start with a full view.
FSTViewDocumentChanges *changes =
[view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1, doc2, doc3, doc4, doc5 ])];
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(changes.documentSet, ContainsDocs({doc1, doc2, doc3}));
2017-10-03 08:55:22 -07:00
XCTAssertFalse(changes.needsRefill);
XCTAssertEqual(3, changes.changeSet.GetChanges().size());
2017-10-03 08:55:22 -07:00
[view applyChangesToDocuments:changes];
// Move one of the docs.
2018-11-01 09:44:30 -07:00
doc1 = FSTTestDoc("rooms/eros/messages/0", 1, @{@"order" : @3}, FSTDocumentStateSynced);
2017-10-03 08:55:22 -07:00
changes = [view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1 ])];
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(changes.documentSet, ContainsDocs({doc2, doc3, doc1}));
2017-10-03 08:55:22 -07:00
XCTAssertFalse(changes.needsRefill);
XCTAssertEqual(1, changes.changeSet.GetChanges().size());
2017-10-03 08:55:22 -07:00
[view applyChangesToDocuments:changes];
}
- (void)testDoesntNeedRefillOnReorderAfterLimitQuery {
FSTQuery *query = [self queryForMessages];
query =
[query queryByAddingSortOrder:[FSTSortOrder sortOrderWithFieldPath:testutil::Field("order")
2017-10-03 08:55:22 -07:00
ascending:YES]];
query = [query queryBySettingLimit:3];
FSTDocument *doc1 =
FSTTestDoc("rooms/eros/messages/0", 0, @{@"order" : @1}, FSTDocumentStateSynced);
FSTDocument *doc2 =
FSTTestDoc("rooms/eros/messages/1", 0, @{@"order" : @2}, FSTDocumentStateSynced);
FSTDocument *doc3 =
FSTTestDoc("rooms/eros/messages/2", 0, @{@"order" : @3}, FSTDocumentStateSynced);
FSTDocument *doc4 =
FSTTestDoc("rooms/eros/messages/3", 0, @{@"order" : @4}, FSTDocumentStateSynced);
FSTDocument *doc5 =
FSTTestDoc("rooms/eros/messages/4", 0, @{@"order" : @5}, FSTDocumentStateSynced);
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
2017-10-03 08:55:22 -07:00
// Start with a full view.
FSTViewDocumentChanges *changes =
[view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1, doc2, doc3, doc4, doc5 ])];
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(changes.documentSet, ContainsDocs({doc1, doc2, doc3}));
2017-10-03 08:55:22 -07:00
XCTAssertFalse(changes.needsRefill);
XCTAssertEqual(3, changes.changeSet.GetChanges().size());
2017-10-03 08:55:22 -07:00
[view applyChangesToDocuments:changes];
// Move one of the docs.
2018-11-01 09:44:30 -07:00
doc4 = FSTTestDoc("rooms/eros/messages/3", 1, @{@"order" : @6}, FSTDocumentStateSynced);
2017-10-03 08:55:22 -07:00
changes = [view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc4 ])];
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(changes.documentSet, ContainsDocs({doc1, doc2, doc3}));
2017-10-03 08:55:22 -07:00
XCTAssertFalse(changes.needsRefill);
XCTAssertEqual(0, changes.changeSet.GetChanges().size());
2017-10-03 08:55:22 -07:00
[view applyChangesToDocuments:changes];
}
- (void)testDoesntNeedRefillForAdditionAfterTheLimit {
FSTQuery *query = [[self queryForMessages] queryBySettingLimit:2];
2018-11-01 09:44:30 -07:00
FSTDocument *doc1 = FSTTestDoc("rooms/eros/messages/0", 0, @{}, FSTDocumentStateSynced);
FSTDocument *doc2 = FSTTestDoc("rooms/eros/messages/1", 0, @{}, FSTDocumentStateSynced);
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
2017-10-03 08:55:22 -07:00
// Start with a full view.
FSTViewDocumentChanges *changes =
[view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1, doc2 ])];
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(changes.documentSet, ContainsDocs({doc1, doc2}));
2017-10-03 08:55:22 -07:00
XCTAssertFalse(changes.needsRefill);
XCTAssertEqual(2, changes.changeSet.GetChanges().size());
2017-10-03 08:55:22 -07:00
[view applyChangesToDocuments:changes];
// Add a doc that is past the limit.
2018-11-01 09:44:30 -07:00
FSTDocument *doc3 = FSTTestDoc("rooms/eros/messages/2", 1, @{}, FSTDocumentStateSynced);
2017-10-03 08:55:22 -07:00
changes = [view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc3 ])];
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(changes.documentSet, ContainsDocs({doc1, doc2}));
2017-10-03 08:55:22 -07:00
XCTAssertFalse(changes.needsRefill);
XCTAssertEqual(0, changes.changeSet.GetChanges().size());
2017-10-03 08:55:22 -07:00
[view applyChangesToDocuments:changes];
}
- (void)testDoesntNeedRefillForDeletionsWhenNotNearTheLimit {
FSTQuery *query = [[self queryForMessages] queryBySettingLimit:20];
2018-11-01 09:44:30 -07:00
FSTDocument *doc1 = FSTTestDoc("rooms/eros/messages/0", 0, @{}, FSTDocumentStateSynced);
FSTDocument *doc2 = FSTTestDoc("rooms/eros/messages/1", 0, @{}, FSTDocumentStateSynced);
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
2017-10-03 08:55:22 -07:00
FSTViewDocumentChanges *changes =
[view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1, doc2 ])];
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(changes.documentSet, ContainsDocs({doc1, doc2}));
2017-10-03 08:55:22 -07:00
XCTAssertFalse(changes.needsRefill);
XCTAssertEqual(2, changes.changeSet.GetChanges().size());
2017-10-03 08:55:22 -07:00
[view applyChangesToDocuments:changes];
// Remove one of the docs.
changes = [view computeChangesWithDocuments:FSTTestDocUpdates(@[ FSTTestDeletedDoc(
2018-11-01 09:44:30 -07:00
"rooms/eros/messages/1", 0, NO) ])];
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(changes.documentSet, ContainsDocs({doc1}));
2017-10-03 08:55:22 -07:00
XCTAssertFalse(changes.needsRefill);
XCTAssertEqual(1, changes.changeSet.GetChanges().size());
2017-10-03 08:55:22 -07:00
[view applyChangesToDocuments:changes];
}
- (void)testHandlesApplyingIrrelevantDocs {
FSTQuery *query = [[self queryForMessages] queryBySettingLimit:2];
2018-11-01 09:44:30 -07:00
FSTDocument *doc1 = FSTTestDoc("rooms/eros/messages/0", 0, @{}, FSTDocumentStateSynced);
FSTDocument *doc2 = FSTTestDoc("rooms/eros/messages/1", 0, @{}, FSTDocumentStateSynced);
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
2017-10-03 08:55:22 -07:00
// Start with a full view.
FSTViewDocumentChanges *changes =
[view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1, doc2 ])];
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(changes.documentSet, ContainsDocs({doc1, doc2}));
2017-10-03 08:55:22 -07:00
XCTAssertFalse(changes.needsRefill);
XCTAssertEqual(2, changes.changeSet.GetChanges().size());
2017-10-03 08:55:22 -07:00
[view applyChangesToDocuments:changes];
// Remove a doc that isn't even in the results.
changes = [view computeChangesWithDocuments:FSTTestDocUpdates(@[ FSTTestDeletedDoc(
2018-11-01 09:44:30 -07:00
"rooms/eros/messages/2", 0, NO) ])];
2019-03-25 11:04:21 -07:00
XC_ASSERT_THAT(changes.documentSet, ContainsDocs({doc1, doc2}));
2017-10-03 08:55:22 -07:00
XCTAssertFalse(changes.needsRefill);
XCTAssertEqual(0, changes.changeSet.GetChanges().size());
2017-10-03 08:55:22 -07:00
[view applyChangesToDocuments:changes];
}
- (void)testComputesMutatedKeys {
FSTQuery *query = [self queryForMessages];
2018-11-01 09:44:30 -07:00
FSTDocument *doc1 = FSTTestDoc("rooms/eros/messages/0", 0, @{}, FSTDocumentStateSynced);
FSTDocument *doc2 = FSTTestDoc("rooms/eros/messages/1", 0, @{}, FSTDocumentStateSynced);
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
2017-10-03 08:55:22 -07:00
// Start with a full view.
FSTViewDocumentChanges *changes =
[view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1, doc2 ])];
[view applyChangesToDocuments:changes];
XCTAssertEqual(changes.mutatedKeys, DocumentKeySet{});
2017-10-03 08:55:22 -07:00
2018-11-01 09:44:30 -07:00
FSTDocument *doc3 = FSTTestDoc("rooms/eros/messages/2", 0, @{}, FSTDocumentStateLocalMutations);
2017-10-03 08:55:22 -07:00
changes = [view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc3 ])];
XCTAssertEqual(changes.mutatedKeys, DocumentKeySet{doc3.key});
2017-10-03 08:55:22 -07:00
}
- (void)testRemovesKeysFromMutatedKeysWhenNewDocHasNoLocalChanges {
FSTQuery *query = [self queryForMessages];
2018-11-01 09:44:30 -07:00
FSTDocument *doc1 = FSTTestDoc("rooms/eros/messages/0", 0, @{}, FSTDocumentStateSynced);
FSTDocument *doc2 = FSTTestDoc("rooms/eros/messages/1", 0, @{}, FSTDocumentStateLocalMutations);
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
2017-10-03 08:55:22 -07:00
// Start with a full view.
FSTViewDocumentChanges *changes =
[view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1, doc2 ])];
[view applyChangesToDocuments:changes];
XCTAssertEqual(changes.mutatedKeys, (DocumentKeySet{doc2.key}));
2017-10-03 08:55:22 -07:00
2018-11-01 09:44:30 -07:00
FSTDocument *doc2Prime = FSTTestDoc("rooms/eros/messages/1", 0, @{}, FSTDocumentStateSynced);
2017-10-03 08:55:22 -07:00
changes = [view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc2Prime ])];
[view applyChangesToDocuments:changes];
XCTAssertEqual(changes.mutatedKeys, DocumentKeySet{});
2017-10-03 08:55:22 -07:00
}
- (void)testRemembersLocalMutationsFromPreviousSnapshot {
FSTQuery *query = [self queryForMessages];
2018-11-01 09:44:30 -07:00
FSTDocument *doc1 = FSTTestDoc("rooms/eros/messages/0", 0, @{}, FSTDocumentStateSynced);
FSTDocument *doc2 = FSTTestDoc("rooms/eros/messages/1", 0, @{}, FSTDocumentStateLocalMutations);
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
2017-10-03 08:55:22 -07:00
// Start with a full view.
FSTViewDocumentChanges *changes =
[view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1, doc2 ])];
[view applyChangesToDocuments:changes];
XCTAssertEqual(changes.mutatedKeys, (DocumentKeySet{doc2.key}));
2017-10-03 08:55:22 -07:00
2018-11-01 09:44:30 -07:00
FSTDocument *doc3 = FSTTestDoc("rooms/eros/messages/2", 0, @{}, FSTDocumentStateSynced);
2017-10-03 08:55:22 -07:00
changes = [view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc3 ])];
[view applyChangesToDocuments:changes];
XCTAssertEqual(changes.mutatedKeys, (DocumentKeySet{doc2.key}));
2017-10-03 08:55:22 -07:00
}
- (void)testRemembersLocalMutationsFromPreviousCallToComputeChangesWithDocuments {
FSTQuery *query = [self queryForMessages];
2018-11-01 09:44:30 -07:00
FSTDocument *doc1 = FSTTestDoc("rooms/eros/messages/0", 0, @{}, FSTDocumentStateSynced);
FSTDocument *doc2 = FSTTestDoc("rooms/eros/messages/1", 0, @{}, FSTDocumentStateLocalMutations);
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
2017-10-03 08:55:22 -07:00
// Start with a full view.
FSTViewDocumentChanges *changes =
[view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1, doc2 ])];
XCTAssertEqual(changes.mutatedKeys, (DocumentKeySet{doc2.key}));
2017-10-03 08:55:22 -07:00
2018-11-01 09:44:30 -07:00
FSTDocument *doc3 = FSTTestDoc("rooms/eros/messages/2", 0, @{}, FSTDocumentStateSynced);
2017-10-03 08:55:22 -07:00
changes = [view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc3 ]) previousChanges:changes];
XCTAssertEqual(changes.mutatedKeys, (DocumentKeySet{doc2.key}));
2017-10-03 08:55:22 -07:00
}
2018-11-01 09:44:30 -07:00
- (void)testRaisesHasPendingWritesForPendingMutationsInInitialSnapshot {
FSTQuery *query = [self queryForMessages];
FSTDocument *doc1 = FSTTestDoc("rooms/eros/messages/1", 0, @{}, FSTDocumentStateLocalMutations);
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
FSTViewDocumentChanges *changes = [view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1 ])];
FSTViewChange *viewChange = [view applyChangesToDocuments:changes];
2019-03-01 14:16:41 -05:00
XCTAssertTrue(viewChange.snapshot.value().has_pending_writes());
2018-11-01 09:44:30 -07:00
}
- (void)testDoesntRaiseHasPendingWritesForCommittedMutationsInInitialSnapshot {
FSTQuery *query = [self queryForMessages];
FSTDocument *doc1 =
FSTTestDoc("rooms/eros/messages/1", 0, @{}, FSTDocumentStateCommittedMutations);
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
FSTViewDocumentChanges *changes = [view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1 ])];
FSTViewChange *viewChange = [view applyChangesToDocuments:changes];
2019-03-01 14:16:41 -05:00
XCTAssertFalse(viewChange.snapshot.value().has_pending_writes());
2018-11-01 09:44:30 -07:00
}
- (void)testSuppressesWriteAcknowledgementIfWatchHasNotCaughtUp {
// This test verifies that we don't get three events for an FSTServerTimestamp mutation. We
// suppress the event generated by the write acknowledgement and instead wait for Watch to catch
// up.
FSTQuery *query = [self queryForMessages];
FSTDocument *doc1 =
FSTTestDoc("rooms/eros/messages/1", 1, @{@"time" : @1}, FSTDocumentStateLocalMutations);
FSTDocument *doc1Committed =
FSTTestDoc("rooms/eros/messages/1", 2, @{@"time" : @2}, FSTDocumentStateCommittedMutations);
FSTDocument *doc1Acknowledged =
FSTTestDoc("rooms/eros/messages/1", 2, @{@"time" : @2}, FSTDocumentStateSynced);
FSTDocument *doc2 =
FSTTestDoc("rooms/eros/messages/2", 1, @{@"time" : @1}, FSTDocumentStateLocalMutations);
FSTDocument *doc2Modified =
FSTTestDoc("rooms/eros/messages/2", 2, @{@"time" : @3}, FSTDocumentStateLocalMutations);
FSTDocument *doc2Acknowledged =
FSTTestDoc("rooms/eros/messages/2", 2, @{@"time" : @3}, FSTDocumentStateSynced);
2018-11-01 09:44:30 -07:00
FSTView *view = [[FSTView alloc] initWithQuery:query remoteDocuments:DocumentKeySet{}];
FSTViewDocumentChanges *changes =
[view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1, doc2 ])];
FSTViewChange *viewChange = [view applyChangesToDocuments:changes];
2019-03-21 14:48:55 -07:00
XC_ASSERT_THAT(viewChange.snapshot.value().document_changes(),
ElementsAre(DocumentViewChange{doc1, DocumentViewChange::Type::kAdded},
DocumentViewChange{doc2, DocumentViewChange::Type::kAdded}));
2018-11-01 09:44:30 -07:00
changes = [view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1Committed, doc2Modified ])];
viewChange = [view applyChangesToDocuments:changes];
// The 'doc1Committed' update is suppressed
2019-03-21 14:48:55 -07:00
XC_ASSERT_THAT(
viewChange.snapshot.value().document_changes(),
ElementsAre(DocumentViewChange{doc2Modified, DocumentViewChange::Type::kModified}));
2018-11-01 09:44:30 -07:00
changes =
[view computeChangesWithDocuments:FSTTestDocUpdates(@[ doc1Acknowledged, doc2Acknowledged ])];
viewChange = [view applyChangesToDocuments:changes];
2019-03-21 14:48:55 -07:00
XC_ASSERT_THAT(
viewChange.snapshot.value().document_changes(),
ElementsAre(DocumentViewChange{doc1Acknowledged, DocumentViewChange::Type::kModified},
DocumentViewChange{doc2Acknowledged, DocumentViewChange::Type::kMetadata}));
2018-11-01 09:44:30 -07:00
}
2017-10-03 08:55:22 -07:00
@end
NS_ASSUME_NONNULL_END