From 65315fe653a35680ba31475ffee564b21bec7c27 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Fri, 3 May 2024 00:05:16 +0200 Subject: [PATCH] Fix JSON. (#1088) * Fix JSON. * Simplify json. --- .../GraphQL/Types/Assets/AssetGraphType.cs | 2 +- .../Assets/EnrichedAssetEventGraphType.cs | 2 +- .../GraphQL/Types/Contents/ContentFields.cs | 4 +- .../Contents/EnrichedContentEventGraphType.cs | 4 +- .../GraphQL/Types/Contents/FieldVisitor.cs | 6 +-- .../GraphQL/Types/Primitives/JsonGraphType.cs | 11 +++- .../Types/Primitives/JsonNoopGraphType.cs | 37 ------------- .../Contents/GraphQL/Types/Scalars.cs | 2 - .../Squidex/Config/Domain/QueryServices.cs | 3 -- .../Contents/GraphQL/GraphQLMutationTests.cs | 53 +++++++++++++++++++ 10 files changed, 72 insertions(+), 52 deletions(-) delete mode 100644 backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Primitives/JsonNoopGraphType.cs diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Assets/AssetGraphType.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Assets/AssetGraphType.cs index e5751ae77..85b872f2d 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Assets/AssetGraphType.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Assets/AssetGraphType.cs @@ -214,7 +214,7 @@ internal sealed class AssetGraphType : SharedObjectGraphType { Name = "metadata", Arguments = AssetActions.Metadata.Arguments, - ResolvedType = Scalars.JsonNoop, + ResolvedType = Scalars.Json, Resolver = AssetActions.Metadata.Resolver, Description = FieldDescriptions.AssetMetadata }); diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Assets/EnrichedAssetEventGraphType.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Assets/EnrichedAssetEventGraphType.cs index 99f43a9b5..b13631174 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Assets/EnrichedAssetEventGraphType.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Assets/EnrichedAssetEventGraphType.cs @@ -213,7 +213,7 @@ internal sealed class EnrichedAssetEventGraphType : SharedObjectGraphType x.Data), Description = FieldDescriptions.ContentData }; @@ -241,7 +241,7 @@ internal static class ContentFields public static readonly FieldType RichTextFieldValue = new FieldType { Name = "value", - ResolvedType = Scalars.JsonNoop, + ResolvedType = Scalars.Json, Resolver = Resolvers.Sync(x => x.Root), Description = FieldDescriptions.RichTextFieldValue }; diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/EnrichedContentEventGraphType.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/EnrichedContentEventGraphType.cs index 66f9c028c..9a12d2ebc 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/EnrichedContentEventGraphType.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/EnrichedContentEventGraphType.cs @@ -110,7 +110,7 @@ internal sealed class EnrichedContentEventGraphType : SharedObjectGraphType x.Data), Description = FieldDescriptions.ContentData }); @@ -118,7 +118,7 @@ internal sealed class EnrichedContentEventGraphType : SharedObjectGraphType x.DataOld), Description = FieldDescriptions.ContentDataOld }); diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/FieldVisitor.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/FieldVisitor.cs index e346be2ba..eea9c056f 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/FieldVisitor.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Contents/FieldVisitor.cs @@ -24,7 +24,7 @@ public delegate Task AsyncValueResolver(JsonValue value, IResolveFieldCont internal sealed class FieldVisitor : IFieldVisitor { - public static readonly IFieldResolver JsonNoop = CreateValueResolver((value, fieldContext, contex) => value.Value); + public static readonly IFieldResolver JsonScalar = CreateValueResolver((value, fieldContext, contex) => value.Value); public static readonly IFieldResolver JsonPath = CreateValueResolver(ContentActions.Json.Resolver); private static readonly IFieldResolver JsonBoolean = CreateValueResolver((value, fieldContext, contex) => @@ -171,7 +171,7 @@ internal sealed class FieldVisitor : IFieldVisitor return default; } - return new (type, JsonNoop, null); + return new (type, JsonScalar, null); } public FieldGraphSchema Visit(IField field, FieldInfo args) @@ -197,7 +197,7 @@ internal sealed class FieldVisitor : IFieldVisitor if (schema.Length > 0) { - return new (schema[0], JsonNoop, null); + return new (schema[0], JsonScalar, null); } return new (Scalars.Json, JsonPath, ContentActions.Json.Arguments); diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Primitives/JsonGraphType.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Primitives/JsonGraphType.cs index e66cd4c67..4f8fd8ef8 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Primitives/JsonGraphType.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Primitives/JsonGraphType.cs @@ -6,13 +6,22 @@ // ========================================================================== using System.Globalization; +using GraphQL.Types; using GraphQLParser.AST; using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Primitives; -public sealed class JsonGraphType : JsonNoopGraphType +public sealed class JsonGraphType : ScalarGraphType { + public JsonGraphType() + { + // The name is used for equal comparison. Therefore it is important to treat it as readonly. + Name = "JsonScalar"; + + Description = "Unstructured Json object"; + } + public override object? Serialize(object? value) { return value; diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Primitives/JsonNoopGraphType.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Primitives/JsonNoopGraphType.cs deleted file mode 100644 index 5bc4eef04..000000000 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Primitives/JsonNoopGraphType.cs +++ /dev/null @@ -1,37 +0,0 @@ -// ========================================================================== -// Squidex Headless CMS -// ========================================================================== -// Copyright (c) Squidex UG (haftungsbeschraenkt) -// All rights reserved. Licensed under the MIT license. -// ========================================================================== - -using GraphQL.Types; -using GraphQLParser.AST; - -namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types.Primitives; - -public class JsonNoopGraphType : ScalarGraphType -{ - public JsonNoopGraphType() - { - // The name is used for equal comparison. Therefore it is important to treat it as readonly. - Name = "JsonScalar"; - - Description = "Unstructured Json object"; - } - - public override object? ParseLiteral(GraphQLValue value) - { - return value; - } - - public override object? ParseValue(object? value) - { - return value; - } - - public override object? Serialize(object? value) - { - return value; - } -} diff --git a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Scalars.cs b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Scalars.cs index eeec9efb3..faf2e9ae3 100644 --- a/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Scalars.cs +++ b/backend/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/Scalars.cs @@ -20,8 +20,6 @@ public static class Scalars public static readonly IGraphType Json = new JsonGraphType(); - public static readonly IGraphType JsonNoop = new JsonNoopGraphType(); - public static readonly IGraphType Float = new FloatGraphType(); public static readonly IGraphType String = new StringGraphType(); diff --git a/backend/src/Squidex/Config/Domain/QueryServices.cs b/backend/src/Squidex/Config/Domain/QueryServices.cs index 918960e4d..7fe728f45 100644 --- a/backend/src/Squidex/Config/Domain/QueryServices.cs +++ b/backend/src/Squidex/Config/Domain/QueryServices.cs @@ -31,8 +31,5 @@ public static class QueryServices services.AddSingletonAs() .AsSelf(); - - services.AddSingletonAs() - .AsSelf(); } } diff --git a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLMutationTests.cs b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLMutationTests.cs index 0aea4303d..bc7898b54 100644 --- a/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLMutationTests.cs +++ b/backend/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLMutationTests.cs @@ -127,6 +127,59 @@ public class GraphQLMutationTests : GraphQLTestBase .MustHaveHappened(); } + [Fact] + public async Task Should_create_content_with_variable() + { + commandContext.Complete(content); + + var actual = await ExecuteAsync(new TestQuery + { + Query = @" + mutation MyMutation($location: JsonScalar) { + createMySchemaContent(data: { + myGeolocation: { + iv: $location + } + }) { + id + } + }", + Args = new + { + fields = TestContent.AllFields + }, + Variables = new + { + location = new + { + latitude = 42, + longitude = 13 + } + }, + Permission = PermissionIds.AppContentsCreate + }); + + var expected = new + { + data = new + { + createMySchemaContent = new + { + id = content.Id, + } + } + }; + + AssertResult(expected, actual); + + A.CallTo(() => commandBus.PublishAsync( + A.That.Matches(x => + x.ExpectedVersion == EtagVersion.Any && + x.SchemaId.Equals(TestSchemas.Default.NamedId())), + A._)) + .MustHaveHappened(); + } + [Fact] public async Task Should_return_single_content_if_creating_content_with_custom_id() {