Example #1
0
        public void SubscribeForObjects_WhenTwoQueriesOverlap_SynchronizesTheUnion()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async() =>
            {
                using (var realm = await GetPartialRealm())
                {
                    await GetSession(realm).WaitForDownloadAsync();

                    Assert.That(realm.All <ObjectB>().Count(), Is.EqualTo(0));
                    Assert.That(realm.All <ObjectA>().Count(), Is.EqualTo(0));

                    var youngerThan3 = await realm.SubscribeToObjectsAsync <ObjectA>("IntValue < 3").Timeout(2000);
                    var range1to6    = await realm.SubscribeToObjectsAsync <ObjectA>("IntValue > 1 AND IntValue < 6").Timeout(2000);

                    Assert.That(youngerThan3.Count(), Is.EqualTo(3));
                    Assert.That(range1to6.Count(), Is.EqualTo(4));

                    Assert.That(youngerThan3.ToArray().All(o => o.IntValue < 3));
                    Assert.That(range1to6.ToArray().All(o => o.IntValue > 1 && o.IntValue < 6));

                    var allInRealm = realm.All <ObjectA>();

                    Assert.That(allInRealm.Count(), Is.EqualTo(6));
                    Assert.That(allInRealm.ToArray().All(o => o.IntValue < 6));
                }
            });
        }
Example #2
0
        public void SubscribeForObjects_SynchronizesOnlyMatchingObjects()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async() =>
            {
                using (var realm = await GetPartialRealm())
                {
                    await GetSession(realm).WaitForDownloadAsync();

                    Assert.That(realm.All <ObjectB>().Count(), Is.EqualTo(0));
                    Assert.That(realm.All <ObjectA>().Count(), Is.EqualTo(0));

                    await realm.SubscribeToObjectsAsync <ObjectA>("IntValue < 5").Timeout(2000);

                    var queriedObjectAs = realm.All <ObjectA>().Where(o => o.IntValue < 5);

                    Assert.That(queriedObjectAs.Count(), Is.EqualTo(5));

                    foreach (var a in queriedObjectAs)
                    {
                        Assert.That(a.IntValue < 5);
                        Assert.That(a.B, Is.Not.Null);
                        Assert.That(a.B.BoolValue, Is.EqualTo(a.IntValue % 2 == 0));
                    }
                }
            });
        }
