Browse Source

Fix OpenAPI type mapping.

pull/959/head
Sebastian 3 years ago
parent
commit
11ff97724b
  1. 2
      backend/src/Squidex.Infrastructure/Reflection/AssemblyTypeProvider.cs
  2. 14
      backend/src/Squidex.Infrastructure/Reflection/TypeConfig.cs
  3. 5
      backend/src/Squidex/Areas/Api/Config/OpenApi/DiscriminatorProcessor.cs
  4. 5
      backend/src/Squidex/Areas/Api/Views/Shared/Docs.cshtml
  5. 12
      backend/tests/Squidex.Infrastructure.Tests/Reflection/TypeRegistryTests.cs

2
backend/src/Squidex.Infrastructure/Reflection/AssemblyTypeProvider.cs

@ -31,7 +31,7 @@ public sealed class AssemblyTypeProvider<T> : ITypeProvider where T : class
public void Map(TypeRegistry typeRegistry)
{
var baseType = typeof(T);
var baseType = typeof(T);
foreach (var derivedType in assembly.GetTypes())
{

14
backend/src/Squidex.Infrastructure/Reflection/TypeConfig.cs

@ -17,9 +17,9 @@ public sealed class TypeConfig
public string? DiscriminatorProperty { get; set; }
public IReadOnlyList<(Type DerivedType, string TypeName)> DerivedTypes
public bool IsEmpty
{
get => derivedTypes;
get => derivedTypes.Count == 0;
}
internal void Add(Type derivedType, string typeName)
@ -43,6 +43,14 @@ public sealed class TypeConfig
mapByType = null;
}
public IEnumerable<(Type DerivedType, string TypeName)> DerivedTypes()
{
var map = mapByType ??= BuildMapByType();
// The mapping can have multiple names per type, but the last is the default.
return map.Select(x => (x.Key, x.Value));
}
public bool TryGetType(string typeName, [MaybeNullWhen(false)] out Type derivedType)
{
var map = mapByName ??= BuildMapByName();
@ -61,6 +69,7 @@ public sealed class TypeConfig
{
var result = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase);
// Ensure that the last registration wins and becomes the default.
foreach (var (derivedType, typeName) in derivedTypes)
{
result[typeName] = derivedType;
@ -73,6 +82,7 @@ public sealed class TypeConfig
{
var result = new Dictionary<Type, string>();
// Ensure that the last registration wins and becomes the default.
foreach (var (derivedType, typeName) in derivedTypes)
{
result[derivedType] = typeName;

5
backend/src/Squidex/Areas/Api/Config/OpenApi/DiscriminatorProcessor.cs

@ -5,6 +5,7 @@
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using GraphQL.Utilities;
using NJsonSchema;
using NJsonSchema.Generation;
using Squidex.Infrastructure.Reflection;
@ -28,7 +29,7 @@ public sealed class DiscriminatorProcessor : ISchemaProcessor
}
if (!typeRegistry.TryGetConfig(context.ContextualType.Type, out var config) ||
config.DerivedTypes.Count <= 0 ||
config.IsEmpty ||
config.DiscriminatorProperty == null)
{
return;
@ -42,7 +43,7 @@ public sealed class DiscriminatorProcessor : ISchemaProcessor
var schema = context.Schema;
foreach (var (derivedType, typeName) in config.DerivedTypes)
foreach (var (derivedType, typeName) in config.DerivedTypes().OrderBy(x => x.TypeName))
{
var derivedSchema = context.Generator.Generate(derivedType, context.Resolver);

5
backend/src/Squidex/Areas/Api/Views/Shared/Docs.cshtml

@ -35,7 +35,7 @@
<body>
<div id="redoc-container"></div>
<script src="https://cdn.jsdelivr.net/npm/redoc@2.0.0-rc.57/bundles/redoc.standalone.js"></script>
<script src="https://cdn.jsdelivr.net/npm/redoc@2.0.0/bundles/redoc.standalone.js"></script>
<script>
Redoc.init('@Url.Content(Model!.Specification)', {
theme: {
@ -45,6 +45,9 @@
}
}
},
sortOperationsAlphabetically: true,
sortEnumValuesAlphabetically: true,
sortTagsAlphabetically: true,
nativeScrollbars: true
}, document.getElementById('redoc-container'))
</script>

12
backend/tests/Squidex.Infrastructure.Tests/Reflection/TypeRegistryTests.cs

@ -112,6 +112,18 @@ public class TypeRegistryTests
Assert.Equal(typeof(DerivedEvent), sut.GetType<Base>("DerivedEventV2"));
}
[Fact]
public void Should_provide_last_registration_for_list()
{
sut.Add<Base>(typeof(DerivedCustom), "Custom1");
sut.Add<Base>(typeof(DerivedCustom), "Custom2");
sut.Add<Base>(typeof(DerivedBase), "Base");
sut.TryGetConfig<Base>(out var config);
Assert.Equal(new[] { (typeof(DerivedCustom), "Custom2"), (typeof(DerivedBase), "Base") }, config?.DerivedTypes().ToArray());
}
[Fact]
public void Should_throw_exception_if_type_name_not_found()
{

Loading…
Cancel
Save