From cf442f78c029fa118eb2520e223b81231ed98f28 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 28 Jul 2020 15:33:54 +1000 Subject: [PATCH] updates prop value converter to filter out all content/settings blocks outside of the layout from reaching razor + test --- .../BlockListPropertyValueConverterTests.cs | 79 +++++++++++++++++++ .../BlockListPropertyValueConverter.cs | 13 ++- 2 files changed, 88 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Tests/PropertyEditors/BlockListPropertyValueConverterTests.cs b/src/Umbraco.Tests/PropertyEditors/BlockListPropertyValueConverterTests.cs index 7ff2077d77..23cc782106 100644 --- a/src/Umbraco.Tests/PropertyEditors/BlockListPropertyValueConverterTests.cs +++ b/src/Umbraco.Tests/PropertyEditors/BlockListPropertyValueConverterTests.cs @@ -366,5 +366,84 @@ data: []}"; } + [Test] + public void Data_Item_Removed_If_Removed_From_Config() + { + var editor = CreateConverter(); + + // The data below expects that ContentKey1 + ContentKey2 + SettingsKey1 + SettingsKey2 exist but only ContentKey2 exists so + // the data should all be filtered. + var config = new BlockListConfiguration + { + Blocks = new[] { + new BlockListConfiguration.BlockConfiguration + { + ContentElementTypeKey = ContentKey2, + SettingsElementTypeKey = null + } + } + }; + + var propertyType = GetPropertyType(config); + var publishedElement = Mock.Of(); + + var json = @" +{ + layout: { + '" + Constants.PropertyEditors.Aliases.BlockList + @"': [ + { + 'contentUdi': 'umb://element/1304E1DDAC87439684FE8A399231CB3D', + 'settingsUdi': 'umb://element/1F613E26CE274898908A561437AF5100' + }, + { + 'contentUdi': 'umb://element/0A4A416E547D464FABCC6F345C17809A', + 'settingsUdi': 'umb://element/63027539B0DB45E7B70459762D4E83DD' + } + ] + }, + contentData: [ + { + 'contentTypeKey': '" + ContentKey1 + @"', + 'udi': 'umb://element/1304E1DDAC87439684FE8A399231CB3D' + }, + { + 'contentTypeKey': '" + ContentKey2 + @"', + 'udi': 'umb://element/E05A034704424AB3A520E048E6197E79' + }, + { + 'contentTypeKey': '" + ContentKey2 + @"', + 'udi': 'umb://element/0A4A416E547D464FABCC6F345C17809A' + } + ], + settingsData: [ + { + 'contentTypeKey': '" + SettingKey1 + @"', + 'udi': 'umb://element/63027539B0DB45E7B70459762D4E83DD' + }, + { + 'contentTypeKey': '" + SettingKey2 + @"', + 'udi': 'umb://element/1F613E26CE274898908A561437AF5100' + }, + { + 'contentTypeKey': '" + SettingKey2 + @"', + 'udi': 'umb://element/BCF4BA3DA40C496C93EC58FAC85F18B9' + } + ], +}"; + + var converted = editor.ConvertIntermediateToObject(publishedElement, propertyType, PropertyCacheLevel.None, json, false) as BlockListModel; + + Assert.IsNotNull(converted); + Assert.AreEqual(2, converted.ContentData.Count()); + Assert.AreEqual(0, converted.SettingsData.Count()); + Assert.AreEqual(1, converted.Layout.Count()); + + var item0 = converted.Layout.ElementAt(0); + Assert.AreEqual(Guid.Parse("0A4A416E-547D-464F-ABCC-6F345C17809A"), item0.Content.Key); + Assert.AreEqual("Test2", item0.Content.ContentType.Alias); + Assert.IsNull(item0.Settings); + + } + } } diff --git a/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs b/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs index b04ef2d444..25b22e1a9c 100644 --- a/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs +++ b/src/Umbraco.Web/PropertyEditors/ValueConverters/BlockListPropertyValueConverter.cs @@ -52,8 +52,8 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters using (_proflog.DebugDuration($"ConvertPropertyToBlockList ({propertyType.DataType.Id})")) { var configuration = propertyType.DataType.ConfigurationAs(); - var contentTypes = configuration.Blocks; - var contentElementTypeMap = contentTypes.ToDictionary(x => x.ContentElementTypeKey); + var blockConfigMap = configuration.Blocks.ToDictionary(x => x.ContentElementTypeKey); + var validSettingElementTypes = blockConfigMap.Values.Select(x => x.SettingsElementTypeKey).Where(x => x.HasValue).Distinct().ToList(); var contentPublishedElements = new Dictionary(); var settingsPublishedElements = new Dictionary(); @@ -71,6 +71,8 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters // convert the content data foreach (var data in converted.BlockValue.ContentData) { + if (!blockConfigMap.ContainsKey(data.ContentTypeKey)) continue; + var element = _blockConverter.ConvertToElement(data, referenceCacheLevel, preview); if (element == null) continue; contentPublishedElements[element.Key] = element; @@ -78,6 +80,8 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters // convert the settings data foreach (var data in converted.BlockValue.SettingsData) { + if (!validSettingElementTypes.Contains(data.ContentTypeKey)) continue; + var element = _blockConverter.ConvertToElement(data, referenceCacheLevel, preview); if (element == null) continue; settingsPublishedElements[element.Key] = element; @@ -96,12 +100,13 @@ namespace Umbraco.Web.PropertyEditors.ValueConverters // get the setting reference IPublishedElement settingsData = null; var settingGuidUdi = layoutItem.SettingsUdi != null ? (GuidUdi)layoutItem.SettingsUdi : null; - if (settingGuidUdi != null) settingsPublishedElements.TryGetValue(settingGuidUdi.Guid, out settingsData); + if (settingGuidUdi != null) + settingsPublishedElements.TryGetValue(settingGuidUdi.Guid, out settingsData); if (!contentData.ContentType.TryGetKey(out var contentTypeKey)) throw new InvalidOperationException("The content type was not of type " + typeof(IPublishedContentType2)); - if (!contentElementTypeMap.TryGetValue(contentTypeKey, out var blockConfig)) + if (!blockConfigMap.TryGetValue(contentTypeKey, out var blockConfig)) continue; // this can happen if they have a settings type, save content, remove the settings type, and display the front-end page before saving the content again