* Only validate segment values for cultures they are defined for. * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Integration test suppressions. * Remove previous implementation using ISegmentService and rely on values provided in the model to determine segments with cultures. * Omit null culture and remove passing but unrealistic tests. * Fixed nullability error. * Apply suggestions from code review Co-authored-by: Kenn Jacobsen <kja@umbraco.dk> * Relocated function following code review. * Reset unchanged files. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Kenn Jacobsen <kja@umbraco.dk>
This commit is contained in:
@@ -50,7 +50,7 @@ internal abstract class ContentValidationServiceBase<TContentType>
|
||||
cultures = await GetCultureCodes();
|
||||
}
|
||||
|
||||
// we don't have any managed segments, so we have to make do with the ones passed in the model
|
||||
// We don't have managed segments, so we have to make do with the ones passed in the model.
|
||||
var segments =
|
||||
new string?[] { null }
|
||||
.Union(contentEditingModelBase.Variants
|
||||
@@ -105,21 +105,39 @@ internal abstract class ContentValidationServiceBase<TContentType>
|
||||
}
|
||||
}
|
||||
|
||||
foreach (IPropertyType propertyType in cultureAndSegmentVariantPropertyTypes)
|
||||
if (cultureAndSegmentVariantPropertyTypes.Length > 0)
|
||||
{
|
||||
foreach (var culture in cultures)
|
||||
{
|
||||
foreach (var segment in segments.DefaultIfEmpty(null))
|
||||
{
|
||||
var validationContext = new PropertyValidationContext
|
||||
{
|
||||
Culture = culture, Segment = segment, CulturesBeingValidated = cultures, SegmentsBeingValidated = segments
|
||||
};
|
||||
// Get a mapping of segments to their associated cultures based on the variants and properties provided in the model.
|
||||
// Without managed segments again we need to rely on the model data.
|
||||
Dictionary<string, HashSet<string>> segmentCultures = GetPopulatedSegmentCultures(contentEditingModelBase, cultures);
|
||||
|
||||
PropertyValueModel? propertyValueModel = contentEditingModelBase
|
||||
.Properties
|
||||
.FirstOrDefault(propertyValue => propertyValue.Alias == propertyType.Alias && propertyValue.Culture.InvariantEquals(culture) && propertyValue.Segment.InvariantEquals(segment));
|
||||
validationErrors.AddRange(ValidateProperty(propertyType, propertyValueModel, validationContext));
|
||||
foreach (IPropertyType propertyType in cultureAndSegmentVariantPropertyTypes)
|
||||
{
|
||||
foreach (var culture in cultures)
|
||||
{
|
||||
foreach (var segment in segments.DefaultIfEmpty(null))
|
||||
{
|
||||
// Skip validation if the segment has cultures defined and the current culture is not included.
|
||||
if (segment is not null &&
|
||||
segmentCultures.TryGetValue(segment, out HashSet<string>? associatedCultures) &&
|
||||
associatedCultures.Contains(culture) is false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var validationContext = new PropertyValidationContext
|
||||
{
|
||||
Culture = culture,
|
||||
Segment = segment,
|
||||
CulturesBeingValidated = cultures,
|
||||
SegmentsBeingValidated = segments,
|
||||
};
|
||||
|
||||
PropertyValueModel? propertyValueModel = contentEditingModelBase
|
||||
.Properties
|
||||
.FirstOrDefault(propertyValue => propertyValue.Alias == propertyType.Alias && propertyValue.Culture.InvariantEquals(culture) && propertyValue.Segment.InvariantEquals(segment));
|
||||
validationErrors.AddRange(ValidateProperty(propertyType, propertyValueModel, validationContext));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -140,6 +158,31 @@ internal abstract class ContentValidationServiceBase<TContentType>
|
||||
|
||||
private async Task<string[]> GetCultureCodes() => (await _languageService.GetAllIsoCodesAsync()).ToArray();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a dictionary of segments along with the cultures they are associated with.
|
||||
/// </summary>
|
||||
/// <param name="contentEditingModel">The content editing model.</param>
|
||||
/// <param name="cultures">The cultures to consider when finding associated cultures for each segment.</param>
|
||||
/// <returns>
|
||||
/// A dictionary where the key is a unique segment from <see cref="ContentEditingModelBase.Variants"/> and the value is
|
||||
/// the set of cultures that have at least one property defined for that segment in <see cref="ContentEditingModelBase.Properties"/>.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// Internal to support unit testing.
|
||||
/// </remarks>
|
||||
internal static Dictionary<string, HashSet<string>> GetPopulatedSegmentCultures(ContentEditingModelBase contentEditingModel, string[] cultures)
|
||||
{
|
||||
IEnumerable<string> uniqueSegments = contentEditingModel.Variants.Select(variant => variant.Segment).WhereNotNull().Distinct();
|
||||
|
||||
return uniqueSegments.ToDictionary(
|
||||
segment => segment,
|
||||
segment => contentEditingModel.Properties
|
||||
.Where(property => property.Segment.InvariantEquals(segment))
|
||||
.Where(property => property.Culture is not null && cultures.Contains(property.Culture))
|
||||
.Select(property => property.Culture!)
|
||||
.ToHashSet());
|
||||
}
|
||||
|
||||
private IEnumerable<PropertyValidationError> ValidateProperty(IPropertyType propertyType, PropertyValueModel? propertyValueModel, PropertyValidationContext validationContext)
|
||||
{
|
||||
ValidationResult[] validationResults = _propertyValidationService
|
||||
|
||||
Reference in New Issue
Block a user