From d52695d81f607cc24c8a96ac95a82f9869c2a065 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Thu, 12 Mar 2020 15:45:21 +0100 Subject: [PATCH 1/3] Update dependency for 7.15.4 --- build/NuSpecs/UmbracoCms.Core.nuspec | 2 +- src/SolutionInfo.cs | 4 ++-- src/Umbraco.Core/Configuration/UmbracoVersion.cs | 2 +- src/Umbraco.Core/Umbraco.Core.csproj | 5 +++-- src/Umbraco.Core/packages.config | 2 +- src/Umbraco.Web.UI.Client/bower.json | 4 ++-- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 9 +++++---- src/Umbraco.Web.UI/packages.config | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 5 +++-- src/Umbraco.Web/packages.config | 2 +- src/umbraco.cms/packages.config | 2 +- src/umbraco.cms/umbraco.cms.csproj | 5 +++-- src/umbraco.controls/packages.config | 2 +- src/umbraco.controls/umbraco.controls.csproj | 5 +++-- src/umbraco.editorControls/packages.config | 2 +- src/umbraco.editorControls/umbraco.editorControls.csproj | 5 +++-- 16 files changed, 32 insertions(+), 26 deletions(-) diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index 9f507b4915..747beb44a1 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -29,7 +29,7 @@ - + diff --git a/src/SolutionInfo.cs b/src/SolutionInfo.cs index 97ebd98e8c..b5a8fbc738 100644 --- a/src/SolutionInfo.cs +++ b/src/SolutionInfo.cs @@ -11,5 +11,5 @@ using System.Resources; [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyFileVersion("7.15.3")] -[assembly: AssemblyInformationalVersion("7.15.3")] +[assembly: AssemblyFileVersion("7.15.4")] +[assembly: AssemblyInformationalVersion("7.15.4")] diff --git a/src/Umbraco.Core/Configuration/UmbracoVersion.cs b/src/Umbraco.Core/Configuration/UmbracoVersion.cs index 8c8755577a..65bd4f8694 100644 --- a/src/Umbraco.Core/Configuration/UmbracoVersion.cs +++ b/src/Umbraco.Core/Configuration/UmbracoVersion.cs @@ -6,7 +6,7 @@ namespace Umbraco.Core.Configuration { public class UmbracoVersion { - private static readonly Version Version = new Version("7.15.3"); + private static readonly Version Version = new Version("7.15.4"); /// /// Gets the current version of Umbraco. diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 3b5d0aaff6..0259c0212d 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -45,8 +45,9 @@ ..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll - - ..\packages\ClientDependency.1.9.7\lib\net45\ClientDependency.Core.dll + + ..\packages\ClientDependency.1.9.9\lib\net45\ClientDependency.Core.dll + True ..\packages\HtmlAgilityPack.1.8.8\lib\Net45\HtmlAgilityPack.dll diff --git a/src/Umbraco.Core/packages.config b/src/Umbraco.Core/packages.config index 60ee650d15..ea2880269e 100644 --- a/src/Umbraco.Core/packages.config +++ b/src/Umbraco.Core/packages.config @@ -1,7 +1,7 @@  - + diff --git a/src/Umbraco.Web.UI.Client/bower.json b/src/Umbraco.Web.UI.Client/bower.json index b173909c63..e6d75231a6 100644 --- a/src/Umbraco.Web.UI.Client/bower.json +++ b/src/Umbraco.Web.UI.Client/bower.json @@ -25,11 +25,11 @@ "jquery-migrate": "1.4.0", "angular-dynamic-locale": "0.1.28", "ng-file-upload": "~7.3.8", - "tinymce": "~4.9.4", + "tinymce": "4.9.5", "codemirror": "~5.3.0", "angular-local-storage": "~0.2.3", "moment": "~2.10.3", - "ace-builds": "^1.2.3", + "ace-builds": "1.4.5", "clipboard": "1.7.1", "font-awesome": "~4.7" }, diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 76d2765672..83e5a75ade 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -122,8 +122,9 @@ ..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll True - - ..\packages\ClientDependency.1.9.7\lib\net45\ClientDependency.Core.dll + + ..\packages\ClientDependency.1.9.9\lib\net45\ClientDependency.Core.dll + True ..\packages\ClientDependency-Mvc5.1.8.0.0\lib\net45\ClientDependency.Core.Mvc.dll @@ -1028,9 +1029,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.1\x86\*.* "$(TargetDir)x86\" True True - 7153 + 7154 / - http://localhost:7153 + http://localhost:7154 False False diff --git a/src/Umbraco.Web.UI/packages.config b/src/Umbraco.Web.UI/packages.config index a8271c1370..20da49c180 100644 --- a/src/Umbraco.Web.UI/packages.config +++ b/src/Umbraco.Web.UI/packages.config @@ -1,7 +1,7 @@  - + diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 01524e5962..2d328d5476 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -107,8 +107,9 @@ ..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll True - - ..\packages\ClientDependency.1.9.7\lib\net45\ClientDependency.Core.dll + + ..\packages\ClientDependency.1.9.9\lib\net45\ClientDependency.Core.dll + True ..\packages\dotless.1.5.2\lib\dotless.Core.dll diff --git a/src/Umbraco.Web/packages.config b/src/Umbraco.Web/packages.config index 06bfad4856..08b76cdbe8 100644 --- a/src/Umbraco.Web/packages.config +++ b/src/Umbraco.Web/packages.config @@ -1,7 +1,7 @@  - + diff --git a/src/umbraco.cms/packages.config b/src/umbraco.cms/packages.config index 54bd2136bc..d9267779cf 100644 --- a/src/umbraco.cms/packages.config +++ b/src/umbraco.cms/packages.config @@ -1,6 +1,6 @@  - + diff --git a/src/umbraco.cms/umbraco.cms.csproj b/src/umbraco.cms/umbraco.cms.csproj index 811c221b54..ba0d180b1e 100644 --- a/src/umbraco.cms/umbraco.cms.csproj +++ b/src/umbraco.cms/umbraco.cms.csproj @@ -106,8 +106,9 @@ false - - ..\packages\ClientDependency.1.9.7\lib\net45\ClientDependency.Core.dll + + ..\packages\ClientDependency.1.9.9\lib\net45\ClientDependency.Core.dll + True ..\packages\HtmlAgilityPack.1.8.8\lib\Net45\HtmlAgilityPack.dll diff --git a/src/umbraco.controls/packages.config b/src/umbraco.controls/packages.config index cbccba27be..1c393b5f2a 100644 --- a/src/umbraco.controls/packages.config +++ b/src/umbraco.controls/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/umbraco.controls/umbraco.controls.csproj b/src/umbraco.controls/umbraco.controls.csproj index 834713ac9a..4858b916db 100644 --- a/src/umbraco.controls/umbraco.controls.csproj +++ b/src/umbraco.controls/umbraco.controls.csproj @@ -68,8 +68,9 @@ false - - ..\packages\ClientDependency.1.9.7\lib\net45\ClientDependency.Core.dll + + ..\packages\ClientDependency.1.9.9\lib\net45\ClientDependency.Core.dll + True diff --git a/src/umbraco.editorControls/packages.config b/src/umbraco.editorControls/packages.config index cbccba27be..1c393b5f2a 100644 --- a/src/umbraco.editorControls/packages.config +++ b/src/umbraco.editorControls/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/umbraco.editorControls/umbraco.editorControls.csproj b/src/umbraco.editorControls/umbraco.editorControls.csproj index cd98635ed1..aabdc4bf63 100644 --- a/src/umbraco.editorControls/umbraco.editorControls.csproj +++ b/src/umbraco.editorControls/umbraco.editorControls.csproj @@ -114,8 +114,9 @@ {651E1350-91B6-44B7-BD60-7207006D7003} Umbraco.Web - - ..\packages\ClientDependency.1.9.7\lib\net45\ClientDependency.Core.dll + + ..\packages\ClientDependency.1.9.9\lib\net45\ClientDependency.Core.dll + True System From e8d63d9a7a108804586ddab31fe4706a9fa4c72c Mon Sep 17 00:00:00 2001 From: Alexander Karlsson Date: Tue, 10 Mar 2020 11:02:23 +0100 Subject: [PATCH 2/3] #7780 Show all filters that is more then 0 hits --- .../src/views/users/views/users/users.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/users/views/users/users.html b/src/Umbraco.Web.UI.Client/src/views/users/views/users/users.html index e4fd2d24be..c0ddfc329a 100644 --- a/src/Umbraco.Web.UI.Client/src/views/users/views/users/users.html +++ b/src/Umbraco.Web.UI.Client/src/views/users/views/users/users.html @@ -124,7 +124,7 @@ - +
Date: Thu, 26 Mar 2020 19:56:21 +1100 Subject: [PATCH 3/3] Fixes issue with deep cloning Property main problem was that it was duplicating the _pvalue value when it shouldn't have. The real fix is that the Values property solves all these problems with it's setter but that wasn't being used by the DeepClone engine because that explicitly looks for certain collection types and IReadOnlyCollection wasn't one of them. With that included and PropertyValue marked as IDeepCloneable, it all just works. I've added tests. --- src/Umbraco.Core/Models/DeepCloneHelper.cs | 5 +- src/Umbraco.Core/Models/Property.cs | 26 +++----- src/Umbraco.Tests/Models/ContentTests.cs | 73 ++++++++++++---------- src/Umbraco.Tests/Models/PropertyTests.cs | 63 +++++++++++++++++++ src/Umbraco.Tests/Umbraco.Tests.csproj | 1 + 5 files changed, 116 insertions(+), 52 deletions(-) create mode 100644 src/Umbraco.Tests/Models/PropertyTests.cs diff --git a/src/Umbraco.Core/Models/DeepCloneHelper.cs b/src/Umbraco.Core/Models/DeepCloneHelper.cs index 6470de912b..453b455d4b 100644 --- a/src/Umbraco.Core/Models/DeepCloneHelper.cs +++ b/src/Umbraco.Core/Models/DeepCloneHelper.cs @@ -81,9 +81,10 @@ namespace Umbraco.Core.Models if (propertyInfo.PropertyType.IsGenericType && (propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IEnumerable<>) || propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(ICollection<>) - || propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IList<>))) + || propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IList<>) + || propertyInfo.PropertyType.GetGenericTypeDefinition() == typeof(IReadOnlyCollection<>))) { - //if it is a IEnumerable<>, IList or ICollection<> we'll use a List<> + //if it is a IEnumerable<>, IReadOnlyCollection, IList or ICollection<> we'll use a List<> since it implements them all var genericType = typeof(List<>).MakeGenericType(propertyInfo.PropertyType.GetGenericArguments()); return new ClonePropertyInfo(propertyInfo) { GenericListType = genericType }; } diff --git a/src/Umbraco.Core/Models/Property.cs b/src/Umbraco.Core/Models/Property.cs index f51f70faf6..1d044aa20d 100644 --- a/src/Umbraco.Core/Models/Property.cs +++ b/src/Umbraco.Core/Models/Property.cs @@ -50,7 +50,7 @@ namespace Umbraco.Core.Models /// /// Represents a property value. /// - public class PropertyValue : IEquatable + public class PropertyValue : IDeepCloneable, IEquatable { // TODO: Either we allow change tracking at this class level, or we add some special change tracking collections to the Property // class to deal with change tracking which variants have changed @@ -96,6 +96,8 @@ namespace Umbraco.Core.Models public PropertyValue Clone() => new PropertyValue { _culture = _culture, _segment = _segment, PublishedValue = PublishedValue, EditedValue = EditedValue }; + public object DeepClone() => Clone(); + public override bool Equals(object obj) { return Equals(obj as PropertyValue); @@ -105,14 +107,18 @@ namespace Umbraco.Core.Models { return other != null && _culture == other._culture && - _segment == other._segment; + _segment == other._segment && + EqualityComparer.Default.Equals(EditedValue, other.EditedValue) && + EqualityComparer.Default.Equals(PublishedValue, other.PublishedValue); } public override int GetHashCode() { - var hashCode = -1254204277; + var hashCode = 1885328050; hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(_culture); hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(_segment); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(EditedValue); + hashCode = hashCode * -1521134295 + EqualityComparer.Default.GetHashCode(PublishedValue); return hashCode; } } @@ -358,20 +364,6 @@ namespace Umbraco.Core.Models var clonedEntity = (Property)clone; - //manually clone _values, _pvalue, _vvalues - clonedEntity._values = _values?.Select(x => x.Clone()).ToList(); // all values get copied - clonedEntity._pvalue = _pvalue?.Clone(); - // the tricky part here is that _values contains ALL values including the values in the _vvalues - // dictionary and they are by reference which is why we have equality overloads on PropertyValue - if (clonedEntity._vvalues != null) - { - clonedEntity._vvalues = new Dictionary(); - foreach (var item in _vvalues) - { - clonedEntity._vvalues[item.Key] = clonedEntity._values.First(x => x.Equals(item.Value)); - } - } - //need to manually assign since this is a readonly property clonedEntity.PropertyType = (PropertyType) PropertyType.DeepClone(); } diff --git a/src/Umbraco.Tests/Models/ContentTests.cs b/src/Umbraco.Tests/Models/ContentTests.cs index 3116087669..5bb30e1606 100644 --- a/src/Umbraco.Tests/Models/ContentTests.cs +++ b/src/Umbraco.Tests/Models/ContentTests.cs @@ -24,7 +24,6 @@ using Umbraco.Web.PropertyEditors; namespace Umbraco.Tests.Models { - [TestFixture] public class ContentTests : UmbracoTestBase { @@ -42,7 +41,7 @@ namespace Umbraco.Tests.Models // all this is required so we can validate properties... var editor = new TextboxPropertyEditor(Mock.Of()) { Alias = "test" }; - Composition.Register(_ => new DataEditorCollection(new [] { editor })); + Composition.Register(_ => new DataEditorCollection(new[] { editor })); Composition.Register(); var dataType = Mock.Of(); Mock.Get(dataType).Setup(x => x.Configuration).Returns(() => new object()); @@ -55,7 +54,7 @@ namespace Umbraco.Tests.Models var mediaTypeService = Mock.Of(); var memberTypeService = Mock.Of(); Composition.Register(_ => ServiceContext.CreatePartial(dataTypeService: dataTypeService, contentTypeBaseServiceProvider: new ContentTypeBaseServiceProvider(_contentTypeService, mediaTypeService, memberTypeService))); - + } [Test] @@ -458,7 +457,7 @@ namespace Umbraco.Tests.Models Assert.IsTrue(prop.WasPropertyDirty("Id")); } Assert.IsTrue(content.WasPropertyDirty("CultureInfos")); - foreach(var culture in content.CultureInfos) + foreach (var culture in content.CultureInfos) { Assert.IsTrue(culture.WasDirty()); Assert.IsTrue(culture.WasPropertyDirty("Name")); @@ -539,7 +538,7 @@ namespace Umbraco.Tests.Models var content = MockedContent.CreateTextpageContent(contentType, "Textpage", -1); // Act - content.PropertyValues(new { title = "This is the new title"}); + content.PropertyValues(new { title = "This is the new title" }); // Assert Assert.That(content.Properties.Any(), Is.True); @@ -603,13 +602,13 @@ namespace Umbraco.Tests.Models // Act contentType.PropertyGroups["Content"].PropertyTypes.Add(new PropertyType("test", ValueStorageType.Ntext, "subtitle") - { - Name = "Subtitle", - Description = "Optional subtitle", - Mandatory = false, - SortOrder = 3, - DataTypeId = -88 - }); + { + Name = "Subtitle", + Description = "Optional subtitle", + Mandatory = false, + SortOrder = 3, + DataTypeId = -88 + }); // Assert Assert.That(contentType.PropertyGroups["Content"].PropertyTypes.Count, Is.EqualTo(3)); @@ -626,9 +625,13 @@ namespace Umbraco.Tests.Models // Act var propertyType = new PropertyType("test", ValueStorageType.Ntext, "subtitle") - { - Name = "Subtitle", Description = "Optional subtitle", Mandatory = false, SortOrder = 3, DataTypeId = -88 - }; + { + Name = "Subtitle", + Description = "Optional subtitle", + Mandatory = false, + SortOrder = 3, + DataTypeId = -88 + }; contentType.PropertyGroups["Content"].PropertyTypes.Add(propertyType); var newProperty = new Property(propertyType); newProperty.SetValue("This is a subtitle Test"); @@ -650,14 +653,14 @@ namespace Umbraco.Tests.Models // Act var propertyType = new PropertyType("test", ValueStorageType.Ntext, "subtitle") - { - Name = "Subtitle", - Description = "Optional subtitle", - Mandatory = false, - SortOrder = 3, - DataTypeId = -88 - }; - var propertyGroup = new PropertyGroup(true) { Name = "Test Group", SortOrder = 3}; + { + Name = "Subtitle", + Description = "Optional subtitle", + Mandatory = false, + SortOrder = 3, + DataTypeId = -88 + }; + var propertyGroup = new PropertyGroup(true) { Name = "Test Group", SortOrder = 3 }; propertyGroup.PropertyTypes.Add(propertyType); contentType.PropertyGroups.Add(propertyGroup); var newProperty = new Property(propertyType); @@ -681,9 +684,13 @@ namespace Umbraco.Tests.Models // Act - note that the PropertyType's properties like SortOrder is not updated through the Content object var propertyType = new PropertyType("test", ValueStorageType.Ntext, "title") - { - Name = "Title", Description = "Title description added", Mandatory = false, SortOrder = 10, DataTypeId = -88 - }; + { + Name = "Title", + Description = "Title description added", + Mandatory = false, + SortOrder = 10, + DataTypeId = -88 + }; content.Properties.Add(new Property(propertyType)); // Assert @@ -911,13 +918,13 @@ namespace Umbraco.Tests.Models // Act var propertyType = new PropertyType("test", ValueStorageType.Ntext, "subtitle") - { - Name = "Subtitle", - Description = "Optional subtitle", - Mandatory = false, - SortOrder = 3, - DataTypeId = -88 - }; + { + Name = "Subtitle", + Description = "Optional subtitle", + Mandatory = false, + SortOrder = 3, + DataTypeId = -88 + }; contentType.PropertyGroups["Content"].PropertyTypes.Add(propertyType); // Assert diff --git a/src/Umbraco.Tests/Models/PropertyTests.cs b/src/Umbraco.Tests/Models/PropertyTests.cs new file mode 100644 index 0000000000..a95afcdd5c --- /dev/null +++ b/src/Umbraco.Tests/Models/PropertyTests.cs @@ -0,0 +1,63 @@ +using System; +using System.Linq; +using NUnit.Framework; +using Umbraco.Core.Models; +using Umbraco.Tests.Testing; + +namespace Umbraco.Tests.Models +{ + [TestFixture] + public class PropertyTests : UmbracoTestBase + { + [Test] + public void Can_Deep_Clone() + { + // needs to be within collection to support publishing + var ptCollection = new PropertyTypeCollection(true, new[] {new PropertyType("TestPropertyEditor", ValueStorageType.Nvarchar, "test") + { + Id = 3, + CreateDate = DateTime.Now, + DataTypeId = 5, + PropertyEditorAlias = "propTest", + Description = "testing", + Key = Guid.NewGuid(), + Mandatory = true, + Name = "Test", + PropertyGroupId = new Lazy(() => 11), + SortOrder = 9, + UpdateDate = DateTime.Now, + ValidationRegExp = "xxxx", + ValueStorageType = ValueStorageType.Nvarchar + }}); + + var property = new Property(123, ptCollection[0]) + { + CreateDate = DateTime.Now, + Id = 4, + Key = Guid.NewGuid(), + UpdateDate = DateTime.Now + }; + + property.SetValue("hello"); + property.PublishValues(); + + var clone = (Property)property.DeepClone(); + + Assert.AreNotSame(clone, property); + Assert.AreNotSame(clone.Values, property.Values); + Assert.AreNotSame(property.PropertyType, clone.PropertyType); + for (int i = 0; i < property.Values.Count; i++) + { + Assert.AreNotSame(property.Values.ElementAt(i), clone.Values.ElementAt(i)); + } + + + //This double verifies by reflection + var allProps = clone.GetType().GetProperties(); + foreach (var propertyInfo in allProps) + { + Assert.AreEqual(propertyInfo.GetValue(clone, null), propertyInfo.GetValue(property, null)); + } + } + } +} diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 90f9303423..3c359cdde8 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -142,6 +142,7 @@ +