From 1e9182cfa44ec1ed704454de0e1441013ada44d0 Mon Sep 17 00:00:00 2001 From: Mole Date: Tue, 19 Nov 2024 11:14:53 +0100 Subject: [PATCH] V14: Use decimal in slider property editor (#17568) * Allow SliderPropertyEditor to use decimals * Add tests * Boyscout unittest update --------- Co-authored-by: Sven Geusens --- .../PropertyEditors/SliderPropertyEditor.cs | 13 ++--- .../PropertyEditors/SliderValueEditorTests.cs | 47 ++++++++----------- 2 files changed, 27 insertions(+), 33 deletions(-) diff --git a/src/Umbraco.Infrastructure/PropertyEditors/SliderPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/SliderPropertyEditor.cs index 8321915677..b67e4af0a2 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/SliderPropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/SliderPropertyEditor.cs @@ -1,6 +1,7 @@ // Copyright (c) Umbraco. // See LICENSE for more details. +using System.Globalization; using Umbraco.Cms.Core.IO; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Editors; @@ -51,8 +52,8 @@ public class SliderPropertyEditor : DataEditor public override object? ToEditor(IProperty property, string? culture = null, string? segment = null) { - // value is stored as a string - either a single integer value - // or a two integer values separated by comma (for range sliders) + // value is stored as a string - either a single decimal value + // or a two decimal values separated by comma (for range sliders) var value = property.GetValue(culture, segment); if (value is not string stringValue) { @@ -61,7 +62,7 @@ public class SliderPropertyEditor : DataEditor var parts = stringValue.Split(Constants.CharArrays.Comma); var parsed = parts - .Select(s => int.TryParse(s, out var i) ? i : (int?)null) + .Select(s => decimal.TryParse(s, NumberStyles.Number, CultureInfo.InvariantCulture, out var i) ? i : (decimal?)null) .Where(i => i != null) .Select(i => i!.Value) .ToArray(); @@ -78,11 +79,11 @@ public class SliderPropertyEditor : DataEditor internal class SliderRange { - public int From { get; set; } + public decimal From { get; set; } - public int To { get; set; } + public decimal To { get; set; } - public override string ToString() => From == To ? $"{From}" : $"{From},{To}"; + public override string ToString() => From == To ? $"{From.ToString(CultureInfo.InvariantCulture)}" : $"{From.ToString(CultureInfo.InvariantCulture)},{To.ToString(CultureInfo.InvariantCulture)}"; } } } diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/SliderValueEditorTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/SliderValueEditorTests.cs index 0850422598..6ec212c02e 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/SliderValueEditorTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/SliderValueEditorTests.cs @@ -6,7 +6,6 @@ using Umbraco.Cms.Core.IO; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Editors; using Umbraco.Cms.Core.PropertyEditors; -using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Strings; using Umbraco.Cms.Infrastructure.Serialization; @@ -15,19 +14,11 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.PropertyEditors; [TestFixture] public class SliderValueEditorTests { - // annoyingly we can't use decimals etc. in attributes, so we can't turn these into test cases :( - private List _invalidValues = new(); - - [SetUp] - public void SetUp() => _invalidValues = new List + public static object[] InvalidCaseData = new object[] { 123m, 123, -123, - 123.45d, - "123.45", - "1.234,56", - "1.2.3.4", "something", true, new object(), @@ -36,21 +27,19 @@ public class SliderValueEditorTests new GuidUdi(Constants.UdiEntityType.Document, Guid.NewGuid()) }; - [Test] - public void Can_Handle_Invalid_Values_From_Editor() + [TestCaseSource(nameof(InvalidCaseData))] + public void Can_Handle_Invalid_Values_From_Editor(object value) { - foreach (var value in _invalidValues) - { - var fromEditor = FromEditor(value); - Assert.IsNull(fromEditor, message: $"Failed for: {value}"); - } + var fromEditor = FromEditor(value); + Assert.IsNull(fromEditor); } [TestCase("1", 1)] [TestCase("0", 0)] [TestCase("-1", -1)] [TestCase("123456789", 123456789)] - public void Can_Parse_Single_Value_To_Editor(string value, int expected) + [TestCase("123.45", 123.45)] + public void Can_Parse_Single_Value_To_Editor(string value, decimal expected) { var toEditor = ToEditor(value) as SliderPropertyEditor.SliderPropertyValueEditor.SliderRange; Assert.IsNotNull(toEditor); @@ -62,7 +51,10 @@ public class SliderValueEditorTests [TestCase("0,0", 0, 0)] [TestCase("-1,-1", -1, -1)] [TestCase("10,123456789", 10, 123456789)] - public void Can_Parse_Range_Value_To_Editor(string value, int expectedFrom, int expectedTo) + [TestCase("1.234,56", 1.234, 56)] + [TestCase("4,6.234", 4, 6.234)] + [TestCase("10.45,15.3", 10.45, 15.3)] + public void Can_Parse_Range_Value_To_Editor(string value, decimal expectedFrom, decimal expectedTo) { var toEditor = ToEditor(value) as SliderPropertyEditor.SliderPropertyValueEditor.SliderRange; Assert.IsNotNull(toEditor); @@ -75,21 +67,22 @@ public class SliderValueEditorTests [TestCase(0, 0, "0")] [TestCase(-10, -10, "-10")] [TestCase(10, 123456789, "10,123456789")] - public void Can_Parse_Valid_Value_From_Editor(int from, int to, string expectedResult) + [TestCase(1.5, 1.5, "1.5")] + [TestCase(0, 0.5, "0,0.5")] + [TestCase(5, 5.4, "5,5.4")] + [TestCase(0.5, 0.6, "0.5,0.6")] + public void Can_Parse_Valid_Value_From_Editor(decimal from, decimal to, string expectedResult) { var value = JsonNode.Parse($"{{\"from\": {from}, \"to\": {to}}}"); var fromEditor = FromEditor(value) as string; Assert.AreEqual(expectedResult, fromEditor); } - [Test] - public void Can_Handle_Invalid_Values_To_Editor() + [TestCaseSource(nameof(InvalidCaseData))] + public void Can_Handle_Invalid_Values_To_Editor(object value) { - foreach (var value in _invalidValues) - { - var toEditor = ToEditor(value); - Assert.IsNull(toEditor, message: $"Failed for: {value}"); - } + var toEditor = ToEditor(value); + Assert.IsNull(toEditor, message: $"Failed for: {value}"); } [Test]