Ensure that value type JSON is translated correctly for Delivery API output (#14839)

This commit is contained in:
Kenn Jacobsen
2023-09-21 09:25:29 +02:00
committed by GitHub
parent aa7632b271
commit 2335924b57
3 changed files with 60 additions and 2 deletions

View File

@@ -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.
/// </remarks>
[DefaultPropertyValueConverter]
public class JsonValueConverter : PropertyValueConverterBase
public class JsonValueConverter : PropertyValueConverterBase, IDeliveryApiPropertyValueConverter
{
private readonly ILogger<JsonValueConverter> _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;
}

View File

@@ -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<IDataValueEditor>(x => x.ValueType == ValueTypes.Json);
var dataEditor = Mock.Of<IDataEditor>(x => x.GetValueEditor() == valueEditor);
var propertyEditors = new PropertyEditorCollection(new DataEditorCollection(() => new[] { dataEditor }));
var propertyType = Mock.Of<IPublishedPropertyType>(x => x.EditorAlias == "My.Custom.Json");
var valueConverter = new JsonValueConverter(propertyEditors, Mock.Of<ILogger<JsonValueConverter>>());
var inter = valueConverter.ConvertSourceToIntermediate(Mock.Of<IPublishedElement>(), propertyType, "{\"message\": \"Hello, JSON\"}", false);
var result = valueConverter.ConvertIntermediateToDeliveryApiObject(Mock.Of<IPublishedElement>(), propertyType, PropertyCacheLevel.Element, inter, false, false);
Assert.IsTrue(result is JsonNode);
JsonNode jsonNode = (JsonNode)result;
Assert.AreEqual("Hello, JSON", jsonNode["message"]!.GetValue<string>());
}
}

View File

@@ -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<IDataValueEditor>(x => x.ValueType == ValueTypes.Json);
var dataEditor = Mock.Of<IDataEditor>(x => x.GetValueEditor() == valueEditor);
var propertyEditors = new PropertyEditorCollection(new DataEditorCollection(() => new[] { dataEditor }));
var propertyType = Mock.Of<IPublishedPropertyType>(x => x.EditorAlias == "My.Custom.Json");
var valueConverter = new JsonValueConverter(propertyEditors, Mock.Of<ILogger<JsonValueConverter>>());
var inter = valueConverter.ConvertSourceToIntermediate(Mock.Of<IPublishedElement>(), propertyType, "{\"message\": \"Hello, JSON\"}", false);
var result = valueConverter.ConvertIntermediateToObject(Mock.Of<IPublishedElement>(), propertyType, PropertyCacheLevel.Element, inter, false) as JObject;
Assert.IsNotNull(result);
Assert.AreEqual("Hello, JSON", result["message"]!.Value<string>());
}
}