Example #3
0
        public void SubscribeForObjects_ReturnsExpectedQuery()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async() =>
            {
                using (var realm = await GetPartialRealm())
                {
                    await GetSession(realm).WaitForDownloadAsync();

                    Assert.That(realm.All <ObjectA>().Count(), Is.EqualTo(0));
                    Assert.That(realm.All <ObjectB>().Count(), Is.EqualTo(0));

                    var objectAs = await realm.SubscribeToObjectsAsync <ObjectA>("IntValue < 5").Timeout(2000);

                    Assert.That(objectAs.Count(), Is.EqualTo(5));

                    foreach (var a in objectAs)
                    {
                        Assert.That(a.IntValue < 5);
                        Assert.That(a.B, Is.Not.Null);
                        Assert.That(a.B.BoolValue, Is.EqualTo(a.IntValue % 2 == 0));
                    }
                }
            });
        }
        public void GetInstanceAsync_ShouldDownloadRealm(bool singleTransaction)
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async() =>
            {
                var user = await SyncTestHelpers.GetUserAsync();

                var realmUri = SyncTestHelpers.RealmUri("~/GetInstanceAsync_ShouldDownloadRealm");

                var config      = new FullSyncConfiguration(realmUri, user, Guid.NewGuid().ToString());
                var asyncConfig = new FullSyncConfiguration(realmUri, user, config.DatabasePath + "_async");

                using (var realm = GetRealm(config))
                {
                    AddDummyData(realm, singleTransaction);

                    await GetSession(realm).WaitForUploadAsync();
                }

                using (var asyncRealm = await GetRealmAsync(asyncConfig))
                {
                    Assert.That(asyncRealm.All <IntPrimaryKeyWithValueObject>().Count(), Is.EqualTo(500));
                }
            });
        }
        public void SyncConfiguration_LoggerFactory_Test(LogLevel logLevel)
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async() =>
            {
                var logBuilder = new StringBuilder();

                SyncConfigurationBase.CustomLogger = (message, level) =>
                {
                    logBuilder.AppendLine($"[{level}] {message}");
                };
                SyncConfigurationBase.LogLevel = logLevel;

                var config = await SyncTestHelpers.GetIntegrationConfigAsync(Guid.NewGuid().ToString());
                using (var realm = await GetRealmAsync(config))
                {
                    realm.Write(() =>
                    {
                        realm.Add(new Person());
                    });

                    await GetSession(realm).WaitForUploadAsync();
                }

                var log = logBuilder.ToString();

                Assert.That(log, Does.Contain($"[{logLevel}]"));
                Assert.That(log, Does.Not.Contain($"[{(logLevel - 1)}]"));
            });
        }
        public void PermissionResponse_WhenOfferIsValid_ShouldSetRealmUrl()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async () =>
            {
                var alice = await SyncTestHelpers.GetUserAsync();
                var bob = await SyncTestHelpers.GetUserAsync();

                // Opening a synced realm with just read permission fails.
                // OS issue: https://github.com/realm/realm-object-store/issues/312
                var realmUrl = await GrantPermissions(alice, bob);
                var syncConfig = new SyncConfiguration(bob, new Uri(realmUrl), Guid.NewGuid().ToString());

                Assert.That(() => GetRealm(syncConfig), Throws.Nothing);
                var handler = new EventHandler<ErrorEventArgs>((sender, e) =>
                {
                    Assert.Fail("Opening the realm should not cause an error.", e.Exception);
                });

                Session.Error += handler;

                await Task.Delay(2000);

                Session.Error -= handler;
            });
        }
        public void Test_ObjectDelete()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async() =>
            {
                var userA = await SyncTestHelpers.GetUserAsync();
                var userB = await SyncTestHelpers.GetUserAsync();

                var realmUri = await CreateRealm(r =>
                {
                    var reader = PermissionRole.Get(r, "reader");
                    reader.Users.Add(userA);
                    reader.Users.Add(userB);

                    var writer = PermissionRole.Get(r, "writer");
                    writer.Users.Add(userA);

                    var obj1 = r.Add(new ObjectWithPermissions
                    {
                        Id          = 1,
                        StringValue = "Value 1"
                    });
                    CreatePermissions(obj1.Permissions);
                }, addObjects: false);

                using (var realmA = GetRealm(userA, realmUri))
                    using (var realmB = GetRealm(userB, realmUri))
                    {
                        var subscriptionB = await SubscribeToObjectsAsync(realmB);
                        var objB          = subscriptionB.Results.Single();
                        realmB.Write(() =>
                        {
                            realmB.Remove(objB);
                        });

                        Assert.That(subscriptionB.Results.Count(), Is.Zero);
                        await WaitForSyncAsync(realmB);
                        Assert.That(subscriptionB.Results.Count(), Is.EqualTo(1));
                        objB = subscriptionB.Results.Single();

                        var subscriptionA = await SubscribeToObjectsAsync(realmA);
                        var objA          = subscriptionA.Results.Single();
                        realmA.Write(() =>
                        {
                            realmA.Remove(objA);
                        });

                        await WaitForSyncAsync(realmA);
                        await WaitForSyncAsync(realmB);

                        Assert.That(subscriptionA.Results.Count(), Is.Zero);
                        Assert.That(subscriptionB.Results.Count(), Is.Zero);

                        Assert.That(objA.IsValid, Is.False);
                        Assert.That(objB.IsValid, Is.False);
                    }
            });
        }
