From ab32bac5d96695eebe4f333a9bd6fa8d8b820f71 Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Mon, 13 May 2024 15:44:07 +0200 Subject: [PATCH] Property source level variation should only be applied when configured (#16270) --- .../Property.cs | 15 ++++++++----- .../PublishedContentVarianceTests.cs | 22 +++++++++++++++++++ 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.PublishedCache.NuCache/Property.cs b/src/Umbraco.PublishedCache.NuCache/Property.cs index 596bae2090c7..ed9f7277eff3 100644 --- a/src/Umbraco.PublishedCache.NuCache/Property.cs +++ b/src/Umbraco.PublishedCache.NuCache/Property.cs @@ -25,7 +25,7 @@ internal class Property : PublishedPropertyBase // the invariant-neutral source and inter values private readonly object? _sourceValue; private readonly ContentVariation _variations; - private bool _sourceValueIsInvariant; + private readonly ContentVariation _sourceVariations; // the variant and non-variant object values private CacheValues? _cacheValues; @@ -88,7 +88,7 @@ public Property( // this variable is used for contextualizing the variation level when calculating property values. // it must be set to the union of variance (the combination of content type and property type variance). _variations = propertyType.Variations | content.ContentType.Variations; - _sourceValueIsInvariant = propertyType.Variations is ContentVariation.Nothing; + _sourceVariations = propertyType.Variations; } // clone for previewing as draft a published content that is published and has no draft @@ -104,7 +104,7 @@ public Property(Property origin, PublishedContent content) _isMember = origin._isMember; _publishedSnapshotAccessor = origin._publishedSnapshotAccessor; _variations = origin._variations; - _sourceValueIsInvariant = origin._sourceValueIsInvariant; + _sourceVariations = origin._sourceVariations; } // used to cache the CacheValues of this property @@ -148,9 +148,14 @@ public override bool HasValue(string? culture = null, string? segment = null) public override object? GetSourceValue(string? culture = null, string? segment = null) { - _content.VariationContextAccessor.ContextualizeVariation(_variations, _content.Id, ref culture, ref segment); + _content.VariationContextAccessor.ContextualizeVariation(_sourceVariations, _content.Id, ref culture, ref segment); + + // source values are tightly bound to the property/schema culture and segment configurations, so we need to + // sanitize the contextualized culture/segment states before using them to access the source values. + culture = _sourceVariations.VariesByCulture() ? culture : string.Empty; + segment = _sourceVariations.VariesBySegment() ? segment : string.Empty; - if (_sourceValueIsInvariant || (culture == string.Empty && segment == string.Empty)) + if (culture == string.Empty && segment == string.Empty) { return _sourceValue; } diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Published/PublishedContentVarianceTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Published/PublishedContentVarianceTests.cs index 7d117b96c5a5..a4a15b8f2255 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Published/PublishedContentVarianceTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Published/PublishedContentVarianceTests.cs @@ -76,6 +76,28 @@ public void Content_Culture_And_Segment_Variation_Can_Get_Culture_And_Segment_Va Assert.AreEqual(expectedValue, value); } + [TestCase(DaCulture, Segment1, "DaDk property value")] + [TestCase(DaCulture, Segment2, "DaDk property value")] + [TestCase(EnCulture, Segment1, "EnUs property value")] + [TestCase(EnCulture, Segment2, "EnUs property value")] + public void Content_Culture_And_Segment_Variation_Can_Get_Culture_Variant_Property(string culture, string segment, string expectedValue) + { + var content = CreatePublishedContent(ContentVariation.CultureAndSegment, ContentVariation.Culture, variationContextCulture: culture, variationContextSegment: segment); + var value = GetPropertyValue(content); + Assert.AreEqual(expectedValue, value); + } + + [TestCase(DaCulture, Segment1, "Segment1 property value")] + [TestCase(DaCulture, Segment2, "Segment2 property value")] + [TestCase(EnCulture, Segment1, "Segment1 property value")] + [TestCase(EnCulture, Segment2, "Segment2 property value")] + public void Content_Culture_And_Segment_Variation_Can_Get_Segment_Variant_Property(string culture, string segment, string expectedValue) + { + var content = CreatePublishedContent(ContentVariation.CultureAndSegment, ContentVariation.Segment, variationContextCulture: culture, variationContextSegment: segment); + var value = GetPropertyValue(content); + Assert.AreEqual(expectedValue, value); + } + private object? GetPropertyValue(IPublishedContent content) => content.GetProperty(PropertyTypeAlias)!.GetValue(); private IPublishedContent CreatePublishedContent(ContentVariation contentTypeVariation, ContentVariation propertyTypeVariation, string? variationContextCulture = null, string? variationContextSegment = null)