Index: Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Service/ClosingStructuresDataSynchronizationService.cs
===================================================================
diff -u -rac8798cf0a66cf04df1294d4fd08e0b1915a5b91 -r916bdbd134da55d8f1373fea9b29aba97db34348
--- Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Service/ClosingStructuresDataSynchronizationService.cs (.../ClosingStructuresDataSynchronizationService.cs) (revision ac8798cf0a66cf04df1294d4fd08e0b1915a5b91)
+++ Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Service/ClosingStructuresDataSynchronizationService.cs (.../ClosingStructuresDataSynchronizationService.cs) (revision 916bdbd134da55d8f1373fea9b29aba97db34348)
@@ -25,6 +25,8 @@
using System.Linq;
using Core.Common.Base;
using Ringtoets.ClosingStructures.Data;
+using Ringtoets.ClosingStructures.Util;
+using Ringtoets.Common.Data;
using Ringtoets.Common.Data.Calculation;
using Ringtoets.Common.Data.Hydraulics;
using Ringtoets.Common.Data.Structures;
@@ -38,6 +40,47 @@
public static class ClosingStructuresDataSynchronizationService
{
///
+ /// Removes the , unassigns it from the calculations in
+ /// and clears all dependent data, either directly or indirectly.
+ ///
+ /// The structure to be removed.
+ /// The
+ /// to clear the data from.
+ /// All objects affected by the removal.
+ /// Thrown when any parameter is null.
+ public static IEnumerable RemoveStructure(ClosingStructure structure,
+ ClosingStructuresFailureMechanism failureMechanism)
+ {
+ if (structure == null)
+ {
+ throw new ArgumentNullException(nameof(structure));
+ }
+
+ if (failureMechanism == null)
+ {
+ throw new ArgumentNullException(nameof(failureMechanism));
+ }
+
+ IEnumerable> calculations =
+ failureMechanism.Calculations.Cast>();
+
+ StructuresCalculation[] calculationWithRemovedStructure = calculations
+ .Where(c => ReferenceEquals(c.InputParameters.Structure, structure))
+ .ToArray();
+
+ List changedObservables = ClearStructureDependentData(
+ failureMechanism.SectionResults2,
+ calculationWithRemovedStructure,
+ calculations);
+
+ StructureCollection structures = failureMechanism.ClosingStructures;
+ structures.Remove(structure);
+ changedObservables.Add(structures);
+
+ return changedObservables;
+ }
+
+ ///
/// Clears the output for all calculations in the .
///
/// The
@@ -133,7 +176,28 @@
input
};
}
+
return Enumerable.Empty();
}
+
+ private static List ClearStructureDependentData(IEnumerable sectionResults,
+ IEnumerable> calculationWithRemovedStructure,
+ IEnumerable> structureCalculations)
+ {
+ var changedObservables = new List();
+ foreach (StructuresCalculation calculation in calculationWithRemovedStructure)
+ {
+ changedObservables.AddRange(RingtoetsCommonDataSynchronizationService.ClearCalculationOutput(calculation));
+
+ calculation.InputParameters.ClearStructure();
+ changedObservables.Add(calculation.InputParameters);
+ }
+
+ IEnumerable affectedSectionResults =
+ ClosingStructuresHelper.UpdateCalculationToSectionResultAssignments(sectionResults, structureCalculations);
+
+ changedObservables.AddRange(affectedSectionResults);
+ return changedObservables;
+ }
}
}
\ No newline at end of file
Index: Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Service/Ringtoets.ClosingStructures.Service.csproj
===================================================================
diff -u -r63fc151e9cf722527465c1eddfa6567a90feb5e6 -r916bdbd134da55d8f1373fea9b29aba97db34348
--- Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Service/Ringtoets.ClosingStructures.Service.csproj (.../Ringtoets.ClosingStructures.Service.csproj) (revision 63fc151e9cf722527465c1eddfa6567a90feb5e6)
+++ Ringtoets/ClosingStructures/src/Ringtoets.ClosingStructures.Service/Ringtoets.ClosingStructures.Service.csproj (.../Ringtoets.ClosingStructures.Service.csproj) (revision 916bdbd134da55d8f1373fea9b29aba97db34348)
@@ -64,6 +64,11 @@
Ringtoets.ClosingStructures.Forms
False
+
+ {673b4a0b-96b1-4e98-bb49-e3c7bcb5f179}
+ Ringtoets.ClosingStructures.Util
+ False
+
Index: Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.Service.Test/ClosingStructureDataSynchronizationServiceTest.cs
===================================================================
diff -u -rac8798cf0a66cf04df1294d4fd08e0b1915a5b91 -r916bdbd134da55d8f1373fea9b29aba97db34348
--- Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.Service.Test/ClosingStructureDataSynchronizationServiceTest.cs (.../ClosingStructureDataSynchronizationServiceTest.cs) (revision ac8798cf0a66cf04df1294d4fd08e0b1915a5b91)
+++ Ringtoets/ClosingStructures/test/Ringtoets.ClosingStructures.Service.Test/ClosingStructureDataSynchronizationServiceTest.cs (.../ClosingStructureDataSynchronizationServiceTest.cs) (revision 916bdbd134da55d8f1373fea9b29aba97db34348)
@@ -40,6 +40,131 @@
public class ClosingStructuresDataSynchronizationServiceTest
{
[Test]
+ public void RemoveStructure_StructureNull_ThrowsArgumentNullException()
+ {
+ // Call
+ TestDelegate test = () => ClosingStructuresDataSynchronizationService.RemoveStructure(
+ null,
+ new ClosingStructuresFailureMechanism());
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("structure", exception.ParamName);
+ }
+
+ [Test]
+ public void RemoveStructure_FailureMechanismNull_ThrowsArgumentNullException()
+ {
+ // Call
+ TestDelegate test = () => ClosingStructuresDataSynchronizationService.RemoveStructure(
+ new TestClosingStructure(),
+ null);
+
+ // Assert
+ var exception = Assert.Throws(test);
+ Assert.AreEqual("failureMechanism", exception.ParamName);
+ }
+
+ [Test]
+ public void RemoveStructure_FullyConfiguredFailureMechanism_RemovesStructureAndClearsDependentData()
+ {
+ // Setup
+ var failureMechanism = new ClosingStructuresFailureMechanism();
+
+ var locationStructureToRemove = new Point2D(0, 0);
+ var structureToRemove = new TestClosingStructure(locationStructureToRemove, "id1");
+
+ var locationStructureToKeep = new Point2D(2, 2);
+ var structureToKeep = new TestClosingStructure(locationStructureToKeep, "id2");
+
+ failureMechanism.ClosingStructures.AddRange(new[]
+ {
+ structureToRemove,
+ structureToKeep
+ }, "path/to/structures");
+
+ var calculationWithOutput = new TestClosingStructuresCalculation
+ {
+ Output = new TestStructuresOutput()
+ };
+ var calculationWithStructureToRemove = new TestClosingStructuresCalculation
+ {
+ InputParameters =
+ {
+ Structure = structureToRemove
+ }
+ };
+ var calculationWithStructureToKeepAndOutput = new TestClosingStructuresCalculation
+ {
+ InputParameters =
+ {
+ Structure = structureToKeep
+ },
+ Output = new TestStructuresOutput()
+ };
+ var calculationWithStructureToRemoveAndOutput = new TestClosingStructuresCalculation
+ {
+ InputParameters =
+ {
+ Structure = structureToRemove
+ },
+ Output = new TestStructuresOutput()
+ };
+ failureMechanism.CalculationsGroup.Children.AddRange(new[]
+ {
+ calculationWithOutput,
+ calculationWithStructureToRemove,
+ calculationWithStructureToKeepAndOutput,
+ calculationWithStructureToRemoveAndOutput
+ });
+
+ var affectedSection = new FailureMechanismSection(string.Empty, new[]
+ {
+ new Point2D(0, 0),
+ new Point2D(1, 1)
+ });
+ failureMechanism.AddSection(affectedSection);
+ ClosingStructuresFailureMechanismSectionResult sectionWithCalculationAtStructureToRemove = failureMechanism.SectionResults2.ElementAt(0);
+ sectionWithCalculationAtStructureToRemove.Calculation = calculationWithStructureToRemove;
+
+ var unaffectedSection = new FailureMechanismSection(string.Empty, new[]
+ {
+ new Point2D(1, 1),
+ new Point2D(2, 2)
+ });
+ failureMechanism.AddSection(unaffectedSection);
+ ClosingStructuresFailureMechanismSectionResult sectionWithCalculationAtStructureToKeep = failureMechanism.SectionResults2.ElementAt(1);
+ sectionWithCalculationAtStructureToKeep.Calculation = calculationWithStructureToKeepAndOutput;
+
+ // Call
+ IEnumerable affectedObjects = ClosingStructuresDataSynchronizationService.RemoveStructure(
+ structureToRemove, failureMechanism);
+
+ // Assert
+ // Note: To make sure the clear is performed regardless of what is done with
+ // the return result, no ToArray() should be called before these assertions:
+ CollectionAssert.DoesNotContain(failureMechanism.ClosingStructures, structureToRemove);
+ Assert.IsNull(calculationWithStructureToRemove.InputParameters.Structure);
+ Assert.IsNull(calculationWithStructureToRemoveAndOutput.InputParameters.Structure);
+ Assert.IsNull(calculationWithStructureToRemoveAndOutput.Output);
+ Assert.IsNull(sectionWithCalculationAtStructureToRemove.Calculation);
+ Assert.IsNotNull(calculationWithOutput.Output);
+ Assert.IsNotNull(calculationWithStructureToKeepAndOutput.Output);
+ Assert.IsNotNull(calculationWithStructureToKeepAndOutput.InputParameters.Structure);
+ Assert.AreSame(sectionWithCalculationAtStructureToKeep.Calculation, calculationWithStructureToKeepAndOutput);
+
+ IObservable[] expectedAffectedObjects =
+ {
+ calculationWithStructureToRemove.InputParameters,
+ calculationWithStructureToRemoveAndOutput,
+ calculationWithStructureToRemoveAndOutput.InputParameters,
+ sectionWithCalculationAtStructureToRemove,
+ failureMechanism.ClosingStructures
+ };
+ CollectionAssert.AreEquivalent(expectedAffectedObjects, affectedObjects);
+ }
+
+ [Test]
public void ClearAllCalculationOutput_FailureMechanismNull_ThrowsArgumentNullException()
{
// Call