Index: Application/Riskeer/src/Application.Riskeer/App.xaml.cs =================================================================== diff -u -r35c595cd0cda9b410a386c8b37878a163071834e -r77da36c3f350a8b9ffe4c419ce00843569271f24 --- Application/Riskeer/src/Application.Riskeer/App.xaml.cs (.../App.xaml.cs) (revision 35c595cd0cda9b410a386c8b37878a163071834e) +++ Application/Riskeer/src/Application.Riskeer/App.xaml.cs (.../App.xaml.cs) (revision 77da36c3f350a8b9ffe4c419ce00843569271f24) @@ -129,7 +129,7 @@ SupportEmailAddressUrl = "https://www.helpdeskwater.nl/onderwerpen/applicaties-modellen/applicaties-per/omgevings/omgevings/riskeer/contact/vraag-ringtoets/", SupportPhoneNumberUrl = "https://www.helpdeskwater.nl/secundaire-navigatie/contact/", ManualFilePath = "Gebruikershandleiding Riskeer 21.1.1.pdf", - OnNewProjectCreatedAction = (g, project) => new AssessmentSectionFromFileCommandHandler(g.MainWindow, g.DocumentViewController).AddAssessmentSectionFromFile((RiskeerProject) project) + OnNewProjectCreatedAction = (g, project) => new AssessmentSectionFromFileHandler(g.MainWindow, g.DocumentViewController).AddAssessmentSectionFromFile((RiskeerProject) project) }; var mainWindow = new MainWindow(); Fisheye: Tag 77da36c3f350a8b9ffe4c419ce00843569271f24 refers to a dead (removed) revision in file `Riskeer/Integration/src/Riskeer.Integration.Plugin/Handlers/AssessmentSectionFromFileCommandHandler.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Riskeer/Integration/src/Riskeer.Integration.Plugin/Handlers/AssessmentSectionFromFileHandler.cs =================================================================== diff -u --- Riskeer/Integration/src/Riskeer.Integration.Plugin/Handlers/AssessmentSectionFromFileHandler.cs (revision 0) +++ Riskeer/Integration/src/Riskeer.Integration.Plugin/Handlers/AssessmentSectionFromFileHandler.cs (revision 77da36c3f350a8b9ffe4c419ce00843569271f24) @@ -0,0 +1,367 @@ +// Copyright (C) Stichting Deltares 2021. All rights reserved. +// +// This file is part of Riskeer. +// +// Riskeer 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.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Windows.Forms; +using Core.Common.Base; +using Core.Common.Base.Data; +using Core.Common.Base.IO; +using Core.Gui.Forms.ViewHost; +using log4net; +using Riskeer.Common.Data.AssessmentSection; +using Riskeer.Common.Data.Contribution; +using Riskeer.Common.Forms.Helpers; +using Riskeer.Common.IO; +using Riskeer.Common.IO.Exceptions; +using Riskeer.Common.IO.ReferenceLines; +using Riskeer.Integration.Data; +using Riskeer.Integration.Forms; +using Riskeer.Integration.Forms.Dialogs; +using Riskeer.Integration.Plugin.Properties; +using IntegrationResources = Riskeer.Integration.Data.Properties.Resources; +using BaseResources = Core.Common.Base.Properties.Resources; + +namespace Riskeer.Integration.Plugin.Handlers +{ + /// + /// This class is responsible for adding an from a predefined location. + /// + public class AssessmentSectionFromFileHandler : IAssessmentSectionFromFileHandler + { + private static readonly ILog log = LogManager.GetLogger(typeof(AssessmentSectionFromFileHandler)); + private readonly string shapeFileDirectory = RiskeerSettingsHelper.GetCommonDocumentsRiskeerShapeFileDirectory(); + + private readonly IWin32Window dialogParent; + private readonly IDocumentViewController viewController; + private IEnumerable settings; + private IEnumerable referenceLineMetas = new List(); + + /// + /// Initializes a new instance of the class. + /// + /// The parent of the dialog. + /// The document view controller. + /// Thrown when any parameter is null. + public AssessmentSectionFromFileHandler(IWin32Window dialogParent, IDocumentViewController viewController) + { + if (dialogParent == null) + { + throw new ArgumentNullException(nameof(dialogParent)); + } + + if (viewController == null) + { + throw new ArgumentNullException(nameof(viewController)); + } + + this.dialogParent = dialogParent; + this.viewController = viewController; + } + + public void AddAssessmentSectionFromFile(RiskeerProject project) + { + if (project == null) + { + throw new ArgumentNullException(nameof(project)); + } + + if (!TryReadSourceFiles()) + { + return; + } + + AssessmentSection assessmentSection = GetAssessmentSectionFromDialog(); + if (assessmentSection == null) + { + return; + } + + SetAssessmentSectionToProject(project, assessmentSection); + } + + #region Dialog + + private AssessmentSection GetAssessmentSectionFromDialog() + { + using (ReferenceLineMetaSelectionDialog dialog = CreateReferenceLineMetaSelectionDialogWithItems()) + { + if (dialog.ShowDialog() != DialogResult.OK) + { + return null; + } + + ReferenceLineMeta selectedItem = dialog.SelectedReferenceLineMeta; + + return selectedItem == null + ? null + : TryCreateAssessmentSection(selectedItem, + dialog.SelectedLowerLimitNorm, + dialog.SelectedSignalingNorm, + dialog.SelectedNormativeNorm); + } + } + + private ReferenceLineMetaSelectionDialog CreateReferenceLineMetaSelectionDialogWithItems() + { + return new ReferenceLineMetaSelectionDialog(dialogParent, referenceLineMetas); + } + + #endregion + + #region Set AssessmentSection to Project + + private static void SetFailureMechanismsValueN(AssessmentSection assessmentSection, int n) + { + var roundedN = (RoundedDouble) n; + assessmentSection.GrassCoverErosionInwards.GeneralInput.N = roundedN; + assessmentSection.GrassCoverErosionOutwards.GeneralInput.N = roundedN; + assessmentSection.HeightStructures.GeneralInput.N = roundedN; + } + + private void SetAssessmentSectionToProject(RiskeerProject riskeerProject, AssessmentSection assessmentSection) + { + assessmentSection.Name = GetUniqueForAssessmentSectionName(riskeerProject.AssessmentSections, assessmentSection.Name); + riskeerProject.AssessmentSections.Add(assessmentSection); + riskeerProject.NotifyObservers(); + + viewController.OpenViewForData(assessmentSection); + } + + private static string GetUniqueForAssessmentSectionName(IEnumerable assessmentSections, string baseName) + { + return NamingHelper.GetUniqueName(assessmentSections, baseName, a => a.Name); + } + + #endregion + + #region Create AssessmentSection + + /// + /// Creates a new instance of with + /// set to . + /// + /// The lower limit norm of the assessment section. + /// The signaling norm which of the assessment section. + /// The newly created . + /// Thrown when: + /// + /// is not in the interval [0.000001, 0.1] or is ; + /// is not in the interval [0.000001, 0.1] or is ; + /// The is larger than . + /// + /// + private static AssessmentSection CreateDikeAssessmentSection(double lowerLimitNorm, double signalingNorm) + { + return new AssessmentSection(AssessmentSectionComposition.Dike, lowerLimitNorm, signalingNorm); + } + + /// + /// Creates a new instance of with + /// set to . + /// + /// The lower limit norm of the assessment section. + /// The signaling norm which of the assessment section. + /// The 'N' parameter used to factor in the 'length effect'. + /// The newly created . + /// Thrown when: + /// + /// is not in the interval [0.000001, 0.1] or is ; + /// is not in the interval [0.000001, 0.1] or is ; + /// The is larger than . + /// + /// + private static AssessmentSection CreateDikeAssessmentSection(double lowerLimitNorm, double signalingNorm, int n) + { + AssessmentSection assessmentSection = CreateDikeAssessmentSection(lowerLimitNorm, signalingNorm); + SetFailureMechanismsValueN(assessmentSection, n); + return assessmentSection; + } + + /// + /// Creates a new instance of with + /// set to . + /// + /// The lower limit norm of the assessment section. + /// The signaling norm which of the assessment section. + /// The 'N' parameter used to factor in the 'length effect'. + /// The newly created . + /// Thrown when: + /// + /// is not in the interval [0.000001, 0.1] or is ; + /// is not in the interval [0.000001, 0.1] or is ; + /// The is larger than . + /// + /// + private static AssessmentSection CreateDuneAssessmentSection(double lowerLimitNorm, double signalingNorm, int n) + { + var duneAssessmentSection = new AssessmentSection(AssessmentSectionComposition.Dune, + lowerLimitNorm, + signalingNorm); + SetFailureMechanismsValueN(duneAssessmentSection, n); + return duneAssessmentSection; + } + + /// + /// Creates a new instance of . + /// + /// The selected . + /// The lower limit norm of the assessment section. + /// The signaling norm which of the assessment section. + /// The norm type of the assessment section. + /// The newly created . + /// Thrown when: + /// + /// is not in the interval [0.000001, 0.1] or is ; + /// is not in the interval [0.000001, 0.1] or is ; + /// The is larger than . + /// + /// + private AssessmentSection CreateAssessmentSection(ReferenceLineMeta selectedItem, + double lowerLimitNorm, + double signalingNorm, + NormType normativeNorm) + { + AssessmentSection assessmentSection; + AssessmentSectionSettings settingOfSelectedAssessmentSection = settings.FirstOrDefault(s => s.AssessmentSectionId == selectedItem.AssessmentSectionId); + if (settingOfSelectedAssessmentSection == null) + { + log.Warn(Resources.AssessmentSectionFromFileCommandHandler_CreateAssessmentSection_No_settings_found_for_AssessmentSection); + assessmentSection = CreateDikeAssessmentSection(lowerLimitNorm, signalingNorm); + } + else + { + assessmentSection = settingOfSelectedAssessmentSection.IsDune + ? CreateDuneAssessmentSection(lowerLimitNorm, + signalingNorm, + settingOfSelectedAssessmentSection.N) + : CreateDikeAssessmentSection(lowerLimitNorm, + signalingNorm, + settingOfSelectedAssessmentSection.N); + } + + assessmentSection.Name = string.Format(IntegrationResources.AssessmentSection_Id_0, selectedItem.AssessmentSectionId); + assessmentSection.Id = selectedItem.AssessmentSectionId; + + if (!selectedItem.ReferenceLine.Points.Any()) + { + log.Warn(Resources.AssessmentSectionFromFileCommandHandler_CreateAssessmentSection_Importing_ReferenceLineFailed); + } + else + { + assessmentSection.ReferenceLine.SetGeometry(selectedItem.ReferenceLine.Points); + } + + assessmentSection.FailureMechanismContribution.NormativeNorm = normativeNorm; + + return assessmentSection; + } + + private AssessmentSection TryCreateAssessmentSection(ReferenceLineMeta selectedItem, + double lowerLimitNorm, + double signalingNorm, + NormType normativeNorm) + { + try + { + return CreateAssessmentSection(selectedItem, + lowerLimitNorm, + signalingNorm, + normativeNorm); + } + catch (ArgumentOutOfRangeException exception) + { + var normValidityRange = new Range(1.0 / 1000000, 1.0 / 10); + string message = string.Format(Resources.AssessmentSectionFromFileCommandHandler_Unable_to_create_assessmentSection_with_LowerLimitNorm_0_and_SignalingNorm_1_Norms_should_be_in_Range_2_, + ProbabilityFormattingHelper.Format(lowerLimitNorm), + ProbabilityFormattingHelper.Format(signalingNorm), + normValidityRange.ToString(FormattableConstants.ShowAtLeastOneDecimal, CultureInfo.CurrentCulture)); + + log.Error(message, exception); + } + + return null; + } + + #endregion + + #region Validators + + private bool TryReadSourceFiles() + { + ReadAssessmentSectionSettings(); + + try + { + ReadReferenceLineMetas(); + } + catch (CriticalFileValidationException exception) + { + MessageBox.Show(exception.Message, BaseResources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); + log.Error(exception.Message, exception.InnerException); + return false; + } + catch (CriticalFileReadException exception) + { + log.Error(exception.Message, exception.InnerException); + return false; + } + + return true; + } + + /// + /// Reads all objects from the shape file located at . + /// + /// Thrown when: + /// + /// points to an invalid directory. + /// The path does not contain any shape files. + /// Thrown when the shape file does not contain poly lines. + /// + /// Thrown when: + /// + /// The shape file does not contain the required attributes. + /// The assessment section ids in the shape file are not unique or are missing. + /// No could be read from the shape file. + /// + private void ReadReferenceLineMetas() + { + var importer = new ReferenceLineMetaImporter(shapeFileDirectory); + referenceLineMetas = importer.GetReferenceLineMetas(); + + if (!referenceLineMetas.Any()) + { + throw new CriticalFileValidationException(Resources.AssessmentSectionFromFileCommandHandler_ValidateReferenceLineMetas_No_referenceLines_in_file); + } + } + + private void ReadAssessmentSectionSettings() + { + var reader = new AssessmentSectionSettingsReader(); + settings = reader.ReadSettings(); + } + + #endregion + } +} \ No newline at end of file Fisheye: Tag 77da36c3f350a8b9ffe4c419ce00843569271f24 refers to a dead (removed) revision in file `Riskeer/Integration/src/Riskeer.Integration.Plugin/Handlers/IAssessmentSectionFromFileCommandHandler.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Riskeer/Integration/src/Riskeer.Integration.Plugin/Handlers/IAssessmentSectionFromFileHandler.cs =================================================================== diff -u --- Riskeer/Integration/src/Riskeer.Integration.Plugin/Handlers/IAssessmentSectionFromFileHandler.cs (revision 0) +++ Riskeer/Integration/src/Riskeer.Integration.Plugin/Handlers/IAssessmentSectionFromFileHandler.cs (revision 77da36c3f350a8b9ffe4c419ce00843569271f24) @@ -0,0 +1,44 @@ +// Copyright (C) Stichting Deltares 2021. All rights reserved. +// +// This file is part of Riskeer. +// +// Riskeer 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 Core.Common.Base.Data; +using Riskeer.Common.Data.AssessmentSection; + +namespace Riskeer.Integration.Plugin.Handlers +{ + /// + /// Interface for handling adding to a . + /// + /// The type of project. + public interface IAssessmentSectionFromFileHandler + where TProject : IProject + { + /// + /// Displays available objects to the user and asks to select one. + /// The selected , if any, will be added to the . + /// + /// The project to add the to. + /// Thrown when + /// is null. + void AddAssessmentSectionFromFile(TProject project); + } +} \ No newline at end of file Fisheye: Tag 77da36c3f350a8b9ffe4c419ce00843569271f24 refers to a dead (removed) revision in file `Riskeer/Integration/test/Riskeer.Integration.Plugin.Test/Handlers/AssessmentSectionFromFileCommandHandlerTest.cs'. Fisheye: No comparison available. Pass `N' to diff? Index: Riskeer/Integration/test/Riskeer.Integration.Plugin.Test/Handlers/AssessmentSectionFromFileHandlerTest.cs =================================================================== diff -u --- Riskeer/Integration/test/Riskeer.Integration.Plugin.Test/Handlers/AssessmentSectionFromFileHandlerTest.cs (revision 0) +++ Riskeer/Integration/test/Riskeer.Integration.Plugin.Test/Handlers/AssessmentSectionFromFileHandlerTest.cs (revision 77da36c3f350a8b9ffe4c419ce00843569271f24) @@ -0,0 +1,636 @@ +// Copyright (C) Stichting Deltares 2021. All rights reserved. +// +// This file is part of Riskeer. +// +// Riskeer 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 System.Reflection; +using System.Windows.Forms; +using Core.Common.Base.Data; +using Core.Common.Base.Geometry; +using Core.Common.Base.TestUtil.Geometry; +using Core.Common.Controls.DataGrid; +using Core.Common.TestUtil; +using Core.Gui.Forms.ViewHost; +using log4net.Core; +using NUnit.Extensions.Forms; +using NUnit.Framework; +using Rhino.Mocks; +using Riskeer.Common.Data.AssessmentSection; +using Riskeer.Common.Data.Contribution; +using Riskeer.Common.Forms.Helpers; +using Riskeer.Common.Forms.TestUtil; +using Riskeer.Integration.Data; +using Riskeer.Integration.Forms.Dialogs; +using Riskeer.Integration.Plugin.Handlers; + +namespace Riskeer.Integration.Plugin.Test.Handlers +{ + [TestFixture] + public class AssessmentSectionFromFileHandlerTest : NUnitFormTest + { + private readonly string testDataPath = TestHelper.GetTestDataPath(TestDataPath.Riskeer.Common.IO, "ReferenceLineMetaImporter"); + + [Test] + public void Constructor_ParentDialogNull_ThrowsArgumentNullException() + { + // Setup + var mockRepository = new MockRepository(); + var viewController = mockRepository.StrictMock(); + mockRepository.ReplayAll(); + + // Call + void Call() => new AssessmentSectionFromFileHandler(null, viewController); + + // Assert + var exception = Assert.Throws(Call); + Assert.AreEqual("dialogParent", exception.ParamName); + mockRepository.VerifyAll(); + } + + [Test] + public void Constructor_ViewControllerNull_ThrowsArgumentNullException() + { + // Setup + var mockRepository = new MockRepository(); + var parentDialog = mockRepository.StrictMock(); + mockRepository.ReplayAll(); + + // Call + void Call() => new AssessmentSectionFromFileHandler(parentDialog, null); + + // Assert + var exception = Assert.Throws(Call); + Assert.AreEqual("viewController", exception.ParamName); + mockRepository.VerifyAll(); + } + + [Test] + public void Constructor_WithData_ExpectedValues() + { + // Setup + var mockRepository = new MockRepository(); + var parentDialog = mockRepository.StrictMock(); + var viewController = mockRepository.StrictMock(); + mockRepository.ReplayAll(); + + // Call + var assessmentSectionFromFileHandler = new AssessmentSectionFromFileHandler(parentDialog, viewController); + + // Assert + Assert.IsInstanceOf>(assessmentSectionFromFileHandler); + mockRepository.VerifyAll(); + } + + [Test] + public void AddAssessmentSectionFromFile_ProjectNull_ThrowsArgumentNullException() + { + // Setup + var mockRepository = new MockRepository(); + var parentDialog = mockRepository.StrictMock(); + var viewController = mockRepository.StrictMock(); + mockRepository.ReplayAll(); + + var assessmentSectionFromFileHandler = new AssessmentSectionFromFileHandler(parentDialog, viewController); + + // Call + void Call() => assessmentSectionFromFileHandler.AddAssessmentSectionFromFile(null); + + // Assert + var exception = Assert.Throws(Call); + Assert.AreEqual("project", exception.ParamName); + mockRepository.VerifyAll(); + } + + [Test] + public void AddAssessmentSectionFromFile_InvalidDirectory_LogsWarningProjectNotUpdated() + { + // Setup + var mockRepository = new MockRepository(); + var parentDialog = mockRepository.StrictMock(); + var viewController = mockRepository.StrictMock(); + mockRepository.ReplayAll(); + + var assessmentSectionFromFileHandler = new AssessmentSectionFromFileHandler(parentDialog, viewController); + + string pathToNonExistingFolder = Path.Combine(testDataPath, "I do not exist"); + SetShapeFileDirectory(assessmentSectionFromFileHandler, pathToNonExistingFolder); + + var project = new RiskeerProject(); + + // Call + void Action() => assessmentSectionFromFileHandler.AddAssessmentSectionFromFile(project); + + // Assert + var expectedMessage = $"De map met specificaties voor trajecten '{pathToNonExistingFolder}' is niet gevonden."; + TestHelper.AssertLogMessageIsGenerated(Action, expectedMessage); + Assert.IsEmpty(project.AssessmentSections); + mockRepository.VerifyAll(); + } + + [Test] + public void AddAssessmentSectionFromFile_validDirectoryWithEmptyShapeFile_LogsWarningProjectNotUpdated() + { + // Setup + var mockRepository = new MockRepository(); + var parentDialog = mockRepository.StrictMock(); + var viewController = mockRepository.StrictMock(); + mockRepository.ReplayAll(); + + var assessmentSectionFromFileHandler = new AssessmentSectionFromFileHandler(parentDialog, viewController); + + string pathValidFolder = Path.Combine(testDataPath, "EmptyShapeFile"); + SetShapeFileDirectory(assessmentSectionFromFileHandler, pathValidFolder); + + string messageText = null; + DialogBoxHandler = (name, wnd) => + { + var messageBox = new MessageBoxTester(wnd); + messageText = messageBox.Text; + messageBox.ClickOk(); + }; + + var project = new RiskeerProject(); + + // Call + void Action() => assessmentSectionFromFileHandler.AddAssessmentSectionFromFile(project); + + // Assert + const string expectedMessage = "Er kunnen geen trajecten gelezen worden uit het shapebestand."; + TestHelper.AssertLogMessageIsGenerated(Action, expectedMessage); + Assert.AreEqual(expectedMessage, messageText); + Assert.IsEmpty(project.AssessmentSections); + mockRepository.VerifyAll(); + } + + [Test] + public void AddAssessmentSectionFromFile_ValidDirectoryUserClicksCancel_ProjectNotUpdated() + { + // Setup + var mockRepository = new MockRepository(); + var parentDialog = mockRepository.Stub(); + var viewController = mockRepository.StrictMock(); + mockRepository.ReplayAll(); + + var assessmentSectionFromFileHandler = new AssessmentSectionFromFileHandler(parentDialog, viewController); + + string pathValidFolder = Path.Combine(testDataPath, "ValidShapeFile"); + SetShapeFileDirectory(assessmentSectionFromFileHandler, pathValidFolder); + + DialogBoxHandler = (name, wnd) => + { + var selectionDialog = (ReferenceLineMetaSelectionDialog) new FormTester(name).TheObject; + new ButtonTester("Cancel", selectionDialog).Click(); + }; + + var project = new RiskeerProject(); + + // Call + assessmentSectionFromFileHandler.AddAssessmentSectionFromFile(project); + + // Assert + Assert.IsEmpty(project.AssessmentSections); + mockRepository.VerifyAll(); + } + + [Test] + public void AddAssessmentSectionFromFile_ValidDirectoryOkClicked_SetsFirstReadAssessmentSection() + { + // Setup + var mockRepository = new MockRepository(); + var parentDialog = mockRepository.Stub(); + var viewController = mockRepository.StrictMock(); + viewController.Expect(dvc => dvc.OpenViewForData(null)).IgnoreArguments().Return(true); + mockRepository.ReplayAll(); + + var assessmentSectionFromFileHandler = new AssessmentSectionFromFileHandler(parentDialog, viewController); + + string pathValidFolder = Path.Combine(testDataPath, "ValidShapeFile"); + SetShapeFileDirectory(assessmentSectionFromFileHandler, pathValidFolder); + + var rowCount = 0; + DialogBoxHandler = (name, wnd) => + { + var selectionDialog = (ReferenceLineMetaSelectionDialog) new FormTester(name).TheObject; + var grid = (DataGridViewControl) new ControlTester("ReferenceLineMetaDataGridViewControl", selectionDialog).TheObject; + rowCount = grid.Rows.Count; + new ButtonTester("Ok", selectionDialog).Click(); + }; + + var project = new RiskeerProject(); + + // Call + assessmentSectionFromFileHandler.AddAssessmentSectionFromFile(project); + + // Assert + Assert.AreEqual(3, rowCount); + AssessmentSection assessmentSection = project.AssessmentSections.FirstOrDefault(); + Assert.IsNotNull(assessmentSection); + AssertAssessmentSection(TestAssessmentSection1_2(true), assessmentSection); + mockRepository.VerifyAll(); + } + + [Test] + public void AddAssessmentSectionFromFile_ValidDirectoryOkClickedForDuplicateAssessmentSection_SetsFirstReadAssessmentSectionWithUniqueName() + { + // Setup + var mockRepository = new MockRepository(); + var parentDialog = mockRepository.Stub(); + var viewController = mockRepository.StrictMock(); + viewController.Expect(dvc => dvc.OpenViewForData(null)).IgnoreArguments().Return(true); + mockRepository.ReplayAll(); + + var assessmentSectionFromFileHandler = new AssessmentSectionFromFileHandler(parentDialog, viewController); + + string pathValidFolder = Path.Combine(testDataPath, "ValidShapeFile"); + SetShapeFileDirectory(assessmentSectionFromFileHandler, pathValidFolder); + + var project = new RiskeerProject(); + project.AssessmentSections.Add(TestAssessmentSection1_2(true)); + string expectedAssessmentSectionName = NamingHelper.GetUniqueName(project.AssessmentSections, "Traject 1-2", a => a.Name); + + var signallingValueRadioButtonSelected = false; + DialogBoxHandler = (name, wnd) => + { + var selectionDialog = (ReferenceLineMetaSelectionDialog) new FormTester(name).TheObject; + var signallingValueRadioButton = (RadioButton) new RadioButtonTester("SignallingValueRadioButton", selectionDialog).TheObject; + signallingValueRadioButtonSelected = signallingValueRadioButton.Checked; + new ButtonTester("Ok", selectionDialog).Click(); + }; + + // Call + assessmentSectionFromFileHandler.AddAssessmentSectionFromFile(project); + + // Assert + Assert.IsTrue(signallingValueRadioButtonSelected); + Assert.AreEqual(2, project.AssessmentSections.Count); + AssessmentSection assessmentSection = project.AssessmentSections[1]; + Assert.IsNotNull(assessmentSection); + + AssessmentSection expectedAssessmentSection = TestAssessmentSection1_2(true); + expectedAssessmentSection.Name = expectedAssessmentSectionName; + AssertAssessmentSection(expectedAssessmentSection, assessmentSection); + mockRepository.VerifyAll(); + } + + [Test] + public void AddAssessmentSectionFromFile_ValidDirectoryLowLimitSelectedOkClicked_SetsFirstReadAssessmentSectionWithLowLimit() + { + // Setup + var mockRepository = new MockRepository(); + var parentDialog = mockRepository.Stub(); + var viewController = mockRepository.StrictMock(); + viewController.Expect(dvc => dvc.OpenViewForData(null)).IgnoreArguments().Return(true); + mockRepository.ReplayAll(); + + var assessmentSectionFromFileHandler = new AssessmentSectionFromFileHandler(parentDialog, viewController); + + string pathValidFolder = Path.Combine(testDataPath, "ValidShapeFile"); + SetShapeFileDirectory(assessmentSectionFromFileHandler, pathValidFolder); + + DialogBoxHandler = (name, wnd) => + { + var selectionDialog = (ReferenceLineMetaSelectionDialog) new FormTester(name).TheObject; + var lowLimitValueRadioButton = (RadioButton) new RadioButtonTester("LowLimitValueRadioButton", selectionDialog).TheObject; + lowLimitValueRadioButton.Checked = true; + new ButtonTester("Ok", selectionDialog).Click(); + }; + + var project = new RiskeerProject(); + + // Call + assessmentSectionFromFileHandler.AddAssessmentSectionFromFile(project); + + // Assert + AssessmentSection assessmentSection = project.AssessmentSections.FirstOrDefault(); + Assert.IsNotNull(assessmentSection); + AssertAssessmentSection(TestAssessmentSection1_2(false), assessmentSection); + mockRepository.VerifyAll(); + } + + [Test] + public void AddAssessmentSectionFromFile_SecondRowSelectedOkClicked_SetsSecondReadAssessmentSection() + { + // Setup + var mockRepository = new MockRepository(); + var parentDialog = mockRepository.Stub(); + var viewController = mockRepository.StrictMock(); + viewController.Expect(dvc => dvc.OpenViewForData(null)).IgnoreArguments().Return(true); + mockRepository.ReplayAll(); + + var assessmentSectionFromFileHandler = new AssessmentSectionFromFileHandler(parentDialog, viewController); + + string pathValidFolder = Path.Combine(testDataPath, "ValidShapeFile"); + SetShapeFileDirectory(assessmentSectionFromFileHandler, pathValidFolder); + + var rowCount = 0; + DialogBoxHandler = (name, wnd) => + { + var selectionDialog = (ReferenceLineMetaSelectionDialog) new FormTester(name).TheObject; + var grid = (DataGridViewControl) new ControlTester("ReferenceLineMetaDataGridViewControl", selectionDialog).TheObject; + rowCount = grid.Rows.Count; + DataGridView dataGridView = grid.Controls.OfType().First(); + dataGridView[0, 1].Selected = true; + + new ButtonTester("Ok", selectionDialog).Click(); + }; + + var project = new RiskeerProject(); + + // Call + assessmentSectionFromFileHandler.AddAssessmentSectionFromFile(project); + + // Assert + Assert.AreEqual(3, rowCount); + AssessmentSection assessmentSection = project.AssessmentSections.FirstOrDefault(); + Assert.IsNotNull(assessmentSection); + AssertAssessmentSection(TestAssessmentSection2_1(), assessmentSection); + mockRepository.VerifyAll(); + } + + [Test] + public void AddAssessmentSectionFromFile_ThirdRowSelectedOkClicked_SetsThirdReadAssessmentSection() + { + // Setup + var mockRepository = new MockRepository(); + var parentDialog = mockRepository.Stub(); + var viewController = mockRepository.StrictMock(); + viewController.Expect(dvc => dvc.OpenViewForData(null)).IgnoreArguments().Return(true); + mockRepository.ReplayAll(); + + var assessmentSectionFromFileHandler = new AssessmentSectionFromFileHandler(parentDialog, viewController); + + string pathValidFolder = Path.Combine(testDataPath, "ValidShapeFile"); + SetShapeFileDirectory(assessmentSectionFromFileHandler, pathValidFolder); + + DialogBoxHandler = (name, wnd) => + { + var selectionDialog = (ReferenceLineMetaSelectionDialog) new FormTester(name).TheObject; + var grid = (DataGridViewControl) new ControlTester("ReferenceLineMetaDataGridViewControl", selectionDialog).TheObject; + DataGridView dataGridView = grid.Controls.OfType().First(); + dataGridView[0, 2].Selected = true; + + new ButtonTester("Ok", selectionDialog).Click(); + }; + + var project = new RiskeerProject(); + + // Call + void Call() => assessmentSectionFromFileHandler.AddAssessmentSectionFromFile(project); + + // Assert + const string expectedMessage = "Er zijn geen instellingen gevonden voor het geselecteerde traject. Standaardinstellingen zullen gebruikt worden."; + TestHelper.AssertLogMessageIsGenerated(Call, expectedMessage); + AssessmentSection assessmentSection = project.AssessmentSections.FirstOrDefault(); + Assert.IsNotNull(assessmentSection); + AssertAssessmentSection(TestAssessmentSection3_3(), assessmentSection); + mockRepository.VerifyAll(); + } + + [Test] + public void AddAssessmentSectionFromFile_ShapeWithoutPointsOkClicked_LogsAndSetsAssessmentSectionWithoutReferenceLine() + { + // Setup + var mockRepository = new MockRepository(); + var parentDialog = mockRepository.Stub(); + var viewController = mockRepository.StrictMock(); + viewController.Expect(dvc => dvc.OpenViewForData(null)).IgnoreArguments().Return(true); + mockRepository.ReplayAll(); + + var assessmentSectionFromFileHandler = new AssessmentSectionFromFileHandler(parentDialog, viewController); + + string pathValidFolder = Path.Combine(testDataPath, "ShapeWithoutPoints"); + SetShapeFileDirectory(assessmentSectionFromFileHandler, pathValidFolder); + + DialogBoxHandler = (name, wnd) => + { + var selectionDialog = (ReferenceLineMetaSelectionDialog) new FormTester(name).TheObject; + var grid = (DataGridViewControl) new ControlTester("ReferenceLineMetaDataGridViewControl", selectionDialog).TheObject; + DataGridView dataGridView = grid.Controls.OfType().First(); + dataGridView.Rows[1].Selected = true; + + new ButtonTester("Ok", selectionDialog).Click(); + }; + + var project = new RiskeerProject(); + + // Call + void Call() => assessmentSectionFromFileHandler.AddAssessmentSectionFromFile(project); + + // Assert + const string expectedMessage = "Het importeren van de referentielijn is mislukt."; + TestHelper.AssertLogMessageIsGenerated(Call, expectedMessage); + AssessmentSection assessmentSection = project.AssessmentSections.FirstOrDefault(); + Assert.IsNotNull(assessmentSection); + + AssessmentSection expectedAssessmentSection = TestAssessmentSection1_2(true); + expectedAssessmentSection.ReferenceLine.SetGeometry(Enumerable.Empty()); + + AssertAssessmentSection(expectedAssessmentSection, assessmentSection); + mockRepository.VerifyAll(); + } + + [Test] + [SetCulture("nl-NL")] + public void AddAssessmentSectionFromFile_ShapeWithInvalidNorm_LogsAndProjectNotUpdated() + { + // Setup + var mockRepository = new MockRepository(); + var parentDialog = mockRepository.Stub(); + var viewController = mockRepository.StrictMock(); + mockRepository.ReplayAll(); + + var assessmentSectionFromFileHandler = new AssessmentSectionFromFileHandler(parentDialog, viewController); + + string pathValidFolder = Path.Combine(testDataPath, "InvalidNorm"); + SetShapeFileDirectory(assessmentSectionFromFileHandler, pathValidFolder); + + DialogBoxHandler = (name, wnd) => + { + var selectionDialog = (ReferenceLineMetaSelectionDialog) new FormTester(name).TheObject; + + DataGridView dataGridView = ControlTestHelper.GetDataGridView(selectionDialog, "dataGridView"); + dataGridView.Rows[0].Selected = true; + + new ButtonTester("Ok", selectionDialog).Click(); + }; + + var project = new RiskeerProject(); + + // Call + void Call() => assessmentSectionFromFileHandler.AddAssessmentSectionFromFile(project); + + // Assert + const string expectedMessage = "Het traject kan niet aangemaakt worden met een ondergrens van 1/9.999.999 en een signaleringswaarde van 1/8.888.888. " + + "De waarde van de ondergrens en signaleringswaarde moet in het bereik [0,000001, 0,1] liggen en " + + "de ondergrens moet gelijk zijn aan of groter zijn dan de signaleringswaarde."; + TestHelper.AssertLogMessagesWithLevelAndLoggedExceptions(Call, tuples => + { + Tuple tuple = tuples.Single(); + Assert.AreEqual(expectedMessage, tuple.Item1); + Assert.AreEqual(Level.Error, tuple.Item2); + Assert.IsInstanceOf(tuple.Item3); + }); + CollectionAssert.IsEmpty(project.AssessmentSections); + + mockRepository.VerifyAll(); + } + + private static void SetShapeFileDirectory(AssessmentSectionFromFileHandler handler, string nonExistingFolder) + { + const string privateShapeFileDirectoryName = "shapeFileDirectory"; + Type commandHandlerType = handler.GetType(); + FieldInfo fieldInfo = commandHandlerType.GetField(privateShapeFileDirectoryName, BindingFlags.NonPublic | BindingFlags.Instance); + if (fieldInfo == null) + { + Assert.Fail("Unable to find private field '{0}'", privateShapeFileDirectoryName); + } + else + { + fieldInfo.SetValue(handler, nonExistingFolder); + } + } + + #region Test Assessment Sections + + private static AssessmentSection TestAssessmentSection1_2(bool useSignalingValue) + { + var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike, + 1.0 / 1000, + 1.0 / 3000) + { + Id = "1-2", + Name = "Traject 1-2", + FailureMechanismContribution = + { + NormativeNorm = useSignalingValue ? NormType.Signaling : NormType.LowerLimit + } + }; + assessmentSection.GrassCoverErosionInwards.GeneralInput.N = (RoundedDouble) 2.0; + assessmentSection.GrassCoverErosionOutwards.GeneralInput.N = (RoundedDouble) 2.0; + assessmentSection.HeightStructures.GeneralInput.N = (RoundedDouble) 2.0; + assessmentSection.ReferenceLine.SetGeometry(new[] + { + new Point2D(160679.9250, 475072.583), + new Point2D(160892.0751, 474315.4917) + }); + + return assessmentSection; + } + + private static AssessmentSection TestAssessmentSection2_1() + { + var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dune, + 1.0 / 100, + 1.0 / 300) + { + Id = "2-1", + Name = "Traject 2-1", + FailureMechanismContribution = + { + NormativeNorm = NormType.Signaling + }, + GrassCoverErosionInwards = + { + GeneralInput = + { + N = (RoundedDouble) 3.0 + } + }, + GrassCoverErosionOutwards = + { + GeneralInput = + { + N = (RoundedDouble) 3.0 + } + }, + HeightStructures = + { + GeneralInput = + { + N = (RoundedDouble) 3.0 + } + } + }; + + assessmentSection.ReferenceLine.SetGeometry(new[] + { + new Point2D(155556.9191, 464341.1281), + new Point2D(155521.4761, 464360.7401) + }); + + return assessmentSection; + } + + private static AssessmentSection TestAssessmentSection3_3() + { + var assessmentSection = new AssessmentSection(AssessmentSectionComposition.Dike, + 1.0 / 100, + 1.0 / 300) + { + Id = "3-3", + Name = "Traject 3-3", + FailureMechanismContribution = + { + NormativeNorm = NormType.Signaling + } + }; + assessmentSection.ReferenceLine.SetGeometry(new[] + { + new Point2D(147367.32190, 476902.91571), + new Point2D(147410.0515, 476938.9447) + }); + + return assessmentSection; + } + + #endregion + + #region Asserts + + private static void AssertAssessmentSection(AssessmentSection expected, AssessmentSection actual) + { + Assert.AreEqual(expected.Id, actual.Id); + Assert.AreEqual(expected.Name, actual.Name); + Assert.AreEqual(expected.FailureMechanismContribution.LowerLimitNorm, actual.FailureMechanismContribution.LowerLimitNorm); + Assert.AreEqual(expected.FailureMechanismContribution.SignalingNorm, actual.FailureMechanismContribution.SignalingNorm); + Assert.AreEqual(expected.FailureMechanismContribution.NormativeNorm, actual.FailureMechanismContribution.NormativeNorm); + Assert.AreEqual(expected.Composition, actual.Composition); + + Assert.AreEqual(expected.GrassCoverErosionInwards.GeneralInput.N, actual.GrassCoverErosionInwards.GeneralInput.N); + Assert.AreEqual(expected.GrassCoverErosionOutwards.GeneralInput.N, actual.GrassCoverErosionOutwards.GeneralInput.N); + Assert.AreEqual(expected.HeightStructures.GeneralInput.N, actual.HeightStructures.GeneralInput.N); + + AssertReferenceLine(expected.ReferenceLine, actual.ReferenceLine); + } + + private static void AssertReferenceLine(ReferenceLine expected, ReferenceLine actual) + { + Point2D[] expectedPoints = expected.Points.ToArray(); + Point2D[] actualPoints = actual.Points.ToArray(); + CollectionAssert.AreEqual(expectedPoints, actualPoints, + new Point2DComparerWithTolerance(1e-6), + "Unexpected geometry found in ReferenceLine"); + } + + #endregion + } +} \ No newline at end of file