Index: Riskeer/Piping/src/Riskeer.Piping.Plugin/PipingPlugin.cs =================================================================== diff -u -r19c7ce8440cd9da93bd887cca1928eea56bc12ba -rf5ffb52fc4c01ab2809d0c662a4e52a10f9307c7 --- Riskeer/Piping/src/Riskeer.Piping.Plugin/PipingPlugin.cs (.../PipingPlugin.cs) (revision 19c7ce8440cd9da93bd887cca1928eea56bc12ba) +++ Riskeer/Piping/src/Riskeer.Piping.Plugin/PipingPlugin.cs (.../PipingPlugin.cs) (revision f5ffb52fc4c01ab2809d0c662a4e52a10f9307c7) @@ -1,4 +1,4 @@ -// Copyright (C) Stichting Deltares 2019. All rights reserved. +// Copyright (C) Stichting Deltares 2019. All rights reserved. // // This file is part of Riskeer. // @@ -286,6 +286,11 @@ SemiProbabilisticCalculationContextContextMenuStrip, SemiProbabilisticCalculationContextOnNodeRemoved); + yield return RiskeerTreeNodeInfoFactory.CreateCalculationContextTreeNodeInfo( + ProbabilisticCalculationContextChildNodeObjects, + ProbabilisticCalculationContextContextMenuStrip, + ProbabilisticCalculationContextOnNodeRemoved); + yield return RiskeerTreeNodeInfoFactory.CreateCalculationGroupContextTreeNodeInfo( CalculationGroupContextChildNodeObjects, CalculationGroupContextContextMenuStrip, @@ -1008,6 +1013,127 @@ #endregion + #region ProbabilisticPipingCalculationContext TreeNodeInfo + + private static object[] ProbabilisticCalculationContextChildNodeObjects(ProbabilisticPipingCalculationContext context) + { + ProbabilisticPipingCalculation calculation = context.WrappedData; + + var childNodes = new List + { + calculation.Comments, + new ProbabilisticPipingInputContext(calculation.InputParameters, + calculation, + context.AvailablePipingSurfaceLines, + context.AvailableStochasticSoilModels, + context.FailureMechanism, + context.AssessmentSection) + }; + + if (calculation.HasOutput) + { + childNodes.Add(new PipingOutputContext( + calculation.Output, + context.FailureMechanism, + context.AssessmentSection)); + } + else + { + childNodes.Add(new EmptyPipingOutput()); + } + + return childNodes.ToArray(); + } + + private ContextMenuStrip ProbabilisticCalculationContextContextMenuStrip(ProbabilisticPipingCalculationContext nodeData, + object parentData, TreeViewControl treeViewControl) + { + var builder = new RiskeerContextMenuBuilder(Gui.Get(nodeData, treeViewControl)); + + ProbabilisticPipingCalculation calculation = nodeData.WrappedData; + + StrictContextMenuItem updateEntryAndExitPoint = CreateUpdateEntryAndExitPointItem(nodeData); + + return builder.AddExportItem() + .AddSeparator() + .AddDuplicateCalculationItem(calculation, nodeData) + .AddSeparator() + .AddRenameItem() + .AddCustomItem(updateEntryAndExitPoint) + .AddSeparator() + .AddValidateCalculationItem( + nodeData, + Validate) + .AddPerformCalculationItem( + calculation, + nodeData, + Calculate) + .AddSeparator() + .AddClearCalculationOutputItem(calculation) + .AddDeleteItem() + .AddSeparator() + .AddCollapseAllItem() + .AddExpandAllItem() + .AddSeparator() + .AddPropertiesItem() + .Build(); + } + + private StrictContextMenuItem CreateUpdateEntryAndExitPointItem(ProbabilisticPipingCalculationContext context) + { + var contextMenuEnabled = true; + string toolTipMessage = Resources.PipingPlugin_CreateUpdateEntryAndExitPointItem_Update_calculation_with_characteristic_points_ToolTip; + if (context.WrappedData.InputParameters.SurfaceLine == null) + { + contextMenuEnabled = false; + toolTipMessage = Resources.PipingPlugin_CreateUpdateEntryAndExitPointItem_Update_calculation_no_surface_line_ToolTip; + } + else if (context.WrappedData.InputParameters.IsEntryAndExitPointInputSynchronized) + { + contextMenuEnabled = false; + toolTipMessage = RiskeerCommonFormsResources.CalculationItem_No_changes_to_update_ToolTip; + } + + return new StrictContextMenuItem( + Resources.PipingPlugin_CreateUpdateEntryAndExitPointItem_Update_entry_and_exit_point, + toolTipMessage, + RiskeerCommonFormsResources.UpdateItemIcon, + (o, args) => UpdatedSurfaceLineDependentDataOfCalculation(context.WrappedData)) + { + Enabled = contextMenuEnabled + }; + } + + private void UpdatedSurfaceLineDependentDataOfCalculation(IPipingCalculation calculation) + { + string message = RiskeerCommonFormsResources.VerifyUpdate_Confirm_calculation_output_cleared; + if (VerifyEntryAndExitPointUpdates(new[] + { + calculation + }, message)) + { + UpdateSurfaceLineDependentData(calculation); + } + } + + private static void ProbabilisticCalculationContextOnNodeRemoved(ProbabilisticPipingCalculationContext calculationContext, object parentNodeData) + { + if (parentNodeData is PipingCalculationGroupContext calculationGroupContext) + { + bool successfullyRemovedData = calculationGroupContext.WrappedData.Children.Remove(calculationContext.WrappedData); + if (successfullyRemovedData) + { + calculationGroupContext.NotifyObservers(); + } + } + } + + private static void Validate(ProbabilisticPipingCalculationContext context) {} + + private static void Calculate(ProbabilisticPipingCalculation calculation, ProbabilisticPipingCalculationContext context) {} + + #endregion + private static void ValidateAll(IEnumerable> pipingCalculations, IAssessmentSection assessmentSection) { foreach (SemiProbabilisticPipingCalculation calculation in pipingCalculations.OfType()) Index: Riskeer/Piping/test/Riskeer.Piping.Plugin.Test/PipingPluginTest.cs =================================================================== diff -u -r277b8107bf8ffad7dad7fa6dbb75cdb23a0feee2 -rf5ffb52fc4c01ab2809d0c662a4e52a10f9307c7 --- Riskeer/Piping/test/Riskeer.Piping.Plugin.Test/PipingPluginTest.cs (.../PipingPluginTest.cs) (revision 277b8107bf8ffad7dad7fa6dbb75cdb23a0feee2) +++ Riskeer/Piping/test/Riskeer.Piping.Plugin.Test/PipingPluginTest.cs (.../PipingPluginTest.cs) (revision f5ffb52fc4c01ab2809d0c662a4e52a10f9307c7) @@ -128,13 +128,14 @@ TreeNodeInfo[] treeNodeInfos = plugin.GetTreeNodeInfos().ToArray(); // Assert - Assert.AreEqual(13, treeNodeInfos.Length); + Assert.AreEqual(14, treeNodeInfos.Length); Assert.IsTrue(treeNodeInfos.Any(tni => tni.TagType == typeof(PipingSurfaceLinesContext))); Assert.IsTrue(treeNodeInfos.Any(tni => tni.TagType == typeof(PipingSurfaceLine))); Assert.IsTrue(treeNodeInfos.Any(tni => tni.TagType == typeof(PipingStochasticSoilModelCollectionContext))); Assert.IsTrue(treeNodeInfos.Any(tni => tni.TagType == typeof(PipingStochasticSoilModel))); Assert.IsTrue(treeNodeInfos.Any(tni => tni.TagType == typeof(PipingStochasticSoilProfile))); Assert.IsTrue(treeNodeInfos.Any(tni => tni.TagType == typeof(PipingCalculationScenarioContext))); + Assert.IsTrue(treeNodeInfos.Any(tni => tni.TagType == typeof(ProbabilisticPipingCalculationContext))); Assert.IsTrue(treeNodeInfos.Any(tni => tni.TagType == typeof(PipingCalculationGroupContext))); Assert.IsTrue(treeNodeInfos.Any(tni => tni.TagType == typeof(PipingInputContext))); Assert.IsTrue(treeNodeInfos.Any(tni => tni.TagType == typeof(PipingFailureMechanismContext))); Index: Riskeer/Piping/test/Riskeer.Piping.Plugin.Test/Riskeer.Piping.Plugin.Test.csproj =================================================================== diff -u -r08e8d26a0715f0f3db57c1d3e86256aa06934db4 -rf5ffb52fc4c01ab2809d0c662a4e52a10f9307c7 --- Riskeer/Piping/test/Riskeer.Piping.Plugin.Test/Riskeer.Piping.Plugin.Test.csproj (.../Riskeer.Piping.Plugin.Test.csproj) (revision 08e8d26a0715f0f3db57c1d3e86256aa06934db4) +++ Riskeer/Piping/test/Riskeer.Piping.Plugin.Test/Riskeer.Piping.Plugin.Test.csproj (.../Riskeer.Piping.Plugin.Test.csproj) (revision f5ffb52fc4c01ab2809d0c662a4e52a10f9307c7) @@ -13,32 +13,32 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + Index: Riskeer/Piping/test/Riskeer.Piping.Plugin.Test/TreeNodeInfos/ProbabilisticPipingCalculationContextTreeNodeInfoTest.cs =================================================================== diff -u --- Riskeer/Piping/test/Riskeer.Piping.Plugin.Test/TreeNodeInfos/ProbabilisticPipingCalculationContextTreeNodeInfoTest.cs (revision 0) +++ Riskeer/Piping/test/Riskeer.Piping.Plugin.Test/TreeNodeInfos/ProbabilisticPipingCalculationContextTreeNodeInfoTest.cs (revision f5ffb52fc4c01ab2809d0c662a4e52a10f9307c7) @@ -0,0 +1,872 @@ +// Copyright (C) Stichting Deltares 2019. 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.Drawing; +using System.Linq; +using System.Windows.Forms; +using Core.Common.Base; +using Core.Common.Base.Data; +using Core.Common.Base.Geometry; +using Core.Common.Controls.TreeView; +using Core.Common.Gui; +using Core.Common.Gui.ContextMenu; +using Core.Common.Gui.Forms.MainWindow; +using Core.Common.Gui.TestUtil.ContextMenu; +using Core.Common.TestUtil; +using NUnit.Extensions.Forms; +using NUnit.Framework; +using Rhino.Mocks; +using Riskeer.Common.Data; +using Riskeer.Common.Data.AssessmentSection; +using Riskeer.Common.Data.Calculation; +using Riskeer.Piping.Data; +using Riskeer.Piping.Data.SoilProfile; +using Riskeer.Piping.Data.TestUtil; +using Riskeer.Piping.Forms.PresentationObjects; +using Riskeer.Piping.Primitives; +using RiskeerCommonFormsResources = Riskeer.Common.Forms.Properties.Resources; + +namespace Riskeer.Piping.Plugin.Test.TreeNodeInfos +{ + [TestFixture] + public class ProbabilisticPipingCalculationContextTreeNodeInfoTest : NUnitFormTest + { + private const int contextMenuDuplicateIndex = 2; + private const int contextMenuUpdateEntryAndExitPointIndex = 5; + private const int contextMenuValidateIndex = 7; + private const int contextMenuCalculateIndex = 8; + private const int contextMenuClearIndex = 10; + + private MockRepository mocks; + private PipingPlugin plugin; + private TreeNodeInfo info; + + [Test] + public void Initialized_Always_ExpectedPropertiesSet() + { + // Setup + mocks.ReplayAll(); + + // Assert + Assert.IsNotNull(info.Text); + Assert.IsNull(info.ForeColor); + Assert.IsNotNull(info.Image); + Assert.IsNotNull(info.ContextMenuStrip); + Assert.IsNotNull(info.EnsureVisibleOnCreate); + Assert.IsNull(info.ExpandOnCreate); + Assert.IsNotNull(info.ChildNodeObjects); + Assert.IsNotNull(info.CanRename); + Assert.IsNotNull(info.OnNodeRenamed); + Assert.IsNotNull(info.CanRemove); + Assert.IsNotNull(info.OnNodeRemoved); + Assert.IsNull(info.CanCheck); + Assert.IsNull(info.CheckedState); + Assert.IsNull(info.OnNodeChecked); + Assert.IsNotNull(info.CanDrag); + Assert.IsNull(info.CanDrop); + Assert.IsNull(info.CanInsert); + Assert.IsNull(info.OnDrop); + } + + [Test] + public void Image_Always_ReturnsPipingIcon() + { + // Setup + mocks.ReplayAll(); + + // Call + Image image = info.Image(null); + + // Assert + TestHelper.AssertImagesAreEqual(RiskeerCommonFormsResources.CalculationIcon, image); + } + + [Test] + public void ChildNodeObjects_WithOutputData_ReturnOutputChildNode() + { + // Setup + var calculation = new ProbabilisticPipingCalculation(new GeneralPipingInput()) + { + Output = PipingOutputTestFactory.Create() + }; + + var pipingFailureMechanism = new PipingFailureMechanism(); + var assessmentSection = mocks.Stub(); + mocks.ReplayAll(); + + var pipingCalculationContext = new ProbabilisticPipingCalculationContext(calculation, + new CalculationGroup(), + new[] + { + new PipingSurfaceLine(string.Empty) + }, + new[] + { + PipingStochasticSoilModelTestFactory.CreatePipingStochasticSoilModel() + }, + pipingFailureMechanism, + assessmentSection); + + // Call + object[] children = info.ChildNodeObjects(pipingCalculationContext).ToArray(); + + // Assert + Assert.AreEqual(3, children.Length); + var comment = (Comment) children[0]; + Assert.AreSame(pipingCalculationContext.WrappedData.Comments, comment); + + var pipingInputContext = (ProbabilisticPipingInputContext) children[1]; + Assert.AreSame(pipingCalculationContext.WrappedData.InputParameters, pipingInputContext.WrappedData); + CollectionAssert.AreEqual(pipingCalculationContext.AvailablePipingSurfaceLines, pipingInputContext.AvailablePipingSurfaceLines); + CollectionAssert.AreEqual(pipingCalculationContext.AvailableStochasticSoilModels, pipingInputContext.AvailableStochasticSoilModels); + + var pipingOutputContext = (PipingOutputContext) children[2]; + Assert.AreSame(pipingCalculationContext.WrappedData.Output, pipingOutputContext.WrappedData); + Assert.AreSame(pipingCalculationContext.FailureMechanism, pipingOutputContext.FailureMechanism); + Assert.AreSame(pipingCalculationContext.AssessmentSection, pipingOutputContext.AssessmentSection); + } + + [Test] + public void ChildNodeObjects_WithoutOutput_ReturnNoChildNodes() + { + // Setup + var pipingFailureMechanism = new PipingFailureMechanism(); + var assessmentSection = mocks.Stub(); + mocks.ReplayAll(); + + var pipingCalculationContext = new ProbabilisticPipingCalculationContext(new ProbabilisticPipingCalculation(new GeneralPipingInput()), + new CalculationGroup(), + Enumerable.Empty(), + Enumerable.Empty(), + pipingFailureMechanism, + assessmentSection); + + // Call + object[] children = info.ChildNodeObjects(pipingCalculationContext).ToArray(); + + // Assert + Assert.AreEqual(3, children.Length); + var comment = (Comment) children[0]; + Assert.AreSame(pipingCalculationContext.WrappedData.Comments, comment); + + var pipingInputContext = (ProbabilisticPipingInputContext) children[1]; + Assert.AreSame(pipingCalculationContext.WrappedData.InputParameters, pipingInputContext.WrappedData); + CollectionAssert.AreEqual(pipingCalculationContext.AvailablePipingSurfaceLines, pipingInputContext.AvailablePipingSurfaceLines); + CollectionAssert.AreEqual(pipingCalculationContext.AvailableStochasticSoilModels, pipingInputContext.AvailableStochasticSoilModels); + + Assert.IsInstanceOf(children[2]); + } + + [Test] + public void ContextMenuStrip_PipingCalculationWithoutOutput_ContextMenuItemClearOutputDisabledAndTooltipSet() + { + // Setup + using (var treeViewControl = new TreeViewControl()) + { + var calculation = new ProbabilisticPipingCalculation(new GeneralPipingInput()); + var pipingFailureMechanism = new TestPipingFailureMechanism(); + var assessmentSection = mocks.Stub(); + var nodeData = new ProbabilisticPipingCalculationContext(calculation, + new CalculationGroup(), + Enumerable.Empty(), + Enumerable.Empty(), + pipingFailureMechanism, + assessmentSection); + + var gui = mocks.Stub(); + gui.Stub(cmp => cmp.Get(nodeData, treeViewControl)).Return(new CustomItemsOnlyContextMenuBuilder()); + mocks.ReplayAll(); + + plugin.Gui = gui; + + // Call + using (ContextMenuStrip contextMenu = info.ContextMenuStrip(nodeData, null, treeViewControl)) + { + // Assert + TestHelper.AssertContextMenuStripContainsItem(contextMenu, + contextMenuClearIndex, + "&Wis uitvoer...", + "Deze berekening heeft geen uitvoer om te wissen.", + RiskeerCommonFormsResources.ClearIcon, + false); + } + } + } + + [Test] + public void ContextMenuStrip_PipingCalculationWithOutput_ContextMenuItemClearOutputEnabled() + { + // Setup + using (var treeViewControl = new TreeViewControl()) + { + var calculation = new ProbabilisticPipingCalculation(new GeneralPipingInput()) + { + Output = PipingOutputTestFactory.Create() + }; + var pipingFailureMechanism = new TestPipingFailureMechanism(); + var assessmentSection = mocks.Stub(); + var nodeData = new ProbabilisticPipingCalculationContext(calculation, + new CalculationGroup(), + Enumerable.Empty(), + Enumerable.Empty(), + pipingFailureMechanism, + assessmentSection); + + var gui = mocks.Stub(); + gui.Stub(cmp => cmp.Get(nodeData, treeViewControl)).Return(new CustomItemsOnlyContextMenuBuilder()); + mocks.ReplayAll(); + + plugin.Gui = gui; + + // Call + using (ContextMenuStrip contextMenu = info.ContextMenuStrip(nodeData, null, treeViewControl)) + { + // Assert + TestHelper.AssertContextMenuStripContainsItem(contextMenu, + contextMenuClearIndex, + "&Wis uitvoer...", + "Wis de uitvoer van deze berekening.", + RiskeerCommonFormsResources.ClearIcon); + } + } + } + + [Test] + public void ContextMenuStrip_AllRequiredInputSet_ContextMenuItemCalculateAndValidateEnabled() + { + // Setup + using (var treeViewControl = new TreeViewControl()) + { + var calculation = new ProbabilisticPipingCalculation(new GeneralPipingInput()); + var pipingFailureMechanism = new TestPipingFailureMechanism(); + var assessmentSection = mocks.Stub(); + var nodeData = new ProbabilisticPipingCalculationContext(calculation, + new CalculationGroup(), + Enumerable.Empty(), + Enumerable.Empty(), + pipingFailureMechanism, + assessmentSection); + + var gui = mocks.Stub(); + gui.Stub(cmp => cmp.Get(nodeData, treeViewControl)).Return(new CustomItemsOnlyContextMenuBuilder()); + mocks.ReplayAll(); + + plugin.Gui = gui; + + // Call + using (ContextMenuStrip contextMenu = info.ContextMenuStrip(nodeData, null, treeViewControl)) + { + // Assert + TestHelper.AssertContextMenuStripContainsItem(contextMenu, + contextMenuValidateIndex, + "&Valideren", + "Valideer de invoer voor deze berekening.", + RiskeerCommonFormsResources.ValidateIcon); + + TestHelper.AssertContextMenuStripContainsItem(contextMenu, + contextMenuCalculateIndex, + "Be&rekenen", + "Voer deze berekening uit.", + RiskeerCommonFormsResources.CalculateIcon); + } + } + } + + [Test] + public void ContextMenuStrip_Always_AddCustomItems() + { + // Setup + using (var treeViewControl = new TreeViewControl()) + { + var pipingFailureMechanism = new TestPipingFailureMechanism(); + var assessmentSection = mocks.Stub(); + var nodeData = new ProbabilisticPipingCalculationContext(new ProbabilisticPipingCalculation(new GeneralPipingInput()), + new CalculationGroup(), + Enumerable.Empty(), + Enumerable.Empty(), + pipingFailureMechanism, + assessmentSection); + + var gui = mocks.Stub(); + gui.Stub(cmp => cmp.Get(nodeData, treeViewControl)).Return(new CustomItemsOnlyContextMenuBuilder()); + mocks.ReplayAll(); + + plugin.Gui = gui; + + // Call + using (ContextMenuStrip contextMenu = info.ContextMenuStrip(nodeData, null, treeViewControl)) + { + Assert.AreEqual(17, contextMenu.Items.Count); + + // Assert + TestHelper.AssertContextMenuStripContainsItem(contextMenu, + contextMenuDuplicateIndex, + "D&upliceren", + "Dupliceer dit element.", + RiskeerCommonFormsResources.CopyHS); + + TestHelper.AssertContextMenuStripContainsItem(contextMenu, + contextMenuUpdateEntryAndExitPointIndex, + "&Bijwerken intrede- en uittredepunt...", + "Er moet een profielschematisatie geselecteerd zijn.", + RiskeerCommonFormsResources.UpdateItemIcon, + false); + + TestHelper.AssertContextMenuStripContainsItem(contextMenu, + contextMenuValidateIndex, + "&Valideren", + "Valideer de invoer voor deze berekening.", + RiskeerCommonFormsResources.ValidateIcon); + + TestHelper.AssertContextMenuStripContainsItem(contextMenu, + contextMenuCalculateIndex, + "Be&rekenen", + "Voer deze berekening uit.", + RiskeerCommonFormsResources.CalculateIcon); + + TestHelper.AssertContextMenuStripContainsItem(contextMenu, + contextMenuClearIndex, + "&Wis uitvoer...", + "Deze berekening heeft geen uitvoer om te wissen.", + RiskeerCommonFormsResources.ClearIcon, + false); + } + } + } + + [Test] + public void ContextMenuStrip_Always_CallsContextMenuBuilderMethods() + { + // Setup + using (var treeViewControl = new TreeViewControl()) + { + var pipingFailureMechanism = new PipingFailureMechanism(); + var assessmentSection = mocks.Stub(); + var nodeData = new ProbabilisticPipingCalculationContext(new ProbabilisticPipingCalculation(new GeneralPipingInput()), + new CalculationGroup(), + Enumerable.Empty(), + Enumerable.Empty(), + pipingFailureMechanism, + assessmentSection); + + var menuBuilder = mocks.StrictMock(); + using (mocks.Ordered()) + { + menuBuilder.Expect(mb => mb.AddExportItem()).Return(menuBuilder); + menuBuilder.Expect(mb => mb.AddSeparator()).Return(menuBuilder); + menuBuilder.Expect(mb => mb.AddCustomItem(null)).IgnoreArguments().Return(menuBuilder); + menuBuilder.Expect(mb => mb.AddSeparator()).Return(menuBuilder); + menuBuilder.Expect(mb => mb.AddRenameItem()).Return(menuBuilder); + menuBuilder.Expect(mb => mb.AddCustomItem(null)).IgnoreArguments().Return(menuBuilder); + menuBuilder.Expect(mb => mb.AddSeparator()).Return(menuBuilder); + menuBuilder.Expect(mb => mb.AddCustomItem(null)).IgnoreArguments().Return(menuBuilder); + menuBuilder.Expect(mb => mb.AddCustomItem(null)).IgnoreArguments().Return(menuBuilder); + menuBuilder.Expect(mb => mb.AddSeparator()).Return(menuBuilder); + menuBuilder.Expect(mb => mb.AddCustomItem(null)).IgnoreArguments().Return(menuBuilder); + menuBuilder.Expect(mb => mb.AddDeleteItem()).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.AddSeparator()).Return(menuBuilder); + menuBuilder.Expect(mb => mb.AddPropertiesItem()).Return(menuBuilder); + menuBuilder.Expect(mb => mb.Build()).Return(null); + } + + var gui = mocks.Stub(); + gui.Stub(cmp => cmp.Get(nodeData, treeViewControl)).Return(menuBuilder); + mocks.ReplayAll(); + + plugin.Gui = gui; + + // Call + info.ContextMenuStrip(nodeData, null, treeViewControl); + } + + // Assert + // Assert expectancies are called in TearDown() + } + + [Test] + public void ContextMenuStrip_CalculationWithoutSurfaceLine_ContextMenuItemUpdateEntryAndExitPointDisabledAndToolTipSet() + { + // Setup + using (var treeViewControl = new TreeViewControl()) + { + var calculation = new ProbabilisticPipingCalculation(new GeneralPipingInput()); + var pipingFailureMechanism = new TestPipingFailureMechanism(); + var assessmentSection = mocks.Stub(); + var nodeData = new ProbabilisticPipingCalculationContext(calculation, + new CalculationGroup(), + Enumerable.Empty(), + Enumerable.Empty(), + pipingFailureMechanism, + assessmentSection); + + var gui = mocks.Stub(); + gui.Stub(cmp => cmp.Get(nodeData, treeViewControl)).Return(new CustomItemsOnlyContextMenuBuilder()); + mocks.ReplayAll(); + + plugin.Gui = gui; + + // Call + using (ContextMenuStrip contextMenu = info.ContextMenuStrip(nodeData, null, treeViewControl)) + { + // Assert + TestHelper.AssertContextMenuStripContainsItem(contextMenu, + contextMenuUpdateEntryAndExitPointIndex, + "&Bijwerken intrede- en uittredepunt...", + "Er moet een profielschematisatie geselecteerd zijn.", + RiskeerCommonFormsResources.UpdateItemIcon, + false); + } + } + } + + [Test] + public void ContextMenuStrip_CalculationWithSurfaceLineAndInputInSync_ContextMenuItemUpdateEntryAndExitPointDisabledAndToolTipSet() + { + // Setup + using (var treeViewControl = new TreeViewControl()) + { + var surfaceLine = new PipingSurfaceLine(string.Empty); + surfaceLine.SetGeometry(new[] + { + new Point3D(1, 2, 3), + new Point3D(4, 5, 6) + }); + var calculation = new ProbabilisticPipingCalculation(new GeneralPipingInput()) + { + InputParameters = + { + SurfaceLine = surfaceLine + } + }; + var pipingFailureMechanism = new TestPipingFailureMechanism(); + var assessmentSection = mocks.Stub(); + var nodeData = new ProbabilisticPipingCalculationContext(calculation, + new CalculationGroup(), + Enumerable.Empty(), + Enumerable.Empty(), + pipingFailureMechanism, + assessmentSection); + + var gui = mocks.Stub(); + gui.Stub(cmp => cmp.Get(nodeData, treeViewControl)).Return(new CustomItemsOnlyContextMenuBuilder()); + mocks.ReplayAll(); + + plugin.Gui = gui; + + // Call + using (ContextMenuStrip contextMenu = info.ContextMenuStrip(nodeData, null, treeViewControl)) + { + // Assert + TestHelper.AssertContextMenuStripContainsItem(contextMenu, + contextMenuUpdateEntryAndExitPointIndex, + "&Bijwerken intrede- en uittredepunt...", + "Er zijn geen wijzigingen om bij te werken.", + RiskeerCommonFormsResources.UpdateItemIcon, + false); + } + } + } + + [Test] + public void ContextMenuStrip_CalculationWithSurfaceLineAndInputOutOfSync_ContextMenuItemUpdateEntryAndExitPointEnabledAndToolTipSet() + { + // Setup + using (var treeViewControl = new TreeViewControl()) + { + var surfaceLine = new PipingSurfaceLine(string.Empty); + surfaceLine.SetGeometry(new[] + { + new Point3D(1, 2, 3), + new Point3D(4, 5, 6) + }); + var calculation = new ProbabilisticPipingCalculation(new GeneralPipingInput()) + { + InputParameters = + { + SurfaceLine = surfaceLine + } + }; + var pipingFailureMechanism = new TestPipingFailureMechanism(); + var assessmentSection = mocks.Stub(); + var nodeData = new ProbabilisticPipingCalculationContext(calculation, + new CalculationGroup(), + Enumerable.Empty(), + Enumerable.Empty(), + pipingFailureMechanism, + assessmentSection); + + var gui = mocks.Stub(); + gui.Stub(cmp => cmp.Get(nodeData, treeViewControl)).Return(new CustomItemsOnlyContextMenuBuilder()); + mocks.ReplayAll(); + + plugin.Gui = gui; + + ChangeSurfaceLine(surfaceLine); + + // Call + using (ContextMenuStrip contextMenu = info.ContextMenuStrip(nodeData, null, treeViewControl)) + { + // Assert + TestHelper.AssertContextMenuStripContainsItem(contextMenu, + contextMenuUpdateEntryAndExitPointIndex, + "&Bijwerken intrede- en uittredepunt...", + "Berekening bijwerken met de karakteristieke punten.", + RiskeerCommonFormsResources.UpdateItemIcon); + } + } + } + + [Test] + public void GivenCalculationWithoutOutputAndWithInputOutOfSync_WhenUpdateEntryAndExitPointClicked_ThenNoInquiryAndCalculationUpdatedAndInputObserverNotified() + { + using (var treeViewControl = new TreeViewControl()) + { + // Given + PipingSurfaceLine surfaceLine; + ProbabilisticPipingCalculation calculation; + CreateCalculationWithSurfaceLine(out calculation, out surfaceLine); + + var pipingFailureMechanism = new TestPipingFailureMechanism(); + var assessmentSection = mocks.Stub(); + var nodeData = new ProbabilisticPipingCalculationContext(calculation, + new CalculationGroup(), + Enumerable.Empty(), + Enumerable.Empty(), + pipingFailureMechanism, + assessmentSection); + + var inputObserver = mocks.StrictMock(); + inputObserver.Expect(obs => obs.UpdateObserver()); + calculation.InputParameters.Attach(inputObserver); + + var calculationObserver = mocks.StrictMock(); + calculation.Attach(calculationObserver); + + var mainWindow = mocks.Stub(); + var gui = mocks.Stub(); + gui.Stub(cmp => cmp.Get(nodeData, treeViewControl)).Return(new CustomItemsOnlyContextMenuBuilder()); + gui.Stub(g => g.MainWindow).Return(mainWindow); + mocks.ReplayAll(); + + plugin.Gui = gui; + + ChangeSurfaceLine(surfaceLine); + + using (ContextMenuStrip contextMenuStrip = info.ContextMenuStrip(nodeData, null, treeViewControl)) + { + // When + contextMenuStrip.Items[contextMenuUpdateEntryAndExitPointIndex].PerformClick(); + + // Then + Assert.IsTrue(calculation.InputParameters.IsEntryAndExitPointInputSynchronized); + + // Note: observer assertions are verified in TearDown + } + } + } + + [Test] + public void GivenCalculationWithOutputAndInputOutOfSync_WhenUpdateEntryAndExitPointClickedAndCancelled_ThenInquiryAndCalculationNotUpdatedAndObserversNotNotified() + { + using (var treeViewControl = new TreeViewControl()) + { + // Given + PipingSurfaceLine surfaceLine; + ProbabilisticPipingCalculation calculation; + CreateCalculationWithSurfaceLine(out calculation, out surfaceLine); + calculation.Output = PipingOutputTestFactory.Create(); + + var pipingFailureMechanism = new TestPipingFailureMechanism(); + var assessmentSection = mocks.Stub(); + var nodeData = new ProbabilisticPipingCalculationContext(calculation, + new CalculationGroup(), + Enumerable.Empty(), + Enumerable.Empty(), + pipingFailureMechanism, + assessmentSection); + + var inputObserver = mocks.StrictMock(); + calculation.InputParameters.Attach(inputObserver); + + var calculationObserver = mocks.StrictMock(); + calculation.Attach(calculationObserver); + + var mainWindow = mocks.Stub(); + var gui = mocks.Stub(); + gui.Stub(cmp => cmp.Get(nodeData, treeViewControl)).Return(new CustomItemsOnlyContextMenuBuilder()); + gui.Stub(g => g.MainWindow).Return(mainWindow); + mocks.ReplayAll(); + + plugin.Gui = gui; + + string textBoxMessage = null; + DialogBoxHandler = (name, wnd) => + { + var helper = new MessageBoxTester(wnd); + textBoxMessage = helper.Text; + helper.ClickCancel(); + }; + + ChangeSurfaceLine(surfaceLine); + + using (ContextMenuStrip contextMenuStrip = info.ContextMenuStrip(nodeData, null, treeViewControl)) + { + // When + contextMenuStrip.Items[contextMenuUpdateEntryAndExitPointIndex].PerformClick(); + + // Then + Assert.IsTrue(calculation.HasOutput); + Assert.IsFalse(calculation.InputParameters.IsEntryAndExitPointInputSynchronized); + + string expectedMessage = "Als u kiest voor bijwerken, dan wordt het resultaat van deze berekening " + + $"verwijderd.{Environment.NewLine}{Environment.NewLine}Weet u zeker dat u wilt doorgaan?"; + Assert.AreEqual(expectedMessage, textBoxMessage); + + // Note: observer assertions are verified in TearDown + } + } + } + + [Test] + public void GivenCalculationWithOutputAndInputOutOfSync_WhenUpdateEntryAndExitPointClickedAndContinued_ThenInquiryAndCalculationUpdatedAndObserversNotified() + { + using (var treeViewControl = new TreeViewControl()) + { + // Given + PipingSurfaceLine surfaceLine; + ProbabilisticPipingCalculation calculation; + CreateCalculationWithSurfaceLine(out calculation, out surfaceLine); + calculation.Output = PipingOutputTestFactory.Create(); + + var pipingFailureMechanism = new TestPipingFailureMechanism(); + var assessmentSection = mocks.Stub(); + var nodeData = new ProbabilisticPipingCalculationContext(calculation, + new CalculationGroup(), + Enumerable.Empty(), + Enumerable.Empty(), + pipingFailureMechanism, + assessmentSection); + + var inputObserver = mocks.StrictMock(); + inputObserver.Expect(obs => obs.UpdateObserver()); + calculation.InputParameters.Attach(inputObserver); + + var calculationObserver = mocks.StrictMock(); + calculationObserver.Expect(obs => obs.UpdateObserver()); + calculation.Attach(calculationObserver); + + var mainWindow = mocks.Stub(); + var gui = mocks.Stub(); + gui.Stub(cmp => cmp.Get(nodeData, treeViewControl)).Return(new CustomItemsOnlyContextMenuBuilder()); + gui.Stub(g => g.MainWindow).Return(mainWindow); + mocks.ReplayAll(); + + plugin.Gui = gui; + + string textBoxMessage = null; + DialogBoxHandler = (name, wnd) => + { + var helper = new MessageBoxTester(wnd); + textBoxMessage = helper.Text; + helper.ClickOk(); + }; + + ChangeSurfaceLine(surfaceLine); + + using (ContextMenuStrip contextMenuStrip = info.ContextMenuStrip(nodeData, null, treeViewControl)) + { + // When + contextMenuStrip.Items[contextMenuUpdateEntryAndExitPointIndex].PerformClick(); + + // Then + Assert.IsFalse(calculation.HasOutput); + Assert.IsTrue(calculation.InputParameters.IsEntryAndExitPointInputSynchronized); + + string expectedMessage = "Als u kiest voor bijwerken, dan wordt het resultaat van deze berekening " + + $"verwijderd.{Environment.NewLine}{Environment.NewLine}Weet u zeker dat u wilt doorgaan?"; + Assert.AreEqual(expectedMessage, textBoxMessage); + + // Note: observer assertions are verified in TearDown + } + } + } + + [Test] + public void OnNodeRemoved_ParentIsPipingCalculationGroupContext_RemoveCalculationFromGroup() + { + // Setup + var observer = mocks.StrictMock(); + observer.Expect(o => o.UpdateObserver()); + + var elementToBeRemoved = new ProbabilisticPipingCalculation(new GeneralPipingInput()); + + var group = new CalculationGroup(); + group.Children.Add(elementToBeRemoved); + group.Children.Add(new ProbabilisticPipingCalculation(new GeneralPipingInput())); + group.Attach(observer); + + var pipingFailureMechanism = new PipingFailureMechanism(); + var assessmentSection = mocks.Stub(); + mocks.ReplayAll(); + + var calculationContext = new ProbabilisticPipingCalculationContext(elementToBeRemoved, + group, + Enumerable.Empty(), + Enumerable.Empty(), + pipingFailureMechanism, + assessmentSection); + var groupContext = new PipingCalculationGroupContext(group, + null, + Enumerable.Empty(), + Enumerable.Empty(), + pipingFailureMechanism, + assessmentSection); + + // Precondition + Assert.IsTrue(info.CanRemove(calculationContext, groupContext)); + Assert.AreEqual(2, group.Children.Count); + + // Call + info.OnNodeRemoved(calculationContext, groupContext); + + // Assert + Assert.AreEqual(1, group.Children.Count); + CollectionAssert.DoesNotContain(group.Children, elementToBeRemoved); + } + + [Test] + [TestCase(true)] + [TestCase(false)] + public void GivenPipingCalculationWithOutput_WhenClearingOutputFromContextMenu_ThenPipingCalculationOutputClearedAndNotified(bool confirm) + { + // Given + using (var treeViewControl = new TreeViewControl()) + { + var calculation = new ProbabilisticPipingCalculation(new GeneralPipingInput()); + var pipingFailureMechanism = new PipingFailureMechanism(); + var assessmentSection = mocks.Stub(); + + var pipingCalculationContext = new ProbabilisticPipingCalculationContext(calculation, + new CalculationGroup(), + Enumerable.Empty(), + Enumerable.Empty(), + pipingFailureMechanism, + assessmentSection); + + var gui = mocks.Stub(); + gui.Stub(cmp => cmp.Get(pipingCalculationContext, treeViewControl)).Return(new CustomItemsOnlyContextMenuBuilder()); + + var observer = mocks.StrictMock(); + if (confirm) + { + observer.Expect(o => o.UpdateObserver()); + } + + mocks.ReplayAll(); + + plugin.Gui = gui; + + calculation.Output = PipingOutputTestFactory.Create(); + calculation.Attach(observer); + + string messageBoxText = null, messageBoxTitle = null; + DialogBoxHandler = (name, wnd) => + { + var messageBox = new MessageBoxTester(wnd); + messageBoxText = messageBox.Text; + messageBoxTitle = messageBox.Title; + if (confirm) + { + messageBox.ClickOk(); + } + else + { + messageBox.ClickCancel(); + } + }; + + using (ContextMenuStrip contextMenuStrip = info.ContextMenuStrip(pipingCalculationContext, null, treeViewControl)) + { + // When + contextMenuStrip.Items[contextMenuClearIndex].PerformClick(); + + // Then + Assert.AreNotEqual(confirm, calculation.HasOutput); + Assert.AreEqual("Bevestigen", messageBoxTitle); + Assert.AreEqual("Weet u zeker dat u de uitvoer van deze berekening wilt wissen?", messageBoxText); + } + } + } + + public override void Setup() + { + mocks = new MockRepository(); + plugin = new PipingPlugin(); + info = plugin.GetTreeNodeInfos().First(tni => tni.TagType == typeof(ProbabilisticPipingCalculationContext)); + } + + public override void TearDown() + { + plugin.Dispose(); + mocks.VerifyAll(); + + base.TearDown(); + } + + private static void ChangeSurfaceLine(PipingSurfaceLine surfaceLine) + { + surfaceLine.SetGeometry(new[] + { + new Point3D(0, 0, 0), + new Point3D(1, 0, 2), + new Point3D(2, 0, 3), + new Point3D(3, 0, 0), + new Point3D(4, 0, 2), + new Point3D(5, 0, 3) + }); + surfaceLine.SetDikeToeAtRiverAt(new Point3D(2, 0, 3)); + surfaceLine.SetDikeToeAtPolderAt(new Point3D(3, 0, 0)); + } + + private static void CreateCalculationWithSurfaceLine(out ProbabilisticPipingCalculation calculation, out PipingSurfaceLine surfaceLine) + { + surfaceLine = new PipingSurfaceLine(string.Empty); + surfaceLine.SetGeometry(new[] + { + new Point3D(1, 2, 3), + new Point3D(4, 5, 6) + }); + calculation = new ProbabilisticPipingCalculation(new GeneralPipingInput()) + { + InputParameters = + { + SurfaceLine = surfaceLine, + EntryPointL = (RoundedDouble) 0, + ExitPointL = (RoundedDouble) 1 + } + }; + } + } +} \ No newline at end of file