public void ObjectDownloadedWhenThereAreLocalChanges_ChangesPreserved()
        {
            var obj = new DbSyncClientObject
            {
                Text = "123",
            };
            var realm = GetRealm();

            realm.Write(() =>
            {
                realm.Add(obj);
            });
            _realmiusSyncService.Realm.Refresh();
            _realmiusSyncService.Realmius.Refresh();

            _apiClientMock.Raise(x => x.NewDataDownloaded += null, _apiClientMock.Object, new DownloadDataResponse()
            {
                ChangedObjects = new List <DownloadResponseItem>
                {
                    new DownloadResponseItem
                    {
                        Type             = nameof(DbSyncClientObject),
                        SerializedObject = "{Text: 'zxc' }",
                        MobilePrimaryKey = obj.MobilePrimaryKey,
                    }
                }
            });
            realm.Refresh();

            var obj2 = realm.Find <DbSyncClientObject>(obj.Id);

            obj2.Text.Should().BeEquivalentTo("123");
        }
        public void AddSkipUpload()
        {
            SetupCorrectUploadResponse();
            var obj = new DbSyncClientObject
            {
                Text = "123",
                Tags = "qwe"
            };
            var realm = GetRealm();

            realm.Write(() =>
            {
                realm.AddSkipUpload(obj);
            });

            _realmiusSyncService.Realm.Refresh();
            _realmiusSyncService.Realmius.Refresh();

            Thread.Sleep(70);
            _uploadDataCounter.Should().Be(0);

            realm.Write(
                () =>
            {
                obj.Text = "zxc";
            });

            _realmiusSyncService.Realm.Refresh();
            _realmiusSyncService.Realmius.Refresh();
            Thread.Sleep(20);

            _uploadDataCounter.Should().Be(1);
            string.Join(", ", _lastUploadRequest.ChangeNotifications).Should().BeEquivalentTo($"Type: DbSyncClientObject, PrimaryKey: {obj.Id}, SerializedObject: {{ \"Text\": \"zxc\"}}");
        }
        public void AddObject_NotSucceeded_Update_UploadDataIsCalled()
        {
            var realm = GetRealm();

            var obj = new DbSyncClientObject
            {
                Text = "zxczxczxc",
            };

            realm.Write(() =>
            {
                realm.Add(obj);
            });
            _realmiusSyncService.Realm.Refresh();
            _realmiusSyncService.Realmius.Refresh();

            _uploadTask.Wait();
            SetupCorrectUploadResponse();
            realm.Write(() =>
            {
                obj.Text = "123";
            });
            _realmiusSyncService.Realm.Refresh();
            _realmiusSyncService.Realmius.Refresh();

            _uploadTask.Wait();

            _lastUploadRequest.Should().NotBeNull("UploadData should be called");
            string.Join(", ", _lastUploadRequest.ChangeNotifications)
            .Should().MatchEquivalentOf($"Type: DbSyncClientObject, PrimaryKey: {obj.Id}, SerializedObject: {{ \"Id\": \"{obj.Id}\", \"Text\": \"123\", \"Tags\": null, \"MobilePrimaryKey\": \"{obj.Id}\"}}");
            _apiClientMock.Verify(x => x.UploadData(It.IsAny <UploadDataRequest>()), Times.AtLeast(2));
        }
        public void TwoObjects_DuplicateKeys()
        {
            var obj = new DbSyncClientObject
            {
                Text = "123",
            };
            var obj2 = new DbSyncClientObject2
            {
                Id   = obj.Id,
                Text = "1234",
            };

            SetupCorrectUploadResponse();

            var realm = GetRealm();

            realm.Write(() =>
            {
                realm.Add(obj);
                realm.Add(obj2);
            });

            _realmiusSyncService.Realm.Refresh();
            _uploadTask.Wait();
            _realmiusSyncService.Realmius.Refresh();
            _uploadTask.Wait();
            //Thread.Sleep(100);

            _apiClientMock.Verify(z => z.UploadData(It.IsAny <UploadDataRequest>()), Times.AtLeastOnce);
            string.Join(", ", _uploadRequests.SelectMany(x => x.ChangeNotifications).Select(x => x.Type + ": " + x.PrimaryKey))
            .Should()
            .MatchEquivalentOf($"DbSyncClientObject: {obj.Id}, DbSyncClientObject2: {obj.Id}");
        }
        public void AddObject_NotConnected_DataNotSent_Connected_DataSent()
        {
            var realm = GetRealm();

            _apiClientMock.SetupGet(x => x.IsConnected).Returns(false);

            var obj = new DbSyncClientObject
            {
                Text = "zxczxczxc",
            };

            realm.Write(() =>
            {
                realm.Add(obj);
            });
            _realmiusSyncService.Realm.Refresh();
            _realmiusSyncService.Realmius.Refresh();

            _uploadTask?.Wait();

            _lastUploadRequest.Should().BeNull("UploadData should not be called, because client is not connected");

            _apiClientMock.SetupGet(x => x.IsConnected).Returns(true);
            _apiClientMock.Raise(x => x.ConnectedStateChanged += null, _apiClientMock.Object, EventArgs.Empty);

            _uploadTask?.Wait();

            _lastUploadRequest.Should().NotBeNull("UploadData should be called after client is connected");


            string.Join(", ", _lastUploadRequest.ChangeNotifications)
            .Should().MatchEquivalentOf($"Type: DbSyncClientObject, PrimaryKey: {obj.Id}, SerializedObject: {{ \"Id\": \"{obj.Id}\", \"Text\": \"zxczxczxc\", \"Tags\": null, \"MobilePrimaryKey\": \"{obj.Id}\"}}");
            _apiClientMock.Verify(x => x.UploadData(It.IsAny <UploadDataRequest>()), Times.Once);
        }
        public void HandleDownloadedData_NewObject_Updated()
        {
            var realm = GetRealm();

            var key = Guid.NewGuid().ToString();
            var obj = new DbSyncClientObject
            {
                Text = "zxczxczxc",
                Id   = key
            };

            _apiClientMock.Raise(x => x.NewDataDownloaded += null, _apiClientMock.Object, new DownloadDataResponse()
            {
                LastChange = new Dictionary <string, DateTimeOffset>()
                {
                    { "all", DateTimeOffset.Now }
                },
                ChangedObjects =
                {
                    new DownloadResponseItem
                    {
                        Type             = nameof(DbSyncClientObject),
                        MobilePrimaryKey = key,
                        SerializedObject = _realmiusSyncService.SerializeObject(obj),
                    }
                }
            });
            _apiClientMock.Raise(x => x.NewDataDownloaded += null, _apiClientMock.Object, new DownloadDataResponse()
            {
                LastChange = new Dictionary <string, DateTimeOffset>()
                {
                    { "all", DateTimeOffset.Now }
                },
                ChangedObjects =
                {
                    new DownloadResponseItem
                    {
                        Type             = nameof(DbSyncClientObject),
                        MobilePrimaryKey = key,
                        SerializedObject = "{ Text: \"qwe\" }",
                    }
                }
            });

            realm.Refresh();
            var obj2 = realm.Find <DbSyncClientObject>(key);

            obj2.Should().NotBeNull();
            obj2.Text.ShouldBeEquivalentTo("qwe");
            obj2.Id.ShouldBeEquivalentTo(key);

            _realmiusSyncService.Realm.Refresh();
            _realmiusSyncService.Realmius.Refresh();

            _apiClientMock.Verify(x => x.UploadData(It.IsAny <UploadDataRequest>()), Times.Never);
        }
        public void AddObject_NotSucceeded_DelayedDataUpload()
        {
            var realm = GetRealm();

            _syncServiceMock.Setup(x => x.StartUploadTask()).Callback(() => { });
            SetupIncorrectUploadResponse();
            _apiClientMock.ResetCalls();
            var obj = new DbSyncClientObject
            {
                Text = "zxczxczxc",
            };

            realm.Write(() =>
            {
                realm.Add(obj);
            });
            _realmiusSyncService.Realm.Refresh();
            _realmiusSyncService.Realmius.Refresh();

            _realmiusSyncService.Upload().Wait();
            _apiClientMock.Verify(x => x.UploadData(It.IsAny <UploadDataRequest>()), Times.Exactly(1));

            _realmiusSyncService.Upload().Wait();
            _apiClientMock.Verify(x => x.UploadData(It.IsAny <UploadDataRequest>()), Times.Exactly(2));

            _realmiusSyncService.Upload().Wait();
            _apiClientMock.Verify(x => x.UploadData(It.IsAny <UploadDataRequest>()), Times.Exactly(3));

            //after 3 attempts upload should be delayed for several seconds
            _realmiusSyncService.Upload().Wait();
            _apiClientMock.Verify(x => x.UploadData(It.IsAny <UploadDataRequest>()), Times.Exactly(3));

            _realmiusSyncService.Upload().Wait();
            _apiClientMock.Verify(x => x.UploadData(It.IsAny <UploadDataRequest>()), Times.Exactly(3));

            var uploadRequestItem = _realmiusSyncService.Realmius.All <UploadRequestItemRealm>().First();

            uploadRequestItem.NextUploadAttemptDate.Should()
            .BeAfter(DateTimeOffset.Now + TimeSpan.FromSeconds(10))
            .And.BeBefore(DateTimeOffset.Now + TimeSpan.FromSeconds(60));

            _realmiusSyncService.Realmius.Write(() =>
            {
                uploadRequestItem.NextUploadAttemptDate = DateTimeOffset.Now;
            });
            _realmiusSyncService.Upload().Wait();
            _apiClientMock.Verify(x => x.UploadData(It.IsAny <UploadDataRequest>()), Times.Exactly(4));
        }
        public void SyncEnabledAfterSomeObjectsWereInsertedInRealm_Modify()
        {
            _realmiusSyncService.Dispose();

            var obj = new DbSyncClientObject
            {
                Text = "123",
            };
            var realm = GetRealm();

            realm.Write(() =>
            {
                realm.Add(obj);
            });

            var syncServiceMock = CreateSyncService();
            var syncService     = syncServiceMock.Object;

            var realm2 = GetRealm();
            var obj2   = realm2.Find <DbSyncClientObject>(obj.Id);

            _lastUploadRequest = null;

            realm2.Write(() =>
            {
                obj2.Text = "456";
                realm2.Add(obj2, true);
            });

            syncService.Realm.Refresh();
            syncService.Realmius.Refresh();
            syncServiceMock.Verify(x => x.ObjectChanged(It.Is <IRealmCollection <RealmObject> >(z => z != null), It.Is <ChangeSet>(z => z != null), It.IsAny <Exception>()), Times.Once);
            _uploadTask.Wait();
            Wait(() => _lastUploadRequest != null);

            _apiClientMock.Verify(z => z.UploadData(It.IsAny <UploadDataRequest>()), Times.Once);
            string.Join(", ", _lastUploadRequest.ChangeNotifications.Select(x => x.SerializedObject))
            .Should()
            .MatchEquivalentOf("{\r\n  \"Id\": \"" + obj.Id + "\",\r\n  \"Text\": \"456\",\r\n  \"Tags\": null,\r\n  \"MobilePrimaryKey\": \"" + obj.Id + "\"\r\n}");
        }
        public void DownloadData_DeleteObject()
        {
            var realm = GetRealm();
            var key   = "1";
            var obj   = new DbSyncClientObject
            {
                Text = "zxczxczxc",
                Id   = key
            };

            realm.Write(
                () =>
                { realm.Add(obj); });

            _apiClientMock.Raise(x => x.NewDataDownloaded += null, _apiClientMock.Object, new DownloadDataResponse
            {
                LastChange = new Dictionary <string, DateTimeOffset>()
                {
                    { "all", DateTimeOffset.Now }
                },
                ChangedObjects =
                {
                    new DownloadResponseItem()
                    {
                        Type             = nameof(DbSyncClientObject),
                        MobilePrimaryKey = obj.Id,
                        IsDeleted        = true,
                        SerializedObject = "",
                    }
                }
            });

            realm.Refresh();

            var obj2 = realm.Find <DbSyncClientObject>(key);

            obj2.Should().BeNull();
        }
        public void AddObject_Succeeded_Update_UploadDataIsCalled()
        {
            var realm = GetRealm();

            var obj = new DbSyncClientObject
            {
                Text = "444",
            };

            SetupCorrectUploadResponse();

            realm.Write(() =>
            {
                realm.Add(obj);
            });
            _realmiusSyncService.Realm.Refresh();
            _realmiusSyncService.Realmius.Refresh();

            _uploadTask.Wait();

            _uploadTask.Wait();
            _uploadTask        = null;
            _lastUploadRequest = null;
            Console.WriteLine("Before update");
            realm.Write(() =>
            {
                obj.Text = "555";
            });
            _realmiusSyncService.Realm.Refresh();
            _realmiusSyncService.Realmius.Refresh();

            Wait(() => _lastUploadRequest != null);

            _lastUploadRequest.Should().NotBeNull("UploadData should be called");
            string.Join(", ", _lastUploadRequest.ChangeNotifications)
            .Should().MatchEquivalentOf($"Type: DbSyncClientObject, PrimaryKey: {obj.Id}, SerializedObject: {{ \"Text\": \"555\"}}");
            _apiClientMock.Verify(x => x.UploadData(It.IsAny <UploadDataRequest>()), Times.AtLeast(2));
        }
        public void DeleteObject()
        {
            SetupCorrectUploadResponse();
            var obj = new DbSyncClientObject
            {
                Text = "123",
                Tags = "qwe"
            };
            var realm = GetRealm();

            realm.Write(() =>
            {
                realm.Add(obj);
            });
            _realmiusSyncService.Realm.Refresh();
            _realmiusSyncService.Realmius.Refresh();
            _uploadTask?.Wait();
            _uploadTask?.Wait();
            _uploadDataCounter = 0;

            var id = obj.Id;

            realm.Write(
                () =>
            {
                realm.RemoveAndSync(obj);
            });
            _uploadTask.Wait();

            _realmiusSyncService.Realm.Refresh();
            _realmiusSyncService.Realmius.Refresh();
            _uploadTask.Wait();

            _uploadDataCounter.Should().Be(1);

            string.Join(", ", _lastUploadRequest.ChangeNotifications).Should().BeEquivalentTo($"Type: DbSyncClientObject, PrimaryKey: {id}, Deleted");
        }