Example #8
0
        private async Task <Realm> GetPartialRealm(Action <SyncConfiguration> setupConfig = null, [CallerMemberName] string realmPath = null)
        {
            SyncTestHelpers.RequiresRos();

            var user = await SyncTestHelpers.GetUserAsync();

            var config = new SyncConfiguration(user, SyncTestHelpers.RealmUri($"~/{realmPath}"), Guid.NewGuid().ToString())
            {
                ObjectClasses = new[] { typeof(ObjectA), typeof(ObjectB) },
                IsPartial     = true
            };

            setupConfig?.Invoke(config);

            using (var original = GetRealm(config))
            {
                original.Write(() =>
                {
                    for (var i = 0; i < 10; i++)
                    {
                        original.Add(new ObjectA
                        {
                            StringValue = "A #" + i,
                            IntValue    = i,
                            B           = new ObjectB
                            {
                                StringValue = "B #" + i,
                                BoolValue   = i % 2 == 0,
                            }
                        });
                    }
                });

                await GetSession(original).WaitForUploadAsync();
            }

            try
            {
                Realm.DeleteRealm(config);
            }
            catch
            {
            }

            config = new SyncConfiguration(config.User, config.ServerUri, config.DatabasePath + "_partial")
            {
                ObjectClasses = config.ObjectClasses,
                IsPartial     = true
            };

            var result = GetRealm(config);

            await GetSession(result).WaitForDownloadAsync();

            Assert.That(result.All <ObjectB>().Count(), Is.EqualTo(0));
            Assert.That(result.All <ObjectA>().Count(), Is.EqualTo(0));

            return(result);
        }
        public void Test_ClassUpdate()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async() =>
            {
                var userA = await SyncTestHelpers.GetUserAsync();
                var userB = await SyncTestHelpers.GetUserAsync();

                var realmUri = await CreateRealm(r =>
                {
                    CreatePermissions(ClassPermission.Get <ObjectWithPermissions>(r).Permissions);

                    var reader = PermissionRole.Get(r, "reader");
                    reader.Users.Add(userA);
                    reader.Users.Add(userB);

                    var writer = PermissionRole.Get(r, "writer");
                    writer.Users.Add(userA);
                });

                using (var realm = GetRealm(userA, realmUri))
                {
                    var subscription = await SubscribeToObjectsAsync(realm);
                    AssertRealmPrivileges(realm, RealmPrivileges.Read | RealmPrivileges.Update | RealmPrivileges.ModifySchema | RealmPrivileges.SetPermissions);
                    AssertClassPrivileges(realm, ClassPrivileges.Read | ClassPrivileges.Subscribe | ClassPrivileges.Update | ClassPrivileges.Create);
                    AssertObjectPrivileges(realm, ObjectPrivileges.Read | ObjectPrivileges.Update | ObjectPrivileges.Delete | ObjectPrivileges.SetPermissions);

                    var obj = realm.Find <ObjectWithPermissions>(1);
                    realm.Write(() =>
                    {
                        obj.StringValue = "New value";
                    });

                    await WaitForSyncAsync(realm);
                    Assert.That(obj.StringValue, Is.EqualTo("New value"));
                }

                using (var realm = GetRealm(userB, realmUri))
                {
                    var subscription = await SubscribeToObjectsAsync(realm);
                    AssertRealmPrivileges(realm, RealmPrivileges.Read | RealmPrivileges.Update | RealmPrivileges.ModifySchema | RealmPrivileges.SetPermissions);
                    AssertClassPrivileges(realm, ClassPrivileges.Read | ClassPrivileges.Subscribe);
                    AssertObjectPrivileges(realm, ObjectPrivileges.Read);

                    var obj = realm.Find <ObjectWithPermissions>(1);
                    realm.Write(() =>
                    {
                        obj.StringValue = "New value 2";
                    });

                    Assert.That(obj.StringValue, Is.EqualTo("New value 2"));
                    await WaitForSyncAsync(realm);

                    // Change is reverted
                    Assert.That(obj.StringValue, Is.EqualTo("New value"));
                }
            });
        }
        public void EnableSSLValidation_WhenFalse_ValidatesCorrectly(bool openAsync)
        {
            SyncTestHelpers.RequiresRos();

            TestSSLCore(config =>
            {
                config.EnableSSLValidation = false;
            }, openAsync);
        }
        public void TrustedCA_WhenProvided_ValidatesCorrectly(bool openAsync)
        {
            SyncTestHelpers.RequiresRos();

            TestSSLCore(config =>
            {
                config.TrustedCAPath = TestHelpers.CopyBundledDatabaseToDocuments("trusted_ca.pem", "trusted_ca.pem");
            }, openAsync);
        }
        public void Test_RealmUpdate()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async() =>
            {
                var userA = await SyncTestHelpers.GetUserAsync();
                var userB = await SyncTestHelpers.GetUserAsync();

                var realmUri = await CreateRealm(r =>
                {
                    CreatePermissions(RealmPermission.Get(r).Permissions);
                    var reader = PermissionRole.Get(r, "reader");
                    reader.Users.Add(userA);
                    reader.Users.Add(userB);

                    var writer = PermissionRole.Get(r, "writer");
                    writer.Users.Add(userA);
                });

                using (var realm = GetRealm(userA, realmUri))
                {
                    var subscription = await SubscribeToObjectsAsync(realm);
                    AssertRealmPrivileges(realm, RealmPrivileges.Read | RealmPrivileges.Update);
                    AssertClassPrivileges(realm, ClassPrivileges.Read | ClassPrivileges.Subscribe |
                                          ClassPrivileges.Create | ClassPrivileges.SetPermissions | ClassPrivileges.Update);
                    AssertObjectPrivileges(realm, ObjectPrivileges.Read | ObjectPrivileges.Delete |
                                           ObjectPrivileges.SetPermissions | ObjectPrivileges.Update);

                    Assert.That(subscription.Results.Count(), Is.EqualTo(3));
                    AddObjectsToRealm(realm, new[] { 4, 5, 6 });

                    Assert.That(subscription.Results.Count(), Is.EqualTo(6));

                    await WaitForSyncAsync(realm);
                    Assert.That(subscription.Results.Count(), Is.EqualTo(6));
                }

                using (var realm = GetRealm(userB, realmUri))
                {
                    var subscription = await SubscribeToObjectsAsync(realm);

                    AssertRealmPrivileges(realm, RealmPrivileges.Read);
                    AssertClassPrivileges(realm, ClassPrivileges.Read | ClassPrivileges.Subscribe);
                    AssertObjectPrivileges(realm, ObjectPrivileges.Read);

                    Assert.That(subscription.Results.Count(), Is.EqualTo(6));
                    AddObjectsToRealm(realm, new[] { 7, 8, 9 });

                    Assert.That(subscription.Results.Count(), Is.EqualTo(9));

                    await WaitForSyncAsync(realm);
                    Assert.That(subscription.Results.Count(), Is.EqualTo(6));
                }
            });
        }
        public void Test_ObjectUpdate()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async() =>
            {
                var userA = await SyncTestHelpers.GetUserAsync();
                var userB = await SyncTestHelpers.GetUserAsync();

                var realmUri = await CreateRealm(r =>
                {
                    var reader = PermissionRole.Get(r, "reader");
                    reader.Users.Add(userA);
                    reader.Users.Add(userB);

                    var writer = PermissionRole.Get(r, "writer");
                    writer.Users.Add(userA);

                    var obj1 = r.Add(new ObjectWithPermissions
                    {
                        Id          = 1,
                        StringValue = "Value 1"
                    });
                    CreatePermissions(obj1.Permissions);
                }, addObjects: false);

                using (var realm = GetRealm(userA, realmUri))
                {
                    var subscription = await SubscribeToObjectsAsync(realm);
                    var obj1         = subscription.Results.Single();
                    realm.Write(() =>
                    {
                        obj1.StringValue = "New value";
                    });

                    await WaitForSyncAsync(realm);

                    Assert.That(obj1.StringValue, Is.EqualTo("New value"));
                }

                using (var realm = GetRealm(userB, realmUri))
                {
                    var subscription = await SubscribeToObjectsAsync(realm);
                    var obj1         = subscription.Results.Single();
                    realm.Write(() =>
                    {
                        obj1.StringValue = "New value #2";
                    });

                    Assert.That(obj1.StringValue, Is.EqualTo("New value #2"));
                    await WaitForSyncAsync(realm);

                    Assert.That(obj1.StringValue, Is.EqualTo("New value"));
                }
            });
        }
        public void PermissionChange_IsProcessedByServer()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async () =>
            {
                var user = await SyncTestHelpers.GetUserAsync();
                var permissionChange = await CreateChange(user, "*");
                Assert.That(permissionChange.Status, Is.EqualTo(ManagementObjectStatus.Success));
            });
        }
        public void User_ApplyPermissions_WithUserId_GrantsAndRevokesPermissions()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async () =>
            {
                var alice = await SyncTestHelpers.GetUserAsync();
                var bob = await SyncTestHelpers.GetUserAsync();

                await TestApplyPermissions(alice, bob, PermissionCondition.UserId(bob.Identity)).Timeout(1000000);
            });
        }
