From a2ca5353b10cde0121b92e63305f9725e95a3fa4 Mon Sep 17 00:00:00 2001 From: Kaleb Luhman Date: Mon, 30 Jan 2017 19:56:02 -0600 Subject: [PATCH] allows type handler to be executed even if the value type already matches target type and added test to verify --- CHANGELOG.md | 1 + .../Attributes/TrimStringPropertyAttribute.cs | 24 +++++++++++++++++++ .../Handlers/TrimStringTypeHandler.cs | 20 ++++++++++++++++ .../Models/ExampleModelAllTypes.cs | 4 ++++ UmbracoVault.Tests/UmbracoContextTests.cs | 7 ++++++ UmbracoVault.Tests/UmbracoVault.Tests.csproj | 2 ++ UmbracoVault/Base/BaseUmbracoContext.cs | 20 ++++++++-------- UmbracoVault/UmbracoVault.nuspec | 1 + 8 files changed, 69 insertions(+), 10 deletions(-) create mode 100644 UmbracoVault.Tests/Attributes/TrimStringPropertyAttribute.cs create mode 100644 UmbracoVault.Tests/Handlers/TrimStringTypeHandler.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 6618f4f..245b815 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## v1.3.2 * Updates UmbracoWebContext.GetCurrent to use the PublishedContent from the PublishedContentRequest rather than getting a page by the current id. +* Updated value transformation process to execute type handler even if value type already matches target type to ensure all proper transforms are applied. ## v1.3.1 diff --git a/UmbracoVault.Tests/Attributes/TrimStringPropertyAttribute.cs b/UmbracoVault.Tests/Attributes/TrimStringPropertyAttribute.cs new file mode 100644 index 0000000..874c35b --- /dev/null +++ b/UmbracoVault.Tests/Attributes/TrimStringPropertyAttribute.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using UmbracoVault.Attributes; +using UmbracoVault.Tests.Handlers; + +namespace UmbracoVault.Tests.Attributes +{ + public class TrimStringPropertyAttribute : UmbracoPropertyAttribute + { + public TrimStringPropertyAttribute() + { + TypeHandler = new TrimStringTypeHandler(); + } + + public TrimStringPropertyAttribute(string alias) : base(alias) + { + TypeHandler = new TrimStringTypeHandler(); + } + } +} diff --git a/UmbracoVault.Tests/Handlers/TrimStringTypeHandler.cs b/UmbracoVault.Tests/Handlers/TrimStringTypeHandler.cs new file mode 100644 index 0000000..526908b --- /dev/null +++ b/UmbracoVault.Tests/Handlers/TrimStringTypeHandler.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using UmbracoVault.TypeHandlers; + +namespace UmbracoVault.Tests.Handlers +{ + class TrimStringTypeHandler : ITypeHandler + { + public object GetAsType(object input) + { + return input?.ToString()?.Trim(); + } + + public Type TypeSupported => typeof(string); + } +} diff --git a/UmbracoVault.Tests/Models/ExampleModelAllTypes.cs b/UmbracoVault.Tests/Models/ExampleModelAllTypes.cs index 23d5e98..d50f757 100644 --- a/UmbracoVault.Tests/Models/ExampleModelAllTypes.cs +++ b/UmbracoVault.Tests/Models/ExampleModelAllTypes.cs @@ -1,4 +1,5 @@ using UmbracoVault.Attributes; +using UmbracoVault.Tests.Attributes; namespace UmbracoVault.Tests.Models { @@ -57,5 +58,8 @@ public class ExampleModelAllTypes [UmbracoEnumProperty] public ExampleEnum ExampleEnum { get; set; } + + [TrimStringProperty] + public string TypeHandledString { get; set; } } } diff --git a/UmbracoVault.Tests/UmbracoContextTests.cs b/UmbracoVault.Tests/UmbracoContextTests.cs index 45a5115..fdccb88 100644 --- a/UmbracoVault.Tests/UmbracoContextTests.cs +++ b/UmbracoVault.Tests/UmbracoContextTests.cs @@ -31,6 +31,7 @@ public void Initialize() Source.StringArray = new[] {"100", "200", "300"}; Source.Object = new { Name = "TestObject" }; Source.ExampleEnum = ExampleEnum.Harry; + Source.TypeHandledString = " this string needs to be trimmed "; var specialCases = new NameValueCollection { @@ -170,6 +171,12 @@ public void String_IsSet() Assert.AreEqual(Source.String, Destination.String); } + [TestMethod] + public void TypeHandler_ShouldExecute_EvenWhenTypesAlreadyMatch() + { + Assert.AreEqual(Source.TypeHandledString.Trim(), Destination.TypeHandledString); + } + [TestMethod] public void UInt_IsSet() { diff --git a/UmbracoVault.Tests/UmbracoVault.Tests.csproj b/UmbracoVault.Tests/UmbracoVault.Tests.csproj index 4aa2d2f..d7e9326 100644 --- a/UmbracoVault.Tests/UmbracoVault.Tests.csproj +++ b/UmbracoVault.Tests/UmbracoVault.Tests.csproj @@ -63,7 +63,9 @@ + + diff --git a/UmbracoVault/Base/BaseUmbracoContext.cs b/UmbracoVault/Base/BaseUmbracoContext.cs index 17e9175..7fc3e95 100644 --- a/UmbracoVault/Base/BaseUmbracoContext.cs +++ b/UmbracoVault/Base/BaseUmbracoContext.cs @@ -286,19 +286,21 @@ protected object TransformParsedValue(PropertyInfo propertyInfo, UmbracoProperty (current, transform) => transform.Transform(current)); */ - if (value.GetType() == propertyType) + var typeHandler = GetTypeHandler(propertyType, propertyMetaData); + + //unsupported if the value is not target type and there is no handler + if (value.GetType() != propertyType && typeHandler == null) { - return value; + throw new NotSupportedException($"The property type {propertyType} is not supported by Umbraco Vault."); } - var typeHandler = GetTypeHandler(propertyType, propertyMetaData); - + //if there is no handler, but value is already the target type, return value if (typeHandler == null) { - throw new NotSupportedException( - $"The property type {propertyType} is not supported by Umbraco Vault."); + return value; } + //apply handler if (typeHandler is EnumTypeHandler) { // Unfortunately, the EnumTypeHandler currently requires special attention because the GetAsType has a "where T : class" constraint. @@ -314,16 +316,14 @@ protected object TransformParsedValue(PropertyInfo propertyInfo, UmbracoProperty { var method = typeHandler.GetType().GetMethod("GetAsType"); var generic = method.MakeGenericMethod(propertyInfo.PropertyType.GetGenericArguments()[0]); - value = generic.Invoke(typeHandler, new[] { value }); + return generic.Invoke(typeHandler, new[] { value }); } else { var method = typeHandler.GetType().GetMethod("GetAsType"); var generic = method.MakeGenericMethod(propertyInfo.PropertyType); - value = generic.Invoke(typeHandler, new[] { value }); + return generic.Invoke(typeHandler, new[] { value }); } - - return value; } private ITypeHandler GetTypeHandler(Type propertyType, UmbracoPropertyAttribute propertyMetaData) diff --git a/UmbracoVault/UmbracoVault.nuspec b/UmbracoVault/UmbracoVault.nuspec index 0a70d12..95b6bf9 100644 --- a/UmbracoVault/UmbracoVault.nuspec +++ b/UmbracoVault/UmbracoVault.nuspec @@ -13,6 +13,7 @@ Vault for Umbraco is an easy-to-use, extensible ORM to quickly and easily get strongly-typed Umbraco CMS data into your views. * Updates UmbracoWebContext.GetCurrent to use the PublishedContent from the PublishedContentRequest rather than getting a page by the current id. + * Updated value transformation process to execute type handler even if value type already matches target type to ensure all proper transforms are applied. (c) The Nerdery LLC 2016. All Rights Reserved. Umbraco UmbracoVault Mapping ObjectMapper ORM CMS