Browse Source

Fix/graphql json (#847)

* Fix graphql json.

* Fix naming.
pull/848/head
Sebastian Stehle 4 years ago
committed by GitHub
parent
commit
87d98bdce0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      backend/src/Squidex.Domain.Apps.Core.Model/Schemas/FieldTypeProvider.cs
  2. 4
      backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleTypeProvider.cs
  3. 3
      backend/src/Squidex.Web/GraphQL/DynamicUserContextBuilder.cs
  4. 4
      backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionProcessor.cs
  5. 4
      backend/src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs
  6. 4
      backend/src/Squidex/Config/Domain/RuleServices.cs
  7. 24
      backend/src/Squidex/Config/Domain/SerializationServices.cs
  8. 1
      backend/src/Squidex/Config/Web/WebServices.cs
  9. 2
      backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleElementRegistryTests.cs
  10. 4
      backend/tests/Squidex.Domain.Apps.Core.Tests/TestHelpers/TestUtils.cs
  11. 37
      backend/tools/TestSuite/TestSuite.ApiTests/GraphQLTests.cs

5
backend/src/Squidex.Domain.Apps.Core.Model/Schemas/FieldRegistry.cs → backend/src/Squidex.Domain.Apps.Core.Model/Schemas/FieldTypeProvider.cs

@ -9,14 +9,14 @@ using Squidex.Infrastructure.Reflection;
namespace Squidex.Domain.Apps.Core.Schemas namespace Squidex.Domain.Apps.Core.Schemas
{ {
public class FieldRegistry : ITypeProvider public class FieldTypeProvider : ITypeProvider
{ {
private const string Suffix = "Properties"; private const string Suffix = "Properties";
private const string SuffixOld = "FieldProperties"; private const string SuffixOld = "FieldProperties";
public void Map(TypeNameRegistry typeNameRegistry) public void Map(TypeNameRegistry typeNameRegistry)
{ {
var types = typeof(FieldRegistry).Assembly.GetTypes().Where(x => typeof(FieldProperties).IsAssignableFrom(x) && !x.IsAbstract); var types = typeof(FieldTypeProvider).Assembly.GetTypes().Where(x => typeof(FieldProperties).IsAssignableFrom(x) && !x.IsAbstract);
var addedTypes = new HashSet<Type>(); var addedTypes = new HashSet<Type>();
@ -25,7 +25,6 @@ namespace Squidex.Domain.Apps.Core.Schemas
if (addedTypes.Add(type)) if (addedTypes.Add(type))
{ {
typeNameRegistry.Map(type, type.TypeName(false, Suffix)); typeNameRegistry.Map(type, type.TypeName(false, Suffix));
typeNameRegistry.MapObsolete(type, type.TypeName(false, SuffixOld)); typeNameRegistry.MapObsolete(type, type.TypeName(false, SuffixOld));
} }
} }

4
backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleRegistry.cs → backend/src/Squidex.Domain.Apps.Core.Operations/HandleRules/RuleTypeProvider.cs

@ -16,7 +16,7 @@ using Squidex.Text;
namespace Squidex.Domain.Apps.Core.HandleRules namespace Squidex.Domain.Apps.Core.HandleRules
{ {
public sealed class RuleRegistry : ITypeProvider public sealed class RuleTypeProvider : ITypeProvider
{ {
private const string ActionSuffix = "Action"; private const string ActionSuffix = "Action";
private const string ActionSuffixV2 = "ActionV2"; private const string ActionSuffixV2 = "ActionV2";
@ -27,7 +27,7 @@ namespace Squidex.Domain.Apps.Core.HandleRules
get => actionTypes; get => actionTypes;
} }
public RuleRegistry(IEnumerable<RuleActionRegistration>? registrations = null) public RuleTypeProvider(IEnumerable<RuleActionRegistration>? registrations = null)
{ {
if (registrations != null) if (registrations != null)
{ {

3
backend/src/Squidex.Web/GraphQL/DynamicUserContextBuilder.cs

@ -5,6 +5,7 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using GraphQL;
using GraphQL.Server.Transports.AspNetCore; using GraphQL.Server.Transports.AspNetCore;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -19,6 +20,8 @@ namespace Squidex.Web.GraphQL
public Task<IDictionary<string, object>> BuildUserContext(HttpContext httpContext) public Task<IDictionary<string, object>> BuildUserContext(HttpContext httpContext)
{ {
var x = httpContext.RequestServices.GetRequiredService<IDocumentWriter>();
var executionContext = (GraphQLExecutionContext)factory(httpContext.RequestServices, new object[] { httpContext.Context() }); var executionContext = (GraphQLExecutionContext)factory(httpContext.RequestServices, new object[] { httpContext.Context() });
return Task.FromResult<IDictionary<string, object>>(executionContext); return Task.FromResult<IDictionary<string, object>>(executionContext);

4
backend/src/Squidex/Areas/Api/Controllers/Rules/Models/RuleActionProcessor.cs

@ -17,9 +17,9 @@ namespace Squidex.Areas.Api.Controllers.Rules.Models
{ {
public sealed class RuleActionProcessor : IDocumentProcessor public sealed class RuleActionProcessor : IDocumentProcessor
{ {
private readonly RuleRegistry ruleRegistry; private readonly RuleTypeProvider ruleRegistry;
public RuleActionProcessor(RuleRegistry ruleRegistry) public RuleActionProcessor(RuleTypeProvider ruleRegistry)
{ {
this.ruleRegistry = ruleRegistry; this.ruleRegistry = ruleRegistry;
} }

4
backend/src/Squidex/Areas/Api/Controllers/Rules/RulesController.cs

@ -34,14 +34,14 @@ namespace Squidex.Areas.Api.Controllers.Rules
private readonly IRuleEventRepository ruleEventsRepository; private readonly IRuleEventRepository ruleEventsRepository;
private readonly IRuleQueryService ruleQuery; private readonly IRuleQueryService ruleQuery;
private readonly IRuleRunnerService ruleRunnerService; private readonly IRuleRunnerService ruleRunnerService;
private readonly RuleRegistry ruleRegistry; private readonly RuleTypeProvider ruleRegistry;
public RulesController(ICommandBus commandBus, public RulesController(ICommandBus commandBus,
IAppProvider appProvider, IAppProvider appProvider,
IRuleEventRepository ruleEventsRepository, IRuleEventRepository ruleEventsRepository,
IRuleQueryService ruleQuery, IRuleQueryService ruleQuery,
IRuleRunnerService ruleRunnerService, IRuleRunnerService ruleRunnerService,
RuleRegistry ruleRegistry, RuleTypeProvider ruleRegistry,
EventJsonSchemaGenerator eventJsonSchemaGenerator) EventJsonSchemaGenerator eventJsonSchemaGenerator)
: base(commandBus) : base(commandBus)
{ {

4
backend/src/Squidex/Config/Domain/RuleServices.cs

@ -83,7 +83,7 @@ namespace Squidex.Config.Domain
services.AddSingletonAs<EventJsonSchemaGenerator>() services.AddSingletonAs<EventJsonSchemaGenerator>()
.AsSelf(); .AsSelf();
services.AddSingletonAs<RuleRegistry>() services.AddSingletonAs<RuleTypeProvider>()
.As<ITypeProvider>().AsSelf(); .As<ITypeProvider>().AsSelf();
services.AddSingletonAs<EventJintExtension>() services.AddSingletonAs<EventJintExtension>()
@ -104,7 +104,7 @@ namespace Squidex.Config.Domain
services.AddSingletonAs<GrainBootstrap<IRuleDequeuerGrain>>() services.AddSingletonAs<GrainBootstrap<IRuleDequeuerGrain>>()
.AsSelf(); .AsSelf();
services.AddInitializer<RuleRegistry>("Serializer (Rules)", registry => services.AddInitializer<RuleTypeProvider>("Serializer (Rules)", registry =>
{ {
RuleActionConverter.Mapping = registry.Actions.ToDictionary(x => x.Key, x => x.Value.Type); RuleActionConverter.Mapping = registry.Actions.ToDictionary(x => x.Key, x => x.Value.Type);
}, -1); }, -1);

24
backend/src/Squidex/Config/Domain/SerializationServices.cs

@ -7,9 +7,9 @@
using System.Security.Claims; using System.Security.Claims;
using GraphQL; using GraphQL;
using GraphQL.DI;
using GraphQL.Execution; using GraphQL.Execution;
using GraphQL.NewtonsoftJson; using GraphQL.NewtonsoftJson;
using GraphQL.Server;
using Migrations; using Migrations;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Converters; using Newtonsoft.Json.Converters;
@ -30,6 +30,7 @@ using Squidex.Infrastructure.Json.Objects;
using Squidex.Infrastructure.Queries; using Squidex.Infrastructure.Queries;
using Squidex.Infrastructure.Queries.Json; using Squidex.Infrastructure.Queries.Json;
using Squidex.Infrastructure.Reflection; using Squidex.Infrastructure.Reflection;
using IGraphQLBuilder = GraphQL.DI.IGraphQLBuilder;
namespace Squidex.Config.Domain namespace Squidex.Config.Domain
{ {
@ -44,7 +45,6 @@ namespace Squidex.Config.Domain
new CompareOperatorJsonConverter(), new CompareOperatorJsonConverter(),
new ContentFieldDataConverter(), new ContentFieldDataConverter(),
new EnvelopeHeadersConverter(), new EnvelopeHeadersConverter(),
new ExecutionResultJsonConverter(new ErrorInfoProvider()),
new JsonValueConverter(), new JsonValueConverter(),
new StringEnumConverter(), new StringEnumConverter(),
new SurrogateConverter<ClaimsPrincipal, ClaimsPrincipalSurrogate>(), new SurrogateConverter<ClaimsPrincipal, ClaimsPrincipalSurrogate>(),
@ -82,7 +82,7 @@ namespace Squidex.Config.Domain
services.AddSingletonAs<AutoAssembyTypeProvider<SquidexMigrations>>() services.AddSingletonAs<AutoAssembyTypeProvider<SquidexMigrations>>()
.As<ITypeProvider>(); .As<ITypeProvider>();
services.AddSingletonAs<FieldRegistry>() services.AddSingletonAs<FieldTypeProvider>()
.As<ITypeProvider>(); .As<ITypeProvider>();
services.AddSingletonAs<NewtonsoftJsonSerializer>() services.AddSingletonAs<NewtonsoftJsonSerializer>()
@ -122,5 +122,23 @@ namespace Squidex.Config.Domain
return builder; return builder;
} }
public static IGraphQLBuilder AddSquidexJson(this IGraphQLBuilder builder)
{
builder.AddDocumentWriter(c =>
{
var errorInfoProvider = c.GetRequiredService<IErrorInfoProvider>();
return new DocumentWriter(options =>
{
options.ContractResolver = new ExecutionResultContractResolver(new ErrorInfoProvider());
options.Converters.Add(new JsonValueConverter());
options.Converters.Add(new WriteonlyGeoJsonConverter());
});
});
return builder;
}
} }
} }

1
backend/src/Squidex/Config/Web/WebServices.cs

@ -94,6 +94,7 @@ namespace Squidex.Config.Web
}) })
.AddSchema<DummySchema>() .AddSchema<DummySchema>()
.AddSystemTextJson() .AddSystemTextJson()
.AddSquidexJson() // Use Newtonsoft.JSON for custom converters.
.AddDataLoader(); .AddDataLoader();
services.AddSingletonAs<DummySchema>() services.AddSingletonAs<DummySchema>()

2
backend/tests/Squidex.Domain.Apps.Core.Tests/Operations/HandleRules/RuleElementRegistryTests.cs

@ -16,7 +16,7 @@ namespace Squidex.Domain.Apps.Core.Operations.HandleRules
{ {
public class RuleElementRegistryTests public class RuleElementRegistryTests
{ {
private readonly RuleRegistry sut = new RuleRegistry(); private readonly RuleTypeProvider sut = new RuleTypeProvider();
private abstract class MyRuleActionHandler : RuleActionHandler<MyRuleAction, string> private abstract class MyRuleActionHandler : RuleActionHandler<MyRuleAction, string>
{ {

4
backend/tests/Squidex.Domain.Apps.Core.Tests/TestHelpers/TestUtils.cs

@ -41,8 +41,8 @@ namespace Squidex.Domain.Apps.Core.TestHelpers
{ {
var typeNameRegistry = var typeNameRegistry =
new TypeNameRegistry() new TypeNameRegistry()
.Map(new FieldRegistry()) .Map(new FieldTypeProvider())
.Map(new RuleRegistry()) .Map(new RuleTypeProvider())
.MapUnmapped(typeof(TestUtils).Assembly); .MapUnmapped(typeof(TestUtils).Assembly);
var serializerSettings = new JsonSerializerSettings var serializerSettings = new JsonSerializerSettings

37
backend/tools/TestSuite/TestSuite.ApiTests/GraphQLTests.cs

@ -9,6 +9,7 @@ using Newtonsoft.Json.Linq;
using Squidex.ClientLibrary; using Squidex.ClientLibrary;
using Squidex.ClientLibrary.Management; using Squidex.ClientLibrary.Management;
using TestSuite.Fixtures; using TestSuite.Fixtures;
using TestSuite.Model;
using Xunit; using Xunit;
#pragma warning disable SA1300 // Element should begin with upper-case letter #pragma warning disable SA1300 // Element should begin with upper-case letter
@ -63,6 +64,42 @@ namespace TestSuite.ApiTests
public string Name { get; set; } public string Name { get; set; }
} }
[Fact]
public async Task Should_query_json()
{
// STEP 1: Create a content with JSON.
var content_0 = await _.Contents.CreateAsync(new TestEntityData
{
Json = JToken.FromObject(new
{
value = 1,
obj = new
{
value = 2
}
})
}, ContentCreateOptions.AsPublish);
// STEP 2: Query this content.
var query = new
{
query = @"
{
findMyWritesContent(id: ""<ID>"") {
flatData {
json
}
}
}".Replace("<ID>", content_0.Id, StringComparison.Ordinal)
};
var result1 = await _.Contents.GraphQlAsync<JToken>(query);
Assert.Equal(1, result1["findMyWritesContent"]["flatData"]["json"]["value"].Value<int>());
Assert.Equal(2, result1["findMyWritesContent"]["flatData"]["json"]["obj"]["value"].Value<int>());
}
[Fact] [Fact]
public async Task Should_create_and_query_with_graphql() public async Task Should_create_and_query_with_graphql()
{ {

Loading…
Cancel
Save