Example #16
0
        public void UserLookup_WhenTargetUserDoesNotExist_ShouldReturnNull()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async() =>
            {
                var admin = await User.LoginAsync(SyncTestHelpers.AdminCredentials(), SyncTestHelpers.AuthServerUri);

                var lookupResponse = await admin.RetrieveInfoForUserAsync(Credentials.Provider.UsernamePassword, "something");
                Assert.That(lookupResponse, Is.Null);
            });
        }
        public void PermissionOffer_WhenValid_TokenIsSet()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async () =>
            {
                var user = await SyncTestHelpers.GetUserAsync();
                var permissionOffer = await CreateOffer(user);
                Assert.That(permissionOffer.Status, Is.EqualTo(ManagementObjectStatus.Success));
                Assert.That(permissionOffer.Token, Is.Not.Null);
            });
        }
Example #18
0
        public void UserLogin_WhenAnonymousAndDifferentCredentials_ShouldLoginDifferentUser()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async() =>
            {
                var first  = await User.LoginAsync(Credentials.Anonymous(), SyncTestHelpers.AuthServerUri);
                var second = await User.LoginAsync(Credentials.Anonymous(), SyncTestHelpers.AuthServerUri);

                Assert.That(first.Identity, Is.Not.EqualTo(second.Identity));
                Assert.That(User.AllLoggedIn.Length, Is.EqualTo(2));
            });
        }
        public void PermissionResponse_WhenTokenIsInvalid_ShouldGetError()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async () =>
            {
                var user = await SyncTestHelpers.GetUserAsync();
                var permissionResponse = await CreateResponse(user, "Some string");
                Assert.That(permissionResponse.Status, Is.EqualTo(ManagementObjectStatus.Error));
                Assert.That(permissionResponse.ErrorCode, Is.EqualTo(ErrorCode.InvalidParameters));
                Assert.That(permissionResponse.StatusMessage, Is.Not.Null);
            });
        }
