in database/testapp/Assets/Firebase/Sample/Database/UIHandlerAutomated.cs [2001:2159]
Task TestOnDisconnect() {
return Task.Run(() => {
// This test queues many OnDisconnect actions, then goes offline and validates that they ran.
// It will also validate that they did not run before going offline and that they don't
// run a second time if we go offline again.
// Long list of constants:
string childKey = "ChildKey";
string cancelDirectChild = "Cancel";
string cancelParentChild = "CancelParentChild";
string cancelParentParent = "CancelParent";
string cancelValue = "CancelValue";
string removeValueChild = "RemoveValue";
string removeValueValue = "RemoveValueValue";
string setValueChild = "SetValue";
string setValueValue = "SetValueValue";
string setValueAndStringPriorityChild = "SetValueAndStringPriority";
string setValueAndStringValue = "SetValueAndStringPriorityValue";
string setValueAndStringPriority = "SetValueAndStringPriority";
string setValueAndDoublePriorityChild = "SetValueAndDoublePriority";
string setValueAndDoubleValue = "SetValueAndDoublePriorityValue";
double setValueAndDoublePriority = 3.14d;
string updateChildrenChild = "UpdateChildren";
Dictionary<string, object> initialValue = new Dictionary<string, object>();
initialValue["stay"] = "This should be unchanged";
initialValue["change"] = "This should change";
initialValue["remove"] = "This should be removed";
Dictionary<string, object> change = new Dictionary<string, object>();
change["new"] = "This is new";
change["change"] = "This is changed";
change["remove"] = null; // setting it to null removes the child
// "stay" is not mentioned and should therefore stay the same
Dictionary<string, object> expectedValue = new Dictionary<string, object>();
expectedValue["stay"] = "This should be unchanged";
expectedValue["new"] = "This is new";
expectedValue["change"] = "This is changed";
// End of the long list of constants
// We use Push to create a random child to not interfere with someone else running this test.
var parent = database.RootReference.Child("TestTree").Push();
try {
var r = parent.Child(childKey);
// 1. Queue lots of OnDisconnect stuff
WaitAndAssertCompleted("OnDisconnect.RemoveValue",
r.Child(removeValueChild).OnDisconnect().RemoveValue());
// Queue something, then cancel it.
WaitAndAssertCompleted("OnDisconnect.RemoveValue",
r.Child(cancelDirectChild).OnDisconnect().RemoveValue());
WaitAndAssertCompleted("OnDisconnect.Cancel",
r.Child(cancelDirectChild).OnDisconnect().Cancel());
WaitAndAssertCompleted("OnDisconnect.RemoveValue",
r.Child(cancelParentParent).Child(cancelParentChild).OnDisconnect().RemoveValue());
// Cancelling at the parent level also cancels actions for child nodes:
WaitAndAssertCompleted("OnDisconnect.Cancel",
r.Child(cancelParentParent).OnDisconnect().Cancel());
WaitAndAssertCompleted("OnDisconnect.SetValue",
r.Child(setValueChild).OnDisconnect().SetValue(setValueValue));
WaitAndAssertCompleted("OnDisconnect.SetValueAndPriority",
r.Child(setValueAndStringPriorityChild).OnDisconnect().
SetValue(setValueAndStringValue, setValueAndStringPriority));
WaitAndAssertCompleted("OnDisconnect.SetValueAndPriority",
r.Child(setValueAndDoublePriorityChild).OnDisconnect().
SetValue(setValueAndDoubleValue, setValueAndDoublePriority));
WaitAndAssertCompleted("OnDisconnect.UpdateChildren",
r.Child(updateChildrenChild).OnDisconnect().UpdateChildren(change));
// 2. Set pre-existing values
// (We intentionally do that AFTER queueing the OnDisconnect actions.)
WaitAndAssertCompleted("RemoveValue", r.RemoveValueAsync());
WaitAndAssertCompleted("SetValue", r.Child(cancelDirectChild).SetValueAsync(cancelValue));
WaitAndAssertCompleted("SetValue",
r.Child(cancelParentParent).Child(cancelParentChild).SetValueAsync(cancelValue));
WaitAndAssertCompleted("SetValue", r.Child(removeValueChild).SetValueAsync(removeValueValue));
WaitAndAssertCompleted("SetValue", r.Child(updateChildrenChild).SetValueAsync(initialValue));
// 3. Some asserts that things have not run yet:
Task<DataSnapshot> t;
t = r.GetValueAsync();
WaitAndAssertCompleted("GetValue", t);
AssertEq("Number of children before offline", 4, t.Result.ChildrenCount);
Assert("To be removed child still there", t.Result.HasChild(removeValueChild));
// GoOffline to trigger the OnDisconnect actions
database.GoOffline();
database.GoOnline();
// Validate that everything is as expexted
t = r.GetValueAsync();
WaitAndAssertCompleted("GetValue", t);
AssertEq("Number of children", 6, t.Result.ChildrenCount);
Assert("Cancel child exists", t.Result.HasChild(cancelDirectChild));
AssertEq("Cancel child unchanged", t.Result.Child(cancelDirectChild).Value, cancelValue);
Assert("Cancel parent child exists",
t.Result.HasChild(cancelParentParent) &&
t.Result.Child(cancelParentParent).HasChild(cancelParentChild));
AssertEq("Cancel parent child unchanged",
t.Result.Child(cancelParentParent).Child(cancelParentChild).Value, cancelValue);
Assert("Removed child does not exist", !t.Result.HasChild(removeValueChild));
AssertEq("SetValue value", t.Result.Child(setValueChild).Value, setValueValue);
AssertEq("SetValue priority", t.Result.Child(setValueChild).Priority, null);
AssertEq("SetValueAndStringPriority value",
t.Result.Child(setValueAndStringPriorityChild).Value, setValueAndStringValue);
AssertEq("SetValueAndStringPriority priority",
t.Result.Child(setValueAndStringPriorityChild).Priority, setValueAndStringPriority);
AssertEq("SetValueAndDoublePriority value",
t.Result.Child(setValueAndDoublePriorityChild).Value, setValueAndDoubleValue);
AssertEq("SetValueAndDoublePriority priority",
t.Result.Child(setValueAndDoublePriorityChild).Priority, setValueAndDoublePriority);
Assert("UpdateChildren value as expected",
EqualContent(t.Result.Child(updateChildrenChild).Value, expectedValue));
// Redo everything, to check that OnDisconnect actions are only run once.
WaitAndAssertCompleted("RemoveValue", r.RemoveValueAsync());
WaitAndAssertCompleted("SetValue", r.Child(cancelDirectChild).SetValueAsync(cancelValue));
WaitAndAssertCompleted("SetValue",
r.Child(cancelParentParent).Child(cancelParentChild).SetValueAsync(cancelValue));
WaitAndAssertCompleted("SetValue", r.Child(removeValueChild).SetValueAsync(removeValueValue));
WaitAndAssertCompleted("SetValue", r.Child(updateChildrenChild).SetValueAsync(initialValue));
t = r.GetValueAsync();
WaitAndAssertCompleted("GetValue", t);
AssertEq("Number of children before offline", 4, t.Result.ChildrenCount);
Assert("To be removed child still there", t.Result.HasChild(removeValueChild));
// GoOffline again (this time, there should be no OnDisconnect actions)
database.GoOffline();
database.GoOnline();
// This time, the state should not have changed
t = r.GetValueAsync();
WaitAndAssertCompleted("GetValue", t);
AssertEq("Number of children before offline", 4, t.Result.ChildrenCount);
Assert("To be removed child still there", t.Result.HasChild(removeValueChild));
} finally {
// Finally, cleanup, as to not pollute the test database
parent.RemoveValueAsync();
}
});
}