// Copyright (C) Stichting Deltares 2016. All rights reserved. // // This file is part of Ringtoets. // // Ringtoets is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . // // All names, logos, and references to "Deltares" are registered trademarks of // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. using System; using System.IO; using System.Linq; using Core.Common.Base.Geometry; using Core.Common.TestUtil; using NUnit.Framework; using Rhino.Mocks; using Ringtoets.Common.Data.AssessmentSection; using Ringtoets.Common.Data.Contribution; using Ringtoets.Common.Data.DikeProfiles; using Ringtoets.Common.Data.FailureMechanism; using Ringtoets.GrassCoverErosionInwards.Data; using Ringtoets.HydraRing.Calculation.Parsers; using Ringtoets.HydraRing.Calculation.TestUtil.Calculator; using Ringtoets.HydraRing.Data; namespace Ringtoets.GrassCoverErosionInwards.Service.Test { [TestFixture] public class GrassCoverErosionInwardsCalculationServiceTest { private readonly string testDataPath = TestHelper.GetTestDataPath(TestDataPath.Ringtoets.Integration.Service, "HydraRingCalculation"); [Test] public void Validate_NoHydraulicBoundaryDatabase_LogsErrorAndReturnsFalse() { // Setup var grassCoverErosionInwardsFailureMechanism = new GrassCoverErosionInwardsFailureMechanism(); var mockRepository = new MockRepository(); var assessmentSectionStub = CreateAssessmentSectionStub(grassCoverErosionInwardsFailureMechanism, mockRepository); mockRepository.ReplayAll(); assessmentSectionStub.HydraulicBoundaryDatabase = null; const string name = ""; GrassCoverErosionInwardsCalculation calculation = new GrassCoverErosionInwardsCalculation { Name = name, InputParameters = { DikeProfile = new DikeProfile(new Point2D(0, 0), new RoughnessPoint[0], new Point2D[0], null, new DikeProfile.ConstructionProperties()) } }; // Call bool isValid = false; Action call = () => isValid = new GrassCoverErosionInwardsCalculationService().Validate(calculation, assessmentSectionStub); // Assert TestHelper.AssertLogMessages(call, messages => { var msgs = messages.ToArray(); Assert.AreEqual(3, msgs.Length); StringAssert.StartsWith(string.Format("Validatie van '{0}' gestart om: ", name), msgs[0]); StringAssert.StartsWith("Validatie mislukt: Er is geen hydraulische randvoorwaardenlocatie geselecteerd.", msgs[1]); StringAssert.StartsWith(string.Format("Validatie van '{0}' beëindigd om: ", name), msgs[2]); }); Assert.IsFalse(isValid); mockRepository.VerifyAll(); } [Test] public void Validate_InvalidHydraulicBoundaryDatabase_ReturnsFalse() { // Setup var grassCoverErosionInwardsFailureMechanism = new GrassCoverErosionInwardsFailureMechanism(); var mockRepository = new MockRepository(); var assessmentSectionStub = CreateAssessmentSectionStub(grassCoverErosionInwardsFailureMechanism, mockRepository); mockRepository.ReplayAll(); assessmentSectionStub.HydraulicBoundaryDatabase = new HydraulicBoundaryDatabase { FilePath = Path.Combine(testDataPath, "notexisting.sqlite") }; const string name = ""; GrassCoverErosionInwardsCalculation calculation = new GrassCoverErosionInwardsCalculation { Name = name, InputParameters = { HydraulicBoundaryLocation = new HydraulicBoundaryLocation(1, "name", 2, 2), DikeProfile = new DikeProfile(new Point2D(0, 0), new RoughnessPoint[0], new Point2D[0], null, new DikeProfile.ConstructionProperties()) } }; // Call bool isValid = false; Action call = () => isValid = new GrassCoverErosionInwardsCalculationService().Validate(calculation, assessmentSectionStub); // Assert TestHelper.AssertLogMessages(call, messages => { var msgs = messages.ToArray(); Assert.AreEqual(3, msgs.Length); StringAssert.StartsWith(string.Format("Validatie van '{0}' gestart om: ", name), msgs[0]); StringAssert.StartsWith("Validatie mislukt: Fout bij het lezen van bestand", msgs[1]); StringAssert.StartsWith(string.Format("Validatie van '{0}' beëindigd om: ", name), msgs[2]); }); Assert.IsFalse(isValid); mockRepository.VerifyAll(); } [Test] public void Validate_NoDikeProfile_ReturnsTrue() { // Setup var grassCoverErosionInwardsFailureMechanism = new GrassCoverErosionInwardsFailureMechanism(); var mockRepository = new MockRepository(); var assessmentSectionStub = CreateAssessmentSectionStub(grassCoverErosionInwardsFailureMechanism, mockRepository); mockRepository.ReplayAll(); const string name = ""; GrassCoverErosionInwardsCalculation calculation = new GrassCoverErosionInwardsCalculation { Name = name, InputParameters = { HydraulicBoundaryLocation = new HydraulicBoundaryLocation(1, "name", 2, 2) } }; // Call bool isValid = false; Action call = () => isValid = new GrassCoverErosionInwardsCalculationService().Validate(calculation, assessmentSectionStub); // Assert TestHelper.AssertLogMessages(call, messages => { var msgs = messages.ToArray(); Assert.AreEqual(3, msgs.Length); StringAssert.StartsWith(string.Format("Validatie van '{0}' gestart om: ", name), msgs[0]); StringAssert.StartsWith("Validatie mislukt: Er is geen dijkprofiel geselecteerd.", msgs[1]); StringAssert.StartsWith(string.Format("Validatie van '{0}' beëindigd om: ", name), msgs[2]); }); Assert.IsFalse(isValid); mockRepository.VerifyAll(); } [Test] [TestCase(double.NaN)] [TestCase(double.NegativeInfinity)] [TestCase(double.PositiveInfinity)] public void Validate_ValidInputAndValidateBreakWaterHeight_ReturnsFalse(double breakWaterHeight) { // Setup var grassCoverErosionInwardsFailureMechanism = new GrassCoverErosionInwardsFailureMechanism(); var mockRepository = new MockRepository(); var assessmentSectionStub = CreateAssessmentSectionStub(grassCoverErosionInwardsFailureMechanism, mockRepository); mockRepository.ReplayAll(); const string name = ""; GrassCoverErosionInwardsCalculation calculation = GetCalculationWithBreakWater(name, breakWaterHeight); calculation.InputParameters.UseBreakWater = true; // Call bool isValid = false; Action call = () => isValid = new GrassCoverErosionInwardsCalculationService().Validate(calculation, assessmentSectionStub); // Assert TestHelper.AssertLogMessages(call, messages => { var msgs = messages.ToArray(); Assert.AreEqual(3, msgs.Length); StringAssert.StartsWith(string.Format("Validatie van '{0}' gestart om: ", name), msgs[0]); Assert.AreEqual("Validatie mislukt: Er is geen geldige damhoogte ingevoerd.", msgs[1]); StringAssert.StartsWith(string.Format("Validatie van '{0}' beëindigd om: ", name), msgs[2]); }); Assert.IsFalse(isValid); mockRepository.VerifyAll(); } [Test] [TestCase(true, 10.0)] [TestCase(false, 10.0)] [TestCase(false, double.NaN)] [TestCase(false, double.PositiveInfinity)] [TestCase(false, double.NegativeInfinity)] public void Validate_ValidInputAndValidateBreakWaterHeight_ReturnsTrue(bool useBreakWater, double breakWaterHeight) { // Setup var grassCoverErosionInwardsFailureMechanism = new GrassCoverErosionInwardsFailureMechanism(); var mockRepository = new MockRepository(); var assessmentSectionStub = CreateAssessmentSectionStub(grassCoverErosionInwardsFailureMechanism, mockRepository); mockRepository.ReplayAll(); const string name = ""; GrassCoverErosionInwardsCalculation calculation = GetCalculationWithBreakWater(name, breakWaterHeight); calculation.InputParameters.UseBreakWater = useBreakWater; // Call bool isValid = false; Action call = () => isValid = new GrassCoverErosionInwardsCalculationService().Validate(calculation, assessmentSectionStub); // Assert TestHelper.AssertLogMessages(call, messages => { var msgs = messages.ToArray(); Assert.AreEqual(2, msgs.Length); StringAssert.StartsWith(string.Format("Validatie van '{0}' gestart om: ", name), msgs[0]); StringAssert.StartsWith(string.Format("Validatie van '{0}' beëindigd om: ", name), msgs[1]); }); Assert.IsTrue(isValid); mockRepository.VerifyAll(); } [Test] public void Validate_ValidInput_ReturnsTrue() { // Setup var grassCoverErosionInwardsFailureMechanism = new GrassCoverErosionInwardsFailureMechanism(); var mockRepository = new MockRepository(); var assessmentSectionStub = CreateAssessmentSectionStub(grassCoverErosionInwardsFailureMechanism, mockRepository); mockRepository.ReplayAll(); const string name = ""; GrassCoverErosionInwardsCalculation calculation = new GrassCoverErosionInwardsCalculation { Name = name, InputParameters = { HydraulicBoundaryLocation = new HydraulicBoundaryLocation(1, "name", 2, 2), DikeProfile = new DikeProfile(new Point2D(0, 0), new RoughnessPoint[0], new Point2D[0], null, new DikeProfile.ConstructionProperties()) } }; // Call bool isValid = false; Action call = () => isValid = new GrassCoverErosionInwardsCalculationService().Validate(calculation, assessmentSectionStub); // Assert TestHelper.AssertLogMessages(call, messages => { var msgs = messages.ToArray(); Assert.AreEqual(2, msgs.Length); StringAssert.StartsWith(string.Format("Validatie van '{0}' gestart om: ", name), msgs[0]); StringAssert.StartsWith(string.Format("Validatie van '{0}' beëindigd om: ", name), msgs[1]); }); Assert.IsTrue(isValid); mockRepository.VerifyAll(); } [Test] [TestCase(true, false)] [TestCase(false, true)] public void CalculateDikeHeight_CalculationValid_DikeHeightCalculated(bool useForeland, bool calculateDikeHeight) { // Setup var grassCoverErosionInwardsFailureMechanism = new GrassCoverErosionInwardsFailureMechanism(); AddSectionToFailureMechanism(grassCoverErosionInwardsFailureMechanism); var mockRepository = new MockRepository(); var assessmentSectionStub = CreateAssessmentSectionStub(grassCoverErosionInwardsFailureMechanism, mockRepository); mockRepository.ReplayAll(); var dikeProfile = GetDikeProfile(); var calculation = new GrassCoverErosionInwardsCalculation { InputParameters = { HydraulicBoundaryLocation = assessmentSectionStub.HydraulicBoundaryDatabase.Locations.First(hl => hl.Id == 1300001), DikeProfile = dikeProfile, CalculateDikeHeight = calculateDikeHeight, UseForeshore = useForeland } }; var failureMechanismSection = grassCoverErosionInwardsFailureMechanism.Sections.First(); using (new HydraRingCalculatorFactoryConfig()) { // Call new GrassCoverErosionInwardsCalculationService().CalculateDikeHeight(calculation, assessmentSectionStub, failureMechanismSection, grassCoverErosionInwardsFailureMechanism.GeneralInput, grassCoverErosionInwardsFailureMechanism.Contribution, testDataPath); } // Assert Assert.IsFalse(double.IsNaN(calculation.Output.WaveHeight)); Assert.IsNotNull(calculation.Output.ProbabilityAssessmentOutput); Assert.IsFalse(double.IsNaN(calculation.Output.ProbabilityAssessmentOutput.FactorOfSafety)); Assert.IsFalse(double.IsNaN(calculation.Output.ProbabilityAssessmentOutput.Probability)); Assert.IsFalse(double.IsNaN(calculation.Output.ProbabilityAssessmentOutput.Reliability)); Assert.IsFalse(double.IsNaN(calculation.Output.ProbabilityAssessmentOutput.RequiredProbability)); Assert.IsFalse(double.IsNaN(calculation.Output.ProbabilityAssessmentOutput.RequiredReliability)); Assert.AreNotEqual(calculateDikeHeight, double.IsNaN(calculation.Output.DikeHeight)); Assert.AreEqual(calculateDikeHeight, calculation.Output.DikeHeightCalculated); Assert.IsFalse(calculation.Output.IsOvertoppingDominant); mockRepository.VerifyAll(); } [Test] public void CalculateDikeHeight_DikeHeightCalculationFails_DikeHeightOutputNaN() { // Setup var grassCoverErosionInwardsFailureMechanism = new GrassCoverErosionInwardsFailureMechanism(); AddSectionToFailureMechanism(grassCoverErosionInwardsFailureMechanism); var mockRepository = new MockRepository(); var assessmentSectionStub = CreateAssessmentSectionStub(grassCoverErosionInwardsFailureMechanism, mockRepository); mockRepository.ReplayAll(); var dikeProfile = GetDikeProfile(); var calculation = new GrassCoverErosionInwardsCalculation { InputParameters = { HydraulicBoundaryLocation = assessmentSectionStub.HydraulicBoundaryDatabase.Locations.First(hl => hl.Id == 1300001), DikeProfile = dikeProfile, CalculateDikeHeight = true } }; var failureMechanismSection = grassCoverErosionInwardsFailureMechanism.Sections.First(); double? output = null; bool expectedExceptionThrown = false; // Call Action call = () => { try { new GrassCoverErosionInwardsCalculationService().CalculateDikeHeight(calculation, assessmentSectionStub, failureMechanismSection, grassCoverErosionInwardsFailureMechanism.GeneralInput, grassCoverErosionInwardsFailureMechanism.Contribution, testDataPath); } catch (HydraRingFileParserException) { expectedExceptionThrown = true; } }; // Assert TestHelper.AssertLogMessages(call, messages => { var msgs = messages.ToArray(); Assert.AreEqual(5, msgs.Length); StringAssert.StartsWith(string.Format("Berekening van '{0}' gestart om: ", calculation.Name), msgs[0]); StringAssert.StartsWith("Overloop berekeningsverslag. Klik op details voor meer informatie.\n", msgs[1]); StringAssert.StartsWith(string.Format("De HBN berekening voor grasbekleding erosie kruin en binnentalud '{0}' is niet gelukt.", calculation.Name), msgs[2]); StringAssert.StartsWith("Dijkhoogte berekeningsverslag. Klik op details voor meer informatie.\n", msgs[3]); StringAssert.StartsWith(string.Format("Berekening van '{0}' beëindigd om: ", calculation.Name), msgs[4]); }); Assert.IsFalse(expectedExceptionThrown); Assert.IsNotNull(calculation.Output); Assert.IsNaN(calculation.Output.DikeHeight); Assert.IsTrue(calculation.Output.DikeHeightCalculated); mockRepository.VerifyAll(); } private static void AddSectionToFailureMechanism(GrassCoverErosionInwardsFailureMechanism failureMechanism) { failureMechanism.AddSection(new FailureMechanismSection("test section", new[] { new Point2D(0, 0), new Point2D(1, 1) })); } private static DikeProfile GetDikeProfile() { return new DikeProfile( new Point2D(0, 0), new[] { new RoughnessPoint(new Point2D(1.1, 2.2), 0.6), new RoughnessPoint(new Point2D(3.3, 4.4), 0.7) }, new[] { new Point2D(-2.0, -2.0), new Point2D(-1.0, -1.0) }, null, new DikeProfile.ConstructionProperties { Orientation = 5.5, DikeHeight = 10 }); } private static GrassCoverErosionInwardsCalculation GetCalculationWithBreakWater(string name, double breakWaterHeight) { return new GrassCoverErosionInwardsCalculation { Name = name, InputParameters = { HydraulicBoundaryLocation = new HydraulicBoundaryLocation(1, "name", 2, 2), DikeProfile = new DikeProfile(new Point2D(0, 0), new RoughnessPoint[0], new Point2D[0], new BreakWater(BreakWaterType.Dam, breakWaterHeight), new DikeProfile.ConstructionProperties()), } }; } private static IAssessmentSection CreateAssessmentSectionStub(IFailureMechanism failureMechanism, MockRepository mockRepository) { var assessmentSectionStub = mockRepository.Stub(); assessmentSectionStub.Stub(a => a.Id).Return("21"); assessmentSectionStub.Stub(a => a.FailureMechanismContribution).Return(new FailureMechanismContribution(new[] { failureMechanism }, 1, 2)); assessmentSectionStub.HydraulicBoundaryDatabase = new HydraulicBoundaryDatabase { Locations = { new HydraulicBoundaryLocation(1300001, String.Empty, 0, 0) } }; return assessmentSectionStub; } } }