480 lines
16 KiB
C#
480 lines
16 KiB
C#
// ------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
|
// ------------------------------------------------------------
|
|
|
|
using System;
|
|
using System.Linq;
|
|
using Microsoft.OData.Edm;
|
|
using Microsoft.OpenApi.Extensions;
|
|
using Microsoft.OpenApi.Models;
|
|
using Microsoft.OpenApi.OData.Generator;
|
|
using Xunit;
|
|
using Xunit.Abstractions;
|
|
|
|
namespace Microsoft.OpenApi.OData.Tests
|
|
{
|
|
public class OpenApiEdmTypeSchemaGeneratorTest
|
|
{
|
|
private ITestOutputHelper _output;
|
|
public OpenApiEdmTypeSchemaGeneratorTest(ITestOutputHelper output)
|
|
{
|
|
_output = output;
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateEdmTypeSchemaThrowArgumentNullContext()
|
|
{
|
|
// Arrange
|
|
ODataContext context = null;
|
|
|
|
// Act & Assert
|
|
Assert.Throws<ArgumentNullException>("context", () => context.CreateEdmTypeSchema(edmTypeReference: null));
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateEdmTypeSchemaThrowArgumentNullEdmTypeReference()
|
|
{
|
|
// Arrange
|
|
ODataContext context = new ODataContext(EdmCoreModel.Instance);
|
|
|
|
// Act & Assert
|
|
Assert.Throws<ArgumentNullException>("edmTypeReference", () => context.CreateEdmTypeSchema(edmTypeReference: null));
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateEdmTypeSchemaReturnSchemaForNullableCollectionComplexType()
|
|
{
|
|
// Arrange
|
|
IEdmModel model = EdmModelHelper.TripServiceModel;
|
|
IEdmComplexType complex = model.SchemaElements.OfType<IEdmComplexType>().First(c => c.Name == "AirportLocation");
|
|
ODataContext context = new ODataContext(model);
|
|
IEdmCollectionTypeReference collectionType = new EdmCollectionTypeReference(
|
|
new EdmCollectionType(new EdmComplexTypeReference(complex, true)));
|
|
|
|
// Act
|
|
var schema = context.CreateEdmTypeSchema(collectionType);
|
|
Assert.NotNull(schema);
|
|
string json = schema.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
|
|
|
// & Assert
|
|
Assert.Equal(@"{
|
|
""type"": ""array"",
|
|
""items"": {
|
|
""anyOf"": [
|
|
{
|
|
""$ref"": ""#/components/schemas/Microsoft.OData.Service.Sample.TrippinInMemory.Models.AirportLocation""
|
|
}
|
|
],
|
|
""nullable"": true
|
|
}
|
|
}".ChangeLineBreaks(), json);
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateEdmTypeSchemaReturnSchemaForNonNullableCollectionComplexType()
|
|
{
|
|
// Arrange
|
|
IEdmModel model = EdmModelHelper.TripServiceModel;
|
|
IEdmComplexType complex = model.SchemaElements.OfType<IEdmComplexType>().First(c => c.Name == "AirportLocation");
|
|
ODataContext context = new ODataContext(model);
|
|
IEdmCollectionTypeReference collectionType = new EdmCollectionTypeReference(
|
|
new EdmCollectionType(new EdmComplexTypeReference(complex, false)));
|
|
|
|
// Act
|
|
var schema = context.CreateEdmTypeSchema(collectionType);
|
|
Assert.NotNull(schema);
|
|
string json = schema.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
|
|
|
// & Assert
|
|
Assert.Equal(@"{
|
|
""type"": ""array"",
|
|
""items"": {
|
|
""$ref"": ""#/components/schemas/Microsoft.OData.Service.Sample.TrippinInMemory.Models.AirportLocation""
|
|
}
|
|
}".ChangeLineBreaks(), json);
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateEdmTypeSchemaReturnSchemaForNonNullableCollectionPrimitiveType()
|
|
{
|
|
// Arrange
|
|
IEdmModel model = EdmCoreModel.Instance;
|
|
ODataContext context = new ODataContext(model);
|
|
IEdmCollectionTypeReference collectionType = new EdmCollectionTypeReference(
|
|
new EdmCollectionType(EdmCoreModel.Instance.GetString(false)));
|
|
|
|
// Act
|
|
var schema = context.CreateEdmTypeSchema(collectionType);
|
|
Assert.NotNull(schema);
|
|
string json = schema.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
|
|
|
// & Assert
|
|
Assert.Equal(@"{
|
|
""type"": ""array"",
|
|
""items"": {
|
|
""type"": ""string""
|
|
}
|
|
}".ChangeLineBreaks(), json);
|
|
}
|
|
|
|
[Fact]
|
|
public void CreateEdmTypeSchemaReturnSchemaForNullableCollectionPrimitiveType()
|
|
{
|
|
// Arrange
|
|
IEdmModel model = EdmCoreModel.Instance;
|
|
ODataContext context = new ODataContext(model);
|
|
IEdmCollectionTypeReference collectionType = new EdmCollectionTypeReference(
|
|
new EdmCollectionType(EdmCoreModel.Instance.GetInt32(true)));
|
|
|
|
// Act
|
|
var schema = context.CreateEdmTypeSchema(collectionType);
|
|
Assert.NotNull(schema);
|
|
string json = schema.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
|
|
|
// & Assert
|
|
Assert.Equal(@"{
|
|
""type"": ""array"",
|
|
""items"": {
|
|
""maximum"": 2147483647,
|
|
""minimum"": -2147483648,
|
|
""type"": ""integer"",
|
|
""format"": ""int32"",
|
|
""nullable"": true
|
|
}
|
|
}".ChangeLineBreaks(), json);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(true)]
|
|
[InlineData(false)]
|
|
public void CreateEdmTypeSchemaReturnSchemaForEnumType(bool isNullable)
|
|
{
|
|
// Arrange
|
|
IEdmModel model = EdmModelHelper.TripServiceModel;
|
|
IEdmEnumType enumType = model.SchemaElements.OfType<IEdmEnumType>().First(c => c.Name == "PersonGender");
|
|
Assert.NotNull(enumType); // guard
|
|
IEdmEnumTypeReference enumTypeReference = new EdmEnumTypeReference(enumType, isNullable);
|
|
ODataContext context = new ODataContext(model);
|
|
|
|
// Act
|
|
var schema = context.CreateEdmTypeSchema(enumTypeReference);
|
|
|
|
// & Assert
|
|
Assert.NotNull(schema);
|
|
Assert.Equal(isNullable, schema.Nullable);
|
|
Assert.Null(schema.Reference);
|
|
Assert.NotNull(schema.AnyOf);
|
|
Assert.NotEmpty(schema.AnyOf);
|
|
var anyOf = Assert.Single(schema.AnyOf);
|
|
Assert.NotNull(anyOf.Reference);
|
|
Assert.Equal(ReferenceType.Schema, anyOf.Reference.Type);
|
|
Assert.Equal(enumType.FullTypeName(), anyOf.Reference.Id);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(true)]
|
|
[InlineData(false)]
|
|
public void CreateEdmTypeSchemaReturnSchemaForComplexType(bool isNullable)
|
|
{
|
|
// Arrange
|
|
IEdmModel model = EdmModelHelper.TripServiceModel;
|
|
IEdmComplexType complex = model.SchemaElements.OfType<IEdmComplexType>().First(c => c.Name == "AirportLocation");
|
|
Assert.NotNull(complex); // guard
|
|
IEdmComplexTypeReference complexTypeReference = new EdmComplexTypeReference(complex, isNullable);
|
|
ODataContext context = new ODataContext(model);
|
|
|
|
// Act
|
|
var schema = context.CreateEdmTypeSchema(complexTypeReference);
|
|
|
|
// & Assert
|
|
Assert.NotNull(schema);
|
|
|
|
if (isNullable)
|
|
{
|
|
Assert.Null(schema.Reference);
|
|
Assert.NotNull(schema.AnyOf);
|
|
Assert.NotEmpty(schema.AnyOf);
|
|
var anyOf = Assert.Single(schema.AnyOf);
|
|
Assert.NotNull(anyOf.Reference);
|
|
Assert.Equal(ReferenceType.Schema, anyOf.Reference.Type);
|
|
Assert.Equal(complex.FullTypeName(), anyOf.Reference.Id);
|
|
}
|
|
else
|
|
{
|
|
Assert.Null(schema.AnyOf);
|
|
Assert.NotNull(schema.Reference);
|
|
Assert.Equal(ReferenceType.Schema, schema.Reference.Type);
|
|
Assert.Equal(complex.FullTypeName(), schema.Reference.Id);
|
|
}
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(true)]
|
|
[InlineData(false)]
|
|
public void CreateEdmTypeSchemaReturnSchemaForEntityType(bool isNullable)
|
|
{
|
|
// Arrange
|
|
IEdmModel model = EdmModelHelper.TripServiceModel;
|
|
IEdmEntityType entity = model.SchemaElements.OfType<IEdmEntityType>().First(c => c.Name == "Manager");
|
|
Assert.NotNull(entity); // guard
|
|
IEdmEntityTypeReference entityTypeReference = new EdmEntityTypeReference(entity, isNullable);
|
|
ODataContext context = new ODataContext(model);
|
|
|
|
// Act
|
|
var schema = context.CreateEdmTypeSchema(entityTypeReference);
|
|
|
|
// & Assert
|
|
Assert.NotNull(schema);
|
|
|
|
if (isNullable)
|
|
{
|
|
Assert.Null(schema.Reference);
|
|
Assert.NotNull(schema.AnyOf);
|
|
Assert.NotEmpty(schema.AnyOf);
|
|
var anyOf = Assert.Single(schema.AnyOf);
|
|
Assert.NotNull(anyOf.Reference);
|
|
Assert.Equal(ReferenceType.Schema, anyOf.Reference.Type);
|
|
Assert.Equal(entity.FullTypeName(), anyOf.Reference.Id);
|
|
}
|
|
else
|
|
{
|
|
Assert.Null(schema.AnyOf);
|
|
Assert.NotNull(schema.Reference);
|
|
Assert.Equal(ReferenceType.Schema, schema.Reference.Type);
|
|
Assert.Equal(entity.FullTypeName(), schema.Reference.Id);
|
|
}
|
|
}
|
|
|
|
#region Primitive type schema
|
|
|
|
[Theory]
|
|
[InlineData(true)]
|
|
[InlineData(false)]
|
|
public void CreateEdmTypeSchemaReturnSchemaForString(bool isNullable)
|
|
{
|
|
// Arrange
|
|
IEdmModel model = EdmCoreModel.Instance;
|
|
ODataContext context = new ODataContext(model);
|
|
IEdmTypeReference edmTypeReference = EdmCoreModel.Instance.GetString(isNullable);
|
|
|
|
// Act
|
|
var schema = context.CreateEdmTypeSchema(edmTypeReference);
|
|
Assert.NotNull(schema); // guard
|
|
string json = schema.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
|
|
|
// & Assert
|
|
if (isNullable)
|
|
{
|
|
Assert.Equal(@"{
|
|
""type"": ""string"",
|
|
""nullable"": true
|
|
}".ChangeLineBreaks(), json);
|
|
}
|
|
else
|
|
{
|
|
Assert.Equal(@"{
|
|
""type"": ""string""
|
|
}".ChangeLineBreaks(), json);
|
|
}
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(true)]
|
|
[InlineData(false)]
|
|
public void CreateEdmTypeSchemaReturnSchemaForInt32(bool isNullable)
|
|
{
|
|
// Arrange
|
|
IEdmModel model = EdmCoreModel.Instance;
|
|
ODataContext context = new ODataContext(model);
|
|
IEdmTypeReference edmTypeReference = EdmCoreModel.Instance.GetInt32(isNullable);
|
|
|
|
// Act
|
|
var schema = context.CreateEdmTypeSchema(edmTypeReference);
|
|
Assert.NotNull(schema); // guard
|
|
string json = schema.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
|
|
|
// & Assert
|
|
if (isNullable)
|
|
{
|
|
Assert.Equal(@"{
|
|
""maximum"": 2147483647,
|
|
""minimum"": -2147483648,
|
|
""type"": ""integer"",
|
|
""format"": ""int32"",
|
|
""nullable"": true
|
|
}".ChangeLineBreaks(), json);
|
|
}
|
|
else
|
|
{
|
|
Assert.Equal(@"{
|
|
""maximum"": 2147483647,
|
|
""minimum"": -2147483648,
|
|
""type"": ""integer"",
|
|
""format"": ""int32""
|
|
}".ChangeLineBreaks(), json);
|
|
}
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(true, true)]
|
|
[InlineData(true, false)]
|
|
[InlineData(false, true)]
|
|
[InlineData(false, false)]
|
|
public void CreateEdmTypeSchemaReturnSchemaForDecimal(bool isNullable, bool IEEE754Compatible)
|
|
{
|
|
// Arrange
|
|
IEdmModel model = EdmCoreModel.Instance;
|
|
OpenApiConvertSettings settings = new OpenApiConvertSettings
|
|
{
|
|
IEEE754Compatible = IEEE754Compatible
|
|
};
|
|
|
|
ODataContext context = new ODataContext(model, settings);
|
|
IEdmTypeReference edmTypeReference = EdmCoreModel.Instance.GetDecimal(isNullable);
|
|
|
|
// Act
|
|
var schema = context.CreateEdmTypeSchema(edmTypeReference);
|
|
Assert.NotNull(schema); // guard
|
|
|
|
// & Assert
|
|
if (IEEE754Compatible)
|
|
{
|
|
Assert.Null(schema.Type);
|
|
Assert.NotNull(schema.AnyOf);
|
|
Assert.Equal(2, schema.AnyOf.Count);
|
|
Assert.Equal(new[] { "number", "string" }, schema.AnyOf.Select(a => a.Type));
|
|
}
|
|
else
|
|
{
|
|
Assert.Equal("number", schema.Type);
|
|
Assert.Null(schema.AnyOf);
|
|
}
|
|
|
|
Assert.Equal(isNullable, schema.Nullable);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(true, true)]
|
|
[InlineData(true, false)]
|
|
[InlineData(false, true)]
|
|
[InlineData(false, false)]
|
|
public void CreateEdmTypeSchemaReturnSchemaForInt64(bool isNullable, bool IEEE754Compatible)
|
|
{
|
|
// Arrange
|
|
IEdmModel model = EdmCoreModel.Instance;
|
|
OpenApiConvertSettings settings = new OpenApiConvertSettings
|
|
{
|
|
IEEE754Compatible = IEEE754Compatible
|
|
};
|
|
|
|
ODataContext context = new ODataContext(model, settings);
|
|
IEdmTypeReference edmTypeReference = EdmCoreModel.Instance.GetInt64(isNullable);
|
|
|
|
// Act
|
|
var schema = context.CreateEdmTypeSchema(edmTypeReference);
|
|
Assert.NotNull(schema); // guard
|
|
|
|
// & Assert
|
|
if (IEEE754Compatible)
|
|
{
|
|
Assert.Null(schema.Type);
|
|
Assert.NotNull(schema.AnyOf);
|
|
Assert.Equal(2, schema.AnyOf.Count);
|
|
Assert.Equal(new[] { "integer", "string" }, schema.AnyOf.Select(a => a.Type));
|
|
}
|
|
else
|
|
{
|
|
Assert.Equal("integer", schema.Type);
|
|
Assert.Null(schema.AnyOf);
|
|
}
|
|
|
|
Assert.Equal(isNullable, schema.Nullable);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(true)]
|
|
[InlineData(false)]
|
|
public void CreateEdmTypeSchemaReturnSchemaForGuid(bool isNullable)
|
|
{
|
|
// Arrange
|
|
IEdmModel model = EdmCoreModel.Instance;
|
|
ODataContext context = new ODataContext(model);
|
|
IEdmTypeReference edmTypeReference = EdmCoreModel.Instance.GetGuid(isNullable);
|
|
|
|
// Act
|
|
var schema = context.CreateEdmTypeSchema(edmTypeReference);
|
|
Assert.NotNull(schema); // guard
|
|
string json = schema.SerializeAsJson(OpenApiSpecVersion.OpenApi3_0);
|
|
|
|
// & Assert
|
|
if (isNullable)
|
|
{
|
|
Assert.Equal(@"{
|
|
""pattern"": ""^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"",
|
|
""type"": ""string"",
|
|
""format"": ""uuid"",
|
|
""nullable"": true
|
|
}".ChangeLineBreaks(), json);
|
|
}
|
|
else
|
|
{
|
|
Assert.Equal(@"{
|
|
""pattern"": ""^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$"",
|
|
""type"": ""string"",
|
|
""format"": ""uuid""
|
|
}".ChangeLineBreaks(), json);
|
|
}
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(true)]
|
|
[InlineData(false)]
|
|
public void CreateEdmTypeSchemaReturnSchemaForDouble(bool isNullable)
|
|
{
|
|
// Arrange
|
|
IEdmModel model = EdmCoreModel.Instance;
|
|
ODataContext context = new ODataContext(model);
|
|
IEdmTypeReference edmTypeReference = EdmCoreModel.Instance.GetDouble(isNullable);
|
|
|
|
// Act
|
|
var schema = context.CreateEdmTypeSchema(edmTypeReference);
|
|
Assert.NotNull(schema); // guard
|
|
|
|
// & Assert
|
|
Assert.Null(schema.Type);
|
|
|
|
Assert.Equal("double", schema.Format);
|
|
Assert.Equal(isNullable, schema.Nullable);
|
|
|
|
Assert.NotNull(schema.OneOf);
|
|
Assert.Equal(3, schema.OneOf.Count);
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(true)]
|
|
[InlineData(false)]
|
|
public void CreateEdmTypeSchemaReturnSchemaForSingle(bool isNullable)
|
|
{
|
|
// Arrange
|
|
IEdmModel model = EdmCoreModel.Instance;
|
|
ODataContext context = new ODataContext(model);
|
|
IEdmTypeReference edmTypeReference = EdmCoreModel.Instance.GetSingle(isNullable);
|
|
|
|
// Act
|
|
var schema = context.CreateEdmTypeSchema(edmTypeReference);
|
|
Assert.NotNull(schema); // guard
|
|
|
|
// & Assert
|
|
Assert.Null(schema.Type);
|
|
|
|
Assert.Equal("float", schema.Format);
|
|
Assert.Equal(isNullable, schema.Nullable);
|
|
|
|
Assert.NotNull(schema.OneOf);
|
|
Assert.Equal(3, schema.OneOf.Count);
|
|
}
|
|
#endregion
|
|
}
|
|
}
|