diff --git a/mRemoteNGTests/Container/ContainerInfoTests.cs b/mRemoteNGTests/Container/ContainerInfoTests.cs index 8c08a4193..0c8cb3b3f 100644 --- a/mRemoteNGTests/Container/ContainerInfoTests.cs +++ b/mRemoteNGTests/Container/ContainerInfoTests.cs @@ -2,12 +2,13 @@ using System.Linq; using mRemoteNG.Connection; using mRemoteNG.Container; +using mRemoteNGTests.TestHelpers; using NUnit.Framework; namespace mRemoteNGTests.Container { - public class ContainerInfoTests + public class ContainerInfoTests { private ContainerInfo _containerInfo; private ConnectionInfo _con1; @@ -434,5 +435,69 @@ namespace mRemoteNGTests.Container var grandchildOrderAfterSort = _containerInfo.Children.ToArray(); Assert.That(grandchildOrderAfterSort, Is.Ordered.Descending.By(nameof(ConnectionInfo.ConstantID))); } - } + + [Test] + public void CanApplyConnectionSettingsToChildren() + { + var comparer = new ConnectionInfoAllConnectionPropertiesEqualityComparer(); + var container = new ContainerInfo(); + var con1 = ConnectionInfoHelpers.GetRandomizedConnectionInfo(); + var con2 = ConnectionInfoHelpers.GetRandomizedConnectionInfo(); + container.AddChild(con1); + container.AddChild(con2); + + container.ApplyConnectionPropertiesToChildren(); + + Assert.That(con1, Is.EqualTo(container).Using(comparer)); + Assert.That(con2, Is.EqualTo(container).Using(comparer)); + } + + [Test] + public void ApplyConnectionPropertiesToChildrenWorksRecursively() + { + var comparer = new ConnectionInfoAllConnectionPropertiesEqualityComparer(); + var container = new ContainerInfo(); + var subContainer = ConnectionInfoHelpers.GetRandomizedContainerInfo(); + var con1 = ConnectionInfoHelpers.GetRandomizedConnectionInfo(); + container.AddChild(subContainer); + subContainer.AddChild(con1); + + container.ApplyConnectionPropertiesToChildren(); + + Assert.That(subContainer, Is.EqualTo(container).Using(comparer)); + Assert.That(con1, Is.EqualTo(container).Using(comparer)); + } + + [Test] + public void CanApplyInheritanceSettingsToChildren() + { + var comparer = new ConnectionInheritanceAllPropertiesEqualityComparer(); + var container = new ContainerInfo(); + var con1 = ConnectionInfoHelpers.GetRandomizedConnectionInfo(randomizeInheritance:true); + var con2 = ConnectionInfoHelpers.GetRandomizedConnectionInfo(randomizeInheritance: true); + container.AddChild(con1); + container.AddChild(con2); + + container.ApplyInheritancePropertiesToChildren(); + + Assert.That(con1.Inheritance, Is.EqualTo(container.Inheritance).Using(comparer)); + Assert.That(con2.Inheritance, Is.EqualTo(container.Inheritance).Using(comparer)); + } + + [Test] + public void ApplyInheritancePropertiesToChildrenWorksRecursively() + { + var comparer = new ConnectionInheritanceAllPropertiesEqualityComparer(); + var container = new ContainerInfo(); + var subContainer = ConnectionInfoHelpers.GetRandomizedContainerInfo(randomizeInheritance: true); + var con1 = ConnectionInfoHelpers.GetRandomizedConnectionInfo(randomizeInheritance: true); + container.AddChild(subContainer); + subContainer.AddChild(con1); + + container.ApplyInheritancePropertiesToChildren(); + + Assert.That(subContainer.Inheritance, Is.EqualTo(container.Inheritance).Using(comparer)); + Assert.That(con1.Inheritance, Is.EqualTo(container.Inheritance).Using(comparer)); + } + } } \ No newline at end of file diff --git a/mRemoteNGTests/TestHelpers/ConnectionInfoAllConnectionPropertiesEqualityComparer.cs b/mRemoteNGTests/TestHelpers/ConnectionInfoAllConnectionPropertiesEqualityComparer.cs new file mode 100644 index 000000000..33aaf9263 --- /dev/null +++ b/mRemoteNGTests/TestHelpers/ConnectionInfoAllConnectionPropertiesEqualityComparer.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using System.Linq; +using mRemoteNG.Connection; + +namespace mRemoteNGTests.TestHelpers +{ + public class ConnectionInfoAllConnectionPropertiesEqualityComparer : IEqualityComparer + { + public bool Equals(ConnectionInfo x, ConnectionInfo y) + { + if (x == null && y == null) + return true; + if ((x == null) != (y == null)) + return false; + return GetHashCode(x) == GetHashCode(y); + } + + public int GetHashCode(ConnectionInfo connectionInfo) + { + var allProperties = connectionInfo.GetSerializableProperties(); + + unchecked // Overflow is fine, just wrap + { + return allProperties + .Aggregate(17, + (current, prop) => current * 23 + prop.GetValue(connectionInfo).GetHashCode()); + } + } + } +} diff --git a/mRemoteNGTests/TestHelpers/ConnectionInheritanceAllPropertiesEqualityComparer.cs b/mRemoteNGTests/TestHelpers/ConnectionInheritanceAllPropertiesEqualityComparer.cs new file mode 100644 index 000000000..21fef6f9c --- /dev/null +++ b/mRemoteNGTests/TestHelpers/ConnectionInheritanceAllPropertiesEqualityComparer.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using System.Linq; +using mRemoteNG.Connection; + +namespace mRemoteNGTests.TestHelpers +{ + public class ConnectionInheritanceAllPropertiesEqualityComparer : IEqualityComparer + { + public bool Equals(ConnectionInfoInheritance x, ConnectionInfoInheritance y) + { + if (x == null && y == null) + return true; + if ((x == null) != (y == null)) + return false; + return GetHashCode(x) == GetHashCode(y); + } + + public int GetHashCode(ConnectionInfoInheritance inheritance) + { + var allProperties = inheritance.GetProperties(); + + unchecked // Overflow is fine, just wrap + { + return allProperties + .Aggregate(17, + (current, prop) => current * 23 + prop.GetValue(inheritance).GetHashCode()); + } + } + } +} diff --git a/mRemoteNGTests/mRemoteNGTests.csproj b/mRemoteNGTests/mRemoteNGTests.csproj index 255dc1360..159eeec54 100644 --- a/mRemoteNGTests/mRemoteNGTests.csproj +++ b/mRemoteNGTests/mRemoteNGTests.csproj @@ -177,7 +177,9 @@ + + diff --git a/mRemoteV1/Container/ContainerInfo.cs b/mRemoteV1/Container/ContainerInfo.cs index fa2e901c1..90cf6a5d3 100644 --- a/mRemoteV1/Container/ContainerInfo.cs +++ b/mRemoteV1/Container/ContainerInfo.cs @@ -263,6 +263,34 @@ namespace mRemoteNG.Container return childList; } + /// + /// Pushes the connection properties of this container to all + /// children recursively. + /// + public void ApplyConnectionPropertiesToChildren() + { + var children = GetRecursiveChildList(); + + foreach (var child in children) + { + child.CopyFrom(this); + } + } + + /// + /// Pushes the inheritance settings of this container to all + /// children recursively. + /// + public void ApplyInheritancePropertiesToChildren() + { + var children = GetRecursiveChildList(); + + foreach (var child in children) + { + child.Inheritance = Inheritance.Clone(child); + } + } + private IEnumerable GetRecursiveFavoritChildList(ContainerInfo container) { var childList = new List();