Index: Ringtoets/Common/src/Ringtoets.Common.Data/DikeProfiles/ForeshoreProfile.cs =================================================================== diff -u -r76c82f11791024d9a22f40d0f918cd2b9b13d2ef -r3327c16cf8fc44952976b5505944226edf78fe1c --- Ringtoets/Common/src/Ringtoets.Common.Data/DikeProfiles/ForeshoreProfile.cs (.../ForeshoreProfile.cs) (revision 76c82f11791024d9a22f40d0f918cd2b9b13d2ef) +++ Ringtoets/Common/src/Ringtoets.Common.Data/DikeProfiles/ForeshoreProfile.cs (.../ForeshoreProfile.cs) (revision 3327c16cf8fc44952976b5505944226edf78fe1c) @@ -22,6 +22,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Core.Common.Base; using Core.Common.Base.Data; using Core.Common.Base.Geometry; using Ringtoets.Common.Data.Properties; @@ -31,7 +32,7 @@ /// /// Definition for a foreshore profile for a failure mechanism. /// - public class ForeshoreProfile + public class ForeshoreProfile : Observable { /// /// Creates a new instance of the class. Index: Ringtoets/Common/test/Ringtoets.Common.Data.Test/DikeProfiles/ForeshoreProfileTest.cs =================================================================== diff -u -r76c82f11791024d9a22f40d0f918cd2b9b13d2ef -r3327c16cf8fc44952976b5505944226edf78fe1c --- Ringtoets/Common/test/Ringtoets.Common.Data.Test/DikeProfiles/ForeshoreProfileTest.cs (.../ForeshoreProfileTest.cs) (revision 76c82f11791024d9a22f40d0f918cd2b9b13d2ef) +++ Ringtoets/Common/test/Ringtoets.Common.Data.Test/DikeProfiles/ForeshoreProfileTest.cs (.../ForeshoreProfileTest.cs) (revision 3327c16cf8fc44952976b5505944226edf78fe1c) @@ -20,6 +20,7 @@ // All rights reserved. using System; +using Core.Common.Base; using Core.Common.Base.Data; using Core.Common.Base.Geometry; using Core.Common.TestUtil; @@ -52,6 +53,8 @@ }); // Assert + Assert.IsInstanceOf(foreshoreProfile); + Assert.IsInstanceOf(foreshoreProfile.Orientation); Assert.IsInstanceOf(foreshoreProfile.X0); Index: Ringtoets/Integration/src/Ringtoets.Integration.Plugin/FileImporters/ForeshoreProfileUpdateDataStrategy.cs =================================================================== diff -u -rebde35e650a398aa9ce1b9c6950b91d2a47c007c -r3327c16cf8fc44952976b5505944226edf78fe1c --- Ringtoets/Integration/src/Ringtoets.Integration.Plugin/FileImporters/ForeshoreProfileUpdateDataStrategy.cs (.../ForeshoreProfileUpdateDataStrategy.cs) (revision ebde35e650a398aa9ce1b9c6950b91d2a47c007c) +++ Ringtoets/Integration/src/Ringtoets.Integration.Plugin/FileImporters/ForeshoreProfileUpdateDataStrategy.cs (.../ForeshoreProfileUpdateDataStrategy.cs) (revision 3327c16cf8fc44952976b5505944226edf78fe1c) @@ -37,8 +37,11 @@ protected override IEnumerable UpdateObjectAndDependentData(ForeshoreProfile objectToUpdate, ForeshoreProfile objectToUpdateFrom) { - // TODO - return new IObservable[0]; + objectToUpdate.CopyProperties(objectToUpdateFrom); + return new IObservable[] + { + objectToUpdate + }; } protected override IEnumerable RemoveObjectAndDependentData(ForeshoreProfile removedObject) Index: Ringtoets/Integration/test/Ringtoets.Integration.Plugin.Test/FileImporters/ForeshoreProfileUpdateDataStrategyTest.cs =================================================================== diff -u -rebde35e650a398aa9ce1b9c6950b91d2a47c007c -r3327c16cf8fc44952976b5505944226edf78fe1c --- Ringtoets/Integration/test/Ringtoets.Integration.Plugin.Test/FileImporters/ForeshoreProfileUpdateDataStrategyTest.cs (.../ForeshoreProfileUpdateDataStrategyTest.cs) (revision ebde35e650a398aa9ce1b9c6950b91d2a47c007c) +++ Ringtoets/Integration/test/Ringtoets.Integration.Plugin.Test/FileImporters/ForeshoreProfileUpdateDataStrategyTest.cs (.../ForeshoreProfileUpdateDataStrategyTest.cs) (revision 3327c16cf8fc44952976b5505944226edf78fe1c) @@ -19,9 +19,13 @@ // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. +using System; using System.Collections.Generic; using System.Linq; using Core.Common.Base; +using Core.Common.Base.Data; +using Core.Common.Base.Geometry; +using Core.Common.TestUtil; using NUnit.Framework; using Ringtoets.Common.Data.DikeProfiles; using Ringtoets.Common.Data.Exceptions; @@ -50,6 +54,34 @@ } [Test] + public void UpdateForeshoreProfilesWithImportedData_ForeshoreProfilePropertiesChanged_UpdateRelevantProperties() + { + // Setup + var profileToBeUpdated = new TestForeshoreProfile("Name", "Profile ID"); + var profileToUpdateFrom = DeepCloneAndModify(profileToBeUpdated); + + var targetCollection = new ForeshoreProfileCollection(); + targetCollection.AddRange(new[] + { + profileToBeUpdated + }, sourceFilePath); + + var strategy = new ForeshoreProfileUpdateDataStrategy(new TestFailureMechanism()); + + // Call + strategy.UpdateForeshoreProfilesWithImportedData(targetCollection, + new[] + { + profileToUpdateFrom + }, sourceFilePath); + + // Assert + Assert.AreEqual(1, targetCollection.Count); + Assert.AreSame(profileToBeUpdated, targetCollection[0]); + AssertForeshoreProfile(profileToUpdateFrom, profileToBeUpdated); + } + + [Test] public void UpdateForeshoreProfilesWithImportedData_CurrentAndImportedCollectionEmpty_DoesNothing() { // Setup @@ -68,16 +100,11 @@ } [Test] - public void UpdateForeshoreProfilesWithImportedData_CurrentCollectionNotEmptyImportedCollectionContainDuplicateIDs_ThrowUpdateException() + public void UpdateForeshoreProfilesWithImportedData_CurrentCollectionEmptyImportedCollectionContainDuplicateIDs_ThrowUpdateException() { // Setup var strategy = new ForeshoreProfileUpdateDataStrategy(new TestFailureMechanism()); - var foreshoreProfiles = new ForeshoreProfileCollection(); - foreshoreProfiles.AddRange(new[] - { - new TestForeshoreProfile("name 1", "different ID") - }, sourceFilePath); const string duplicateId = "duplicate ID"; var importedForeshoreProfiles = new[] @@ -153,6 +180,39 @@ } [Test] + public void UpdateForeshoreProfilesWithImportedData_WithCurrentCollectionNotEmptyAndImportedCollectionHasProfilesWithSameId_ThrowsUpdateException() + { + // Setup + var strategy = new ForeshoreProfileUpdateDataStrategy(new TestFailureMechanism()); + + var foreshoreProfiles = new ForeshoreProfileCollection(); + var originalForeshoreProfiles = new[] + { + new TestForeshoreProfile("name 1", "different ID") + }; + foreshoreProfiles.AddRange(originalForeshoreProfiles, sourceFilePath); + + const string duplicateId = "duplicate ID"; + var importedForeshoreProfiles = new[] + { + new TestForeshoreProfile("Name A", duplicateId), + new TestForeshoreProfile("Name B", duplicateId) + }; + + // Call + TestDelegate call = () => strategy.UpdateForeshoreProfilesWithImportedData(foreshoreProfiles, + importedForeshoreProfiles, + sourceFilePath); + + // Assert + var exception = Assert.Throws(call); + string expectedMessage = $"Voorlandprofielen moeten een unieke id hebben. Gevonden dubbele elementen: {duplicateId}."; + Assert.AreEqual(expectedMessage, exception.Message); + + CollectionAssert.IsEmpty(foreshoreProfiles); + } + + [Test] public void UpdateForeshoreProfilesWithImportedData_CurrentCollectionAndImportedCollectionHasNoOverlap_UpdatesTargetCollection() { // Setup @@ -189,5 +249,137 @@ foreshoreProfiles }, affectedObjects); } + + [Test] + public void UpdateForeshoreProfilesWithImportedData_WithCurrentCollectionAndImportedCollectionHasFullOverlap_UpdatesTargetDataCollection() + { + // Setup + var strategy = new ForeshoreProfileUpdateDataStrategy(new TestFailureMechanism()); + + var foreshoreProfiles = new ForeshoreProfileCollection(); + var targetForeshoreProfile = new TestForeshoreProfile("Name", "ID"); + foreshoreProfiles.AddRange(new[] + { + targetForeshoreProfile + }, sourceFilePath); + + var readForeshoreProfile = DeepCloneAndModify(targetForeshoreProfile); + var importedForeshoreProfiles = new[] + { + readForeshoreProfile + }; + + // Call + IEnumerable affectedObjects = strategy.UpdateForeshoreProfilesWithImportedData(foreshoreProfiles, + importedForeshoreProfiles, + sourceFilePath); + + // Assert + Assert.AreEqual(1, foreshoreProfiles.Count); + Assert.AreSame(targetForeshoreProfile, foreshoreProfiles[0]); + AssertForeshoreProfile(readForeshoreProfile, targetForeshoreProfile); + + CollectionAssert.AreEquivalent(new IObservable[] + { + targetForeshoreProfile, + foreshoreProfiles + }, affectedObjects); + } + + [Test] + public void UpdateForeshoreProfilesWithImportedData_WithCurrentCollectionAndImportedCollectionHasPartialOverlap_UpdatesTargetDataCollection() + { + // Setup + var strategy = new ForeshoreProfileUpdateDataStrategy(new TestFailureMechanism()); + + var commonName = "Name"; + var foreshoreProfileToBeUpdated = new TestForeshoreProfile(commonName, "Updated ID"); + var foreshoreProfileToBeRemoved = new TestForeshoreProfile(commonName, "Removed ID"); + + var foreshoreProfiles = new ForeshoreProfileCollection(); + foreshoreProfiles.AddRange(new[] + { + foreshoreProfileToBeUpdated, + foreshoreProfileToBeRemoved + }, sourceFilePath); + + var foreshoreProfileToUpdateFrom = DeepCloneAndModify(foreshoreProfileToBeUpdated); + var foreshoreProfileToBeAdded = new TestForeshoreProfile(commonName, "Added ID"); + var importedForeshoreProfiles = new[] + { + foreshoreProfileToUpdateFrom, + foreshoreProfileToBeAdded + }; + + // Call + IEnumerable affectedObjects = strategy.UpdateForeshoreProfilesWithImportedData(foreshoreProfiles, + importedForeshoreProfiles, + sourceFilePath); + + // Assert + Assert.AreEqual(2, foreshoreProfiles.Count); + CollectionAssert.AreEqual(new[] + { + foreshoreProfileToBeUpdated, + foreshoreProfileToBeAdded + }, foreshoreProfiles); + + ForeshoreProfile updatedForeshoreProfile = foreshoreProfiles[0]; + Assert.AreSame(foreshoreProfileToBeUpdated, updatedForeshoreProfile); + AssertForeshoreProfile(foreshoreProfileToUpdateFrom, updatedForeshoreProfile); + + ForeshoreProfile addedForeshoreProfile = foreshoreProfiles[1]; + Assert.AreSame(foreshoreProfileToBeAdded, addedForeshoreProfile); + AssertForeshoreProfile(foreshoreProfileToBeAdded, addedForeshoreProfile); + + CollectionAssert.AreEquivalent(new IObservable[] + { + foreshoreProfileToBeUpdated, + foreshoreProfiles + }, affectedObjects); + } + + private static ForeshoreProfile DeepCloneAndModify(ForeshoreProfile foreshoreProfile) + { + var random = new Random(21); + + Point2D originalWorldCoordinate = foreshoreProfile.WorldReferencePoint; + var modifiedWorldCoordinate = new Point2D(originalWorldCoordinate.X + random.NextDouble(), + originalWorldCoordinate.Y + random.NextDouble()); + + List modifiedForeshoreGeometry = foreshoreProfile.Geometry.ToList(); + modifiedForeshoreGeometry.Add(new Point2D(1, 2)); + + RoundedDouble originalBreakWaterHeight = foreshoreProfile.BreakWater?.Height ?? (RoundedDouble) 0.0; + var modifiedBreakWater = new BreakWater(random.NextEnumValue(), + originalBreakWaterHeight + random.NextDouble()); + + string modifiedName = $"new_name_{foreshoreProfile.Name}"; + double modifiedOrientation = foreshoreProfile.Orientation + random.NextDouble(); + double modifiedX0 = foreshoreProfile.X0 + random.NextDouble(); + + return new ForeshoreProfile(modifiedWorldCoordinate, modifiedForeshoreGeometry, + modifiedBreakWater, + new ForeshoreProfile.ConstructionProperties + { + Name = modifiedName, + Id = foreshoreProfile.Id, + Orientation = modifiedOrientation, + X0 = modifiedX0 + }); + } + + private static void AssertForeshoreProfile(ForeshoreProfile expectedForeshoreProfile, + ForeshoreProfile actualForeshoreProfile) + { + Assert.AreEqual(expectedForeshoreProfile.WorldReferencePoint, actualForeshoreProfile.WorldReferencePoint); + CollectionAssert.AreEqual(expectedForeshoreProfile.Geometry, actualForeshoreProfile.Geometry); + Assert.AreEqual(expectedForeshoreProfile.BreakWater, actualForeshoreProfile.BreakWater); + + Assert.AreEqual(expectedForeshoreProfile.Id, actualForeshoreProfile.Id); + Assert.AreEqual(expectedForeshoreProfile.Name, actualForeshoreProfile.Name); + Assert.AreEqual(expectedForeshoreProfile.X0, actualForeshoreProfile.X0); + Assert.AreEqual(expectedForeshoreProfile.Orientation, actualForeshoreProfile.Orientation); + } } } \ No newline at end of file