diff options
author | Greg Soltis <gsoltis@google.com> | 2018-04-20 13:33:54 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-20 13:33:54 -0700 |
commit | 11b6c014fb8799b8eff1acf795e7d4c366ea029e (patch) | |
tree | 29f19e55a6e4aa9fa4749eca76b30f74a3ec6234 /Firestore/Example | |
parent | eed6e194ba04eb277e3a596f3d4d1c8e4ea6185c (diff) |
Filter out document updates from target association changes (#1122)
* Filter out document updates from target association changes
* Move remote-event-modifying methods onto remote event
* Style
Diffstat (limited to 'Firestore/Example')
-rw-r--r-- | Firestore/Example/Tests/Remote/FSTRemoteEventTests.mm | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/Firestore/Example/Tests/Remote/FSTRemoteEventTests.mm b/Firestore/Example/Tests/Remote/FSTRemoteEventTests.mm index c4800d4..6ac2a6b 100644 --- a/Firestore/Example/Tests/Remote/FSTRemoteEventTests.mm +++ b/Firestore/Example/Tests/Remote/FSTRemoteEventTests.mm @@ -23,10 +23,13 @@ #import "Firestore/Source/Model/FSTDocumentKey.h" #import "Firestore/Source/Remote/FSTExistenceFilter.h" #import "Firestore/Source/Remote/FSTWatchChange.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" #import "Firestore/Example/Tests/Remote/FSTWatchChange+Testing.h" #import "Firestore/Example/Tests/Util/FSTHelpers.h" +using firebase::firestore::model::DocumentKey; + NS_ASSUME_NONNULL_BEGIN @interface FSTRemoteEventTests : XCTestCase @@ -551,6 +554,91 @@ NS_ASSUME_NONNULL_BEGIN XCTAssertEqualObjects(event.targetChanges[@2].resumeToken, resumeToken3); } +- (void)testSynthesizeDeletes { + FSTWatchChange *shouldSynthesize = + [FSTWatchTargetChange changeWithState:FSTWatchTargetChangeStateCurrent targetIDs:@[ @1 ]]; + FSTWatchChange *wrongState = + [FSTWatchTargetChange changeWithState:FSTWatchTargetChangeStateNoChange targetIDs:@[ @2 ]]; + FSTWatchChange *hasDocument = + [FSTWatchTargetChange changeWithState:FSTWatchTargetChangeStateCurrent targetIDs:@[ @3 ]]; + FSTDocument *doc = FSTTestDoc("docs/1", 1, @{ @"value" : @1 }, NO); + FSTWatchChange *docChange = [[FSTDocumentWatchChange alloc] initWithUpdatedTargetIDs:@[ @3 ] + removedTargetIDs:@[] + documentKey:doc.key + document:doc]; + + FSTWatchChangeAggregator *aggregator = + [self aggregatorWithTargets:@[ @1, @2, @3 ] + outstanding:_noPendingResponses + changes:@[ shouldSynthesize, wrongState, hasDocument, docChange ]]; + + FSTRemoteEvent *event = [aggregator remoteEvent]; + DocumentKey synthesized = DocumentKey::FromPathString("docs/2"); + XCTAssertEqual(event.documentUpdates.find(synthesized), event.documentUpdates.end()); + + FSTTargetChange *limboTargetChange = event.targetChanges[@1]; + [event synthesizeDeleteForLimboTargetChange:limboTargetChange key:synthesized]; + FSTDeletedDocument *expected = + [FSTDeletedDocument documentWithKey:synthesized version:event.snapshotVersion]; + XCTAssertEqualObjects(expected, event.documentUpdates.at(synthesized)); + + DocumentKey notSynthesized1 = DocumentKey::FromPathString("docs/no1"); + [event synthesizeDeleteForLimboTargetChange:event.targetChanges[@2] key:notSynthesized1]; + XCTAssertEqual(event.documentUpdates.find(notSynthesized1), event.documentUpdates.end()); + + [event synthesizeDeleteForLimboTargetChange:event.targetChanges[@3] key:doc.key]; + FSTMaybeDocument *docData = event.documentUpdates.at(doc.key); + XCTAssertFalse([docData isKindOfClass:[FSTDeletedDocument class]]); +} + +- (void)testFilterUpdates { + FSTDocument *newDoc = FSTTestDoc("docs/new", 1, @{@"key" : @"value"}, NO); + FSTDocument *existingDoc = FSTTestDoc("docs/existing", 1, @{@"some" : @"data"}, NO); + FSTWatchChange *newDocChange = [[FSTDocumentWatchChange alloc] initWithUpdatedTargetIDs:@[ @1 ] + removedTargetIDs:@[] + documentKey:newDoc.key + document:newDoc]; + + FSTWatchTargetChange *resetTargetChange = + [FSTWatchTargetChange changeWithState:FSTWatchTargetChangeStateReset + targetIDs:@[ @2 ] + resumeToken:_resumeToken1]; + + FSTWatchChange *existingDocChange = + [[FSTDocumentWatchChange alloc] initWithUpdatedTargetIDs:@[ @1, @2 ] + removedTargetIDs:@[] + documentKey:existingDoc.key + document:existingDoc]; + + FSTWatchChangeAggregator *aggregator = + [self aggregatorWithTargets:@[ @1, @2 ] + outstanding:_noPendingResponses + changes:@[ newDocChange, resetTargetChange, existingDocChange ]]; + FSTRemoteEvent *event = [aggregator remoteEvent]; + FSTDocumentKeySet *existingKeys = [[FSTDocumentKeySet keySet] setByAddingObject:existingDoc.key]; + + FSTTargetChange *updateChange = event.targetChanges[@1]; + XCTAssertTrue([updateChange.mapping isKindOfClass:[FSTUpdateMapping class]]); + FSTUpdateMapping *update = (FSTUpdateMapping *)updateChange.mapping; + FSTDocumentKey *existingDocKey = existingDoc.key; + FSTDocumentKey *newDocKey = newDoc.key; + XCTAssertTrue([update.addedDocuments containsObject:existingDocKey]); + + [event filterUpdatesFromTargetChange:updateChange existingDocuments:existingKeys]; + // Now it's been filtered, since it already existed. + XCTAssertFalse([update.addedDocuments containsObject:existingDocKey]); + XCTAssertTrue([update.addedDocuments containsObject:newDocKey]); + + FSTTargetChange *resetChange = event.targetChanges[@2]; + XCTAssertTrue([resetChange.mapping isKindOfClass:[FSTResetMapping class]]); + FSTResetMapping *resetMapping = (FSTResetMapping *)resetChange.mapping; + XCTAssertTrue([resetMapping.documents containsObject:existingDocKey]); + + [event filterUpdatesFromTargetChange:resetChange existingDocuments:existingKeys]; + // Document is still there, even though it already exists. Reset mappings don't get filtered. + XCTAssertTrue([resetMapping.documents containsObject:existingDocKey]); +} + @end NS_ASSUME_NONNULL_END |