diff --git a/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs b/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs index bc5971a377..0c05df2342 100644 --- a/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs +++ b/src/Umbraco.Tests/FrontEnd/UmbracoHelperTests.cs @@ -1,6 +1,14 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; +using System.Text; +using LightInject; +using Moq; using NUnit.Framework; using Umbraco.Core; +using Umbraco.Core.Cache; +using Umbraco.Core.Composing; +using Umbraco.Core.Logging; +using Umbraco.Tests.TestHelpers; using Umbraco.Web; namespace Umbraco.Tests.FrontEnd @@ -8,59 +16,51 @@ namespace Umbraco.Tests.FrontEnd [TestFixture] public class UmbracoHelperTests { - [Test] - public void Truncate_Simple() - { - var text = "Hello world, this is some text with a link"; + private const string SampleWithAnchorElement = "Hello world, this is some text with a link"; + private const string SampleWithBoldAndAnchorElements = "Hello world, this is some text with a link"; + [Test] + public static void Truncate_Simple() + { var helper = new UmbracoHelper(); - var result = helper.Truncate(text, 25).ToString(); - - Assert.AreEqual("Hello world, this is some…", result); - } - - /// - /// If a truncated string ends with a space, we should trim the space before appending the ellipsis. - /// - [Test] - public void Truncate_Simple_With_Trimming() - { - var text = "Hello world, this is some text with a link"; - - var helper = new UmbracoHelper(); - - var result = helper.Truncate(text, 26).ToString(); + var result = helper.Truncate(SampleWithAnchorElement, 25).ToString(); Assert.AreEqual("Hello world, this is some…", result); } [Test] - public void Truncate_Inside_Word() + public static void When_Truncating_A_String_Ends_With_A_Space_We_Should_Trim_The_Space_Before_Appending_The_Ellipsis() { - var text = "Hello world, this is some text with a link"; - var helper = new UmbracoHelper(); - var result = helper.Truncate(text, 24).ToString(); + var result = helper.Truncate(SampleWithAnchorElement, 26).ToString(); + + Assert.AreEqual("Hello world, this is some…", result); + } + + [Test] + public static void Truncate_Inside_Word() + { + var helper = new UmbracoHelper(); + + var result = helper.Truncate(SampleWithAnchorElement, 24).ToString(); Assert.AreEqual("Hello world, this is som…", result); } [Test] - public void Truncate_With_Tag() + public static void Truncate_With_Tag() { - var text = "Hello world, this is some text with a link"; - var helper = new UmbracoHelper(); - var result = helper.Truncate(text, 35).ToString(); + var result = helper.Truncate(SampleWithAnchorElement, 35).ToString(); Assert.AreEqual("Hello world, this is some text with…", result); } [Test] - public void Create_Encrypted_RouteString_From_Anonymous_Object() + public static void Create_Encrypted_RouteString_From_Anonymous_Object() { var additionalRouteValues = new { @@ -68,16 +68,24 @@ namespace Umbraco.Tests.FrontEnd key2 = "value2", Key3 = "Value3", keY4 = "valuE4" - }; - var encryptedRouteString = UmbracoHelper.CreateEncryptedRouteString("FormController", "FormAction", "", additionalRouteValues); + }; + + var encryptedRouteString = UmbracoHelper.CreateEncryptedRouteString( + "FormController", + "FormAction", + "", + additionalRouteValues + ); + var result = encryptedRouteString.DecryptWithMachineKey(); - var expectedResult = "c=FormController&a=FormAction&ar=&key1=value1&key2=value2&Key3=Value3&keY4=valuE4"; + + const string expectedResult = "c=FormController&a=FormAction&ar=&key1=value1&key2=value2&Key3=Value3&keY4=valuE4"; Assert.AreEqual(expectedResult, result); } [Test] - public void Create_Encrypted_RouteString_From_Dictionary() + public static void Create_Encrypted_RouteString_From_Dictionary() { var additionalRouteValues = new Dictionary() { @@ -86,79 +94,77 @@ namespace Umbraco.Tests.FrontEnd {"Key3", "Value3"}, {"keY4", "valuE4"} }; - var encryptedRouteString = UmbracoHelper.CreateEncryptedRouteString("FormController", "FormAction", "", additionalRouteValues); + + var encryptedRouteString = UmbracoHelper.CreateEncryptedRouteString( + "FormController", + "FormAction", + "", + additionalRouteValues + ); + var result = encryptedRouteString.DecryptWithMachineKey(); - var expectedResult = "c=FormController&a=FormAction&ar=&key1=value1&key2=value2&Key3=Value3&keY4=valuE4"; + + const string expectedResult = "c=FormController&a=FormAction&ar=&key1=value1&key2=value2&Key3=Value3&keY4=valuE4"; Assert.AreEqual(expectedResult, result); } [Test] - public void Truncate_By_Words() + public static void Truncate_By_Words() { - var text = "Hello world, this is some text with a link"; - var helper = new UmbracoHelper(); - var result = helper.TruncateByWords(text, 4).ToString(); + var result = helper.TruncateByWords(SampleWithAnchorElement, 4).ToString(); Assert.AreEqual("Hello world, this is…", result); } [Test] - public void Truncate_By_Words_With_Tag() + public static void Truncate_By_Words_With_Tag() { - var text = "Hello world, this is some text with a link"; - var helper = new UmbracoHelper(); - var result = helper.TruncateByWords(text, 4).ToString(); + var result = helper.TruncateByWords(SampleWithBoldAndAnchorElements, 4).ToString(); Assert.AreEqual("Hello world, this is…", result); } [Test] - public void Truncate_By_Words_Mid_Tag() + public static void Truncate_By_Words_Mid_Tag() { - var text = "Hello world, this is some text with a link"; - var helper = new UmbracoHelper(); - var result = helper.TruncateByWords(text, 7).ToString(); + var result = helper.TruncateByWords(SampleWithAnchorElement, 7).ToString(); Assert.AreEqual("Hello world, this is some text with…", result); } [Test] - public void Strip_All_Html() + public static void Strip_All_Html() { - var text = "Hello world, this is some text with a link"; - var helper = new UmbracoHelper(); - var result = helper.StripHtml(text, null).ToString(); + var result = helper.StripHtml(SampleWithBoldAndAnchorElements, null).ToString(); Assert.AreEqual("Hello world, this is some text with a link", result); } [Test] - public void Strip_Specific_Html() + public static void Strip_Specific_Html() { - var text = "Hello world, this is some text with a link"; - - string [] tags = {"b"}; + string[] tags = { "b" }; var helper = new UmbracoHelper(); - var result = helper.StripHtml(text, tags).ToString(); + var result = helper.StripHtml(SampleWithBoldAndAnchorElements, tags).ToString(); Assert.AreEqual("Hello world, this is some text with a link", result); } [Test] - public void Strip_Invalid_Html() + public static void Strip_Invalid_Html() { - var text = "Hello world, is some text with a link"; + const string text = "Hello world, is some text with a link"; var helper = new UmbracoHelper(); @@ -166,5 +172,252 @@ namespace Umbraco.Tests.FrontEnd Assert.AreEqual("Hello world, is some text with a link", result); } + + // ------- Int32 conversion tests + [Test] + public static void Converting_Boxed_34_To_An_Int_Returns_34() + { + // Arrange + const int sample = 34; + + // Act + bool success = UmbracoHelper.ConvertIdObjectToInt( + sample, + out int result + ); + + // Assert + Assert.IsTrue(success); + Assert.That(result, Is.EqualTo(34)); + } + + [Test] + public static void Converting_String_54_To_An_Int_Returns_54() + { + // Arrange + const string sample = "54"; + + // Act + bool success = UmbracoHelper.ConvertIdObjectToInt( + sample, + out int result + ); + + // Assert + Assert.IsTrue(success); + Assert.That(result, Is.EqualTo(54)); + } + + [Test] + public static void Converting_Hello_To_An_Int_Returns_False() + { + // Arrange + const string sample = "Hello"; + + // Act + bool success = UmbracoHelper.ConvertIdObjectToInt( + sample, + out int result + ); + + // Assert + Assert.IsFalse(success); + Assert.That(result, Is.EqualTo(0)); + } + + [Test] + public static void Converting_Unsupported_Object_To_An_Int_Returns_False() + { + // Arrange + var clearlyWillNotConvertToInt = new StringBuilder(0); + + // Act + bool success = UmbracoHelper.ConvertIdObjectToInt( + clearlyWillNotConvertToInt, + out int result + ); + + // Assert + Assert.IsFalse(success); + Assert.That(result, Is.EqualTo(0)); + } + + // ------- GUID conversion tests + [Test] + public static void Converting_Boxed_Guid_To_A_Guid_Returns_Original_Guid_Value() + { + // Arrange + Guid sample = Guid.NewGuid(); + + // Act + bool success = UmbracoHelper.ConvertIdObjectToGuid( + sample, + out Guid result + ); + + // Assert + Assert.IsTrue(success); + Assert.That(result, Is.EqualTo(sample)); + } + + [Test] + public static void Converting_String_Guid_To_A_Guid_Returns_Original_Guid_Value() + { + // Arrange + Guid sample = Guid.NewGuid(); + + // Act + bool success = UmbracoHelper.ConvertIdObjectToGuid( + sample.ToString(), + out Guid result + ); + + // Assert + Assert.IsTrue(success); + Assert.That(result, Is.EqualTo(sample)); + } + + [Test] + public static void Converting_Hello_To_A_Guid_Returns_False() + { + // Arrange + const string sample = "Hello"; + + // Act + bool success = UmbracoHelper.ConvertIdObjectToGuid( + sample, + out Guid result + ); + + // Assert + Assert.IsFalse(success); + Assert.That(result, Is.EqualTo(new Guid("00000000-0000-0000-0000-000000000000"))); + } + + [Test] + public static void Converting_Unsupported_Object_To_A_Guid_Returns_False() + { + // Arrange + var clearlyWillNotConvertToGuid = new StringBuilder(0); + + // Act + bool success = UmbracoHelper.ConvertIdObjectToGuid( + clearlyWillNotConvertToGuid, + out Guid result + ); + + // Assert + Assert.IsFalse(success); + Assert.That(result, Is.EqualTo(new Guid("00000000-0000-0000-0000-000000000000"))); + } + + // ------- UDI Conversion Tests + [Test] + public void Converting_Boxed_Udi_To_A_Udi_Returns_Original_Udi_Value() + { + // Arrange + SetUpDependencyContainer(); + Udi.ResetUdiTypes(); + + Udi sample = new GuidUdi(Constants.UdiEntityType.AnyGuid, Guid.NewGuid()); + + // Act + bool success = UmbracoHelper.ConvertIdObjectToUdi( + sample, + out Udi result + ); + + // Assert + ResetDependencyContainer(); + + Assert.IsTrue(success); + Assert.That(result, Is.EqualTo(sample)); + } + + [Test] + public void Converting_String_Udi_To_A_Udi_Returns_Original_Udi_Value() + { + // Arrange + SetUpDependencyContainer(); + Udi.ResetUdiTypes(); + + Udi sample = new GuidUdi(Constants.UdiEntityType.AnyGuid, Guid.NewGuid()); + + // Act + bool success = UmbracoHelper.ConvertIdObjectToUdi( + sample.ToString(), + out Udi result + ); + + // Assert + ResetDependencyContainer(); + + Assert.IsTrue(success); + Assert.That(result, Is.EqualTo(sample)); + } + + [Test] + public void Converting_Hello_To_A_Udi_Returns_False() + { + // Arrange + SetUpDependencyContainer(); + Udi.ResetUdiTypes(); + + const string SAMPLE = "Hello"; + + // Act + bool success = UmbracoHelper.ConvertIdObjectToUdi( + SAMPLE, + out Udi result + ); + + // Assert + ResetDependencyContainer(); + + Assert.IsFalse(success); + Assert.That(result, Is.Null); + } + + [Test] + public void Converting_Unsupported_Object_To_A_Udi_Returns_False() + { + // Arrange + SetUpDependencyContainer(); + Udi.ResetUdiTypes(); + + var clearlyWillNotConvertToGuid = new StringBuilder(0); + + // Act + bool success = UmbracoHelper.ConvertIdObjectToUdi( + clearlyWillNotConvertToGuid, + out Udi result + ); + + // Assert + ResetDependencyContainer(); + + Assert.IsFalse(success); + Assert.That(result, Is.Null); + } + + private void SetUpDependencyContainer() + { + // fixme - bad in a unit test - but Udi has a static ctor that wants it?! + var container = new Mock(); + var globalSettings = SettingsForTests.GenerateMockGlobalSettings(); + + container + .Setup(x => x.GetInstance(typeof(TypeLoader))) + .Returns(new TypeLoader( + NullCacheProvider.Instance, + globalSettings, + new ProfilingLogger(Mock.Of(), Mock.Of()) + ) + ); + + Current.Container = container.Object; + } + + private void ResetDependencyContainer() => Current.Reset(); } } diff --git a/src/Umbraco.Web/UmbracoHelper.cs b/src/Umbraco.Web/UmbracoHelper.cs index 411a3fc2e1..62f49c5fa8 100644 --- a/src/Umbraco.Web/UmbracoHelper.cs +++ b/src/Umbraco.Web/UmbracoHelper.cs @@ -1,24 +1,20 @@ using System; +using System.Collections.Generic; using System.ComponentModel; +using System.Linq; using System.Web; -using System.Web.Security; using System.Xml.XPath; using Umbraco.Core; -using Umbraco.Core.Dictionary; -using Umbraco.Core.Security; -using Umbraco.Core.Services; -using Umbraco.Core.Xml; -using Umbraco.Web.Routing; -using Umbraco.Web.Security; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Web.Mvc; using Umbraco.Core.Cache; +using Umbraco.Core.Dictionary; using Umbraco.Core.Exceptions; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.Services; +using Umbraco.Core.Xml; using Umbraco.Web.Composing; +using Umbraco.Web.Routing; +using Umbraco.Web.Security; namespace Umbraco.Web { @@ -577,37 +573,38 @@ namespace Umbraco.Web return ContentQuery.ContentAtRoot(); } - private static bool ConvertIdObjectToInt(object id, out int intId) + internal static bool ConvertIdObjectToInt(object id, out int intId) { - var s = id as string; - if (s != null) + switch (id) { - return int.TryParse(s, out intId); - } + case string s: + return int.TryParse(s, out intId); - if (id is int) - { - intId = (int) id; - return true; + case int i: + intId = i; + return true; + + default: + intId = default; + return false; } - intId = default(int); - return false; } - private static bool ConvertIdObjectToGuid(object id, out Guid guidId) + internal static bool ConvertIdObjectToGuid(object id, out Guid guidId) { - var s = id as string; - if (s != null) + switch (id) { - return Guid.TryParse(s, out guidId); + case string s: + return Guid.TryParse(s, out guidId); + + case Guid g: + guidId = g; + return true; + + default: + guidId = default; + return false; } - if (id is Guid) - { - guidId = (Guid) id; - return true; - } - guidId = default(Guid); - return false; } private static bool ConvertIdsObjectToInts(IEnumerable ids, out IEnumerable intIds) @@ -641,17 +638,21 @@ namespace Umbraco.Web return true; } - private static bool ConvertIdObjectToUdi(object id, out Udi guidId) + internal static bool ConvertIdObjectToUdi(object id, out Udi guidId) { - if (id is string s) - return Udi.TryParse(s, out guidId); - if (id is Udi) + switch (id) { - guidId = (Udi) id; - return true; + case string s: + return Udi.TryParse(s, out guidId); + + case Udi u: + guidId = u; + return true; + + default: + guidId = default; + return false; } - guidId = null; - return false; } #endregion