Correct handling of step values of zero. (#18532)

This commit is contained in:
Andy Butland
2025-03-04 11:18:23 +01:00
parent b650e7984e
commit d167a60373
4 changed files with 27 additions and 20 deletions

View File

@@ -19,6 +19,11 @@ public static class ValidationHelper
return true; // Outside of the range, so we expect another validator will have picked this up.
}
if (step == 0)
{
return true; // A step of zero would trigger a divide by zero error in evaluating. So we always pass validation for zero, as effectively any step value is valid.
}
return (value - min) % step == 0;
}
}

View File

@@ -132,11 +132,12 @@ public class DecimalValueEditorTests
}
}
[TestCase(1.4, false)]
[TestCase(1.5, true)]
public void Validates_Matches_Configured_Step(object value, bool expectedSuccess)
[TestCase(0.2, 1.4, false)]
[TestCase(0.2, 1.5, true)]
[TestCase(0.0, 1.4, true)] // A step of zero would trigger a divide by zero error in evaluating. So we always pass validation for zero, as effectively any step value is valid.
public void Validates_Matches_Configured_Step(double step, object value, bool expectedSuccess)
{
var editor = CreateValueEditor();
var editor = CreateValueEditor(step: step);
var result = editor.Validate(value, false, null, PropertyValidationContext.Empty());
if (expectedSuccess)
{
@@ -164,7 +165,7 @@ public class DecimalValueEditorTests
return CreateValueEditor().ToEditor(property.Object);
}
private static DecimalPropertyEditor.DecimalPropertyValueEditor CreateValueEditor()
private static DecimalPropertyEditor.DecimalPropertyValueEditor CreateValueEditor(double step = 0.2)
{
var localizedTextServiceMock = new Mock<ILocalizedTextService>();
localizedTextServiceMock.Setup(x => x.Localize(
@@ -184,7 +185,7 @@ public class DecimalValueEditorTests
{
{ "min", 1.1 },
{ "max", 1.9 },
{ "step", 0.2 }
{ "step", step }
}
};
}

View File

@@ -132,11 +132,12 @@ public class IntegerValueEditorTests
}
}
[TestCase(17, false)]
[TestCase(18, true)]
public void Validates_Matches_Configured_Step(object value, bool expectedSuccess)
[TestCase(2, 17, false)]
[TestCase(2, 18, true)]
[TestCase(0, 17, true)] // A step of zero would trigger a divide by zero error in evaluating. So we always pass validation for zero, as effectively any step value is valid.
public void Validates_Matches_Configured_Step(int step, object value, bool expectedSuccess)
{
var editor = CreateValueEditor();
var editor = CreateValueEditor(step: step);
var result = editor.Validate(value, false, null, PropertyValidationContext.Empty());
if (expectedSuccess)
{
@@ -164,7 +165,7 @@ public class IntegerValueEditorTests
return CreateValueEditor().ToEditor(property.Object);
}
private static IntegerPropertyEditor.IntegerPropertyValueEditor CreateValueEditor()
private static IntegerPropertyEditor.IntegerPropertyValueEditor CreateValueEditor(int step = 2)
{
var localizedTextServiceMock = new Mock<ILocalizedTextService>();
localizedTextServiceMock.Setup(x => x.Localize(
@@ -184,7 +185,7 @@ public class IntegerValueEditorTests
{
{ "min", 10 },
{ "max", 20 },
{ "step", 2 }
{ "step", step }
}
};
}

View File

@@ -8,7 +8,6 @@ using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Editors;
using Umbraco.Cms.Core.Models.Validation;
using Umbraco.Cms.Core.PropertyEditors;
using Umbraco.Cms.Core.Serialization;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Strings;
using Umbraco.Cms.Infrastructure.Serialization;
@@ -206,17 +205,18 @@ public class SliderValueEditorTests
}
}
[TestCase(1.3, 1.7, true)]
[TestCase(1.4, 1.7, false)]
[TestCase(1.3, 1.6, false)]
public void Validates_Matches_Configured_Step(decimal from, decimal to, bool expectedSuccess)
[TestCase(0.2, 1.3, 1.7, true)]
[TestCase(0.2, 1.4, 1.7, false)]
[TestCase(0.2, 1.3, 1.6, false)]
[TestCase(0.0, 1.4, 1.7, true)] // A step of zero would trigger a divide by zero error in evaluating. So we always pass validation for zero, as effectively any step value is valid.
public void Validates_Matches_Configured_Step(decimal step, decimal from, decimal to, bool expectedSuccess)
{
var value = new JsonObject
{
{ "from", from },
{ "to", to },
};
var editor = CreateValueEditor();
var editor = CreateValueEditor(step: step);
var result = editor.Validate(value, false, null, PropertyValidationContext.Empty());
if (expectedSuccess)
{
@@ -244,7 +244,7 @@ public class SliderValueEditorTests
return CreateValueEditor().ToEditor(property.Object);
}
private static SliderPropertyEditor.SliderPropertyValueEditor CreateValueEditor(bool enableRange = true)
private static SliderPropertyEditor.SliderPropertyValueEditor CreateValueEditor(bool enableRange = true, decimal step = 0.2m)
{
var localizedTextServiceMock = new Mock<ILocalizedTextService>();
localizedTextServiceMock.Setup(x => x.Localize(
@@ -265,7 +265,7 @@ public class SliderValueEditorTests
EnableRange = enableRange,
MinimumValue = 1.1m,
MaximumValue = 1.9m,
Step = 0.2m
Step = step
},
};
}