diff --git a/Tests/Realm.Tests/Database/NotificationTests.cs b/Tests/Realm.Tests/Database/NotificationTests.cs index 91d9796220..a1f7eee2ca 100644 --- a/Tests/Realm.Tests/Database/NotificationTests.cs +++ b/Tests/Realm.Tests/Database/NotificationTests.cs @@ -77,6 +77,53 @@ public void ResultsShouldSendNotifications() } } + [Test] + public void Results_WhenEmbeddedObjectIsModified_Notifies() + { + var query = _realm.All(); + var actualChanges = new List(); + void OnNotification(IRealmCollection collection, ChangeSet? changes) => actualChanges.Add(changes); + + Assert.That(query.Count, Is.EqualTo(0)); + + using (query.SubscribeForNotifications(OnNotification)) + { + _realm.Refresh(); + + // Notification from subscribing. + Assert.That(actualChanges.Count, Is.EqualTo(1)); + + var testObject = _realm.Write(() => _realm.Add(new TestNotificationObject())); + + _realm.Refresh(); + Assert.That(actualChanges.Count, Is.EqualTo(2)); + Assert.That(actualChanges[1], Is.Not.Null); + Assert.That(actualChanges[1]!.InsertedIndices, Is.EquivalentTo(new[] { 0 })); + + _realm.Write(() => + { + testObject.EmbeddedObject = new EmbeddedIntPropertyObject { Int = 1 }; + }); + + _realm.Refresh(); + Assert.That(actualChanges.Count, Is.EqualTo(3)); + Assert.That(actualChanges[2], Is.Not.Null); + Assert.That(actualChanges[2]!.NewModifiedIndices, Is.EquivalentTo(new[] { 0 })); + Assert.That(actualChanges[2]!.ModifiedIndices, Is.EquivalentTo(new[] { 0 })); + + _realm.Write(() => + { + testObject.EmbeddedObject!.Int++; + }); + + _realm.Refresh(); + Assert.That(actualChanges.Count, Is.EqualTo(4)); + Assert.That(actualChanges[3], Is.Not.Null); + Assert.That(actualChanges[3]!.NewModifiedIndices, Is.EquivalentTo(new[] { 0 })); + Assert.That(actualChanges[3]!.ModifiedIndices, Is.EquivalentTo(new[] { 0 })); + } + } + [Test] public void ListShouldSendNotifications() { diff --git a/Tests/Realm.Tests/Database/TestNotificationObject.cs b/Tests/Realm.Tests/Database/TestNotificationObject.cs index 27db9ab08b..7d5d7fa6e4 100644 --- a/Tests/Realm.Tests/Database/TestNotificationObject.cs +++ b/Tests/Realm.Tests/Database/TestNotificationObject.cs @@ -58,5 +58,7 @@ public partial class TestNotificationObject : TestRealmObject [Backlink(nameof(LinkSameType))] public IQueryable Backlink { get; } = null!; + + public EmbeddedIntPropertyObject? EmbeddedObject { get; set; } } } diff --git a/Tests/Realm.Tests/Generated/Realm.SourceGenerator/Realms.SourceGenerator.RealmGenerator/TestNotificationObject_generated.cs b/Tests/Realm.Tests/Generated/Realm.SourceGenerator/Realms.SourceGenerator.RealmGenerator/TestNotificationObject_generated.cs index 9575cfa3dd..ccc3241185 100644 --- a/Tests/Realm.Tests/Generated/Realm.SourceGenerator/Realms.SourceGenerator.RealmGenerator/TestNotificationObject_generated.cs +++ b/Tests/Realm.Tests/Generated/Realm.SourceGenerator/Realms.SourceGenerator.RealmGenerator/TestNotificationObject_generated.cs @@ -50,6 +50,7 @@ static TestNotificationObject() Realms.Schema.Property.Object("LinkDifferentType", "Person", managedName: "LinkDifferentType"), Realms.Schema.Property.Object("LinkAnotherType", "Owner", managedName: "LinkAnotherType"), Realms.Schema.Property.Backlinks("Backlink", "TestNotificationObject", "LinkSameType", managedName: "Backlink"), + Realms.Schema.Property.Object("EmbeddedObject", "EmbeddedIntPropertyObject", managedName: "EmbeddedObject"), }.Build(); #region IRealmObject implementation @@ -141,6 +142,7 @@ void ISettableManagedAccessor.SetManagedAccessor(Realms.IRealmAccessor managedAc newAccessor.Realm.Add(oldAccessor.LinkAnotherType, update); } newAccessor.LinkAnotherType = oldAccessor.LinkAnotherType; + newAccessor.EmbeddedObject = oldAccessor.EmbeddedObject; } if (_propertyChanged != null) @@ -342,6 +344,8 @@ internal interface ITestNotificationObjectAccessor : Realms.IRealmAccessor Realms.Tests.Owner? LinkAnotherType { get; set; } System.Linq.IQueryable Backlink { get; } + + Realms.Tests.EmbeddedIntPropertyObject? EmbeddedObject { get; set; } } [EditorBrowsable(EditorBrowsableState.Never), Realms.Preserve(AllMembers = true)] @@ -516,6 +520,12 @@ public System.Linq.IQueryable Back return _backlink; } } + + public Realms.Tests.EmbeddedIntPropertyObject? EmbeddedObject + { + get => (Realms.Tests.EmbeddedIntPropertyObject?)GetValue("EmbeddedObject"); + set => SetValue("EmbeddedObject", value); + } } [EditorBrowsable(EditorBrowsableState.Never), Realms.Preserve(AllMembers = true)] @@ -598,6 +608,17 @@ public Realms.Tests.Owner? LinkAnotherType public System.Linq.IQueryable Backlink => throw new NotSupportedException("Using backlinks is only possible for managed(persisted) objects."); + private Realms.Tests.EmbeddedIntPropertyObject? _embeddedObject; + public Realms.Tests.EmbeddedIntPropertyObject? EmbeddedObject + { + get => _embeddedObject; + set + { + _embeddedObject = value; + RaisePropertyChanged("EmbeddedObject"); + } + } + public TestNotificationObjectUnmanagedAccessor(Type objectType) : base(objectType) { } @@ -612,6 +633,7 @@ public override Realms.RealmValue GetValue(string propertyName) "LinkDifferentType" => _linkDifferentType, "LinkAnotherType" => _linkAnotherType, "Backlink" => throw new NotSupportedException("Using backlinks is only possible for managed(persisted) objects."), + "EmbeddedObject" => _embeddedObject, _ => throw new MissingMemberException($"The object does not have a gettable Realm property with name {propertyName}"), }; } @@ -635,6 +657,9 @@ public override void SetValue(string propertyName, Realms.RealmValue val) case "LinkAnotherType": LinkAnotherType = (Realms.Tests.Owner?)val; return; + case "EmbeddedObject": + EmbeddedObject = (Realms.Tests.EmbeddedIntPropertyObject?)val; + return; default: throw new MissingMemberException($"The object does not have a settable Realm property with name {propertyName}"); } @@ -702,6 +727,7 @@ protected override void SerializeValue(MongoDB.Bson.Serialization.BsonSerializat WriteDictionary(context, args, "DictionaryRemappedType", value.DictionaryRemappedType); WriteValue(context, args, "LinkDifferentType", value.LinkDifferentType); WriteValue(context, args, "LinkAnotherType", value.LinkAnotherType); + WriteValue(context, args, "EmbeddedObject", value.EmbeddedObject); context.Writer.WriteEndDocument(); } @@ -727,6 +753,9 @@ protected override void ReadValue(TestNotificationObject instance, string name, case "LinkAnotherType": instance.LinkAnotherType = Realms.Serialization.RealmObjectSerializer.LookupSerializer()!.DeserializeById(context); break; + case "EmbeddedObject": + instance.EmbeddedObject = BsonSerializer.LookupSerializer().Deserialize(context); + break; case "ListSameType": case "SetSameType": case "ListDifferentType":