Add raw value validation to multiple text strings property editor (#18936)

* Add raw value validation to multiple text strings property editor

* Added additional assert on unit test and comment on validation logic.

* Don't remove items to obtain a valid value

---------

Co-authored-by: Andy Butland <abutland73@gmail.com>
This commit is contained in:
Kenn Jacobsen
2025-04-07 09:40:17 +02:00
committed by GitHub
parent 4078e83634
commit ae423decc3
2 changed files with 76 additions and 23 deletions

View File

@@ -89,21 +89,6 @@ public class MultipleTextStringPropertyEditor : DataEditor
return null;
}
if (!(editorValue.DataTypeConfiguration is MultipleTextStringConfiguration config))
{
throw new PanicException(
$"editorValue.DataTypeConfiguration is {editorValue.DataTypeConfiguration?.GetType()} but must be {typeof(MultipleTextStringConfiguration)}");
}
var max = config.Max;
// The legacy property editor saved this data as new line delimited! strange but we have to maintain that.
// only allow the max if over 0
if (max > 0)
{
return string.Join(_newLine, value.Take(max));
}
return string.Join(_newLine, value);
}
@@ -114,9 +99,12 @@ public class MultipleTextStringPropertyEditor : DataEditor
// The legacy property editor saved this data as new line delimited! strange but we have to maintain that.
return value is string stringValue
? stringValue.Split(_newLineDelimiters, StringSplitOptions.None)
? SplitPropertyValue(stringValue)
: Array.Empty<string>();
}
internal static string[] SplitPropertyValue(string propertyValue)
=> propertyValue.Split(_newLineDelimiters, StringSplitOptions.None);
}
/// <summary>
@@ -166,13 +154,13 @@ public class MultipleTextStringPropertyEditor : DataEditor
yield break;
}
// If we have a null value, treat as an empty collection for minimum number validation.
if (value is not IEnumerable<string> stringValues)
{
stringValues = [];
}
var stringCount = stringValues.Count();
// Handle both a newline delimited string and an IEnumerable<string> as the value (see: https://github.com/umbraco/Umbraco-CMS/pull/18936).
// If we have a null value, treat as a string count of zero for minimum number validation.
var stringCount = value is string stringValue
? MultipleTextStringPropertyValueEditor.SplitPropertyValue(stringValue).Length
: value is IEnumerable<string> strings
? strings.Count()
: 0;
if (stringCount < multipleTextStringConfiguration.Min)
{

View File

@@ -82,6 +82,20 @@ public class MultipleTextStringPropertyValueEditorTests
Assert.AreEqual("The First Value\nThe Second Value\nThe Third Value", fromEditor);
}
[Test]
public void Can_Parse_More_Items_Than_Allowed_From_Editor()
{
var valueEditor = CreateValueEditor();
var fromEditor = valueEditor.FromEditor(new ContentPropertyData(new[] { "One", "Two", "Three", "Four", "Five" }, new MultipleTextStringConfiguration { Max = 4 }), null) as string;
Assert.AreEqual("One\nTwo\nThree\nFour\nFive", fromEditor);
var validationResults = valueEditor.Validate(fromEditor, false, null, PropertyValidationContext.Empty());
Assert.AreEqual(1, validationResults.Count());
var validationResult = validationResults.First();
Assert.AreEqual($"validation_outOfRangeMultipleItemsMaximum", validationResult.ErrorMessage);
}
[Test]
public void Can_Parse_Single_Value_To_Editor()
{
@@ -150,6 +164,27 @@ public class MultipleTextStringPropertyValueEditorTests
}
}
[TestCase("", false)]
[TestCase("one", false)]
[TestCase("one\ntwo", true)]
[TestCase("one\ntwo\nthree", true)]
public void Validates_Number_Of_Items_Is_Greater_Than_Or_Equal_To_Configured_Min_Raw_Property_Value(string value, bool expectedSuccess)
{
var editor = CreateValueEditor();
var result = editor.Validate(value, false, null, PropertyValidationContext.Empty());
if (expectedSuccess)
{
Assert.IsEmpty(result);
}
else
{
Assert.AreEqual(1, result.Count());
var validationResult = result.First();
Assert.AreEqual($"validation_outOfRangeSingleItemMinimum", validationResult.ErrorMessage);
}
}
[TestCase(3, true)]
[TestCase(4, true)]
[TestCase(5, false)]
@@ -171,6 +206,36 @@ public class MultipleTextStringPropertyValueEditorTests
}
}
[TestCase("one\ntwo\nthree", true)]
[TestCase("one\ntwo\nthree\nfour", true)]
[TestCase("one\ntwo\nthree\nfour\nfive", false)]
public void Validates_Number_Of_Items_Is_Less_Than_Or_Equal_To_Configured_Max_Raw_Property_Value(string value, bool expectedSuccess)
{
var editor = CreateValueEditor();
var result = editor.Validate(value, false, null, PropertyValidationContext.Empty());
if (expectedSuccess)
{
Assert.IsEmpty(result);
}
else
{
Assert.AreEqual(1, result.Count());
var validationResult = result.First();
Assert.AreEqual("validation_outOfRangeMultipleItemsMaximum", validationResult.ErrorMessage);
}
}
[TestCase("one\ntwo\nthree")]
[TestCase("one\rtwo\rthree")]
[TestCase("one\r\ntwo\r\nthree")]
public void Can_Parse_Supported_Property_Value_Delimiters(string value)
{
var editor = CreateValueEditor();
var result = editor.Validate(value, false, null, PropertyValidationContext.Empty());
Assert.IsEmpty(result);
}
[Test]
public void Max_Item_Validation_Respects_0_As_Unlimited()
{