From 9c6e3ff9283cf04ce3cd705a974ef321336579b5 Mon Sep 17 00:00:00 2001 From: Kenn Jacobsen Date: Wed, 29 Jan 2025 12:00:01 +0100 Subject: [PATCH] Elements level property cache should cache by variation (#18080) --- .../PublishedCache/PublishedElement.cs | 29 +++++++-- .../PublishedElementPropertyBase.cs | 11 +++- .../ValueConverters/BlockEditorConverter.cs | 2 +- ...stElementLevelVariationTests.Publishing.cs | 63 +++++++++++++++++++ .../Umbraco.Core/DeliveryApi/CacheTests.cs | 2 +- .../DeliveryApi/ContentBuilderTests.cs | 4 +- .../ContentPickerValueConverterTests.cs | 4 +- .../MultiNodeTreePickerValueConverterTests.cs | 4 +- .../OutputExpansionStrategyTestBase.cs | 16 ++--- .../PropertyValueConverterTests.cs | 2 + .../DeliveryApi/RichTextParserTests.cs | 2 +- .../PropertyEditors/ConvertersTests.cs | 6 +- .../Umbraco.Core/Published/ConvertersTests.cs | 8 +-- .../Published/PropertyCacheLevelTests.cs | 5 +- 14 files changed, 126 insertions(+), 32 deletions(-) diff --git a/src/Umbraco.Core/PublishedCache/PublishedElement.cs b/src/Umbraco.Core/PublishedCache/PublishedElement.cs index 92d8646539..1d13b688ff 100644 --- a/src/Umbraco.Core/PublishedCache/PublishedElement.cs +++ b/src/Umbraco.Core/PublishedCache/PublishedElement.cs @@ -1,3 +1,5 @@ +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Models.PublishedContent; using Umbraco.Cms.Core.PropertyEditors; @@ -16,9 +18,28 @@ public class PublishedElement : IPublishedElement private readonly IPublishedProperty[] _propertiesArray; + [Obsolete("Please use the non-obsolete constructor. Will be removed in V17.")] + public PublishedElement(IPublishedContentType contentType, Guid key, Dictionary values, bool previewing) + : this(contentType, key, values, previewing, PropertyCacheLevel.None, null) + { + } + + [Obsolete("Please use the non-obsolete constructor. Will be removed in V17.")] + public PublishedElement(IPublishedContentType contentType, Guid key, Dictionary? values, bool previewing, PropertyCacheLevel referenceCacheLevel, ICacheManager? cacheManager) + : this( + contentType, + key, + values, + previewing, + referenceCacheLevel, + StaticServiceProvider.Instance.GetRequiredService().VariationContext ?? new VariationContext(), + cacheManager) + { + } + // initializes a new instance of the PublishedElement class // within the context of a published snapshot service (eg a published content property value) - public PublishedElement(IPublishedContentType contentType, Guid key, Dictionary? values, bool previewing, PropertyCacheLevel referenceCacheLevel, ICacheManager? cacheManager) + public PublishedElement(IPublishedContentType contentType, Guid key, Dictionary? values, bool previewing, PropertyCacheLevel referenceCacheLevel, VariationContext variationContext, ICacheManager? cacheManager) { if (key == Guid.Empty) { @@ -40,7 +61,7 @@ public class PublishedElement : IPublishedElement .Select(propertyType => { values.TryGetValue(propertyType.Alias, out var value); - return (IPublishedProperty)new PublishedElementPropertyBase(propertyType, this, previewing, referenceCacheLevel,cacheManager, value); + return (IPublishedProperty)new PublishedElementPropertyBase(propertyType, this, previewing, referenceCacheLevel, variationContext, cacheManager, value); }) .ToArray() ?? new IPublishedProperty[0]; @@ -51,8 +72,8 @@ public class PublishedElement : IPublishedElement // + using an initial reference cache level of .None ensures that everything will be // cached at .Content level - and that reference cache level will propagate to all // properties - public PublishedElement(IPublishedContentType contentType, Guid key, Dictionary values, bool previewing) - : this(contentType, key, values, previewing, PropertyCacheLevel.None, null) + public PublishedElement(IPublishedContentType contentType, Guid key, Dictionary values, bool previewing, VariationContext variationContext) + : this(contentType, key, values, previewing, PropertyCacheLevel.None, variationContext, null) { } diff --git a/src/Umbraco.Core/PublishedCache/PublishedElementPropertyBase.cs b/src/Umbraco.Core/PublishedCache/PublishedElementPropertyBase.cs index f290afe5ea..fb4ed21ef6 100644 --- a/src/Umbraco.Core/PublishedCache/PublishedElementPropertyBase.cs +++ b/src/Umbraco.Core/PublishedCache/PublishedElementPropertyBase.cs @@ -1,4 +1,3 @@ -using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Models.PublishedContent; using Umbraco.Cms.Core.PropertyEditors; using Umbraco.Extensions; @@ -13,11 +12,11 @@ internal class PublishedElementPropertyBase : PublishedPropertyBase // to store eg routes, property converted values, anything - caching // means faster execution, but uses memory - not sure if we want it // so making it configurable. - private const bool FullCacheWhenPreviewing = true; private readonly Lock _locko = new(); private readonly object? _sourceValue; protected readonly bool IsMember; protected readonly bool IsPreviewing; + private readonly VariationContext _variationContext; private readonly ICacheManager? _cacheManager; private CacheValues? _cacheValues; @@ -30,6 +29,7 @@ internal class PublishedElementPropertyBase : PublishedPropertyBase IPublishedElement element, bool previewing, PropertyCacheLevel referenceCacheLevel, + VariationContext variationContext, ICacheManager? cacheManager, object? sourceValue = null) : base(propertyType, referenceCacheLevel) @@ -37,17 +37,22 @@ internal class PublishedElementPropertyBase : PublishedPropertyBase _sourceValue = sourceValue; Element = element; IsPreviewing = previewing; + _variationContext = variationContext; _cacheManager = cacheManager; IsMember = propertyType.ContentType?.ItemType == PublishedItemType.Member; } // used to cache the CacheValues of this property // ReSharper disable InconsistentlySynchronizedField - internal string ValuesCacheKey => _valuesCacheKey ??= PropertyCacheValues(Element.Key, Alias, IsPreviewing); + private string ValuesCacheKey => _valuesCacheKey ??= PropertyCacheValuesKey(); + [Obsolete("Do not use this. Will be removed in V17.")] public static string PropertyCacheValues(Guid contentUid, string typeAlias, bool previewing) => "PublishedSnapshot.Property.CacheValues[" + (previewing ? "D:" : "P:") + contentUid + ":" + typeAlias + "]"; + private string PropertyCacheValuesKey() => + $"PublishedSnapshot.Property.CacheValues[{(IsPreviewing ? "D:" : "P:")}{Element.Key}:{Alias}:{_variationContext.Culture.IfNullOrWhiteSpace("inv")}+{_variationContext.Segment.IfNullOrWhiteSpace("inv")}]"; + // ReSharper restore InconsistentlySynchronizedField public override bool HasValue(string? culture = null, string? segment = null) { diff --git a/src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/BlockEditorConverter.cs b/src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/BlockEditorConverter.cs index 792cc346dd..1f3707ece4 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/BlockEditorConverter.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/BlockEditorConverter.cs @@ -91,7 +91,7 @@ public sealed class BlockEditorConverter return null; } - IPublishedElement element = new PublishedElement(publishedContentType, key, propertyValues, preview, referenceCacheLevel, _cacheManager); + IPublishedElement element = new PublishedElement(publishedContentType, key, propertyValues, preview, referenceCacheLevel, variationContext, _cacheManager); element = _publishedModelFactory.CreateModel(element); return element; diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/PropertyEditors/BlockListElementLevelVariationTests.Publishing.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/PropertyEditors/BlockListElementLevelVariationTests.Publishing.cs index 9ba8ccef7d..48e225045d 100644 --- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/PropertyEditors/BlockListElementLevelVariationTests.Publishing.cs +++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/PropertyEditors/BlockListElementLevelVariationTests.Publishing.cs @@ -1869,4 +1869,67 @@ internal partial class BlockListElementLevelVariationTests Assert.AreEqual("blocks", publishResult.InvalidProperties.First().Alias); }); } + + [Test] + public async Task Can_Handle_Elements_Level_Property_Cache() + { + var elementType = new ContentTypeBuilder() + .WithAlias("myElementType") + .WithName("My Element Type") + .WithIsElement(true) + .WithContentVariation(ContentVariation.Culture) + .AddPropertyType() + .WithAlias("contentPicker") + .WithName("Content Picker") + .WithDataTypeId(1046) + .WithPropertyEditorAlias(Constants.PropertyEditors.Aliases.ContentPicker) + .WithValueStorageType(ValueStorageType.Nvarchar) + .WithVariations(ContentVariation.Culture) + .Done() + .Build(); + ContentTypeService.Save(elementType); + var blockListDataType = await CreateBlockListDataType(elementType); + var contentType = CreateContentType(ContentVariation.Culture, blockListDataType); + + var pickedContent1 = CreateContent(contentType, elementType, [], true); + var pickedContent2 = CreateContent(contentType, elementType, [], true); + + var content = CreateContent( + contentType, + elementType, + [ + new BlockProperty( + new List + { + new() { Alias = "contentPicker", Value = pickedContent1.GetUdi().ToString(), Culture = "en-US" }, + new() { Alias = "contentPicker", Value = pickedContent2.GetUdi().ToString(), Culture = "da-DK" }, + }, + [], + null, + null) + ], + true); + + AssertPropertyValues("en-US", pickedContent1); + + AssertPropertyValues("da-DK", pickedContent2); + + void AssertPropertyValues(string culture, IContent expectedPickedContent) + { + SetVariationContext(culture, null); + var publishedContent = GetPublishedContent(content.Key); + + var value = publishedContent.Value("blocks"); + Assert.IsNotNull(value); + Assert.AreEqual(1, value.Count); + + var blockListItem = value.First(); + Assert.AreEqual(1, blockListItem.Content.Properties.Count()); + // need to ensure the property type cache level, otherwise this test has little value + Assert.AreEqual(PropertyCacheLevel.Elements, blockListItem.Content.Properties.First().PropertyType.CacheLevel); + var actualPickedPublishedContent = blockListItem.Content.Value("contentPicker"); + Assert.IsNotNull(actualPickedPublishedContent); + Assert.AreEqual(expectedPickedContent.Key, actualPickedPublishedContent.Key); + } + } } diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/CacheTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/CacheTests.cs index c707f6adeb..8149f0b514 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/CacheTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/CacheTests.cs @@ -36,7 +36,7 @@ public class CacheTests : DeliveryApiTests var element = new Mock(); - var prop1 = new PublishedElementPropertyBase(propertyType, element.Object, false, cacheLevel, Mock.Of()); + var prop1 = new PublishedElementPropertyBase(propertyType, element.Object, false, cacheLevel, new VariationContext(), Mock.Of()); var results = new List { diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/ContentBuilderTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/ContentBuilderTests.cs index ff0cfa2f13..aa94d9147b 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/ContentBuilderTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/ContentBuilderTests.cs @@ -17,8 +17,8 @@ public class ContentBuilderTests : DeliveryApiTests { var content = new Mock(); - var prop1 = new PublishedElementPropertyBase(DeliveryApiPropertyType, content.Object, false, PropertyCacheLevel.None, Mock.Of()); - var prop2 = new PublishedElementPropertyBase(DefaultPropertyType, content.Object, false, PropertyCacheLevel.None, Mock.Of()); + var prop1 = new PublishedElementPropertyBase(DeliveryApiPropertyType, content.Object, false, PropertyCacheLevel.None, new VariationContext(), Mock.Of()); + var prop2 = new PublishedElementPropertyBase(DefaultPropertyType, content.Object, false, PropertyCacheLevel.None, new VariationContext(), Mock.Of()); var contentType = new Mock(); contentType.SetupGet(c => c.Alias).Returns("thePageType"); diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/ContentPickerValueConverterTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/ContentPickerValueConverterTests.cs index e88d71f9e1..c876278eec 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/ContentPickerValueConverterTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/ContentPickerValueConverterTests.cs @@ -72,8 +72,8 @@ public class ContentPickerValueConverterTests : PropertyValueConverterTests { var content = new Mock(); - var prop1 = new PublishedElementPropertyBase(DeliveryApiPropertyType, content.Object, false, PropertyCacheLevel.None, Mock.Of()); - var prop2 = new PublishedElementPropertyBase(DefaultPropertyType, content.Object, false, PropertyCacheLevel.None, Mock.Of()); + var prop1 = new PublishedElementPropertyBase(DeliveryApiPropertyType, content.Object, false, PropertyCacheLevel.None, new VariationContext(), Mock.Of()); + var prop2 = new PublishedElementPropertyBase(DefaultPropertyType, content.Object, false, PropertyCacheLevel.None, new VariationContext(), Mock.Of()); var publishedPropertyType = new Mock(); publishedPropertyType.SetupGet(p => p.Alias).Returns("test"); diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/MultiNodeTreePickerValueConverterTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/MultiNodeTreePickerValueConverterTests.cs index cfbd1e5495..fc232d6c95 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/MultiNodeTreePickerValueConverterTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/MultiNodeTreePickerValueConverterTests.cs @@ -101,8 +101,8 @@ public class MultiNodeTreePickerValueConverterTests : PropertyValueConverterTest { var content = new Mock(); - var prop1 = new PublishedElementPropertyBase(DeliveryApiPropertyType, content.Object, false, PropertyCacheLevel.None, CacheManager); - var prop2 = new PublishedElementPropertyBase(DefaultPropertyType, content.Object, false, PropertyCacheLevel.None, CacheManager); + var prop1 = new PublishedElementPropertyBase(DeliveryApiPropertyType, content.Object, false, PropertyCacheLevel.None, new VariationContext(), CacheManager); + var prop2 = new PublishedElementPropertyBase(DefaultPropertyType, content.Object, false, PropertyCacheLevel.None, new VariationContext(), CacheManager); var key = Guid.NewGuid(); var urlSegment = "page-url-segment"; diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/OutputExpansionStrategyTestBase.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/OutputExpansionStrategyTestBase.cs index fe8b45db51..7e4c874523 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/OutputExpansionStrategyTestBase.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/OutputExpansionStrategyTestBase.cs @@ -46,8 +46,8 @@ public abstract class OutputExpansionStrategyTestBase : PropertyValueConverterTe var apiContentBuilder = new ApiContentBuilder(new ApiContentNameProvider(), ApiContentRouteBuilder(), accessor); var content = new Mock(); - var prop1 = new PublishedElementPropertyBase(DeliveryApiPropertyType, content.Object, false, PropertyCacheLevel.None, CacheManager); - var prop2 = new PublishedElementPropertyBase(DefaultPropertyType, content.Object, false, PropertyCacheLevel.None, CacheManager); + var prop1 = new PublishedElementPropertyBase(DeliveryApiPropertyType, content.Object, false, PropertyCacheLevel.None, VariationContext, CacheManager); + var prop2 = new PublishedElementPropertyBase(DefaultPropertyType, content.Object, false, PropertyCacheLevel.None, VariationContext, CacheManager); var contentPickerContent = CreateSimplePickedContent(123, 456); var contentPickerProperty = CreateContentPickerProperty(content.Object, contentPickerContent.Key, "contentPicker", apiContentBuilder); @@ -303,7 +303,7 @@ public abstract class OutputExpansionStrategyTestBase : PropertyValueConverterTe .Returns(expanding ? "Expanding" : "Not expanding"); var propertyType = SetupPublishedPropertyType(valueConverterMock.Object, "theAlias", Constants.PropertyEditors.Aliases.Label); - var property = new PublishedElementPropertyBase(propertyType, content.Object, false, PropertyCacheLevel.None, CacheManager, "The Value"); + var property = new PublishedElementPropertyBase(propertyType, content.Object, false, PropertyCacheLevel.None, VariationContext, CacheManager, "The Value"); SetupContentMock(content, property); @@ -378,7 +378,7 @@ public abstract class OutputExpansionStrategyTestBase : PropertyValueConverterTe ContentPickerValueConverter contentPickerValueConverter = new ContentPickerValueConverter(PublishedContentCacheMock.Object, contentBuilder); var contentPickerPropertyType = SetupPublishedPropertyType(contentPickerValueConverter, propertyTypeAlias, Constants.PropertyEditors.Aliases.ContentPicker); - return new PublishedElementPropertyBase(contentPickerPropertyType, parent, false, PropertyCacheLevel.None, CacheManager, new GuidUdi(Constants.UdiEntityType.Document, pickedContentKey).ToString()); + return new PublishedElementPropertyBase(contentPickerPropertyType, parent, false, PropertyCacheLevel.None, VariationContext, CacheManager, new GuidUdi(Constants.UdiEntityType.Document, pickedContentKey).ToString()); } internal PublishedElementPropertyBase CreateMediaPickerProperty(IPublishedElement parent, Guid pickedMediaKey, string propertyTypeAlias, IApiMediaBuilder mediaBuilder) @@ -389,7 +389,7 @@ public abstract class OutputExpansionStrategyTestBase : PropertyValueConverterTe MediaPickerWithCropsValueConverter mediaPickerValueConverter = new MediaPickerWithCropsValueConverter(CacheManager.Media, PublishedUrlProvider, publishedValueFallback, new SystemTextJsonSerializer(), apiMediaWithCropsBuilder); var mediaPickerPropertyType = SetupPublishedPropertyType(mediaPickerValueConverter, propertyTypeAlias, Constants.PropertyEditors.Aliases.MediaPicker3, new MediaPicker3Configuration()); - return new PublishedElementPropertyBase(mediaPickerPropertyType, parent, false, PropertyCacheLevel.None, CacheManager, new GuidUdi(Constants.UdiEntityType.Media, pickedMediaKey).ToString()); + return new PublishedElementPropertyBase(mediaPickerPropertyType, parent, false, PropertyCacheLevel.None, VariationContext, CacheManager, new GuidUdi(Constants.UdiEntityType.Media, pickedMediaKey).ToString()); } internal PublishedElementPropertyBase CreateMediaPicker3Property(IPublishedElement parent, Guid pickedMediaKey, string propertyTypeAlias, IApiMediaBuilder mediaBuilder) @@ -409,13 +409,13 @@ public abstract class OutputExpansionStrategyTestBase : PropertyValueConverterTe MediaPickerWithCropsValueConverter mediaPickerValueConverter = new MediaPickerWithCropsValueConverter(CacheManager.Media, PublishedUrlProvider, publishedValueFallback, new SystemTextJsonSerializer(), apiMediaWithCropsBuilder); var mediaPickerPropertyType = SetupPublishedPropertyType(mediaPickerValueConverter, propertyTypeAlias, Constants.PropertyEditors.Aliases.MediaPicker3, new MediaPicker3Configuration()); - return new PublishedElementPropertyBase(mediaPickerPropertyType, parent, false, PropertyCacheLevel.None, CacheManager, value); + return new PublishedElementPropertyBase(mediaPickerPropertyType, parent, false, PropertyCacheLevel.None, VariationContext, CacheManager, value); } internal PublishedElementPropertyBase CreateNumberProperty(IPublishedElement parent, int propertyValue, string propertyTypeAlias) { var numberPropertyType = SetupPublishedPropertyType(new IntegerValueConverter(), propertyTypeAlias, Constants.PropertyEditors.Aliases.Label); - return new PublishedElementPropertyBase(numberPropertyType, parent, false, PropertyCacheLevel.None, CacheManager, propertyValue); + return new PublishedElementPropertyBase(numberPropertyType, parent, false, PropertyCacheLevel.None, VariationContext, CacheManager, propertyValue); } internal PublishedElementPropertyBase CreateElementProperty( @@ -452,7 +452,7 @@ public abstract class OutputExpansionStrategyTestBase : PropertyValueConverterTe elementValueConverter.Setup(p => p.GetDeliveryApiPropertyCacheLevelForExpansion(It.IsAny())).Returns(PropertyCacheLevel.None); var elementPropertyType = SetupPublishedPropertyType(elementValueConverter.Object, elementPropertyAlias, "My.Element.Property"); - return new PublishedElementPropertyBase(elementPropertyType, parent, false, PropertyCacheLevel.None, CacheManager); + return new PublishedElementPropertyBase(elementPropertyType, parent, false, PropertyCacheLevel.None, VariationContext, CacheManager); } protected IApiContentRouteBuilder ApiContentRouteBuilder() => CreateContentRouteBuilder(ApiContentPathProvider, CreateGlobalSettings()); diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/PropertyValueConverterTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/PropertyValueConverterTests.cs index 7050ccada5..7f952c35da 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/PropertyValueConverterTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/PropertyValueConverterTests.cs @@ -29,6 +29,8 @@ public class PropertyValueConverterTests : DeliveryApiTests protected Mock PublishedUrlProviderMock { get; private set; } + protected VariationContext VariationContext { get; } = new(); + [SetUp] public override void Setup() { diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/RichTextParserTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/RichTextParserTests.cs index 928e337e53..cf26a8e92a 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/RichTextParserTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/RichTextParserTests.cs @@ -562,7 +562,7 @@ public class RichTextParserTests : PropertyValueConverterTests element.SetupGet(c => c.ContentType).Returns(elementType.Object); var numberPropertyType = SetupPublishedPropertyType(new IntegerValueConverter(), "number", Constants.PropertyEditors.Aliases.Label); - var property = new PublishedElementPropertyBase(numberPropertyType, element.Object, false, PropertyCacheLevel.None, CacheManager, propertyValue); + var property = new PublishedElementPropertyBase(numberPropertyType, element.Object, false, PropertyCacheLevel.None, VariationContext, CacheManager, propertyValue); element.SetupGet(c => c.Properties).Returns(new[] { property }); return element.Object; diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/ConvertersTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/ConvertersTests.cs index 55a61bafb7..95b7fc0b2e 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/ConvertersTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/ConvertersTests.cs @@ -93,12 +93,14 @@ public class ConvertersTests elementType1, Guid.NewGuid(), new Dictionary { { "prop1", "val1" } }, - false); + false, + new VariationContext()); var element2 = new PublishedElement( elementType2, Guid.NewGuid(), new Dictionary { { "prop2", "1003" } }, - false); + false, + new VariationContext()); var cnt1 = new InternalPublishedContent(contentType1) { Id = 1003, diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Published/ConvertersTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Published/ConvertersTests.cs index 7e05897985..8117e83a35 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Published/ConvertersTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Published/ConvertersTests.cs @@ -43,16 +43,16 @@ public class ConvertersTests var elementType1 = contentTypeFactory.CreateContentType(Guid.NewGuid(), 1000, "element1", CreatePropertyTypes); - var element1 = new PublishedElement(elementType1, Guid.NewGuid(), new Dictionary { { "prop1", "1234" } }, false); + var element1 = new PublishedElement(elementType1, Guid.NewGuid(), new Dictionary { { "prop1", "1234" } }, false, new VariationContext()); Assert.AreEqual(1234, element1.Value(Mock.Of(), "prop1")); // 'null' would be considered a 'missing' value by the default, magic logic - var e = new PublishedElement(elementType1, Guid.NewGuid(), new Dictionary { { "prop1", null } }, false); + var e = new PublishedElement(elementType1, Guid.NewGuid(), new Dictionary { { "prop1", null } }, false, new VariationContext()); Assert.IsFalse(e.HasValue("prop1")); // '0' would not - it's a valid integer - but the converter knows better - e = new PublishedElement(elementType1, Guid.NewGuid(), new Dictionary { { "prop1", "0" } }, false); + e = new PublishedElement(elementType1, Guid.NewGuid(), new Dictionary { { "prop1", "0" } }, false, new VariationContext()); Assert.IsFalse(e.HasValue("prop1")); } @@ -120,7 +120,7 @@ public class ConvertersTests var elementType1 = contentTypeFactory.CreateContentType(Guid.NewGuid(), 1000, "element1", CreatePropertyTypes); - var element1 = new PublishedElement(elementType1, Guid.NewGuid(), new Dictionary { { "prop1", "1234" } }, false); + var element1 = new PublishedElement(elementType1, Guid.NewGuid(), new Dictionary { { "prop1", "1234" } }, false, new VariationContext()); var cntType1 = contentTypeFactory.CreateContentType(Guid.NewGuid(), 1001, "cnt1", t => Enumerable.Empty()); var cnt1 = new InternalPublishedContent(cntType1) { Id = 1234 }; diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Published/PropertyCacheLevelTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Published/PropertyCacheLevelTests.cs index ada873977c..81ada421de 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Published/PropertyCacheLevelTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Published/PropertyCacheLevelTests.cs @@ -56,7 +56,7 @@ public class PropertyCacheLevelTests // anything else is not > None, use Content // // for standalone elements, it's only None or Content - var set1 = new PublishedElement(setType1, Guid.NewGuid(), new Dictionary { { "prop1", "1234" } }, false); + var set1 = new PublishedElement(setType1, Guid.NewGuid(), new Dictionary { { "prop1", "1234" } }, false, new VariationContext()); Assert.AreEqual(1234, set1.Value(Mock.Of(), "prop1")); Assert.AreEqual(1, converter.SourceConverts); @@ -133,6 +133,7 @@ public class PropertyCacheLevelTests }, false, referenceCacheLevel, + new VariationContext(), cacheManager.Object); Assert.AreEqual(1234, set1.Value(Mock.Of(), "prop1")); @@ -185,7 +186,7 @@ public class PropertyCacheLevelTests Assert.Throws(() => { - var unused = new PublishedElement(setType1, Guid.NewGuid(), new Dictionary { { "prop1", "1234" } }, false); + var unused = new PublishedElement(setType1, Guid.NewGuid(), new Dictionary { { "prop1", "1234" } }, false, new VariationContext()); }); }