public void Session_ProgressObservable_WhenModeIsForOutstandingWork_CallsOnCompleted()
        {
            AsyncContext.Run(async() =>
            {
                var realm   = await SyncTestHelpers.GetFakeRealm(isUserAdmin: true);
                var session = realm.GetSession();

                session.SimulateProgress(0, 100, 0, 0);

                var observable = session.GetProgressObservable(ProgressDirection.Download, ProgressMode.ForCurrentlyOutstandingWork);

                var task = Task.Run(() =>
                {
                    return(observable.Wait());
                });

                session.SimulateProgress(50, 100, 0, 0);

                await Task.Delay(50);

                session.SimulateProgress(100, 100, 0, 0);

                var progress = await task.Timeout(500);

                Assert.That(progress.TransferredBytes, Is.EqualTo(100));
                Assert.That(progress.TransferableBytes, Is.EqualTo(100));
            });
        }
        public void Session_Error_WhenInvalidAccessToken()
        {
            AsyncContext.Run(async() =>
            {
                var errors = new List <Exception>();
                using (var realm = await SyncTestHelpers.GetFakeRealm(isUserAdmin: true))
                {
                    EventHandler <Realms.ErrorEventArgs> handler = null;
                    handler = new EventHandler <Realms.ErrorEventArgs>((sender, e) =>
                    {
                        errors.Add(e.Exception);
                    });

                    Session.Error += handler;

                    while (!errors.Any())
                    {
                        await Task.Yield();
                    }

                    Session.Error -= handler;

                    var sessionErrors = errors.OfType <SessionException>().ToArray();
                    Assert.That(sessionErrors.Count, Is.EqualTo(1));
                    Assert.That(sessionErrors[0].ErrorCode, Is.EqualTo(ErrorCode.BadUserAuthentication));
                }
            });
        }
        public void Session_RXThrottleTests()
        {
            AsyncContext.Run(async() =>
            {
                const int ThrottleInterval = 100; // In ms
                const int SafeDelay        = 2 * ThrottleInterval;

                var realm   = await SyncTestHelpers.GetFakeRealm(isUserAdmin: true);
                var session = realm.GetSession();

                var callbacksInvoked = 0;

                var uploadProgress = session.GetProgressObservable(ProgressDirection.Download, ProgressMode.ReportIndefinitely);

                session.SimulateProgress(0, 100, 0, 0);

                var token = uploadProgress.Throttle(TimeSpan.FromMilliseconds(ThrottleInterval))
                            .Subscribe(p =>
                {
                    callbacksInvoked++;
                    Console.WriteLine(p.TransferableBytes);
                });

                await Task.Delay(SafeDelay);
                Assert.That(callbacksInvoked, Is.EqualTo(1));

                for (ulong i = 0; i < 10; i++)
                {
                    session.SimulateProgress(i, 100, 0, 0);
                }

                await Task.Delay(SafeDelay);
                Assert.That(callbacksInvoked, Is.EqualTo(2));

                for (ulong i = 10; i < 20; i++)
                {
                    session.SimulateProgress(i, 100, 0, 0);
                    await Task.Delay(ThrottleInterval / 10);
                }

                Assert.That(callbacksInvoked, Is.EqualTo(2));
                await Task.Delay(SafeDelay);
                Assert.That(callbacksInvoked, Is.EqualTo(3));

                for (ulong i = 20; i < 25; i++)
                {
                    session.SimulateProgress(i, 100, 0, 0);
                    await Task.Delay(SafeDelay);
                }

                Assert.That(callbacksInvoked, Is.EqualTo(8));

                token.Dispose();
                realm.Dispose();
                Realm.DeleteRealm(realm.Config);
            });
        }
        public void Session_RXCombineLatestTests()
        {
            AsyncContext.Run(async() =>
            {
                var realm   = await SyncTestHelpers.GetFakeRealm(isUserAdmin: true);
                var session = realm.GetSession();

                var callbacksInvoked = 0;
                var completionTCS    = new TaskCompletionSource <ulong>();

                var uploadProgress   = session.GetProgressObservable(ProgressDirection.Upload, ProgressMode.ReportIndefinitely);
                var downloadProgress = session.GetProgressObservable(ProgressDirection.Download, ProgressMode.ReportIndefinitely);

                session.SimulateProgress(0, 100, 0, 100);
                var token = uploadProgress.CombineLatest(downloadProgress, (upload, download) =>
                {
                    return(new
                    {
                        TotalTransferred = upload.TransferredBytes + download.TransferredBytes,
                        TotalTransferable = upload.TransferableBytes + download.TransferableBytes
                    });
                })
                            .Subscribe(progress =>
                {
                    callbacksInvoked++;
                    if (progress.TotalTransferred == progress.TotalTransferable)
                    {
                        completionTCS.TrySetResult(progress.TotalTransferred);
                    }
                });

                await Task.Delay(50);
                session.SimulateProgress(50, 100, 0, 100);

                await Task.Delay(50);
                session.SimulateProgress(100, 100, 0, 100);

                await Task.Delay(50);
                session.SimulateProgress(100, 150, 0, 100);

                await Task.Delay(50);
                session.SimulateProgress(100, 150, 100, 100);

                await Task.Delay(50);
                session.SimulateProgress(150, 150, 100, 100);

                var totalTransferred = await completionTCS.Task;

                Assert.That(callbacksInvoked, Is.GreaterThanOrEqualTo(6));
                Assert.That(totalTransferred, Is.EqualTo(250));

                token.Dispose();
                realm.Dispose();
                Realm.DeleteRealm(realm.Config);
            });
        }
 public void Realm_GetSession_ShouldReturnSameObject()
 {
     AsyncContext.Run(async() =>
     {
         using (var realm = await SyncTestHelpers.GetFakeRealm(isUserAdmin: true))
         {
             var session1 = realm.GetSession();
             var session2 = realm.GetSession();
             Assert.That(session1, Is.EqualTo(session2));
             Assert.That(session1.GetHashCode(), Is.EqualTo(session2.GetHashCode()));
         }
     });
 }
        public void Session_GetUser_WhenInvalidSession_ShouldNotThrow()
        {
            AsyncContext.Run(async() =>
            {
                var realm   = await SyncTestHelpers.GetFakeRealm(isUserAdmin: false);
                var session = realm.GetSession();
                session.SimulateError(ErrorCode.BadUserAuthentication, "some error", isFatal: true);

                while (session.State != SessionState.Invalid)
                {
                    await Task.Delay(100);
                }

                Assert.That(() => session.User, Is.Null);
            });
        }
        public void Session_Error_ShouldPassCorrectSession()
        {
            AsyncContext.Run(async() =>
            {
                var realm = await SyncTestHelpers.GetFakeRealm(isUserAdmin: true);

                var session          = realm.GetSession();
                const ErrorCode code = (ErrorCode)102;
                const string message = "Some fake error has occurred";

                var result = await SyncTestHelpers.SimulateSessionError <SessionException>(session, code, message);

                var error = result.Item2;
                Assert.That(error.Message, Is.EqualTo(message));
                Assert.That(error.ErrorCode, Is.EqualTo(code));

                var errorSession = result.Item1;
                Assert.That(errorSession.ServerUri, Is.EqualTo(((SyncConfiguration)realm.Config).ServerUri));

                realm.Dispose();
                Realm.DeleteRealm(realm.Config);
            });
        }
        public void Session_DivergingHistories_ShouldRaiseClientResetException()
        {
            AsyncContext.Run(async() =>
            {
                var realm   = await SyncTestHelpers.GetFakeRealm(isUserAdmin: true);
                var session = realm.GetSession();
                var result  = await SyncTestHelpers.SimulateSessionError <ClientResetException>(session,
                                                                                                ErrorCode.DivergingHistories,
                                                                                                "Fake client reset is required");

                var error = result.Item2;
                Assert.That(error.BackupFilePath, Is.Not.Null);
                Assert.That(error.BackupFilePath, Does.Contain("io.realm.object-server-recovered-realms/recovered_realm"));
                Assert.That(File.Exists(error.BackupFilePath), Is.False);

                realm.Dispose();

                var clientResetSuccess = error.InitiateClientReset();

                Assert.That(clientResetSuccess, Is.True);
                Assert.That(File.Exists(error.BackupFilePath), Is.True);
            });
        }
        public void Session_ProgressObservable_UnitTests(ProgressDirection direction, ProgressMode mode)
        {
            AsyncContext.Run(async() =>
            {
                var callbacksInvoked = 0;
                var completionTCS    = new TaskCompletionSource <ulong>();

                var realm   = await SyncTestHelpers.GetFakeRealm(isUserAdmin: true);
                var session = realm.GetSession();

                session.SimulateProgress(0, 100, 0, 100);

                var observable = session.GetProgressObservable(direction, mode);
                var token      = observable.Subscribe(p =>
                {
                    try
                    {
                        callbacksInvoked++;

                        Assert.That(p.TransferredBytes, Is.LessThanOrEqualTo(p.TransferableBytes));

                        if (mode == ProgressMode.ForCurrentlyOutstandingWork)
                        {
                            Assert.That(p.TransferableBytes, Is.EqualTo(100));
                        }
                    }
                    catch (Exception e)
                    {
                        completionTCS.TrySetException(e);
                    }

                    if (p.TransferredBytes == p.TransferableBytes)
                    {
                        completionTCS.TrySetResult(p.TransferredBytes);
                    }
                });

                session.SimulateProgress(50, 150, 50, 150);
                await Task.Delay(50);

                session.SimulateProgress(100, 200, 100, 200);
                await Task.Delay(50);

                session.SimulateProgress(150, 200, 150, 200);
                await Task.Delay(50);

                session.SimulateProgress(200, 200, 200, 200);
                await Task.Delay(50);

                var totalTransferred = await completionTCS.Task;

                if (mode == ProgressMode.ForCurrentlyOutstandingWork)
                {
                    Assert.That(totalTransferred, Is.EqualTo(100));
                    Assert.That(callbacksInvoked, Is.EqualTo(3));
                }
                else
                {
                    Assert.That(totalTransferred, Is.EqualTo(200));
                    Assert.That(callbacksInvoked, Is.EqualTo(5));
                }

                token.Dispose();
                realm.Dispose();
                Realm.DeleteRealm(realm.Config);
            });
        }