diff --git a/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLModel.cs b/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLModel.cs index ddb6c9fd8..151264b20 100644 --- a/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLModel.cs +++ b/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/GraphQLModel.cs @@ -28,9 +28,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL { public sealed class GraphQLModel : IGraphModel { - private readonly Dictionary contentTypes = new Dictionary(); - private readonly Dictionary contentDataTypes = new Dictionary(); - private readonly Dictionary schemasById; + private readonly Dictionary contentTypes = new Dictionary(); private readonly PartitionResolver partitionResolver; private readonly IAppEntity app; private readonly IGraphType assetType; @@ -54,34 +52,47 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL assetType = new AssetGraphType(this); assetListType = new ListGraphType(new NonNullGraphType(assetType)); - schemasById = schemas.Where(x => x.SchemaDef.IsPublished).ToDictionary(x => x.Id); + var allSchemas = schemas.Where(x => x.SchemaDef.IsPublished).ToList(); - graphQLSchema = BuildSchema(this, pageSizeContents, pageSizeAssets); + BuildSchemas(allSchemas); + + graphQLSchema = BuildSchema(this, pageSizeContents, pageSizeAssets, allSchemas); graphQLSchema.RegisterValueConverter(JsonConverter.Instance); InitializeContentTypes(); } - private static GraphQLSchema BuildSchema(GraphQLModel model, int pageSizeContents, int pageSizeAssets) + private void BuildSchemas(List allSchemas) { - var schemas = model.schemasById.Values; - - return new GraphQLSchema { Query = new AppQueriesGraphType(model, pageSizeContents, pageSizeAssets, schemas) }; + foreach (var schema in allSchemas) + { + contentTypes[schema.Id] = new ContentGraphType(schema); + } } private void InitializeContentTypes() { - foreach (var kvp in contentDataTypes) + foreach (var contentType in contentTypes.Values) { - kvp.Value.Initialize(this, kvp.Key); + contentType.Initialize(this); } - foreach (var kvp in contentTypes) + foreach (var contentType in contentTypes.Values) { - kvp.Value.Initialize(this, kvp.Key, contentDataTypes[kvp.Key]); + graphQLSchema.RegisterType(contentType); } } + private static GraphQLSchema BuildSchema(GraphQLModel model, int pageSizeContents, int pageSizeAssets, List schemas) + { + var schema = new GraphQLSchema + { + Query = new AppQueriesGraphType(model, pageSizeContents, pageSizeAssets, schemas) + }; + + return schema; + } + public IFieldResolver ResolveAssetUrl() { var resolver = new FuncFieldResolver(c => @@ -137,7 +148,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL public (IGraphType ResolveType, ValueResolver Resolver) GetGraphType(ISchemaEntity schema, IField field, string fieldName) { - return field.Accept(new QueryGraphTypeVisitor(schema, contentTypes, GetContentType, this, assetListType, fieldName)); + return field.Accept(new QueryGraphTypeVisitor(schema, contentTypes, this, assetListType, fieldName)); } public IObjectGraphType GetAssetType() @@ -147,16 +158,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL public IObjectGraphType GetContentType(Guid schemaId) { - var schema = schemasById.GetOrDefault(schemaId); - - if (schema == null) - { - return null; - } - - contentDataTypes.GetOrAdd(schema, s => new ContentDataGraphType()); - - return contentTypes.GetOrAdd(schema, s => new ContentGraphType()); + return contentTypes.GetOrDefault(schemaId); } public async Task<(object Data, object[] Errors)> ExecuteAsync(GraphQLExecutionContext context, GraphQLQuery query) diff --git a/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AssetGraphType.cs b/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AssetGraphType.cs index 801f44c81..639ee6d55 100644 --- a/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AssetGraphType.cs +++ b/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/AssetGraphType.cs @@ -17,7 +17,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { public AssetGraphType(IGraphModel model) { - Name = "AssetDto"; + Name = "Asset"; AddField(new FieldType { diff --git a/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentDataGraphType.cs b/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentDataGraphType.cs index c9a63d06b..517776b3f 100644 --- a/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentDataGraphType.cs +++ b/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentDataGraphType.cs @@ -18,21 +18,10 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { public sealed class ContentDataGraphType : ObjectGraphType { - public ContentDataGraphType(ISchemaEntity schema) + public ContentDataGraphType(ISchemaEntity schema, string schemaName, string schemaType, IGraphModel model) { - var schemaType = schema.TypeName(); - var schemaName = schema.DisplayName(); - Name = $"{schemaType}DataDto"; - Description = $"The structure of the {schemaName} content type."; - } - - public void Initialize(IGraphModel model, ISchemaEntity schema) - { - var schemaType = schema.TypeName(); - var schemaName = schema.DisplayName(); - foreach (var (field, fieldName, typeName) in schema.SchemaDef.Fields.SafeFields()) { var (resolvedType, valueResolver) = model.GetGraphType(schema, field, fieldName); @@ -72,6 +61,8 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types }); } } + + Description = $"The structure of the {schemaName} content type."; } private static FuncFieldResolver PartitionResolver(ValueResolver valueResolver, string key) diff --git a/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentGraphType.cs b/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentGraphType.cs index e473627c6..d07ee4b82 100644 --- a/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentGraphType.cs +++ b/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentGraphType.cs @@ -15,12 +15,18 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { public sealed class ContentGraphType : ObjectGraphType { - public ContentGraphType(IGraphModel model, ISchemaEntity schema, IComplexGraphType contentDataType) + private readonly ISchemaEntity schema; + private readonly string schemaType; + private readonly string schemaName; + + public ContentGraphType(ISchemaEntity schema) { - var schemaType = schema.TypeName(); - var schemaName = schema.DisplayName(); + this.schema = schema; + + schemaType = schema.TypeName(); + schemaName = schema.DisplayName(); - Name = $"{schemaType}Dto"; + Name = $"{schemaType}"; AddField(new FieldType { @@ -86,90 +92,20 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types Description = $"The color status of the {schemaName} content." }); - AddField(new FieldType - { - Name = "url", - ResolvedType = AllTypes.NonNullString, - Resolver = model.ResolveContentUrl(schema), - Description = $"The url to the the {schemaName} content." - }); - Interface(); Description = $"The structure of a {schemaName} content type."; + + IsTypeOf = CheckType; } - public void Initialize(IGraphModel model, ISchemaEntity schema, IComplexGraphType contentDataType) + private bool CheckType(object value) { - var schemaType = schema.TypeName(); - var schemaName = schema.DisplayName(); - - Name = $"{schemaType}Dto"; - - AddField(new FieldType - { - Name = "id", - ResolvedType = AllTypes.NonNullGuid, - Resolver = Resolve(x => x.Id), - Description = $"The id of the {schemaName} content." - }); - - AddField(new FieldType - { - Name = "version", - ResolvedType = AllTypes.NonNullInt, - Resolver = Resolve(x => x.Version), - Description = $"The version of the {schemaName} content." - }); - - AddField(new FieldType - { - Name = "created", - ResolvedType = AllTypes.NonNullDate, - Resolver = Resolve(x => x.Created), - Description = $"The date and time when the {schemaName} content has been created." - }); - - AddField(new FieldType - { - Name = "createdBy", - ResolvedType = AllTypes.NonNullString, - Resolver = Resolve(x => x.CreatedBy.ToString()), - Description = $"The user that has created the {schemaName} content." - }); - - AddField(new FieldType - { - Name = "lastModified", - ResolvedType = AllTypes.NonNullDate, - Resolver = Resolve(x => x.LastModified), - Description = $"The date and time when the {schemaName} content has been modified last." - }); - - AddField(new FieldType - { - Name = "lastModifiedBy", - ResolvedType = AllTypes.NonNullString, - Resolver = Resolve(x => x.LastModifiedBy.ToString()), - Description = $"The user that has updated the {schemaName} content last." - }); - - AddField(new FieldType - { - Name = "status", - ResolvedType = AllTypes.NonNullString, - Resolver = Resolve(x => x.Status.Name.ToUpperInvariant()), - Description = $"The the status of the {schemaName} content." - }); - - AddField(new FieldType - { - Name = "statusColor", - ResolvedType = AllTypes.NonNullString, - Resolver = Resolve(x => x.StatusColor), - Description = $"The color status of the {schemaName} content." - }); + return value is IContentEntity content && content.SchemaId?.Id == schema.Id; + } + public void Initialize(IGraphModel model) + { AddField(new FieldType { Name = "url", @@ -178,6 +114,8 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types Description = $"The url to the the {schemaName} content." }); + var contentDataType = new ContentDataGraphType(schema, schemaName, schemaType, model); + if (contentDataType.Fields.Any()) { AddField(new FieldType @@ -196,10 +134,6 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types Description = $"The draft data of the {schemaName} content." }); } - - Interface(); - - Description = $"The structure of a {schemaName} content type."; } private static IFieldResolver Resolve(Func action) diff --git a/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentInterfaceGraphType.cs b/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentInterfaceGraphType.cs index 750879243..b1d0c4615 100644 --- a/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentInterfaceGraphType.cs +++ b/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentInterfaceGraphType.cs @@ -5,20 +5,23 @@ // All rights reserved. Licensed under the MIT license. // ========================================================================== +using System; +using GraphQL.Resolvers; using GraphQL.Types; namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { - public sealed class ContentInterfaceGraphType : InterfaceGraphType + public sealed class ContentInterfaceGraphType : InterfaceGraphType { public ContentInterfaceGraphType() { - Name = $"ContentInfaceDto"; + Name = $"Content"; AddField(new FieldType { Name = "id", ResolvedType = AllTypes.NonNullGuid, + Resolver = Resolve(x => x.Id), Description = $"The id of the content." }); @@ -26,6 +29,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { Name = "version", ResolvedType = AllTypes.NonNullInt, + Resolver = Resolve(x => x.Version), Description = $"The version of the content." }); @@ -33,6 +37,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { Name = "created", ResolvedType = AllTypes.NonNullDate, + Resolver = Resolve(x => x.Created), Description = $"The date and time when the content has been created." }); @@ -40,6 +45,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { Name = "createdBy", ResolvedType = AllTypes.NonNullString, + Resolver = Resolve(x => x.CreatedBy.ToString()), Description = $"The user that has created the content." }); @@ -47,6 +53,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { Name = "lastModified", ResolvedType = AllTypes.NonNullDate, + Resolver = Resolve(x => x.LastModified), Description = $"The date and time when the content has been modified last." }); @@ -54,6 +61,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { Name = "lastModifiedBy", ResolvedType = AllTypes.NonNullString, + Resolver = Resolve(x => x.LastModifiedBy.ToString()), Description = $"The user that has updated the content last." }); @@ -61,6 +69,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { Name = "status", ResolvedType = AllTypes.NonNullString, + Resolver = Resolve(x => x.Status.Name.ToUpperInvariant()), Description = $"The the status of the content." }); @@ -68,17 +77,16 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { Name = "statusColor", ResolvedType = AllTypes.NonNullString, + Resolver = Resolve(x => x.StatusColor), Description = $"The color status of the content." }); - AddField(new FieldType - { - Name = "url", - ResolvedType = AllTypes.NonNullString, - Description = $"The url to the the content." - }); - Description = $"The structure of all content types."; } + + private static IFieldResolver Resolve(Func action) + { + return new FuncFieldResolver(c => action(c.Source)); + } } } diff --git a/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ReferenceGraphType.cs b/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentUnionGraphType.cs similarity index 75% rename from src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ReferenceGraphType.cs rename to src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentUnionGraphType.cs index 5de938132..523b58032 100644 --- a/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ReferenceGraphType.cs +++ b/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/ContentUnionGraphType.cs @@ -9,16 +9,15 @@ using System; using System.Collections.Generic; using System.Linq; using GraphQL.Types; -using Squidex.Domain.Apps.Entities.Schemas; using Squidex.Infrastructure; namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { - public sealed class ReferenceGraphType : UnionGraphType + public sealed class ContentUnionGraphType : UnionGraphType { private readonly Dictionary types = new Dictionary(); - public ReferenceGraphType(string fieldName, IDictionary schemaTypes, IEnumerable schemaIds, Func schemaResolver) + public ContentUnionGraphType(string fieldName, Dictionary schemaTypes, IEnumerable schemaIds) { Name = $"{fieldName}ReferenceUnionDto"; @@ -26,7 +25,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { foreach (var schemaId in schemaIds) { - var schemaType = schemaResolver(schemaId); + var schemaType = schemaTypes.GetOrDefault(schemaId); if (schemaType != null) { @@ -38,7 +37,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { foreach (var schemaType in schemaTypes) { - types[schemaType.Key.Id] = schemaType.Value; + types[schemaType.Key] = schemaType.Value; } } @@ -51,7 +50,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types { if (value is IContentEntity content) { - return types.GetOrDefault(content.Id); + return types.GetOrDefault(content.SchemaId.Id); } return null; diff --git a/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/QueryGraphTypeVisitor.cs b/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/QueryGraphTypeVisitor.cs index 42e10034d..e038b0432 100644 --- a/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/QueryGraphTypeVisitor.cs +++ b/src/Squidex.Domain.Apps.Entities/Contents/GraphQL/Types/QueryGraphTypeVisitor.cs @@ -11,6 +11,7 @@ using System.Linq; using GraphQL.Types; using Squidex.Domain.Apps.Core.Schemas; using Squidex.Domain.Apps.Entities.Schemas; +using Squidex.Infrastructure; using Squidex.Infrastructure.Json.Objects; namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types @@ -20,16 +21,14 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types public sealed class QueryGraphTypeVisitor : IFieldVisitor<(IGraphType ResolveType, ValueResolver Resolver)> { private static readonly ValueResolver NoopResolver = (value, c) => value; + private readonly Dictionary schemaTypes; private readonly ISchemaEntity schema; - private readonly Func schemaResolver; - private readonly IDictionary schemaTypes; private readonly IGraphModel model; private readonly IGraphType assetListType; private readonly string fieldName; public QueryGraphTypeVisitor(ISchemaEntity schema, - IDictionary schemaTypes, - Func schemaResolver, + Dictionary schemaTypes, IGraphModel model, IGraphType assetListType, string fieldName) @@ -37,7 +36,6 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types this.model = model; this.assetListType = assetListType; this.schema = schema; - this.schemaResolver = schemaResolver; this.schemaTypes = schemaTypes; this.fieldName = fieldName; } @@ -123,11 +121,11 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL.Types private (IGraphType ResolveType, ValueResolver Resolver) ResolveReferences(IField field) { - IGraphType contentType = schemaResolver(field.Properties.SingleId()); + IGraphType contentType = schemaTypes.GetOrDefault(field.Properties.SingleId()); if (contentType == null) { - var union = new ReferenceGraphType(fieldName, schemaTypes, field.Properties.SchemaIds, schemaResolver); + var union = new ContentUnionGraphType(fieldName, schemaTypes, field.Properties.SchemaIds); if (!union.PossibleTypes.Any()) { diff --git a/src/Squidex.Domain.Users/UserManagerExtensions.cs b/src/Squidex.Domain.Users/UserManagerExtensions.cs index e89160674..880663a92 100644 --- a/src/Squidex.Domain.Users/UserManagerExtensions.cs +++ b/src/Squidex.Domain.Users/UserManagerExtensions.cs @@ -6,7 +6,6 @@ // ========================================================================== using System; -using System.Collections; using System.Collections.Generic; using System.Linq; using System.Security.Claims; diff --git a/src/Squidex/Areas/Api/Controllers/Schemas/Models/Converters/FieldPropertiesDtoFactory.cs b/src/Squidex/Areas/Api/Controllers/Schemas/Models/Converters/FieldPropertiesDtoFactory.cs index c2cacdb89..9909d8435 100644 --- a/src/Squidex/Areas/Api/Controllers/Schemas/Models/Converters/FieldPropertiesDtoFactory.cs +++ b/src/Squidex/Areas/Api/Controllers/Schemas/Models/Converters/FieldPropertiesDtoFactory.cs @@ -30,6 +30,15 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models.Converters return SimpleMapper.Map(properties, new ArrayFieldPropertiesDto()); } + public FieldPropertiesDto Visit(AssetsFieldProperties properties) + { + var result = SimpleMapper.Map(properties, new AssetsFieldPropertiesDto()); + + result.AllowedExtensions = properties.AllowedExtensions?.ToArray(); + + return result; + } + public FieldPropertiesDto Visit(BooleanFieldProperties properties) { return SimpleMapper.Map(properties, new BooleanFieldPropertiesDto()); @@ -50,50 +59,45 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models.Converters return SimpleMapper.Map(properties, new JsonFieldPropertiesDto()); } - public FieldPropertiesDto Visit(ReferencesFieldProperties properties) - { - return SimpleMapper.Map(properties, new ReferencesFieldPropertiesDto()); - } - - public FieldPropertiesDto Visit(UIFieldProperties properties) - { - return SimpleMapper.Map(properties, new UIFieldPropertiesDto()); - } - - public FieldPropertiesDto Visit(TagsFieldProperties properties) + public FieldPropertiesDto Visit(NumberFieldProperties properties) { - var result = SimpleMapper.Map(properties, new TagsFieldPropertiesDto()); + var result = SimpleMapper.Map(properties, new NumberFieldPropertiesDto()); result.AllowedValues = properties.AllowedValues?.ToArray(); return result; } - public FieldPropertiesDto Visit(AssetsFieldProperties properties) + public FieldPropertiesDto Visit(ReferencesFieldProperties properties) { - var result = SimpleMapper.Map(properties, new AssetsFieldPropertiesDto()); + var result = SimpleMapper.Map(properties, new ReferencesFieldPropertiesDto()); - result.AllowedExtensions = properties.AllowedExtensions?.ToArray(); + result.SchemaIds = properties.SchemaIds?.ToArray(); return result; } - public FieldPropertiesDto Visit(NumberFieldProperties properties) + public FieldPropertiesDto Visit(StringFieldProperties properties) { - var result = SimpleMapper.Map(properties, new NumberFieldPropertiesDto()); + var result = SimpleMapper.Map(properties, new StringFieldPropertiesDto()); result.AllowedValues = properties.AllowedValues?.ToArray(); return result; } - public FieldPropertiesDto Visit(StringFieldProperties properties) + public FieldPropertiesDto Visit(TagsFieldProperties properties) { - var result = SimpleMapper.Map(properties, new StringFieldPropertiesDto()); + var result = SimpleMapper.Map(properties, new TagsFieldPropertiesDto()); result.AllowedValues = properties.AllowedValues?.ToArray(); return result; } + + public FieldPropertiesDto Visit(UIFieldProperties properties) + { + return SimpleMapper.Map(properties, new UIFieldPropertiesDto()); + } } } diff --git a/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs b/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs index 8f144931c..d85708d51 100644 --- a/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs +++ b/src/Squidex/Areas/Api/Controllers/Schemas/Models/Fields/ReferencesFieldPropertiesDto.cs @@ -7,6 +7,7 @@ using System; using Squidex.Domain.Apps.Core.Schemas; +using Squidex.Infrastructure.Collections; using Squidex.Infrastructure.Reflection; namespace Squidex.Areas.Api.Controllers.Schemas.Models.Fields @@ -39,13 +40,20 @@ namespace Squidex.Areas.Api.Controllers.Schemas.Models.Fields public ReferencesFieldEditor Editor { get; set; } /// - /// The id of the referenced schema. + /// The id of the referenced schemas. /// - public Guid SchemaId { get; set; } + public Guid[] SchemaIds { get; set; } public override FieldProperties ToProperties() { - return SimpleMapper.Map(this, new ReferencesFieldProperties()); + var result = SimpleMapper.Map(this, new ReferencesFieldProperties()); + + if (SchemaIds != null) + { + result.SchemaIds = ReadOnlyCollection.Create(SchemaIds); + } + + return result; } } } diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLQueriesTests.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLQueriesTests.cs index fe3b0eb60..78c2ad0c8 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLQueriesTests.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLQueriesTests.cs @@ -18,6 +18,95 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL { public class GraphQLQueriesTests : GraphQLTestBase { + [Fact] + public async Task Should_introspect() + { + const string query = @" + query IntrospectionQuery { + __schema { + queryType { name } + mutationType { name } + subscriptionType { name } + types { + ...FullType + } + directives { + name + description + args { + ...InputValue + } + onOperation + onFragment + onField + } + } + } + + fragment FullType on __Type { + kind + name + description + fields(includeDeprecated: true) { + name + description + args { + ...InputValue + } + type { + ...TypeRef + } + isDeprecated + deprecationReason + } + inputFields { + ...InputValue + } + interfaces { + ...TypeRef + } + enumValues(includeDeprecated: true) { + name + description + isDeprecated + deprecationReason + } + possibleTypes { + ...TypeRef + } + } + + fragment InputValue on __InputValue { + name + description + type { ...TypeRef } + defaultValue + } + + fragment TypeRef on __Type { + kind + name + ofType { + kind + name + ofType { + kind + name + ofType { + kind + name + } + } + } + }"; + + var result = await sut.QueryAsync(requestContext, new GraphQLQuery { Query = query, OperationName = "IntrospectionQuery" }); + + var json = serializer.Serialize(result.Response, true); + + Assert.NotEmpty(json); + } + [Theory] [InlineData(null)] [InlineData("")] @@ -775,7 +864,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL public async Task Should_also_fetch_referenced_contents_when_field_is_included_in_query() { var contentRefId = Guid.NewGuid(); - var contentRef = CreateRefContent(contentRefId, "ref1-field", "ref1"); + var contentRef = CreateRefContent(schemaRefId1, contentRefId, "ref1-field", "ref1"); var contentId = Guid.NewGuid(); var content = CreateContent(contentId, contentRefId, Guid.Empty); @@ -845,7 +934,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL public async Task Should_also_fetch_union_contents_when_field_is_included_in_query() { var contentRefId = Guid.NewGuid(); - var contentRef = CreateRefContent(contentRefId, "ref1-field", "ref1"); + var contentRef = CreateRefContent(schemaRefId1, contentRefId, "ref1-field", "ref1"); var contentId = Guid.NewGuid(); var content = CreateContent(contentId, contentRefId, Guid.Empty); @@ -857,15 +946,17 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL data { myUnion { iv { - id - __typename - ...MyRefSchema1Dto { + ... on Content { + id + } + ... on MyRefSchema1 { data { ref1Field { iv } } } + __typename } } } @@ -889,14 +980,13 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL id = content.Id, data = new { - myReferences = new + myUnion = new { iv = new[] { new { id = contentRefId, - __typename = "MyRefSchema1Dto", data = new { ref1Field = new @@ -904,6 +994,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL iv = "ref1" } }, + __typename = "MyRefSchema1" } } } diff --git a/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLTestBase.cs b/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLTestBase.cs index c9e63c7b5..e5eb10df8 100644 --- a/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLTestBase.cs +++ b/tests/Squidex.Domain.Apps.Entities.Tests/Contents/GraphQL/GraphQLTestBase.cs @@ -109,7 +109,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL sut = CreateSut(); } - protected static IEnrichedContentEntity CreateContent(Guid id, Guid refId, Guid assetId, NamedContentData data = null, NamedContentData dataDraft = null) + protected IEnrichedContentEntity CreateContent(Guid id, Guid refId, Guid assetId, NamedContentData data = null, NamedContentData dataDraft = null) { var now = SystemClock.Instance.GetCurrentInstant(); @@ -173,6 +173,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL LastModifiedBy = new RefToken(RefTokenType.Subject, "user2"), Data = data, DataDraft = dataDraft, + SchemaId = schemaId, Status = Status.Draft, StatusColor = "red" }; @@ -180,7 +181,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL return content; } - protected static IEnrichedContentEntity CreateRefContent(Guid id, string field, string value) + protected static IEnrichedContentEntity CreateRefContent(NamedId schemaId, Guid id, string field, string value) { var now = SystemClock.Instance.GetCurrentInstant(); @@ -200,6 +201,7 @@ namespace Squidex.Domain.Apps.Entities.Contents.GraphQL LastModifiedBy = new RefToken(RefTokenType.Subject, "user2"), Data = data, DataDraft = data, + SchemaId = schemaId, Status = Status.Draft, StatusColor = "red" };