Index: Ringtoets/GrassCoverErosionOutwards/test/Ringtoets.GrassCoverErosionOutwards.Plugin.Test/TreeNodeInfos/GrassCoverErosionOutwardsWaveHeightCalculationsGroupContextTreeNodeInfoTest.cs =================================================================== diff -u -rcf02d465442aeee554f2693d7b999f9d43dc60b0 -rbcab4543e8b75f5d00850c4e7780097cfabf67da --- Ringtoets/GrassCoverErosionOutwards/test/Ringtoets.GrassCoverErosionOutwards.Plugin.Test/TreeNodeInfos/GrassCoverErosionOutwardsWaveHeightCalculationsGroupContextTreeNodeInfoTest.cs (.../GrassCoverErosionOutwardsWaveHeightCalculationsGroupContextTreeNodeInfoTest.cs) (revision cf02d465442aeee554f2693d7b999f9d43dc60b0) +++ Ringtoets/GrassCoverErosionOutwards/test/Ringtoets.GrassCoverErosionOutwards.Plugin.Test/TreeNodeInfos/GrassCoverErosionOutwardsWaveHeightCalculationsGroupContextTreeNodeInfoTest.cs (.../GrassCoverErosionOutwardsWaveHeightCalculationsGroupContextTreeNodeInfoTest.cs) (revision bcab4543e8b75f5d00850c4e7780097cfabf67da) @@ -20,28 +20,45 @@ // All rights reserved. using System; +using System.Collections.Generic; using System.Drawing; +using System.IO; using System.Linq; +using System.Threading; +using System.Windows.Forms; using Core.Common.Base; using Core.Common.Controls.TreeView; using Core.Common.Gui; using Core.Common.Gui.ContextMenu; +using Core.Common.Gui.Forms.MainWindow; +using Core.Common.Gui.Forms.ViewHost; +using Core.Common.Gui.TestUtil.ContextMenu; using Core.Common.TestUtil; +using Core.Common.Util; +using NUnit.Extensions.Forms; using NUnit.Framework; using Rhino.Mocks; using Ringtoets.Common.Data.AssessmentSection; using Ringtoets.Common.Data.Hydraulics; using Ringtoets.Common.Data.TestUtil; using Ringtoets.Common.Service; +using Ringtoets.Common.Service.TestUtil; using Ringtoets.GrassCoverErosionOutwards.Data; using Ringtoets.GrassCoverErosionOutwards.Forms.PresentationObjects; +using Ringtoets.HydraRing.Calculation.Calculator; +using Ringtoets.HydraRing.Calculation.Calculator.Factory; +using Ringtoets.HydraRing.Calculation.Data.Input; +using Ringtoets.HydraRing.Calculation.TestUtil.Calculator; using RingtoetsCommonFormsResources = Ringtoets.Common.Forms.Properties.Resources; namespace Ringtoets.GrassCoverErosionOutwards.Plugin.Test.TreeNodeInfos { [TestFixture] - public class GrassCoverErosionOutwardsWaveHeightCalculationsGroupContextTreeNodeInfoTest + public class GrassCoverErosionOutwardsWaveHeightCalculationsGroupContextTreeNodeInfoTest : NUnitFormTest { + private const int contextMenuRunWaveHeightCalculationsIndex = 0; + private readonly string testDataPath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Integration.Service, "HydraRingCalculation"); + [Test] public void Initialized_Always_ExpectedPropertiesSet() { @@ -109,11 +126,13 @@ { // Setup var mockRepository = new MockRepository(); - var assessmentSection = mockRepository.StrictMock(); + IAssessmentSection assessmentSection = AssessmentSectionHelper.CreateAssessmentSectionStub(mockRepository); var menuBuilder = mockRepository.StrictMock(); using (mockRepository.Ordered()) { + menuBuilder.Expect(mb => mb.AddCustomItem(null)).IgnoreArguments().Return(menuBuilder); + menuBuilder.Expect(mb => mb.AddSeparator()).Return(menuBuilder); menuBuilder.Expect(mb => mb.AddCollapseAllItem()).Return(menuBuilder); menuBuilder.Expect(mb => mb.AddExpandAllItem()).Return(menuBuilder); menuBuilder.Expect(mb => mb.Build()).Return(null); @@ -145,6 +164,218 @@ } [Test] + [Apartment(ApartmentState.STA)] + public void CalculateWaveHeightsFromContextMenu_AllRequiredInputSet_SendsRightInputToCalculationService() + { + // Setup + var mockRepository = new MockRepository(); + var assessmentSection = new AssessmentSectionStub + { + HydraulicBoundaryDatabase = + { + FilePath = Path.Combine(testDataPath, "HRD ijsselmeer.sqlite") + } + }; + + var hydraulicBoundaryLocation1 = new TestHydraulicBoundaryLocation("locationName 1"); + var hydraulicBoundaryLocation2 = new TestHydraulicBoundaryLocation("locationName 2"); + assessmentSection.SetHydraulicBoundaryLocationCalculations(new[] + { + hydraulicBoundaryLocation1, + hydraulicBoundaryLocation2 + }); + + var failureMechanism = new GrassCoverErosionOutwardsFailureMechanism + { + Contribution = 5 + }; + failureMechanism.SetHydraulicBoundaryLocationCalculations(new[] + { + hydraulicBoundaryLocation1, + hydraulicBoundaryLocation2 + }); + + var context = new GrassCoverErosionOutwardsWaveHeightCalculationsGroupContext(new ObservableList(), + failureMechanism, + assessmentSection); + + using (var treeViewControl = new TreeViewControl()) + { + var gui = mockRepository.Stub(); + gui.Stub(g => g.ProjectOpened += null).IgnoreArguments(); + gui.Stub(g => g.ProjectOpened -= null).IgnoreArguments(); + gui.Stub(cmp => cmp.Get(context, treeViewControl)).Return(new CustomItemsOnlyContextMenuBuilder()); + gui.Stub(g => g.MainWindow).Return(mockRepository.Stub()); + gui.Stub(g => g.DocumentViewController).Return(mockRepository.Stub()); + + var waveHeightCalculator = new TestWaveHeightCalculator(); + var calculatorFactory = mockRepository.Stub(); + calculatorFactory.Expect(cf => cf.CreateWaveHeightCalculator(testDataPath, string.Empty)).Return(waveHeightCalculator).Repeat.Times(10); + mockRepository.ReplayAll(); + + DialogBoxHandler = (name, wnd) => + { + // Expect an activity dialog which is automatically closed + }; + + using (var plugin = new GrassCoverErosionOutwardsPlugin()) + { + TreeNodeInfo info = GetInfo(plugin); + plugin.Gui = gui; + plugin.Activate(); + + using (ContextMenuStrip contextMenuAdapter = info.ContextMenuStrip(context, null, treeViewControl)) + using (new HydraRingCalculatorFactoryConfig(calculatorFactory)) + { + // Call + contextMenuAdapter.Items[contextMenuRunWaveHeightCalculationsIndex].PerformClick(); + + // Assert + double mechanismSpecificFactorizedSignalingNorm = GetExpectedNorm(failureMechanism, + () => assessmentSection.FailureMechanismContribution.SignalingNorm / 30); + AssertHydraRingCalculationInput(hydraulicBoundaryLocation1, + mechanismSpecificFactorizedSignalingNorm, + waveHeightCalculator.ReceivedInputs.ElementAt(0)); + AssertHydraRingCalculationInput(hydraulicBoundaryLocation2, + mechanismSpecificFactorizedSignalingNorm, + waveHeightCalculator.ReceivedInputs.ElementAt(1)); + + double mechanismSpecificSignalingNorm = GetExpectedNorm(failureMechanism, () => assessmentSection.FailureMechanismContribution.SignalingNorm); + AssertHydraRingCalculationInput(hydraulicBoundaryLocation1, + mechanismSpecificSignalingNorm, + waveHeightCalculator.ReceivedInputs.ElementAt(2)); + AssertHydraRingCalculationInput(hydraulicBoundaryLocation2, + mechanismSpecificSignalingNorm, + waveHeightCalculator.ReceivedInputs.ElementAt(3)); + + double mechanismSpecificLowerLimitNorm = GetExpectedNorm(failureMechanism, () => assessmentSection.FailureMechanismContribution.LowerLimitNorm); + AssertHydraRingCalculationInput(hydraulicBoundaryLocation1, + mechanismSpecificLowerLimitNorm, + waveHeightCalculator.ReceivedInputs.ElementAt(4)); + AssertHydraRingCalculationInput(hydraulicBoundaryLocation2, + mechanismSpecificLowerLimitNorm, + waveHeightCalculator.ReceivedInputs.ElementAt(5)); + + double lowerLimitNorm = assessmentSection.FailureMechanismContribution.LowerLimitNorm; + AssertHydraRingCalculationInput(hydraulicBoundaryLocation1, + lowerLimitNorm, + waveHeightCalculator.ReceivedInputs.ElementAt(6)); + AssertHydraRingCalculationInput(hydraulicBoundaryLocation2, + lowerLimitNorm, + waveHeightCalculator.ReceivedInputs.ElementAt(7)); + + double factorizedLowerLimitNorm = lowerLimitNorm * 30; + AssertHydraRingCalculationInput(hydraulicBoundaryLocation1, + factorizedLowerLimitNorm, + waveHeightCalculator.ReceivedInputs.ElementAt(8)); + AssertHydraRingCalculationInput(hydraulicBoundaryLocation2, + factorizedLowerLimitNorm, + waveHeightCalculator.ReceivedInputs.ElementAt(9)); + } + } + } + + mockRepository.VerifyAll(); + } + + [Test] + [Apartment(ApartmentState.STA)] + public void GivenHydraulicBoundaryLocationThatSucceeds_CalculatingWaveHeightFromContextMenu_ThenLogMessagesAddedOutputSet() + { + // Given + var mockRepository = new MockRepository(); + var assessmentSection = new AssessmentSectionStub + { + HydraulicBoundaryDatabase = + { + FilePath = Path.Combine(testDataPath, "HRD ijsselmeer.sqlite") + } + }; + + var hydraulicBoundaryLocation = new TestHydraulicBoundaryLocation("locationName"); + assessmentSection.SetHydraulicBoundaryLocationCalculations(new[] + { + hydraulicBoundaryLocation + }); + + var failureMechanism = new GrassCoverErosionOutwardsFailureMechanism + { + Contribution = 5 + }; + failureMechanism.SetHydraulicBoundaryLocationCalculations(new[] + { + hydraulicBoundaryLocation + }); + + var context = new GrassCoverErosionOutwardsWaveHeightCalculationsGroupContext(new ObservableList(), + failureMechanism, + assessmentSection); + + using (var treeViewControl = new TreeViewControl()) + { + var gui = mockRepository.Stub(); + gui.Stub(g => g.ProjectOpened += null).IgnoreArguments(); + gui.Stub(g => g.ProjectOpened -= null).IgnoreArguments(); + gui.Stub(cmp => cmp.Get(context, treeViewControl)).Return(new CustomItemsOnlyContextMenuBuilder()); + gui.Stub(g => g.MainWindow).Return(mockRepository.Stub()); + gui.Stub(g => g.DocumentViewController).Return(mockRepository.Stub()); + + var waveHeightCalculator = new TestWaveHeightCalculator + { + Converged = false + }; + var calculatorFactory = mockRepository.Stub(); + calculatorFactory.Expect(cf => cf.CreateWaveHeightCalculator(testDataPath, string.Empty)).Return(waveHeightCalculator).Repeat.Times(5); + mockRepository.ReplayAll(); + + DialogBoxHandler = (name, wnd) => + { + // Expect an activity dialog which is automatically closed + }; + + using (var plugin = new GrassCoverErosionOutwardsPlugin()) + { + TreeNodeInfo info = GetInfo(plugin); + plugin.Gui = gui; + plugin.Activate(); + + using (ContextMenuStrip contextMenuAdapter = info.ContextMenuStrip(context, null, treeViewControl)) + using (new HydraRingCalculatorFactoryConfig(calculatorFactory)) + { + // When + Action call = () => contextMenuAdapter.Items[contextMenuRunWaveHeightCalculationsIndex].PerformClick(); + + // Then + TestHelper.AssertLogMessages(call, messages => + { + string[] msgs = messages.ToArray(); + Assert.AreEqual(40, msgs.Length); + AssertHydraulicBoundaryLocationCalculationMessages(hydraulicBoundaryLocation, msgs, 0, "Iv->IIv"); + AssertHydraulicBoundaryLocationCalculationMessages(hydraulicBoundaryLocation, msgs, 7, "IIv->IIIv"); + AssertHydraulicBoundaryLocationCalculationMessages(hydraulicBoundaryLocation, msgs, 14, "IIIv->IVv"); + AssertHydraulicBoundaryLocationCalculationMessages(hydraulicBoundaryLocation, msgs, 21, "IVv->Vv"); + AssertHydraulicBoundaryLocationCalculationMessages(hydraulicBoundaryLocation, msgs, 28, "Vv->VIv"); + + Assert.AreEqual($"Golfhoogte berekenen voor locatie '{hydraulicBoundaryLocation.Name}' (Categorie Iv->IIv) is gelukt.", msgs.ElementAt(35)); + Assert.AreEqual($"Golfhoogte berekenen voor locatie '{hydraulicBoundaryLocation.Name}' (Categorie IIv->IIIv) is gelukt.", msgs.ElementAt(36)); + Assert.AreEqual($"Golfhoogte berekenen voor locatie '{hydraulicBoundaryLocation.Name}' (Categorie IIIv->IVv) is gelukt.", msgs.ElementAt(37)); + Assert.AreEqual($"Golfhoogte berekenen voor locatie '{hydraulicBoundaryLocation.Name}' (Categorie IVv->Vv) is gelukt.", msgs.ElementAt(38)); + Assert.AreEqual($"Golfhoogte berekenen voor locatie '{hydraulicBoundaryLocation.Name}' (Categorie Vv->VIv) is gelukt.", msgs.ElementAt(39)); + }); + + AssertHydraulicBoundaryLocationCalculationOutput(waveHeightCalculator, failureMechanism.WaveHeightCalculationsForMechanismSpecificFactorizedSignalingNorm.Single().Output); + AssertHydraulicBoundaryLocationCalculationOutput(waveHeightCalculator, failureMechanism.WaveHeightCalculationsForMechanismSpecificSignalingNorm.Single().Output); + AssertHydraulicBoundaryLocationCalculationOutput(waveHeightCalculator, failureMechanism.WaveHeightCalculationsForMechanismSpecificLowerLimitNorm.Single().Output); + AssertHydraulicBoundaryLocationCalculationOutput(waveHeightCalculator, assessmentSection.WaveHeightCalculationsForLowerLimitNorm.Single().Output); + AssertHydraulicBoundaryLocationCalculationOutput(waveHeightCalculator, assessmentSection.WaveHeightCalculationsForFactorizedLowerLimitNorm.Single().Output); + } + } + } + + mockRepository.VerifyAll(); + } + + [Test] public void ChildNodeObjects_Always_ReturnsExpectedChildData() { // Setup @@ -181,7 +412,7 @@ Assert.AreEqual("Categorie Iv->IIv", calculationsContexts[0].CategoryBoundaryName); Assert.AreSame(failureMechanism.WaveHeightCalculationsForMechanismSpecificFactorizedSignalingNorm, calculationsContexts[0].WrappedData); - Assert.AreEqual(GetExpectedNorm(failureMechanism, () => signalingNorm / 30), calculationsContexts[0].GetNormFunc()); + Assert.AreEqual(GetExpectedNorm(failureMechanism, () => signalingNorm / 30), calculationsContexts[0].GetNormFunc(), 1e-6); Assert.AreEqual("Categorie IIv->IIIv", calculationsContexts[1].CategoryBoundaryName); Assert.AreSame(failureMechanism.WaveHeightCalculationsForMechanismSpecificSignalingNorm, calculationsContexts[1].WrappedData); @@ -201,6 +432,13 @@ } } + private static void AssertHydraulicBoundaryLocationCalculationOutput(IWaveHeightCalculator waveHeightCalculator, + HydraulicBoundaryLocationCalculationOutput actualOutput) + { + Assert.AreEqual(waveHeightCalculator.WaveHeight, actualOutput.Result, actualOutput.Result.GetAccuracy()); + Assert.AreEqual(CalculationConvergence.CalculatedNotConverged, actualOutput.CalculationConvergence); + } + private static double GetExpectedNorm(GrassCoverErosionOutwardsFailureMechanism failureMechanism, Func getNormFunc) { return RingtoetsCommonDataCalculationService.ProfileSpecificRequiredProbability( @@ -213,5 +451,27 @@ { return plugin.GetTreeNodeInfos().First(tni => tni.TagType == typeof(GrassCoverErosionOutwardsWaveHeightCalculationsGroupContext)); } + + private static void AssertHydraulicBoundaryLocationCalculationMessages(HydraulicBoundaryLocation hydraulicBoundaryLocation, + IEnumerable messages, + int startIndex, + string categoryName) + { + Assert.AreEqual($"Golfhoogte berekenen voor locatie '{hydraulicBoundaryLocation.Name}' (Categorie {categoryName}) is gestart.", messages.ElementAt(startIndex)); + CalculationServiceTestHelper.AssertValidationStartMessage(messages.ElementAt(startIndex + 1)); + CalculationServiceTestHelper.AssertValidationEndMessage(messages.ElementAt(startIndex + 2)); + CalculationServiceTestHelper.AssertCalculationStartMessage(messages.ElementAt(startIndex + 3)); + Assert.AreEqual($"Golfhoogte berekening voor locatie '{hydraulicBoundaryLocation.Name}' (Categorie {categoryName}) is niet geconvergeerd.", messages.ElementAt(startIndex + 4)); + StringAssert.StartsWith("Golfhoogte berekening is uitgevoerd op de tijdelijke locatie", messages.ElementAt(startIndex + 5)); + CalculationServiceTestHelper.AssertCalculationEndMessage(messages.ElementAt(startIndex + 6)); + } + + private static void AssertHydraRingCalculationInput(HydraulicBoundaryLocation hydraulicBoundaryLocation, + double norm, + HydraRingCalculationInput actualCalculationInput) + { + Assert.AreEqual(hydraulicBoundaryLocation.Id, actualCalculationInput.HydraulicBoundaryLocationId); + Assert.AreEqual(StatisticsConverter.ProbabilityToReliability(norm), actualCalculationInput.Beta); + } } } \ No newline at end of file