diff --git a/src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/JsonValueConverter.cs b/src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/JsonValueConverter.cs index 4eaa24ecf9..e6345ab61d 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/JsonValueConverter.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/ValueConverters/JsonValueConverter.cs @@ -1,10 +1,12 @@ // Copyright (c) Umbraco. // See LICENSE for more details. +using System.Text.Json.Nodes; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.PropertyEditors.DeliveryApi; using Umbraco.Extensions; namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters; @@ -16,7 +18,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ValueConverters; /// Since this is a default (umbraco) converter it will be ignored if another converter found conflicts with this one. /// [DefaultPropertyValueConverter] -public class JsonValueConverter : PropertyValueConverterBase +public class JsonValueConverter : PropertyValueConverterBase, IDeliveryApiPropertyValueConverter { private readonly ILogger _logger; private readonly PropertyEditorCollection _propertyEditors; @@ -76,5 +78,14 @@ public class JsonValueConverter : PropertyValueConverterBase return sourceString; } - // TODO: Now to convert that to XPath! + public PropertyCacheLevel GetDeliveryApiPropertyCacheLevel(IPublishedPropertyType propertyType) + => GetPropertyCacheLevel(propertyType); + + public Type GetDeliveryApiPropertyValueType(IPublishedPropertyType propertyType) + => typeof(JsonNode); + + public object? ConvertIntermediateToDeliveryApiObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object? inter, bool preview, bool expanding) + => inter is JObject jObject + ? JsonNode.Parse(jObject.ToString()) + : null; } diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/JsonValueConverterTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/JsonValueConverterTests.cs new file mode 100644 index 0000000000..ac22f3985f --- /dev/null +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/DeliveryApi/JsonValueConverterTests.cs @@ -0,0 +1,30 @@ +using System.Text.Json.Nodes; +using Microsoft.Extensions.Logging; +using Moq; +using NUnit.Framework; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.PropertyEditors; +using Umbraco.Cms.Core.PropertyEditors.ValueConverters; + +namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.DeliveryApi; + +[TestFixture] +public class JsonValueConverterTests : PropertyValueConverterTests +{ + [Test] + public void JsonValueConverterTests_ConvertsCustomPropertyWithValueTypeJson() + { + var valueEditor = Mock.Of(x => x.ValueType == ValueTypes.Json); + var dataEditor = Mock.Of(x => x.GetValueEditor() == valueEditor); + var propertyEditors = new PropertyEditorCollection(new DataEditorCollection(() => new[] { dataEditor })); + var propertyType = Mock.Of(x => x.EditorAlias == "My.Custom.Json"); + + var valueConverter = new JsonValueConverter(propertyEditors, Mock.Of>()); + var inter = valueConverter.ConvertSourceToIntermediate(Mock.Of(), propertyType, "{\"message\": \"Hello, JSON\"}", false); + var result = valueConverter.ConvertIntermediateToDeliveryApiObject(Mock.Of(), propertyType, PropertyCacheLevel.Element, inter, false, false); + Assert.IsTrue(result is JsonNode); + JsonNode jsonNode = (JsonNode)result; + Assert.AreEqual("Hello, JSON", jsonNode["message"]!.GetValue()); + } +} diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/PropertyEditorValueConverterTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/PropertyEditorValueConverterTests.cs index b3537c4659..d046064af2 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/PropertyEditorValueConverterTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/PropertyEditorValueConverterTests.cs @@ -3,7 +3,9 @@ using System.Collections.Generic; using System.Linq; +using Microsoft.Extensions.Logging; using Moq; +using Newtonsoft.Json.Linq; using NUnit.Framework; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.PublishedContent; @@ -133,4 +135,19 @@ public class PropertyEditorValueConverterTests Assert.AreEqual(expected, result); } + + [Test] + public void CanConvertManifestBasedPropertyWithValueTypeJson() + { + var valueEditor = Mock.Of(x => x.ValueType == ValueTypes.Json); + var dataEditor = Mock.Of(x => x.GetValueEditor() == valueEditor); + var propertyEditors = new PropertyEditorCollection(new DataEditorCollection(() => new[] { dataEditor })); + var propertyType = Mock.Of(x => x.EditorAlias == "My.Custom.Json"); + + var valueConverter = new JsonValueConverter(propertyEditors, Mock.Of>()); + var inter = valueConverter.ConvertSourceToIntermediate(Mock.Of(), propertyType, "{\"message\": \"Hello, JSON\"}", false); + var result = valueConverter.ConvertIntermediateToObject(Mock.Of(), propertyType, PropertyCacheLevel.Element, inter, false) as JObject; + Assert.IsNotNull(result); + Assert.AreEqual("Hello, JSON", result["message"]!.Value()); + } }