Example #20
0
        public void UserLogin_WhenNickname_LogsUserIn()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async() =>
            {
                var credentials = Credentials.Nickname(Guid.NewGuid().ToString());
                var user        = await User.LoginAsync(credentials, SyncTestHelpers.AuthServerUri);

                Assert.That(user, Is.Not.Null);
                Assert.That(user.Identity, Is.Not.Null);
            });
        }
Example #21
0
        public void UserLogin_WhenAnonymous_LogsUserIn()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async() =>
            {
                var credentials = Credentials.Anonymous();
                var user        = await User.LoginAsync(credentials, SyncTestHelpers.AuthServerUri);

                Assert.That(user, Is.Not.Null);
                Assert.That(user.Identity, Is.Not.Null);
            });
        }
        public void User_ApplyPermissions_WithEmail_GrantsAndRevokesPermissions()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async () =>
            {
                var alice = await SyncTestHelpers.GetUserAsync();
                var bobEmail = $"{Guid.NewGuid()}@foo.bar";
                var bobCredentials = Credentials.UsernamePassword(bobEmail, "a", createUser: true);
                var bob = await User.LoginAsync(bobCredentials, SyncTestHelpers.AuthServerUri);

                await TestApplyPermissions(alice, bob, PermissionCondition.Email(bobEmail)).Timeout(10000);
            });
        }
        public void TrustedCA_WhenFileDoesntExist_Throws()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async () =>
            {
                var user = await SyncTestHelpers.GetUserAsync();
                var config = new FullSyncConfiguration(SyncTestHelpers.RealmUri("~/TrustedCA_WhenFileDoesntExist_Throws"), user)
                {
                    TrustedCAPath = "something.pem"
                };
                Assert.That(() => GetRealm(config), Throws.TypeOf<FileNotFoundException>());
            });
        }
        public void Permission_ValidateWrite()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async () =>
            {
                var alice = await SyncTestHelpers.GetUserAsync();
                var bob = await SyncTestHelpers.GetUserAsync();

                var realmUrl = await GrantPermissions(alice, bob);

                await ValidateWriteAndSync(realmUrl, alice, bob, 1, 2);
            });
        }
        public void PermissionOffer_WhenExpired_ShouldGetError()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async () =>
            {
                var user = await SyncTestHelpers.GetUserAsync();
                var permissionOffer = await CreateOffer(user, expiresAt: DateTimeOffset.UtcNow.AddDays(-1));
                Assert.That(permissionOffer.Status, Is.EqualTo(ManagementObjectStatus.Error));
                Assert.That(permissionOffer.Token, Is.Null);
                Assert.That(permissionOffer.ErrorCode, Is.EqualTo(ErrorCode.ExpiredPermissionOffer));
                Assert.That(permissionOffer.StatusMessage, Is.Not.Null);
            });
        }
        public void User_OfferPermissions_WhenNoAccess_ShouldThrow()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async () =>
            {
                var alice = await SyncTestHelpers.GetUserAsync();

                var realmUrl = SyncTestHelpers.RealmUri($"{alice.Identity}/testPermission").AbsoluteUri;
                EnsureRealmExists(alice, realmUrl);

                await AssertThrows<ArgumentException>(() => alice.OfferPermissionsAsync(realmUrl, AccessLevel.None));
            });
        }
        public void User_AcceptPermissionOffer_WhenTokenIsInvalid_ShouldGetError()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async () =>
            {
                var user = await SyncTestHelpers.GetUserAsync();

                await AssertThrows<PermissionException>(() => user.AcceptPermissionOfferAsync("some string"), ex =>
                {
                    Assert.That(ex.ErrorCode, Is.EqualTo(ErrorCode.InvalidParameters));
                });
            });
        }
