From 8b4849be0576da7bada224d255333ec7ef2d2744 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Mon, 7 Jul 2025 11:33:59 +0200 Subject: [PATCH] Fix issue with preview in delivery API for MNTP property editor (#19668) * Passes the preview flag to the cache retrieval when resolving the delivery API object for the MNTP property editor. * Added unit test verifying fix and adjusted mocks for tests to acoomodate. * Provided preview flag for Razor rendering. --- .../MultiNodeTreePickerValueConverter.cs | 4 +-- .../MultiNodeTreePickerValueConverterTests.cs | 26 +++++++++++++++++-- .../OutputExpansionStrategyTestBase.cs | 2 +- .../PropertyValueConverterTests.cs | 26 +++++++++++++++++-- 4 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Core/PropertyEditors/ValueConverters/MultiNodeTreePickerValueConverter.cs b/src/Umbraco.Core/PropertyEditors/ValueConverters/MultiNodeTreePickerValueConverter.cs index 96e84bfb83..727c28f077 100644 --- a/src/Umbraco.Core/PropertyEditors/ValueConverters/MultiNodeTreePickerValueConverter.cs +++ b/src/Umbraco.Core/PropertyEditors/ValueConverters/MultiNodeTreePickerValueConverter.cs @@ -115,7 +115,7 @@ public class MultiNodeTreePickerValueConverter : PropertyValueConverterBase, IDe udi, ref objectType, UmbracoObjectTypes.Document, - id => _contentCache.GetById(guidUdi.Guid)); + id => _contentCache.GetById(preview, guidUdi.Guid)); break; case Constants.UdiEntityType.Media: multiNodeTreePickerItem = GetPublishedContent( @@ -205,7 +205,7 @@ public class MultiNodeTreePickerValueConverter : PropertyValueConverterBase, IDe { Constants.UdiEntityType.Document => entityTypeUdis.Select(udi => { - IPublishedContent? content = _contentCache.GetById(udi.Guid); + IPublishedContent? content = _contentCache.GetById(preview, udi.Guid); return content != null ? _apiContentBuilder.Build(content) : null; diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/MultiNodeTreePickerValueConverterTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/MultiNodeTreePickerValueConverterTests.cs index 59dd0cee87..4c93f44ce5 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/MultiNodeTreePickerValueConverterTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/MultiNodeTreePickerValueConverterTests.cs @@ -73,7 +73,7 @@ public class MultiNodeTreePickerValueConverterTests : PropertyValueConverterTest var otherContentKey = Guid.NewGuid(); var otherContent = SetupPublishedContent("The other page", otherContentKey, PublishedItemType.Content, PublishedContentType); - RegisterContentWithProviders(otherContent.Object); + RegisterContentWithProviders(otherContent.Object, false); var valueConverter = MultiNodeTreePickerValueConverter(); @@ -94,6 +94,28 @@ public class MultiNodeTreePickerValueConverterTests : PropertyValueConverterTest Assert.AreEqual("TheContentType", result.Last().ContentType); } + [Test] + public void MultiNodeTreePickerValueConverter_InSingleMode_WithPreview_ConvertsValueToListOfContent() + { + var publishedDataType = MultiNodePickerPublishedDataType(false, Constants.UdiEntityType.Document); + var publishedPropertyType = new Mock(); + publishedPropertyType.SetupGet(p => p.DataType).Returns(publishedDataType); + + var valueConverter = MultiNodeTreePickerValueConverter(); + + Assert.AreEqual(typeof(IEnumerable), valueConverter.GetDeliveryApiPropertyValueType(publishedPropertyType.Object)); + + var inter = new Udi[] { new GuidUdi(Constants.UdiEntityType.Document, DraftContent.Key) }; + var result = valueConverter.ConvertIntermediateToDeliveryApiObject(Mock.Of(), publishedPropertyType.Object, PropertyCacheLevel.Element, inter, true, false) as IEnumerable; + Assert.NotNull(result); + Assert.AreEqual(1, result.Count()); + Assert.AreEqual(DraftContent.Name, result.First().Name); + Assert.AreEqual(DraftContent.Key, result.First().Id); + Assert.AreEqual("/the-draft-page-url/", result.First().Route.Path); + Assert.AreEqual("TheContentType", result.First().ContentType); + Assert.IsEmpty(result.First().Properties); + } + [Test] [TestCase(Constants.UdiEntityType.Document)] [TestCase("content")] @@ -113,7 +135,7 @@ public class MultiNodeTreePickerValueConverterTests : PropertyValueConverterTest .Setup(p => p.GetUrl(content.Object, It.IsAny(), It.IsAny(), It.IsAny())) .Returns(content.Object.UrlSegment); PublishedContentCacheMock - .Setup(pcc => pcc.GetById(key)) + .Setup(pcc => pcc.GetById(false, key)) .Returns(content.Object); var publishedDataType = MultiNodePickerPublishedDataType(false, entityType); diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/OutputExpansionStrategyTestBase.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/OutputExpansionStrategyTestBase.cs index 3051bced8a..0f6c3eb168 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/OutputExpansionStrategyTestBase.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/OutputExpansionStrategyTestBase.cs @@ -327,7 +327,7 @@ public abstract class OutputExpansionStrategyTestBase : PropertyValueConverterTe var urlSegment = "url-segment"; ConfigurePublishedContentMock(content, key, name, urlSegment, _contentType, properties); - RegisterContentWithProviders(content.Object); + RegisterContentWithProviders(content.Object, false); } protected void SetupMediaMock(Mock media, params IPublishedProperty[] properties) diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/PropertyValueConverterTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/PropertyValueConverterTests.cs index 59238902f7..23dbd79d9c 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/PropertyValueConverterTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/PropertyValueConverterTests.cs @@ -23,6 +23,8 @@ public class PropertyValueConverterTests : DeliveryApiTests protected IPublishedContent PublishedMedia { get; private set; } + protected IPublishedContent DraftContent { get; private set; } + protected IPublishedContentType PublishedContentType { get; private set; } protected IPublishedContentType PublishedMediaType { get; private set; } @@ -59,10 +61,21 @@ public class PropertyValueConverterTests : DeliveryApiTests var publishedMedia = SetupPublishedContent("The media", mediaKey, PublishedItemType.Media, publishedMediaType.Object); PublishedMedia = publishedMedia.Object; + var draftContentKey = Guid.NewGuid(); + var draftContent = SetupPublishedContent("The page (draft)", draftContentKey, PublishedItemType.Content, publishedContentType.Object); + DraftContent = draftContent.Object; + PublishedContentCacheMock = new Mock(); PublishedContentCacheMock .Setup(pcc => pcc.GetById(contentKey)) .Returns(publishedContent.Object); + PublishedContentCacheMock + .Setup(pcc => pcc.GetById(false, contentKey)) + .Returns(publishedContent.Object); + PublishedContentCacheMock + .Setup(pcc => pcc.GetById(true, draftContentKey)) + .Returns(draftContent.Object); + PublishedMediaCacheMock = new Mock(); PublishedMediaCacheMock .Setup(pcc => pcc.GetById(mediaKey)) @@ -77,6 +90,9 @@ public class PropertyValueConverterTests : DeliveryApiTests PublishedUrlProviderMock .Setup(p => p.GetUrl(publishedContent.Object, It.IsAny(), It.IsAny(), It.IsAny())) .Returns("the-page-url"); + PublishedUrlProviderMock + .Setup(p => p.GetUrl(draftContent.Object, It.IsAny(), It.IsAny(), It.IsAny())) + .Returns("the-draft-page-url"); PublishedUrlProviderMock .Setup(p => p.GetMediaUrl(publishedMedia.Object, It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .Returns("the-media-url"); @@ -97,14 +113,20 @@ public class PropertyValueConverterTests : DeliveryApiTests return content; } - protected void RegisterContentWithProviders(IPublishedContent content) + protected void RegisterContentWithProviders(IPublishedContent content, bool preview) { PublishedUrlProviderMock .Setup(p => p.GetUrl(content, It.IsAny(), It.IsAny(), It.IsAny())) .Returns(content.UrlSegment); PublishedContentCacheMock - .Setup(pcc => pcc.GetById(content.Key)) + .Setup(pcc => pcc.GetById(preview, content.Key)) .Returns(content); + if (preview is false) + { + PublishedContentCacheMock + .Setup(pcc => pcc.GetById(content.Key)) + .Returns(content); + } } protected void RegisterMediaWithProviders(IPublishedContent media)