aboutsummaryrefslogtreecommitdiffhomepage
path: root/Firestore/Example/Tests
diff options
context:
space:
mode:
authorGravatar Michael Lehenbauer <mikelehen@gmail.com>2018-04-16 16:04:26 -0700
committerGravatar GitHub <noreply@github.com>2018-04-16 16:04:26 -0700
commit360e58901c359d7d21da4fff8043894c843427b7 (patch)
tree85c61e3833af53e24dd7f9e61e6fade1586227e1 /Firestore/Example/Tests
parent33701fbc9c34d221fef330c934271a028daea0e5 (diff)
Implement local and server application of arrayUnion and arrayRemove transforms. (#1101)
Diffstat (limited to 'Firestore/Example/Tests')
-rw-r--r--Firestore/Example/Tests/Model/FSTMutationTests.mm144
1 files changed, 143 insertions, 1 deletions
diff --git a/Firestore/Example/Tests/Model/FSTMutationTests.mm b/Firestore/Example/Tests/Model/FSTMutationTests.mm
index 56bf1c2..0bb7518 100644
--- a/Firestore/Example/Tests/Model/FSTMutationTests.mm
+++ b/Firestore/Example/Tests/Model/FSTMutationTests.mm
@@ -185,7 +185,126 @@ using firebase::firestore::model::TransformOperation;
}
}
-- (void)testAppliesServerAckedTransformsToDocuments {
+- (void)testAppliesLocalArrayUnionTransformToMissingField {
+ auto baseDoc = @{};
+ auto transform = @{ @"missing" : [FIRFieldValue fieldValueForArrayUnion:@[ @1, @2 ]] };
+ auto expected = @{ @"missing" : @[ @1, @2 ] };
+ [self transformBaseDoc:baseDoc with:transform expecting:expected];
+}
+
+- (void)testAppliesLocalArrayUnionTransformToNonArrayField {
+ auto baseDoc = @{ @"non-array" : @42 };
+ auto transform = @{ @"non-array" : [FIRFieldValue fieldValueForArrayUnion:@[ @1, @2 ]] };
+ auto expected = @{ @"non-array" : @[ @1, @2 ] };
+ [self transformBaseDoc:baseDoc with:transform expecting:expected];
+}
+
+- (void)testAppliesLocalArrayUnionTransformWithNonExistingElements {
+ auto baseDoc = @{ @"array" : @[ @1, @3 ] };
+ auto transform = @{ @"array" : [FIRFieldValue fieldValueForArrayUnion:@[ @2, @4 ]] };
+ auto expected = @{ @"array" : @[ @1, @3, @2, @4 ] };
+ [self transformBaseDoc:baseDoc with:transform expecting:expected];
+}
+
+- (void)testAppliesLocalArrayUnionTransformWithExistingElements {
+ auto baseDoc = @{ @"array" : @[ @1, @3 ] };
+ auto transform = @{ @"array" : [FIRFieldValue fieldValueForArrayUnion:@[ @1, @3 ]] };
+ auto expected = @{ @"array" : @[ @1, @3 ] };
+ [self transformBaseDoc:baseDoc with:transform expecting:expected];
+}
+
+- (void)testAppliesLocalArrayUnionTransformWithDuplicateExistingElements {
+ // Duplicate entries in your existing array should be preserved.
+ auto baseDoc = @{ @"array" : @[ @1, @2, @2, @3 ] };
+ auto transform = @{ @"array" : [FIRFieldValue fieldValueForArrayUnion:@[ @2 ]] };
+ auto expected = @{ @"array" : @[ @1, @2, @2, @3 ] };
+ [self transformBaseDoc:baseDoc with:transform expecting:expected];
+}
+
+- (void)testAppliesLocalArrayUnionTransformWithDuplicateUnionElements {
+ // Duplicate entries in your union array should only be added once.
+ auto baseDoc = @{ @"array" : @[ @1, @3 ] };
+ auto transform = @{ @"array" : [FIRFieldValue fieldValueForArrayUnion:@[ @2, @2 ]] };
+ auto expected = @{ @"array" : @[ @1, @3, @2 ] };
+ [self transformBaseDoc:baseDoc with:transform expecting:expected];
+}
+
+- (void)testAppliesLocalArrayUnionTransformWithNonPrimitiveElements {
+ // Union nested object values (one existing, one not).
+ auto baseDoc = @{ @"array" : @[ @1, @{@"a" : @"b"} ] };
+ auto transform =
+ @{ @"array" : [FIRFieldValue fieldValueForArrayUnion:@[ @{@"a" : @"b"}, @{@"c" : @"d"} ]] };
+ auto expected = @{ @"array" : @[ @1, @{@"a" : @"b"}, @{@"c" : @"d"} ] };
+ [self transformBaseDoc:baseDoc with:transform expecting:expected];
+}
+
+- (void)testAppliesLocalArrayUnionTransformWithPartiallyOverlappingElements {
+ // Union objects that partially overlap an existing object.
+ auto baseDoc = @{ @"array" : @[ @1, @{@"a" : @"b", @"c" : @"d"} ] };
+ auto transform =
+ @{ @"array" : [FIRFieldValue fieldValueForArrayUnion:@[ @{@"a" : @"b"}, @{@"c" : @"d"} ]] };
+ auto expected =
+ @{ @"array" : @[ @1, @{@"a" : @"b", @"c" : @"d"}, @{@"a" : @"b"}, @{@"c" : @"d"} ] };
+ [self transformBaseDoc:baseDoc with:transform expecting:expected];
+}
+
+- (void)testAppliesLocalArrayRemoveTransformToMissingField {
+ auto baseDoc = @{};
+ auto transform = @{ @"missing" : [FIRFieldValue fieldValueForArrayRemove:@[ @1, @2 ]] };
+ auto expected = @{ @"missing" : @[] };
+ [self transformBaseDoc:baseDoc with:transform expecting:expected];
+}
+
+- (void)testAppliesLocalArrayRemoveTransformToNonArrayField {
+ auto baseDoc = @{ @"non-array" : @42 };
+ auto transform = @{ @"non-array" : [FIRFieldValue fieldValueForArrayRemove:@[ @1, @2 ]] };
+ auto expected = @{ @"non-array" : @[] };
+ [self transformBaseDoc:baseDoc with:transform expecting:expected];
+}
+
+- (void)testAppliesLocalArrayRemoveTransformWithNonExistingElements {
+ auto baseDoc = @{ @"array" : @[ @1, @3 ] };
+ auto transform = @{ @"array" : [FIRFieldValue fieldValueForArrayRemove:@[ @2, @4 ]] };
+ auto expected = @{ @"array" : @[ @1, @3 ] };
+ [self transformBaseDoc:baseDoc with:transform expecting:expected];
+}
+
+- (void)testAppliesLocalArrayRemoveTransformWithExistingElements {
+ auto baseDoc = @{ @"array" : @[ @1, @2, @3, @4 ] };
+ auto transform = @{ @"array" : [FIRFieldValue fieldValueForArrayRemove:@[ @1, @3 ]] };
+ auto expected = @{ @"array" : @[ @2, @4 ] };
+ [self transformBaseDoc:baseDoc with:transform expecting:expected];
+}
+
+- (void)testAppliesLocalArrayRemoveTransformWithNonPrimitiveElements {
+ // Remove nested object values (one existing, one not).
+ auto baseDoc = @{ @"array" : @[ @1, @{@"a" : @"b"} ] };
+ auto transform =
+ @{ @"array" : [FIRFieldValue fieldValueForArrayRemove:@[ @{@"a" : @"b"}, @{@"c" : @"d"} ]] };
+ auto expected = @{ @"array" : @[ @1 ] };
+ [self transformBaseDoc:baseDoc with:transform expecting:expected];
+}
+
+// Helper to test a particular transform scenario.
+- (void)transformBaseDoc:(NSDictionary<NSString *, id> *)baseData
+ with:(NSDictionary<NSString *, id> *)transformData
+ expecting:(NSDictionary<NSString *, id> *)expectedData {
+ FSTDocument *baseDoc = FSTTestDoc("collection/key", 0, baseData, NO);
+
+ FSTMutation *transform = FSTTestTransformMutation(@"collection/key", transformData);
+
+ FSTMaybeDocument *transformedDoc =
+ [transform applyTo:baseDoc baseDocument:baseDoc localWriteTime:_timestamp];
+
+ FSTDocument *expectedDoc = [FSTDocument documentWithData:FSTTestObjectValue(expectedData)
+ key:FSTTestDocKey(@"collection/key")
+ version:FSTTestVersion(0)
+ hasLocalMutations:YES];
+
+ XCTAssertEqualObjects(transformedDoc, expectedDoc);
+}
+
+- (void)testAppliesServerAckedServerTimestampTransformToDocuments {
NSDictionary *docData = @{ @"foo" : @{@"bar" : @"bar-value"}, @"baz" : @"baz-value" };
FSTDocument *baseDoc = FSTTestDoc("collection/key", 0, docData, NO);
@@ -207,6 +326,29 @@ using firebase::firestore::model::TransformOperation;
XCTAssertEqualObjects(transformedDoc, FSTTestDoc("collection/key", 0, expectedData, NO));
}
+- (void)testAppliesServerAckedArrayTransformsToDocuments {
+ NSDictionary *docData = @{ @"array_1" : @[ @1, @2 ], @"array_2" : @[ @"a", @"b" ] };
+ FSTDocument *baseDoc = FSTTestDoc("collection/key", 0, docData, NO);
+
+ FSTMutation *transform = FSTTestTransformMutation(@"collection/key", @{
+ @"array_1" : [FIRFieldValue fieldValueForArrayUnion:@[ @2, @3 ]],
+ @"array_2" : [FIRFieldValue fieldValueForArrayRemove:@[ @"a", @"c" ]]
+ });
+
+ // Server just sends null transform results for array operations.
+ FSTMutationResult *mutationResult = [[FSTMutationResult alloc]
+ initWithVersion:FSTTestVersion(1)
+ transformResults:@[ [FSTNullValue nullValue], [FSTNullValue nullValue] ]];
+
+ FSTMaybeDocument *transformedDoc = [transform applyTo:baseDoc
+ baseDocument:baseDoc
+ localWriteTime:_timestamp
+ mutationResult:mutationResult];
+
+ NSDictionary *expectedData = @{ @"array_1" : @[ @1, @2, @3 ], @"array_2" : @[ @"b" ] };
+ XCTAssertEqualObjects(transformedDoc, FSTTestDoc("collection/key", 0, expectedData, NO));
+}
+
- (void)testDeleteDeletes {
NSDictionary *docData = @{@"foo" : @"bar"};
FSTDocument *baseDoc = FSTTestDoc("collection/key", 0, docData, NO);