Example #28
0
        public void UserLogin_WhenNicknameAfterLogout_LogsSameUserIn()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async() =>
            {
                var nickname = Guid.NewGuid().ToString();
                var first    = await User.LoginAsync(Credentials.Nickname(nickname), SyncTestHelpers.AuthServerUri);
                await first.LogOutAsync();

                var second = await User.LoginAsync(Credentials.Nickname(nickname), SyncTestHelpers.AuthServerUri);

                Assert.That(first.Identity, Is.EqualTo(second.Identity));
            });
        }
        public void Test_RealmRead()
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async() =>
            {
                var userA = await SyncTestHelpers.GetUserAsync();
                var userB = await SyncTestHelpers.GetUserAsync();

                var realmUri = await CreateRealm(r =>
                {
                    CreatePermissions(RealmPermission.Get(r).Permissions);
                    var role = PermissionRole.Get(r, "reader");
                    role.Users.Add(userA);
                });

                using (var realm = GetRealm(userA, realmUri))
                {
                    var query        = realm.All <ObjectWithPermissions>();
                    var subscription = query.Subscribe();
                    await subscription.WaitForSynchronizationAsync().Timeout(2000);

                    AssertRealmPrivileges(realm, RealmPrivileges.Read);
                    AssertClassPrivileges(realm, ClassPrivileges.Read | ClassPrivileges.Subscribe);
                    AssertObjectPrivileges(realm, ObjectPrivileges.Read);

                    Assert.That(subscription.Results.Count(), Is.EqualTo(3));
                    AddObjectsToRealm(realm, new[] { 4, 5, 6 });

                    Assert.That(subscription.Results.Count(), Is.EqualTo(6));

                    await WaitForSyncAsync(realm);
                    Assert.That(subscription.Results.Count(), Is.EqualTo(3));
                }

                using (var realm = GetRealm(userB, realmUri))
                {
                    var query        = realm.All <ObjectWithPermissions>();
                    var subscription = query.Subscribe();
                    await subscription.WaitForSynchronizationAsync().Timeout(2000);

                    AssertRealmPrivileges(realm, 0);
                    AssertClassPrivileges(realm, 0);

                    Assert.That(subscription.Results.Count(), Is.Zero);
                }
            });
        }
        public void GetInstanceAsync_OpensReadonlyRealm(bool singleTransaction)
        {
            SyncTestHelpers.RequiresRos();

            AsyncContext.Run(async() =>
            {
                var alice = await SyncTestHelpers.GetUserAsync();
                var bob   = await SyncTestHelpers.GetUserAsync();

                var realmUri    = SyncTestHelpers.RealmUri($"{alice.Identity}/GetInstanceAsync_OpensReadonlyRealm");
                var aliceConfig = new FullSyncConfiguration(realmUri, alice, Guid.NewGuid().ToString());
                var aliceRealm  = GetRealm(aliceConfig);

                await alice.ApplyPermissionsAsync(PermissionCondition.UserId(bob.Identity), realmUri.AbsoluteUri, AccessLevel.Read).Timeout(1000);

                AddDummyData(aliceRealm, singleTransaction);

                var bobConfig = new FullSyncConfiguration(realmUri, bob, Guid.NewGuid().ToString());
                var bobRealm  = await GetRealmAsync(bobConfig);

                var bobsObjects   = bobRealm.All <IntPrimaryKeyWithValueObject>();
                var alicesObjects = aliceRealm.All <IntPrimaryKeyWithValueObject>();
                Assert.That(bobsObjects.Count(), Is.EqualTo(alicesObjects.Count()));

                var bobTcs = new TaskCompletionSource <object>();
                bobsObjects.AsRealmCollection().CollectionChanged += (sender, e) =>
                {
                    bobTcs.TrySetResult(null);
                };

                aliceRealm.Write(() =>
                {
                    aliceRealm.Add(new IntPrimaryKeyWithValueObject
                    {
                        Id          = 9999,
                        StringValue = "Some value"
                    });
                });

                await bobTcs.Task.Timeout(1000);

                Assert.That(bobsObjects.Count(), Is.EqualTo(alicesObjects.Count()));

                var bobObject = bobRealm.Find <IntPrimaryKeyWithValueObject>(9999);
                Assert.That(bobObject, Is.Not.Null);
                Assert.That(bobObject.StringValue, Is.EqualTo("Some value"));
            });
        }