Skip to content

Commit ae423de

Browse files
kjacAndyButland
andauthored
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 <[email protected]>
1 parent 4078e83 commit ae423de

File tree

2 files changed

+76
-23
lines changed

2 files changed

+76
-23
lines changed

src/Umbraco.Infrastructure/PropertyEditors/MultipleTextStringPropertyEditor.cs

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -89,21 +89,6 @@ public MultipleTextStringPropertyValueEditor(
8989
return null;
9090
}
9191

92-
if (!(editorValue.DataTypeConfiguration is MultipleTextStringConfiguration config))
93-
{
94-
throw new PanicException(
95-
$"editorValue.DataTypeConfiguration is {editorValue.DataTypeConfiguration?.GetType()} but must be {typeof(MultipleTextStringConfiguration)}");
96-
}
97-
98-
var max = config.Max;
99-
100-
// The legacy property editor saved this data as new line delimited! strange but we have to maintain that.
101-
// only allow the max if over 0
102-
if (max > 0)
103-
{
104-
return string.Join(_newLine, value.Take(max));
105-
}
106-
10792
return string.Join(_newLine, value);
10893
}
10994

@@ -114,9 +99,12 @@ public override object ToEditor(IProperty property, string? culture = null, stri
11499

115100
// The legacy property editor saved this data as new line delimited! strange but we have to maintain that.
116101
return value is string stringValue
117-
? stringValue.Split(_newLineDelimiters, StringSplitOptions.None)
102+
? SplitPropertyValue(stringValue)
118103
: Array.Empty<string>();
119104
}
105+
106+
internal static string[] SplitPropertyValue(string propertyValue)
107+
=> propertyValue.Split(_newLineDelimiters, StringSplitOptions.None);
120108
}
121109

122110
/// <summary>
@@ -166,13 +154,13 @@ public IEnumerable<ValidationResult> Validate(object? value, string? valueType,
166154
yield break;
167155
}
168156

169-
// If we have a null value, treat as an empty collection for minimum number validation.
170-
if (value is not IEnumerable<string> stringValues)
171-
{
172-
stringValues = [];
173-
}
174-
175-
var stringCount = stringValues.Count();
157+
// Handle both a newline delimited string and an IEnumerable<string> as the value (see: https://github.com/umbraco/Umbraco-CMS/pull/18936).
158+
// If we have a null value, treat as a string count of zero for minimum number validation.
159+
var stringCount = value is string stringValue
160+
? MultipleTextStringPropertyValueEditor.SplitPropertyValue(stringValue).Length
161+
: value is IEnumerable<string> strings
162+
? strings.Count()
163+
: 0;
176164

177165
if (stringCount < multipleTextStringConfiguration.Min)
178166
{

tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/MultipleTextStringPropertyValueEditorTests.cs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,20 @@ public void Can_Parse_Multi_Value_From_Editor()
8282
Assert.AreEqual("The First Value\nThe Second Value\nThe Third Value", fromEditor);
8383
}
8484

85+
[Test]
86+
public void Can_Parse_More_Items_Than_Allowed_From_Editor()
87+
{
88+
var valueEditor = CreateValueEditor();
89+
var fromEditor = valueEditor.FromEditor(new ContentPropertyData(new[] { "One", "Two", "Three", "Four", "Five" }, new MultipleTextStringConfiguration { Max = 4 }), null) as string;
90+
Assert.AreEqual("One\nTwo\nThree\nFour\nFive", fromEditor);
91+
92+
var validationResults = valueEditor.Validate(fromEditor, false, null, PropertyValidationContext.Empty());
93+
Assert.AreEqual(1, validationResults.Count());
94+
95+
var validationResult = validationResults.First();
96+
Assert.AreEqual($"validation_outOfRangeMultipleItemsMaximum", validationResult.ErrorMessage);
97+
}
98+
8599
[Test]
86100
public void Can_Parse_Single_Value_To_Editor()
87101
{
@@ -150,6 +164,27 @@ public void Validates_Number_Of_Items_Is_Greater_Than_Or_Equal_To_Configured_Min
150164
}
151165
}
152166

167+
[TestCase("", false)]
168+
[TestCase("one", false)]
169+
[TestCase("one\ntwo", true)]
170+
[TestCase("one\ntwo\nthree", true)]
171+
public void Validates_Number_Of_Items_Is_Greater_Than_Or_Equal_To_Configured_Min_Raw_Property_Value(string value, bool expectedSuccess)
172+
{
173+
var editor = CreateValueEditor();
174+
var result = editor.Validate(value, false, null, PropertyValidationContext.Empty());
175+
if (expectedSuccess)
176+
{
177+
Assert.IsEmpty(result);
178+
}
179+
else
180+
{
181+
Assert.AreEqual(1, result.Count());
182+
183+
var validationResult = result.First();
184+
Assert.AreEqual($"validation_outOfRangeSingleItemMinimum", validationResult.ErrorMessage);
185+
}
186+
}
187+
153188
[TestCase(3, true)]
154189
[TestCase(4, true)]
155190
[TestCase(5, false)]
@@ -171,6 +206,36 @@ public void Validates_Number_Of_Items_Is_Less_Than_Or_Equal_To_Configured_Max(in
171206
}
172207
}
173208

209+
[TestCase("one\ntwo\nthree", true)]
210+
[TestCase("one\ntwo\nthree\nfour", true)]
211+
[TestCase("one\ntwo\nthree\nfour\nfive", false)]
212+
public void Validates_Number_Of_Items_Is_Less_Than_Or_Equal_To_Configured_Max_Raw_Property_Value(string value, bool expectedSuccess)
213+
{
214+
var editor = CreateValueEditor();
215+
var result = editor.Validate(value, false, null, PropertyValidationContext.Empty());
216+
if (expectedSuccess)
217+
{
218+
Assert.IsEmpty(result);
219+
}
220+
else
221+
{
222+
Assert.AreEqual(1, result.Count());
223+
224+
var validationResult = result.First();
225+
Assert.AreEqual("validation_outOfRangeMultipleItemsMaximum", validationResult.ErrorMessage);
226+
}
227+
}
228+
229+
[TestCase("one\ntwo\nthree")]
230+
[TestCase("one\rtwo\rthree")]
231+
[TestCase("one\r\ntwo\r\nthree")]
232+
public void Can_Parse_Supported_Property_Value_Delimiters(string value)
233+
{
234+
var editor = CreateValueEditor();
235+
var result = editor.Validate(value, false, null, PropertyValidationContext.Empty());
236+
Assert.IsEmpty(result);
237+
}
238+
174239
[Test]
175240
public void Max_Item_Validation_Respects_0_As_Unlimited()
176241
{

0 commit comments

Comments
 (0)