From 87cb951db28f4df9491f9a98e06058fd30eaf33c Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 14 Dec 2021 16:42:47 +0100 Subject: [PATCH] Allow setting nested values in scripts. --- .../ContentWrapper/ContentFieldProperty.cs | 16 +++-- .../Scripting/ContentWrapper/JsonMapper.cs | 4 +- .../Scripting/ContentDataObjectTests.cs | 61 ++++++++++++++----- 3 files changed, 56 insertions(+), 25 deletions(-) diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentFieldProperty.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentFieldProperty.cs index da2fc5b90..79fe985e4 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentFieldProperty.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/ContentFieldProperty.cs @@ -1,10 +1,11 @@ -// ========================================================================== +// ========================================================================== // Squidex Headless CMS // ========================================================================== // Copyright (c) Squidex UG (haftungsbeschraenkt) // All rights reserved. Licensed under the MIT license. // ========================================================================== +using System.Diagnostics; using Jint.Native; using Squidex.Infrastructure.Json.Objects; @@ -13,10 +14,11 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper public sealed class ContentFieldProperty : CustomProperty { private readonly ContentFieldObject contentField; - private IJsonValue? contentValue; + private IJsonValue contentValue; private JsValue? value; private bool isChanged; + [DebuggerHidden] protected override JsValue? CustomValue { get @@ -33,11 +35,13 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper } set { - if (!Equals(this.value, value)) + var newContentValue = JsonMapper.Map(value); + + if (!Equals(contentValue, newContentValue)) { this.value = value; - contentValue = null; + contentValue = newContentValue; contentField.MarkChanged(); isChanged = true; @@ -58,7 +62,7 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper public ContentFieldProperty(ContentFieldObject contentField, IJsonValue? contentValue = null) { this.contentField = contentField; - this.contentValue = contentValue; + this.contentValue = contentValue ?? JsonValue.Null; } } -} \ No newline at end of file +} diff --git a/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/JsonMapper.cs b/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/JsonMapper.cs index e523575a7..ed1aebcd1 100644 --- a/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/JsonMapper.cs +++ b/backend/src/Squidex.Domain.Apps.Core.Operations/Scripting/ContentWrapper/JsonMapper.cs @@ -59,11 +59,9 @@ namespace Squidex.Domain.Apps.Core.Scripting.ContentWrapper foreach (var (key, value) in obj) { - target.FastAddProperty(key, Map(value, engine), false, true, true); + target.FastAddProperty(key, Map(value, engine), true, true, true); } - target.PreventExtensions(); - return target; } diff --git a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/ContentDataObjectTests.cs b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/ContentDataObjectTests.cs index cba66c070..10c88ec16 100644 --- a/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/ContentDataObjectTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/Scripting/ContentDataObjectTests.cs @@ -173,21 +173,63 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting { var original = new ContentData() - .AddField("number", + .AddField("geo", new ContentFieldData() .AddInvariant(JsonValue.Object().Add("lat", 1.0))); var expected = new ContentData() - .AddField("number", + .AddField("geo", new ContentFieldData() .AddInvariant(JsonValue.Object().Add("lat", 1.0).Add("lon", 4.0))); - var result = ExecuteScript(original, @"data.number.iv = { lat: data.number.iv.lat, lon: data.number.iv.lat + 3 }"); + var result = ExecuteScript(original, @"data.geo.iv = { lat: data.geo.iv.lat, lon: data.geo.iv.lat + 3 }"); + + Assert.Equal(expected, result); + } + + [Fact] + public void Should_update_data_if_changing_nested_field() + { + var original = + new ContentData() + .AddField("geo", + new ContentFieldData() + .AddInvariant(JsonValue.Object().Add("lat", 1.0))); + + var expected = + new ContentData() + .AddField("geo", + new ContentFieldData() + .AddInvariant(JsonValue.Object().Add("lat", 2.0).Add("lon", 4.0))); + + var result = ExecuteScript(original, @" + var nested = data.geo.iv; + nested.lat = 2; + nested.lon = 4; + data.geo.iv = nested"); Assert.Equal(expected, result); } + [Fact] + public void Should_not_update_data_if_not_changing_nested_field() + { + var original = + new ContentData() + .AddField("geo", + new ContentFieldData() + .AddInvariant(JsonValue.Object().Add("lat", 2.0).Add("lon", 4.0))); + + var result = ExecuteScript(original, @" + var nested = data.geo.iv; + nested.lat = 2; + nested.lon = 4; + data.geo.iv = nested"); + + Assert.Same(original, result); + } + [Fact] public void Should_throw_if_defining_property_for_field() { @@ -258,19 +300,6 @@ namespace Squidex.Domain.Apps.Core.Operations.Scripting Assert.Equal(new[] { "1", "2", "3", "4" }, result); } - [Fact] - public void Should_throw_exceptions_if_changing_objects() - { - var original = - new ContentData() - .AddField("obj", - new ContentFieldData() - .AddInvariant(JsonValue.Object().Add("readonly", 1))); - - Assert.Throws(() => ExecuteScript(original, "data.obj.iv.invalid = 1")); - Assert.Throws(() => ExecuteScript(original, "data.obj.iv.readonly = 2")); - } - [Fact] public void Should_not_throw_exceptions_if_changing_arrays() {