// 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.Linq; using System.Windows.Forms; using Core.Common.Base; using Core.Common.Controls.TreeView; using Core.Common.Gui.Commands; using Core.Common.Gui.ContextMenu; using Core.Common.TestUtil; using NUnit.Extensions.Forms; using NUnit.Framework; using Rhino.Mocks; using Ringtoets.Common.Data.Calculation; using Ringtoets.Common.Data.FailureMechanism; using Ringtoets.Common.Forms.PresentationObjects; using Ringtoets.Common.Forms.TreeNodeInfos; using BaseResources = Core.Common.Base.Properties.Resources; using RingtoetsFormsResources = Ringtoets.Common.Forms.Properties.Resources; namespace Ringtoets.Common.Forms.Test.TreeNodeInfos { [TestFixture] public class CalculationTreeNodeInfoFactoryTest : NUnitFormTest { [Test] public void AddCreateCalculationGroupItem_Always_CreatesDecoratedCalculationGroupItem() { // Setup var mocks = new MockRepository(); var applicationFeatureCommandHandler = mocks.Stub(); var exportImportHandler = mocks.Stub(); var viewCommandsHandler = mocks.StrictMock(); var treeViewControl = mocks.StrictMock(); mocks.ReplayAll(); var calculationGroup = new CalculationGroup(); var menuBuilder = new ContextMenuBuilder(applicationFeatureCommandHandler, exportImportHandler, viewCommandsHandler, calculationGroup, treeViewControl); // Call CalculationTreeNodeInfoFactory.AddCreateCalculationGroupItem(menuBuilder, calculationGroup); // Assert TestHelper.AssertContextMenuStripContainsItem(menuBuilder.Build(), 0, RingtoetsFormsResources.CalculationGroup_Add_CalculationGroup, RingtoetsFormsResources.CalculationGroup_Add_CalculationGroup_Tooltip, RingtoetsFormsResources.AddFolderIcon); } [Test] public void AddCreateCalculationGroupItem_PerformClickOnCreatedItem_CalculationGroupAdded() { // Setup var mocks = new MockRepository(); var applicationFeatureCommandHandler = mocks.Stub(); var exportImportHandler = mocks.Stub(); var viewCommandsHandler = mocks.StrictMock(); var treeViewControl = mocks.StrictMock(); mocks.ReplayAll(); var calculationGroup = new CalculationGroup(); var menuBuilder = new ContextMenuBuilder(applicationFeatureCommandHandler, exportImportHandler, viewCommandsHandler, calculationGroup, treeViewControl); CalculationTreeNodeInfoFactory.AddCreateCalculationGroupItem(menuBuilder, calculationGroup); var contextMenuItem = menuBuilder.Build().Items[0]; // Call contextMenuItem.PerformClick(); // Assert Assert.AreEqual(1, calculationGroup.Children.Count); Assert.IsTrue(calculationGroup.Children[0] is CalculationGroup); } [Test] public void AddCreateCalculationItem_Always_CreatesDecoratedCalculationItem() { // Setup var mocks = new MockRepository(); var failureMechanism = mocks.Stub(); var applicationFeatureCommandHandler = mocks.Stub(); var exportImportHandler = mocks.Stub(); var viewCommandsHandler = mocks.StrictMock(); var treeViewControl = mocks.StrictMock(); mocks.ReplayAll(); var calculationGroup = new CalculationGroup(); var calculationGroupContext = new TestCalculationGroupContext(calculationGroup, failureMechanism); var menuBuilder = new ContextMenuBuilder(applicationFeatureCommandHandler, exportImportHandler, viewCommandsHandler, calculationGroup, treeViewControl); // Call CalculationTreeNodeInfoFactory.AddCreateCalculationItem(menuBuilder, calculationGroupContext, null); // Assert TestHelper.AssertContextMenuStripContainsItem(menuBuilder.Build(), 0, RingtoetsFormsResources.CalculationGroup_Add_Calculation, RingtoetsFormsResources.CalculationGroup_Add_Calculation_Tooltip, RingtoetsFormsResources.FailureMechanismIcon); } [Test] public void AddCreateCalculationItem_PerformClickOnCreatedItem_AddCalculationMethodPerformed() { // Setup var mocks = new MockRepository(); var failureMechanism = mocks.Stub(); var applicationFeatureCommandHandler = mocks.Stub(); var exportImportHandler = mocks.Stub(); var viewCommandsHandler = mocks.StrictMock(); var treeViewControl = mocks.StrictMock(); mocks.ReplayAll(); var counter = 0; var calculationGroup = new CalculationGroup(); var calculationGroupContext = new TestCalculationGroupContext(calculationGroup, failureMechanism); var menuBuilder = new ContextMenuBuilder(applicationFeatureCommandHandler, exportImportHandler, viewCommandsHandler, calculationGroup, treeViewControl); CalculationTreeNodeInfoFactory.AddCreateCalculationItem(menuBuilder, calculationGroupContext, context => counter++); var contextMenuItem = menuBuilder.Build().Items[0]; // Call contextMenuItem.PerformClick(); // Assert Assert.AreEqual(1, counter); } [Test] public void AddClearAllCalculationOutputInGroupItem_GroupWithCalculationOutput_CreatesDecoratedAndEnabledClearItem() { // Setup var mocks = new MockRepository(); var applicationFeatureCommandHandler = mocks.Stub(); var exportImportHandler = mocks.Stub(); var viewCommandsHandler = mocks.StrictMock(); var treeViewControl = mocks.StrictMock(); var calculationWithOutput = mocks.StrictMock(); calculationWithOutput.Expect(c => c.HasOutput).Return(true); mocks.ReplayAll(); var calculationGroup = new CalculationGroup { Children = { calculationWithOutput } }; var menuBuilder = new ContextMenuBuilder(applicationFeatureCommandHandler, exportImportHandler, viewCommandsHandler, calculationGroup, treeViewControl); // Call CalculationTreeNodeInfoFactory.AddClearAllCalculationOutputInGroupItem(menuBuilder, calculationGroup); // Assert TestHelper.AssertContextMenuStripContainsItem(menuBuilder.Build(), 0, RingtoetsFormsResources.Clear_all_output, RingtoetsFormsResources.CalculationGroup_ClearOutput_ToolTip, RingtoetsFormsResources.ClearIcon); } [Test] public void AddClearAllCalculationOutputInGroupItem_GroupWithoutCalculationOutput_CreatesDecoratedAndDisabledClearItem() { // Setup var mocks = new MockRepository(); var applicationFeatureCommandHandler = mocks.Stub(); var exportImportHandler = mocks.Stub(); var viewCommandsHandler = mocks.StrictMock(); var treeViewControl = mocks.StrictMock(); var calculationWithoutOutput = mocks.StrictMock(); calculationWithoutOutput.Expect(c => c.HasOutput).Return(false); mocks.ReplayAll(); var calculationGroup = new CalculationGroup { Children = { calculationWithoutOutput } }; var menuBuilder = new ContextMenuBuilder(applicationFeatureCommandHandler, exportImportHandler, viewCommandsHandler, calculationGroup, treeViewControl); // Call CalculationTreeNodeInfoFactory.AddClearAllCalculationOutputInGroupItem(menuBuilder, calculationGroup); // Assert TestHelper.AssertContextMenuStripContainsItem(menuBuilder.Build(), 0, RingtoetsFormsResources.Clear_all_output, RingtoetsFormsResources.CalculationGroup_ClearOutput_No_calculation_with_output_to_clear, RingtoetsFormsResources.ClearIcon, false); } [Test] public void AddClearAllCalculationOutputInGroupItem_PerformClickOnCreatedItemAndConfirmChange_CalculationOutputClearedAndObserversNotified() { var messageBoxText = ""; var messageBoxTitle = ""; var mocks = new MockRepository(); var applicationFeatureCommandHandler = mocks.Stub(); var exportImportHandler = mocks.Stub(); var viewCommandsHandler = mocks.StrictMock(); var treeViewControl = mocks.StrictMock(); var calculationWithOutput1 = mocks.StrictMock(); var calculationWithOutput2 = mocks.StrictMock(); var calculationWithoutOutput = mocks.StrictMock(); calculationWithOutput1.Stub(c => c.HasOutput).Return(true); calculationWithOutput2.Stub(c => c.HasOutput).Return(true); calculationWithoutOutput.Stub(c => c.HasOutput).Return(false); calculationWithOutput1.Expect(c => c.ClearOutput()); calculationWithOutput1.Expect(c => c.NotifyObservers()); calculationWithOutput2.Expect(c => c.ClearOutput()); calculationWithOutput2.Expect(c => c.NotifyObservers()); mocks.ReplayAll(); DialogBoxHandler = (name, wnd) => { var messageBox = new MessageBoxTester(wnd); messageBoxText = messageBox.Text; messageBoxTitle = messageBox.Title; messageBox.ClickOk(); }; var calculationGroup = new CalculationGroup { Children = { calculationWithOutput1, new CalculationGroup { Children = { calculationWithOutput2, calculationWithoutOutput } } } }; var menuBuilder = new ContextMenuBuilder(applicationFeatureCommandHandler, exportImportHandler, viewCommandsHandler, calculationGroup, treeViewControl); CalculationTreeNodeInfoFactory.AddClearAllCalculationOutputInGroupItem(menuBuilder, calculationGroup); var contextMenuItem = menuBuilder.Build().Items[0]; // Call contextMenuItem.PerformClick(); // Assert Assert.AreEqual(BaseResources.Confirm, messageBoxTitle); Assert.AreEqual(RingtoetsFormsResources.CalculationGroup_ClearOutput_Are_you_sure_clear_all_output, messageBoxText); mocks.VerifyAll(); } [Test] public void AddClearAllCalculationOutputInGroupItem_PerformClickOnCreatedItemAndCancelChange_CalculationOutputNotCleared() { var mocks = new MockRepository(); var applicationFeatureCommandHandler = mocks.Stub(); var exportImportHandler = mocks.Stub(); var viewCommandsHandler = mocks.StrictMock(); var treeViewControl = mocks.StrictMock(); var calculationWithOutput1 = mocks.StrictMock(); var calculationWithOutput2 = mocks.StrictMock(); var calculationWithoutOutput = mocks.StrictMock(); calculationWithOutput1.Stub(c => c.HasOutput).Return(true); calculationWithOutput2.Stub(c => c.HasOutput).Return(true); calculationWithoutOutput.Stub(c => c.HasOutput).Return(false); mocks.ReplayAll(); DialogBoxHandler = (name, wnd) => { var messageBox = new MessageBoxTester(wnd); messageBox.ClickCancel(); }; var calculationGroup = new CalculationGroup { Children = { calculationWithOutput1, new CalculationGroup { Children = { calculationWithOutput2, calculationWithoutOutput } } } }; var menuBuilder = new ContextMenuBuilder(applicationFeatureCommandHandler, exportImportHandler, viewCommandsHandler, calculationGroup, treeViewControl); CalculationTreeNodeInfoFactory.AddClearAllCalculationOutputInGroupItem(menuBuilder, calculationGroup); var contextMenuItem = menuBuilder.Build().Items[0]; // Call contextMenuItem.PerformClick(); mocks.VerifyAll(); } [Test] public void AddPerformAllCalculationsInGroupItem_GroupWithCalculations_CreatesDecoratedAndEnabledPerformItem() { // Setup var mocks = new MockRepository(); var applicationFeatureCommandHandler = mocks.Stub(); var exportImportHandler = mocks.Stub(); var viewCommandsHandler = mocks.StrictMock(); var treeViewControl = mocks.StrictMock(); var calculation = mocks.StrictMock(); mocks.ReplayAll(); var calculationGroup = new CalculationGroup { Children = { calculation } }; var menuBuilder = new ContextMenuBuilder(applicationFeatureCommandHandler, exportImportHandler, viewCommandsHandler, calculationGroup, treeViewControl); // Call CalculationTreeNodeInfoFactory.AddPerformAllCalculationsInGroupItem(menuBuilder, calculationGroup, null); // Assert TestHelper.AssertContextMenuStripContainsItem(menuBuilder.Build(), 0, RingtoetsFormsResources.Calculate_all, RingtoetsFormsResources.CalculationGroup_CalculateAll_ToolTip, RingtoetsFormsResources.CalculateAllIcon); } [Test] public void AddPerformAllCalculationsInGroupItem_GroupWithoutCalculations_CreatesDecoratedAndDisabledPerformItem() { // Setup var mocks = new MockRepository(); var applicationFeatureCommandHandler = mocks.Stub(); var exportImportHandler = mocks.Stub(); var viewCommandsHandler = mocks.StrictMock(); var treeViewControl = mocks.StrictMock(); mocks.ReplayAll(); var calculationGroup = new CalculationGroup(); var menuBuilder = new ContextMenuBuilder(applicationFeatureCommandHandler, exportImportHandler, viewCommandsHandler, calculationGroup, treeViewControl); // Call CalculationTreeNodeInfoFactory.AddPerformAllCalculationsInGroupItem(menuBuilder, calculationGroup, null); // Assert TestHelper.AssertContextMenuStripContainsItem(menuBuilder.Build(), 0, RingtoetsFormsResources.Calculate_all, RingtoetsFormsResources.CalculationGroup_CalculateAll_No_calculations_to_run, RingtoetsFormsResources.CalculateAllIcon, false); } [Test] public void AddPerformAllCalculationsInGroupItem_PerformClickOnCreatedItem_PerformAllCalculationMethodPerformed() { // Setup var mocks = new MockRepository(); var applicationFeatureCommandHandler = mocks.Stub(); var exportImportHandler = mocks.Stub(); var viewCommandsHandler = mocks.StrictMock(); var treeViewControl = mocks.StrictMock(); var calculation = mocks.StrictMock(); mocks.ReplayAll(); var counter = 0; var calculationGroup = new CalculationGroup { Children = { calculation } }; var menuBuilder = new ContextMenuBuilder(applicationFeatureCommandHandler, exportImportHandler, viewCommandsHandler, calculationGroup, treeViewControl); CalculationTreeNodeInfoFactory.AddPerformAllCalculationsInGroupItem(menuBuilder, calculationGroup, context => counter++); var contextMenuItem = menuBuilder.Build().Items[0]; // Call contextMenuItem.PerformClick(); // Assert Assert.AreEqual(1, counter); } [Test] public void AddPerformCalculationItem_Always_CreatesPerformItem() { // Setup var mocks = new MockRepository(); var applicationFeatureCommandHandler = mocks.Stub(); var exportImportHandler = mocks.Stub(); var viewCommandsHandler = mocks.StrictMock(); var treeViewControl = mocks.StrictMock(); var calculation = mocks.StrictMock(); mocks.ReplayAll(); var menubuilder = new ContextMenuBuilder(applicationFeatureCommandHandler, exportImportHandler, viewCommandsHandler, calculation, treeViewControl); // Call CalculationTreeNodeInfoFactory.AddPerformCalculationItem(menubuilder, calculation, null); // Assert TestHelper.AssertContextMenuStripContainsItem(menubuilder.Build(), 0, RingtoetsFormsResources.Calculate, RingtoetsFormsResources.Calculate_ToolTip, RingtoetsFormsResources.CalculateIcon); mocks.VerifyAll(); } [Test] public void AddPerformCalculationItem_PerformClickOnCreatedItem_PerformCalculationMethod() { // Setup var mocks = new MockRepository(); var applicationFeatureCommandHandler = mocks.Stub(); var exportImportHandler = mocks.Stub(); var viewCommandsHandler = mocks.StrictMock(); var treeViewControl = mocks.StrictMock(); var calculation = mocks.StrictMock(); mocks.ReplayAll(); var counter = 0; var menuBuilder = new ContextMenuBuilder(applicationFeatureCommandHandler, exportImportHandler, viewCommandsHandler, calculation, treeViewControl); CalculationTreeNodeInfoFactory.AddPerformCalculationItem(menuBuilder, calculation, context => counter++); var contextMenuItem = menuBuilder.Build().Items[0]; // Call contextMenuItem.PerformClick(); // Assert Assert.AreEqual(1, counter); mocks.VerifyAll(); } [Test] public void AddClearCalculationOutputItem_CalculationWithOutput_CreatesDecoratedAndEnabledClearItem() { // Setup var mocks = new MockRepository(); var applicationFeatureCommandHandler = mocks.Stub(); var exportImportHandler = mocks.Stub(); var viewCommandsHandler = mocks.StrictMock(); var treeViewControl = mocks.StrictMock(); var calculationWithOutput = mocks.StrictMock(); calculationWithOutput.Expect(c => c.HasOutput).Return(true); mocks.ReplayAll(); var menuBuilder = new ContextMenuBuilder(applicationFeatureCommandHandler, exportImportHandler, viewCommandsHandler, calculationWithOutput, treeViewControl); // Call CalculationTreeNodeInfoFactory.AddClearCalculationOutputItem(menuBuilder, calculationWithOutput); // Assert TestHelper.AssertContextMenuStripContainsItem(menuBuilder.Build(), 0, RingtoetsFormsResources.Clear_output, RingtoetsFormsResources.Clear_output_ToolTip, RingtoetsFormsResources.ClearIcon); mocks.VerifyAll(); } [Test] public void AddClearCalculationOutputItem_CalculationWithoutOutput_CreatesDecoratedAndDisabledClearItem() { // Setup var mocks = new MockRepository(); var applicationFeatureCommandHandler = mocks.Stub(); var exportImportHandler = mocks.Stub(); var viewCommandsHandler = mocks.StrictMock(); var treeViewControl = mocks.StrictMock(); var calculationWithOutput = mocks.StrictMock(); calculationWithOutput.Expect(c => c.HasOutput).Return(false); mocks.ReplayAll(); var menuBuilder = new ContextMenuBuilder(applicationFeatureCommandHandler, exportImportHandler, viewCommandsHandler, calculationWithOutput, treeViewControl); // Call CalculationTreeNodeInfoFactory.AddClearCalculationOutputItem(menuBuilder, calculationWithOutput); // Assert TestHelper.AssertContextMenuStripContainsItem(menuBuilder.Build(), 0, RingtoetsFormsResources.Clear_output, RingtoetsFormsResources.ClearOutput_No_output_to_clear, RingtoetsFormsResources.ClearIcon, false); mocks.VerifyAll(); } [Test] public void AddClearCalculationOutputItem_PerformClickOnCreatedItemAndConfirmChange_CalculationOutputClearedAndObserversNotified() { var messageBoxText = ""; var messageBoxTitle = ""; var mocks = new MockRepository(); var applicationFeatureCommandHandler = mocks.Stub(); var exportImportHandler = mocks.Stub(); var viewCommandsHandler = mocks.StrictMock(); var treeViewControl = mocks.StrictMock(); var calculationWithOutput = mocks.StrictMock(); calculationWithOutput.Stub(c => c.HasOutput).Return(true); calculationWithOutput.Expect(c => c.ClearOutput()); calculationWithOutput.Expect(c => c.NotifyObservers()); mocks.ReplayAll(); DialogBoxHandler = (name, wnd) => { var messageBox = new MessageBoxTester(wnd); messageBoxText = messageBox.Text; messageBoxTitle = messageBox.Title; messageBox.ClickOk(); }; var menuBuilder = new ContextMenuBuilder(applicationFeatureCommandHandler, exportImportHandler, viewCommandsHandler, calculationWithOutput, treeViewControl); CalculationTreeNodeInfoFactory.AddClearCalculationOutputItem(menuBuilder, calculationWithOutput); var contextMenuItem = menuBuilder.Build().Items[0]; // Call contextMenuItem.PerformClick(); // Assert Assert.AreEqual(BaseResources.Confirm, messageBoxTitle); Assert.AreEqual(RingtoetsFormsResources.Calculation_ContextMenuStrip_Are_you_sure_clear_output, messageBoxText); mocks.VerifyAll(); } [Test] public void AddClearCalculationOutputItem_PerformClickOnCreatedItemAndCancelChange_CalculationOutputNotCleared() { var mocks = new MockRepository(); var applicationFeatureCommandHandler = mocks.Stub(); var exportImportHandler = mocks.Stub(); var viewCommandsHandler = mocks.StrictMock(); var treeViewControl = mocks.StrictMock(); var calculationWithOutput = mocks.StrictMock(); calculationWithOutput.Stub(c => c.HasOutput).Return(true); mocks.ReplayAll(); DialogBoxHandler = (name, wnd) => { var messageBox = new MessageBoxTester(wnd); messageBox.ClickCancel(); }; var menuBuilder = new ContextMenuBuilder(applicationFeatureCommandHandler, exportImportHandler, viewCommandsHandler, calculationWithOutput, treeViewControl); CalculationTreeNodeInfoFactory.AddClearCalculationOutputItem(menuBuilder, calculationWithOutput); var contextMenuItem = menuBuilder.Build().Items[0]; // Call contextMenuItem.PerformClick(); mocks.VerifyAll(); } # region CreateCalculationGroupContextTreeNodeInfo [Test] public void CreateCalculationGroupContextTreeNodeInfo_Always_ExpectedPropertiesSet() { // Setup Func childNodeObjects = context => new object[0]; Func contextMenuStrip = (context, parent, treeViewControl) => new ContextMenuStrip(); Action onNodeRemoved = (context, parent) => { }; // Call var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationGroupContextTreeNodeInfo(childNodeObjects, contextMenuStrip, onNodeRemoved); // Assert Assert.AreEqual(typeof(TestCalculationGroupContext), treeNodeInfo.TagType); Assert.AreSame(childNodeObjects, treeNodeInfo.ChildNodeObjects); Assert.AreSame(contextMenuStrip, treeNodeInfo.ContextMenuStrip); Assert.AreSame(onNodeRemoved, treeNodeInfo.OnNodeRemoved); Assert.IsNull(treeNodeInfo.ForeColor); Assert.IsNull(treeNodeInfo.CanCheck); Assert.IsNull(treeNodeInfo.IsChecked); Assert.IsNull(treeNodeInfo.OnNodeChecked); } [Test] public void Text_CalculationGroup_Always_ReturnsWrappedDataName() { // Setup var mocks = new MockRepository(); var failureMechanismMock = mocks.StrictMock(); mocks.ReplayAll(); var groupName = "testName"; var group = new CalculationGroup { Name = groupName }; var groupContext = new TestCalculationGroupContext(group, failureMechanismMock); var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationGroupContextTreeNodeInfo(null, null, null); // Call var text = treeNodeInfo.Text(groupContext); // Assert Assert.AreEqual(groupName, text); mocks.VerifyAll(); } [Test] public void Image_CalculationGroup_Always_ReturnsFolderIcon() { // Setup var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationGroupContextTreeNodeInfo(null, null, null); // Call var image = treeNodeInfo.Image(null); // Assert TestHelper.AssertImagesAreEqual(RingtoetsFormsResources.GeneralFolderIcon, image); } [Test] public void EnsureVisibleOnCreate_CalculationGroup_ForFailureMechanismCalculationGroup_ReturnsFalse() { // Setup var mocks = new MockRepository(); var failureMechanismMock = mocks.StrictMock>(); mocks.ReplayAll(); var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationGroupContextTreeNodeInfo(null, null, null); // Call var result = treeNodeInfo.EnsureVisibleOnCreate(null, failureMechanismMock); // Assert Assert.IsFalse(result); mocks.VerifyAll(); } [Test] public void EnsureVisibleOnCreate_CalculationGroup_AnyOtherObject_ReturnsTrue() { // Setup var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationGroupContextTreeNodeInfo(null, null, null); // Call var result = treeNodeInfo.EnsureVisibleOnCreate(null, null); // Assert Assert.IsTrue(result); } [Test] public void CanRenameNode_CalculationGroup_NestedCalculationGroup_ReturnsTrue() { // Setup var mocks = new MockRepository(); var calculationGroupMock = mocks.StrictMock(); var failureMechanismMock = mocks.StrictMock(); mocks.ReplayAll(); var groupContext = new TestCalculationGroupContext(calculationGroupMock, failureMechanismMock); var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationGroupContextTreeNodeInfo(null, null, null); // Call bool isRenamingAllowed = treeNodeInfo.CanRename(null, groupContext); // Assert Assert.IsTrue(isRenamingAllowed); mocks.VerifyAll(); } [Test] public void CanRenameNode_CalculationGroup_WithoutParentNodeDefaultBehavior_ReturnsFalse() { // Setup var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationGroupContextTreeNodeInfo(null, null, null); // Call bool isRenamingAllowed = treeNodeInfo.CanRename(null, null); // Assert Assert.IsFalse(isRenamingAllowed); } [Test] public void OnNodeRenamed_CalculationGroup_WithData_RenameGroupAndNotifyObservers() { // Setup var mocks = new MockRepository(); var observer = mocks.StrictMock(); var failureMechanismMock = mocks.StrictMock(); observer.Expect(o => o.UpdateObserver()); mocks.ReplayAll(); const string newName = "new name"; var group = new CalculationGroup(); var nodeData = new TestCalculationGroupContext(group, failureMechanismMock); nodeData.Attach(observer); var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationGroupContextTreeNodeInfo(null, null, null); // Call treeNodeInfo.OnNodeRenamed(nodeData, newName); // Assert Assert.AreEqual(newName, group.Name); mocks.VerifyAll(); } [Test] public void CanRemove_CalculationGroup_NestedCalculationGroup_ReturnsTrue() { // Setup var mocks = new MockRepository(); var failureMechanismMock = mocks.StrictMock(); mocks.ReplayAll(); var nodeData = new TestCalculationGroupContext(new CalculationGroup(), failureMechanismMock); var parentNodeData = new TestCalculationGroupContext(new CalculationGroup(), failureMechanismMock); var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationGroupContextTreeNodeInfo(null, null, null); // Call bool isRemovalAllowed = treeNodeInfo.CanRemove(nodeData, parentNodeData); // Assert Assert.IsTrue(isRemovalAllowed); mocks.VerifyAll(); } [Test] public void CanRemove_CalculationGroup_WithoutParentNodeDefaultBehavior_ReturnsFalse() { // Setup var mocks = new MockRepository(); var failureMechanismMock = mocks.StrictMock(); mocks.ReplayAll(); var nodeData = new TestCalculationGroupContext(new CalculationGroup(), failureMechanismMock); var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationGroupContextTreeNodeInfo(null, null, null); // Call bool isRemovalAllowed = treeNodeInfo.CanRemove(nodeData, null); // Assert Assert.IsFalse(isRemovalAllowed); mocks.VerifyAll(); } [Test] public void CanDrag_CalculationGroup_NestedCalculationGroup_ReturnsTrue() { // Setup var mocks = new MockRepository(); var failureMechanismMock = mocks.StrictMock(); mocks.ReplayAll(); var groupContext = new TestCalculationGroupContext(new CalculationGroup(), failureMechanismMock); var parentGroupContext = new TestCalculationGroupContext(new CalculationGroup(), failureMechanismMock); var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationGroupContextTreeNodeInfo(null, null, null); // Call var canDrag = treeNodeInfo.CanDrag(groupContext, parentGroupContext); // Assert Assert.IsTrue(canDrag); } [Test] public void CanDrag_CalculationGroup_WithoutParentNodeDefaultBehavior_ReturnsFalse() { // Setup var mocks = new MockRepository(); var failureMechanismMock = mocks.StrictMock(); mocks.ReplayAll(); var groupContext = new TestCalculationGroupContext(new CalculationGroup(), failureMechanismMock); var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationGroupContextTreeNodeInfo(null, null, null); // Call var canDrag = treeNodeInfo.CanDrag(groupContext, null); // Assert Assert.IsFalse(canDrag); } [Test] [Combinatorial] public void CanDropOrCanInsert_CalculationGroup_DragCalculationItemOntoGroupNotContainingItem_ReturnsTrue( [Values(DragDropTestMethod.CanDrop, DragDropTestMethod.CanInsert)] DragDropTestMethod methodToTest, [Values(CalculationItemType.Calculation, CalculationItemType.Group)] CalculationItemType draggedItemType) { // Setup var mocks = new MockRepository(); var failureMechanism = mocks.StrictMock(); mocks.ReplayAll(); object draggedItemContext; ICalculationBase draggedItem; CreateCalculationItemAndContext(draggedItemType, out draggedItem, out draggedItemContext, failureMechanism); CalculationGroup targetGroup; TestCalculationGroupContext targetGroupContext; CreateCalculationGroupAndContext(out targetGroup, out targetGroupContext, failureMechanism); var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationGroupContextTreeNodeInfo(null, null, null); switch (methodToTest) { case DragDropTestMethod.CanDrop: // Call var canDrop = treeNodeInfo.CanDrop(draggedItemContext, targetGroupContext); // Assert Assert.IsTrue(canDrop); break; case DragDropTestMethod.CanInsert: // Call bool canInsert = treeNodeInfo.CanInsert(draggedItemContext, targetGroupContext); // Assert Assert.IsTrue(canInsert); break; default: Assert.Fail(methodToTest + " not supported."); break; } mocks.VerifyAll(); } [Test] [Combinatorial] public void CanDropOrInsert_CalculationGroup_DragCalculationItemOntoGroupNotContainingItemOtherFailureMechanism_ReturnsFalse( [Values(DragDropTestMethod.CanDrop, DragDropTestMethod.CanInsert)] DragDropTestMethod methodToTest, [Values(CalculationItemType.Calculation, CalculationItemType.Group)] CalculationItemType draggedItemType) { // Setup var mocks = new MockRepository(); var sourceFailureMechanism = mocks.StrictMock(); var targetFailureMechanism = mocks.StrictMock(); mocks.ReplayAll(); object draggedItemContext; ICalculationBase draggedItem; CreateCalculationItemAndContext(draggedItemType, out draggedItem, out draggedItemContext, targetFailureMechanism); CalculationGroup targetGroup; TestCalculationGroupContext targetGroupContext; CreateCalculationGroupAndContext(out targetGroup, out targetGroupContext, sourceFailureMechanism); var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationGroupContextTreeNodeInfo(null, null, null); switch (methodToTest) { case DragDropTestMethod.CanDrop: // Call var canDrop = treeNodeInfo.CanDrop(draggedItemContext, targetGroupContext); // Assert Assert.IsFalse(canDrop); break; case DragDropTestMethod.CanInsert: // Call bool canInsert = treeNodeInfo.CanInsert(draggedItemContext, targetGroupContext); // Assert Assert.IsFalse(canInsert); break; default: Assert.Fail(methodToTest + " not supported."); break; } mocks.VerifyAll(); } [Test] [Combinatorial] public void OnDrop_CalculationGroup_DragCalculationItemOntoGroupEnd_MoveCalculationItemToNewGroup( [Values(CalculationItemType.Calculation, CalculationItemType.Group)] CalculationItemType draggedItemType) { // Setup var mocks = new MockRepository(); var treeViewControlMock = mocks.StrictMock(); var failureMechanismMock = mocks.StrictMock(); var originalOwnerObserver = mocks.StrictMock(); var newOwnerObserver = mocks.StrictMock(); originalOwnerObserver.Expect(o => o.UpdateObserver()); newOwnerObserver.Expect(o => o.UpdateObserver()); mocks.ReplayAll(); ICalculationBase draggedItem; object draggedItemContext; CreateCalculationItemAndContext(draggedItemType, out draggedItem, out draggedItemContext, failureMechanismMock); CalculationGroup originalOwnerGroup; TestCalculationGroupContext originalOwnerGroupContext; CreateCalculationGroupAndContext(out originalOwnerGroup, out originalOwnerGroupContext, failureMechanismMock); originalOwnerGroup.Children.Add(draggedItem); CalculationGroup newOwnerGroup; TestCalculationGroupContext newOwnerGroupContext; CreateCalculationGroupAndContext(out newOwnerGroup, out newOwnerGroupContext, failureMechanismMock); originalOwnerGroup.Attach(originalOwnerObserver); newOwnerGroup.Attach(newOwnerObserver); var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationGroupContextTreeNodeInfo(null, null, null); // Precondition CollectionAssert.Contains(originalOwnerGroup.Children, draggedItem); CollectionAssert.DoesNotContain(newOwnerGroup.Children, draggedItem); // Call treeNodeInfo.OnDrop(draggedItemContext, newOwnerGroupContext, originalOwnerGroupContext, 0, treeViewControlMock); // Assert CollectionAssert.DoesNotContain(originalOwnerGroup.Children, draggedItem); CollectionAssert.Contains(newOwnerGroup.Children, draggedItem); Assert.AreSame(draggedItem, newOwnerGroup.Children.Last(), "Dragging node at the end of the target TestCalculationGroup should put the dragged data at the end of 'newOwnerGroup'."); mocks.VerifyAll(); } [Test] [Combinatorial] public void OnDrop_CalculationGroup_InsertCalculationItemAtDifferentLocationWithinSameGroup_ChangeItemIndexOfCalculationItem( [Values(CalculationItemType.Calculation, CalculationItemType.Group)] CalculationItemType draggedItemType, [Values(0, 2)] int newIndex) { // Setup var mocks = new MockRepository(); var treeViewControlMock = mocks.StrictMock(); var failureMechanismMock = mocks.StrictMock(); var existingItemStub = mocks.Stub(); var originalOwnerObserver = mocks.StrictMock(); existingItemStub.Stub(ci => ci.Name).Return(""); originalOwnerObserver.Expect(o => o.UpdateObserver()); mocks.ReplayAll(); const string name = "Very cool name"; object draggedItemContext; ICalculationBase draggedItem; CreateCalculationItemAndContext(draggedItemType, out draggedItem, out draggedItemContext, failureMechanismMock, name); CalculationGroup originalOwnerGroup; TestCalculationGroupContext originalOwnerGroupContext; CreateCalculationGroupAndContext(out originalOwnerGroup, out originalOwnerGroupContext, failureMechanismMock); originalOwnerGroup.Children.Add(existingItemStub); originalOwnerGroup.Children.Add(draggedItem); originalOwnerGroup.Children.Add(existingItemStub); originalOwnerGroup.Attach(originalOwnerObserver); var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationGroupContextTreeNodeInfo(null, null, null); // Precondition CollectionAssert.Contains(originalOwnerGroup.Children, draggedItem); // Call treeNodeInfo.OnDrop(draggedItemContext, originalOwnerGroupContext, originalOwnerGroupContext, newIndex, treeViewControlMock); // Assert CollectionAssert.Contains(originalOwnerGroup.Children, draggedItem); Assert.AreNotSame(draggedItem, originalOwnerGroup.Children[1], "Should have removed 'draggedItem' from its original location in the collection."); Assert.AreSame(draggedItem, originalOwnerGroup.Children[newIndex], "Dragging node to specific location within owning TestCalculationGroup should put the dragged data at that index."); Assert.AreEqual(name, draggedItem.Name, "No renaming should occur when dragging within the same TestCalculationGroup."); mocks.VerifyAll(); } [Test] [Combinatorial] public void OnDrop_CalculationGroup_DragCalculationItemOntoGroupWithSameNamedItem_MoveCalculationItemToNewGroupAndRename( [Values(CalculationItemType.Calculation, CalculationItemType.Group)] CalculationItemType draggedItemType) { // Setup var mocks = new MockRepository(); var treeViewControlMock = mocks.StrictMock(); var failureMechanismMock = mocks.StrictMock(); ICalculationBase draggedItem; object draggedItemContext; CreateCalculationItemAndContext(draggedItemType, out draggedItem, out draggedItemContext, failureMechanismMock); CalculationGroup originalOwnerGroup; TestCalculationGroupContext originalOwnerGroupContext; CreateCalculationGroupAndContext(out originalOwnerGroup, out originalOwnerGroupContext, failureMechanismMock); originalOwnerGroup.Children.Add(draggedItem); CalculationGroup newOwnerGroup; TestCalculationGroupContext newOwnerGroupContext; CreateCalculationGroupAndContext(out newOwnerGroup, out newOwnerGroupContext, failureMechanismMock); var sameNamedItem = mocks.Stub(); sameNamedItem.Stub(sni => sni.Name).Return(draggedItem.Name); var originalOwnerObserver = mocks.StrictMock(); originalOwnerObserver.Expect(o => o.UpdateObserver()); var newOwnerObserver = mocks.StrictMock(); newOwnerObserver.Expect(o => o.UpdateObserver()); treeViewControlMock.Expect(tvc => tvc.TryRenameNodeForData(draggedItemContext)); mocks.ReplayAll(); newOwnerGroup.Children.Add(sameNamedItem); originalOwnerGroup.Attach(originalOwnerObserver); newOwnerGroup.Attach(newOwnerObserver); var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationGroupContextTreeNodeInfo(null, null, null); // Precondition CollectionAssert.Contains(originalOwnerGroup.Children, draggedItem); CollectionAssert.DoesNotContain(newOwnerGroup.Children, draggedItem); CollectionAssert.Contains(newOwnerGroup.Children.Select(c => c.Name), draggedItem.Name, "Name of the dragged item should already exist in new owner."); // Call treeNodeInfo.OnDrop(draggedItemContext, newOwnerGroupContext, originalOwnerGroupContext, 0, treeViewControlMock); // Assert CollectionAssert.DoesNotContain(originalOwnerGroup.Children, draggedItem); CollectionAssert.Contains(newOwnerGroup.Children, draggedItem); Assert.AreSame(draggedItem, newOwnerGroup.Children.First(), "Dragging to insert node at start of newOwnerGroup should place the node at the start of the list."); switch (draggedItemType) { case CalculationItemType.Calculation: Assert.AreEqual("Nieuwe berekening", draggedItem.Name); break; case CalculationItemType.Group: Assert.AreEqual("Nieuwe map", draggedItem.Name); break; } mocks.VerifyAll(); } /// /// Creates an instance of and the corresponding . /// /// The created group without any children. /// The context object for , without any other data. /// The failure mechanism the item and context it belong to. private void CreateCalculationGroupAndContext(out CalculationGroup data, out TestCalculationGroupContext dataContext, IFailureMechanism failureMechanism) { data = new CalculationGroup(); dataContext = new TestCalculationGroupContext(data, failureMechanism); } /// /// Creates an instance of and the corresponding context. /// /// Defines the implementation of to be constructed. /// Output: The concrete create class based on . /// Output: The context corresponding with . /// The failure mechanism the item and context belong to. /// Optional: The name of . /// private static void CreateCalculationItemAndContext(CalculationItemType type, out ICalculationBase data, out object dataContext, IFailureMechanism failureMechanism, string initialName = null) { switch (type) { case CalculationItemType.Calculation: var calculation = new TestCalculation(); if (initialName != null) { calculation.Name = initialName; } data = calculation; dataContext = new TestCalculationContext(calculation, failureMechanism); break; case CalculationItemType.Group: var group = new CalculationGroup(); if (initialName != null) { group.Name = initialName; } data = group; dataContext = new TestCalculationGroupContext(group, failureMechanism); break; default: throw new NotSupportedException(); } } #endregion #region CreateCalculationContextTreeNodeInfo [Test] public void CreateCalculationContextTreeNodeInfo_Always_ExpectedPropertiesSet() { // Setup var icon = RingtoetsFormsResources.CalculateIcon; Func childNodeObjects = context => new object[0]; Func contextMenuStrip = (context, parent, treeViewControl) => new ContextMenuStrip(); Action onNodeRemoved = (context, parent) => { }; // Call var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationContextTreeNodeInfo(icon, childNodeObjects, contextMenuStrip, onNodeRemoved); // Assert Assert.AreEqual(typeof(TestCalculationContext), treeNodeInfo.TagType); TestHelper.AssertImagesAreEqual(icon, treeNodeInfo.Image(null)); Assert.AreSame(childNodeObjects, treeNodeInfo.ChildNodeObjects); Assert.AreSame(contextMenuStrip, treeNodeInfo.ContextMenuStrip); Assert.AreSame(onNodeRemoved, treeNodeInfo.OnNodeRemoved); Assert.IsNull(treeNodeInfo.ForeColor); Assert.IsNull(treeNodeInfo.CanCheck); Assert.IsNull(treeNodeInfo.IsChecked); Assert.IsNull(treeNodeInfo.OnNodeChecked); } [Test] public void TextOfCalculationContextTreeNodeInfo_Always_ReturnsWrappedDataName() { // Setup var mocks = new MockRepository(); var failureMechanismMock = mocks.StrictMock(); mocks.ReplayAll(); var calculationName = "calculationName"; var calculation = new TestCalculation { Name = calculationName }; var context = new TestCalculationContext(calculation, failureMechanismMock); var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationContextTreeNodeInfo(null, null, null, null); // Call var text = treeNodeInfo.Text(context); // Assert Assert.AreEqual(calculationName, text); mocks.VerifyAll(); } [Test] public void EnsureVisibleOnCreateOfCalculationContextTreeNodeInfo_Always_ReturnsTrue() { // Setup var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationContextTreeNodeInfo(null, null, null, null); // Call var result = treeNodeInfo.EnsureVisibleOnCreate(null, null); // Assert Assert.IsTrue(result); } [Test] public void CanRenameCalculationContextTreeNodeInfo_Always_ReturnTrue() { // Setup var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationContextTreeNodeInfo(null, null, null, null); // Call var renameAllowed = treeNodeInfo.CanRename(null, null); // Assert Assert.IsTrue(renameAllowed); } [Test] public void OnNodeRenamedOfCalculationContextTreeNodeInfo_Always_SetNewNameToCalculationItemAndNotifyObserver() { // Setup var mocks = new MockRepository(); var observerMock = mocks.StrictMock(); observerMock.Expect(o => o.UpdateObserver()); var failureMechanismMock = mocks.StrictMock(); mocks.ReplayAll(); var calculation = new TestCalculation { Name = "" }; var context = new TestCalculationContext(calculation, failureMechanismMock); var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationContextTreeNodeInfo(null, null, null, null); context.WrappedData.Attach(observerMock); // Call const string newName = ""; treeNodeInfo.OnNodeRenamed(context, newName); // Assert Assert.AreEqual(newName, calculation.Name); mocks.VerifyAll(); } [Test] [TestCase(true)] [TestCase(false)] public void CanRemoveCalculationContextTreeNodeInfo_ParentIsCalculationGroupWithCalculation_ReturnTrue(bool groupNameEditable) { // Setup var calculationToBeRemoved = new TestCalculation(); var group = new CalculationGroup("", groupNameEditable); group.Children.Add(calculationToBeRemoved); var mocks = new MockRepository(); var failureMechanismMock = mocks.StrictMock(); mocks.ReplayAll(); var context = new TestCalculationContext(calculationToBeRemoved, failureMechanismMock); var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationContextTreeNodeInfo(null, null, null, null); var groupContext = new TestCalculationGroupContext(group, failureMechanismMock); // Call bool removalAllowed = treeNodeInfo.CanRemove(context, groupContext); // Assert Assert.IsTrue(removalAllowed); } [Test] [TestCase(true)] [TestCase(false)] public void CanRemoveCalculationContextTreeNodeInfo_ParentIsCalculationGroupWithoutCalculation_ReturnFalse(bool groupNameEditable) { // Setup var calculationToBeRemoved = new TestCalculation(); var group = new CalculationGroup("", groupNameEditable); var mocks = new MockRepository(); var failureMechanismMock = mocks.StrictMock(); mocks.ReplayAll(); var context = new TestCalculationContext(calculationToBeRemoved, failureMechanismMock); var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationContextTreeNodeInfo(null, null, null, null); var groupContext = new TestCalculationGroupContext(group, failureMechanismMock); // Call bool removalAllowed = treeNodeInfo.CanRemove(context, groupContext); // Assert Assert.IsFalse(removalAllowed); } [Test] public void CanRemoveCalculationContextTreeNodeInfo_EverythingElse_ReturnFalse() { // Setup var mocks = new MockRepository(); var dataMock = mocks.StrictMock(); var failureMechanismMock = mocks.StrictMock(); mocks.ReplayAll(); var nodeMock = new TestCalculationContext(new TestCalculation(), failureMechanismMock); var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationContextTreeNodeInfo(null, null, null, null); // Call bool removalAllowed = treeNodeInfo.CanRemove(nodeMock, dataMock); // Assert Assert.IsFalse(removalAllowed); mocks.VerifyAll(); // Expect no calls on arguments } [Test] public void CanDragCalculationContextTreeNodeInfo_Always_ReturnTrue() { // Setup var treeNodeInfo = CalculationTreeNodeInfoFactory.CreateCalculationContextTreeNodeInfo(null, null, null, null); // Call var canDrag = treeNodeInfo.CanDrag(null, null); // Assert Assert.IsTrue(canDrag); } #endregion # region Nested types private class TestCalculationGroupContext : Observable, ICalculationContext { public TestCalculationGroupContext(CalculationGroup wrappedData, IFailureMechanism failureMechanism) { WrappedData = wrappedData; FailureMechanism = failureMechanism; } public CalculationGroup WrappedData { get; private set; } public IFailureMechanism FailureMechanism { get; private set; } } private class TestCalculationContext : Observable, ICalculationContext { public TestCalculationContext(TestCalculation wrappedData, IFailureMechanism failureMechanism) { WrappedData = wrappedData; FailureMechanism = failureMechanism; } public TestCalculation WrappedData { get; private set; } public IFailureMechanism FailureMechanism { get; private set; } } private class TestCalculation : Observable, ICalculation { public TestCalculation() { Name = "Nieuwe berekening"; } public string Name { get; set; } public string Comments { get; set; } public bool HasOutput { get { return false; } } public void ClearOutput() {} public void ClearHydraulicBoundaryLocation() {} public ICalculationInput GetObservableInput() { return null; } } /// /// Type indicator for testing methods on . /// public enum DragDropTestMethod { /// /// Indicates . /// CanDrop, /// /// Indicates . /// CanInsert } /// /// Type indicator for implementations of to be created in a test. /// public enum CalculationItemType { /// /// Indicates . /// Calculation, /// /// Indicates . /// Group } # endregion } }