public void DetectAutoSaveCollections() { // Arrange var resource = new ReferenceResource(); // Act ResourceReferenceTools.InitializeCollections(resource); var autosave = ResourceReferenceTools.GetAutoSaveCollections(resource); Assert.AreEqual(1, autosave.Count); // Validate event raised on modification var overrideAutosave = autosave.First(); ReferenceCollectionChangedEventArgs eventArgs = null; overrideAutosave.CollectionChanged += (sender, args) => eventArgs = args; resource.ChildReferences.Add(new DerivedResource { Id = 42 }); // Assert Assert.NotNull(eventArgs); Assert.AreEqual(resource, eventArgs.Parent); Assert.AreEqual(nameof(Resource.Children), eventArgs.CollectionProperty.Name); }
public void SetReferenceCollection() { // Arrange var resource = new ReferenceResource(); // Act ResourceReferenceTools.InitializeCollections(resource); // Assert Assert.NotNull(resource.References); Assert.NotNull(resource.ChildReferences); }
public void LinkResource() { // Arrange var instance = new ReferenceResource { Id = 1 }; _graph[1] = new ResourceWrapper(instance); _graph[2] = new ResourceWrapper(new SimpleResource { Id = 2, Name = "Ref1" }); _graph[3] = new ResourceWrapper(new SimpleResource { Id = 3, Name = "Pos1" }); _graph[4] = new ResourceWrapper(new DerivedResource { Id = 4, Name = "Ref2" }); _graph[5] = new ResourceWrapper(new DerivedResource { Id = 5, Name = "ChildOnly" }); _graph[6] = new ResourceWrapper(new DerivedResource { Id = 6, Name = "BackRef" }); var relations = new List <ResourceRelationAccessor> { // All Parent-Child relations RelationAccessor(2), RelationAccessor(3), RelationAccessor(4), RelationAccessor(5), RelationAccessor(6, ResourceRelationType.ParentChild, ResourceReferenceRole.Source), // All PossibleExchangeablePart relations RelationAccessor(2, ResourceRelationType.PossibleExchangablePart), RelationAccessor(3, ResourceRelationType.PossibleExchangablePart), RelationAccessor(4, ResourceRelationType.PossibleExchangablePart), // The 2 CurrentExchangeablePart RelationAccessor(2, ResourceRelationType.CurrentExchangablePart, ResourceReferenceRole.Target, nameof(ReferenceResource.Reference)), RelationAccessor(4, ResourceRelationType.CurrentExchangablePart), }; // Act ResourceReferenceTools.InitializeCollections(instance); _linker.LinkReferences(instance, relations); // Assert Assert.NotNull(instance.Parent, "Parent reference not set"); Assert.NotNull(instance.Reference, "Named reference not set"); Assert.NotNull(instance.Reference2, "Type inferred reference not set"); Assert.AreEqual(4, instance.Children.Count, "Children not set"); Assert.AreEqual(4, instance.ChildReferences.Count, "Children override not set"); Assert.AreEqual(3, instance.References.Count, "Possible parts not set"); }
public void RemoveLinking() { // Arrange var instance = new ReferenceResource(); ResourceReferenceTools.InitializeCollections(instance); var deletedRef = new DerivedResource(); instance.Reference2 = deletedRef; instance.References.Add(deletedRef); instance.References.Add(new SimpleResource()); // Act // Call once for each relation _linker.RemoveLinking(deletedRef, instance); _linker.RemoveLinking(deletedRef, instance); // Assert Assert.IsNull(instance.Reference2); Assert.AreEqual(1, instance.References.Count); }
public void ReplaceWithProxy() { // Arrange: Create instance and reference var ref1 = new DerivedResource { Id = 9, Foo = 20 }; var ref2 = new SimpleResource { Id = 10, Foo = 30 }; var nonPub = new NonPublicResource { Name = "NonPublic" }; var instance = new ReferenceResource { Id = 8, Reference = ref1, NonPublic = nonPub }; instance.References = new ReferenceCollection <ISimpleResource>(instance, instance.GetType().GetProperty(nameof(ReferenceResource.References)), new List <IResource>()) { ref2 }; // Act: Convert to proxy and access the reference var proxy = (IReferenceResource)_typeController.GetProxy(instance); var reference = proxy.Reference; var methodRef = proxy.GetReference(); var references = proxy.MoreReferences.ToArray(); var references2 = proxy.GetReferences(); var nonPubProxy = proxy.NonPublic; ISimpleResource eventArgs = null; proxy.ReferenceChanged += (sender, resource) => eventArgs = resource; ISimpleResource[] eventArgs2 = null; proxy.SomeChanged += (sender, resources) => eventArgs2 = resources; // Act: Set resource property through proxy proxy.Reference = references[0]; proxy.SetReference(reference); // Make sure all references where replaced with proxies Assert.AreNotEqual(ref1, reference); Assert.AreNotEqual(ref2, references[0]); Assert.AreNotEqual(ref2, references2[0]); Assert.AreNotEqual(nonPub, nonPubProxy); Assert.AreEqual(20, reference.Foo); Assert.AreEqual(reference, methodRef); Assert.AreEqual(30, references[0].Foo); Assert.AreEqual(30, references2[0].Foo); Assert.NotNull(eventArgs); Assert.AreEqual(30, eventArgs.Foo); Assert.NotNull(eventArgs2); Assert.AreEqual(1, eventArgs2.Length); Assert.AreEqual(30, eventArgs2[0].Foo); Assert.AreEqual("NonPublic", nonPubProxy.Name); // Assert modifications of the setters Assert.AreEqual(instance.Reference, ref2); Assert.AreEqual(instance.References.Count(), 2); Assert.AreEqual(instance.References.ElementAt(1), ref1); }
public void SaveReferences() { // Arrange var instance = new ReferenceResource { Id = 1 }; ResourceReferenceTools.InitializeCollections(instance); // Prepare reference objects var ref1 = new SimpleResource { Id = 2, Name = "Ref1" }; var ref2 = new SimpleResource { Id = 3, Name = "Pos1" }; var ref3 = new DerivedResource { Name = "Ref2" }; ResourceReferenceTools.InitializeCollections(ref3); var ref4 = new DerivedResource { Id = 5, Name = "ChildOnly" }; var ref5 = new DerivedResource { Id = 6, Name = "BackRef" }; ResourceReferenceTools.InitializeCollections(ref5); // Fill graph _graph[1] = new ResourceWrapper(instance); _graph[2] = new ResourceWrapper(ref1); _graph[3] = new ResourceWrapper(ref2); _graph[5] = new ResourceWrapper(ref4); _graph[6] = new ResourceWrapper(ref5); // Set single references instance.Parent = ref5; // Parent is set and // ref5.Children.Add(instance); Bidirectional reference synced --> no longer necessary instance.Reference = ref2; // Reference is changed from ref1 to ref2 instance.Reference2 = ref3; // Reference2 is assigned with a new object // Fill collections instance.References.Add(ref1); // This element remains //instance.References.Add(ref2); // This element was removed instance.References.Add(ref3); // The new element is also added to the list, but is not a child // Fill children with all except the unsaved one to simulate an unchanged collection instance.Children.Add(ref1); instance.Children.Add(ref2); instance.Children.Add(ref4); // Setup uow and repo to simulate the current database var relations = new List <ResourceRelation> { // Parent child relations //Relation(6, ResourceRelationType.ParentChild, ResourceReferenceRole.Source), <-- Represents the missing bidirectional parent relationship created during this test Relation(2, 1), Relation(3, 1), Relation(5, 1), // Current exchangable part Relation(2, 1, ResourceRelationType.CurrentExchangablePart, ResourceReferenceRole.Target, nameof(ReferenceResource.Reference)), // This is changed to ref2 // Possible exchangable part Relation(2, 1, ResourceRelationType.PossibleExchangablePart), // This remains untouched Relation(3, 1, ResourceRelationType.PossibleExchangablePart) // This is removed }; var mocks = SetupDbMocks(relations); // Act var newResources = _linker.SaveReferences(mocks.Item1.Object, instance, new ResourceEntity { Id = 1 }); // Assert Assert.AreEqual(1, newResources.Count); Assert.AreEqual(ref3, newResources[0]); Assert.IsTrue(ref5.Children.Contains(instance), "Backlink sync failed for parent ref5"); Assert.DoesNotThrow(() => mocks.Item3.Verify(repo => repo.Create(), Times.Once), "Linker did not detect the new resource"); Assert.DoesNotThrow(() => mocks.Item2.Verify(repo => repo.Create((int)ResourceRelationType.PossibleExchangablePart), Times.Once), "Linker did not create relation for ref3 in References"); Assert.DoesNotThrow(() => mocks.Item2.Verify(repo => repo.Create((int)ResourceRelationType.ParentChild), Times.Once), "Linker did not create relation for parent ref5"); Assert.DoesNotThrow(() => mocks.Item2.Verify(repo => repo.Remove(It.Is <ResourceRelation>(removed => removed.SourceId == 1 && removed.TargetId == 3)), Times.Once), "Linker did not remove relation 1-3"); var parentChild = relations.Where(r => r.RelationType == (int)ResourceRelationType.ParentChild).ToArray(); Assert.AreEqual(4, parentChild.Length); var currentPart = relations.Where(r => r.RelationType == (int)ResourceRelationType.CurrentExchangablePart).ToArray(); Assert.AreEqual(2, currentPart.Length); Assert.AreEqual(1, currentPart.Count(r => r.Target.Id == 3)); Assert.AreEqual(1, currentPart.Count(r => r.Target.Id == 0)); var possiblePart = relations.Where(r => r.RelationType == (int)ResourceRelationType.PossibleExchangablePart).ToArray(); Assert.AreEqual(2, possiblePart.Length); Assert.AreEqual(1, possiblePart.Count(r => r.Target.Id == 2)); Assert.AreEqual(1, possiblePart.Count(r => r.Target.Id == 0)); }