Fix paths when operation is bound to a type derived from the type of a
navigation property. (#88)
This commit is contained in:
parent
1643ba5ea1
commit
e1763727f5
|
@ -0,0 +1,4 @@
|
|||
[*.{cs,vb}]
|
||||
|
||||
# IDE0009: Member access should be qualified.
|
||||
dotnet_diagnostic.IDE0009.severity = none
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.26730.3
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.30907.101
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.OpenApi.OData.Reader", "src\Microsoft.OpenApi.OData.Reader\Microsoft.OpenApi.OData.Reader.csproj", "{FF3ACD93-19E0-486C-9C0F-FA1C2E7FC8C2}"
|
||||
EndProject
|
||||
|
@ -11,6 +11,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OoasUtil", "src\OoasUtil\Oo
|
|||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OoasGui", "src\OoasGui\OoasGui.csproj", "{79B190E8-EDB0-4C03-8FD8-EB48E4807CFB}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{99C5C9A7-63FD-4E78-96E8-69C402868C3E}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
|
@ -24,7 +24,8 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
/// Generate the list of <see cref="ODataPath"/> based on the given <see cref="IEdmModel"/>.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="settings">The conversion settings.</param>
|
||||
/// <returns>The collection of built <see cref="ODataPath"/>.</returns>
|
||||
IEnumerable<ODataPath> GetPaths(IEdmModel model);
|
||||
IEnumerable<ODataPath> GetPaths(IEdmModel model, OpenApiConvertSettings settings);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -158,7 +158,7 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
/// <returns>All acceptable OData path.</returns>
|
||||
private IEnumerable<ODataPath> LoadAllODataPaths()
|
||||
{
|
||||
IEnumerable<ODataPath> allPaths = _pathProvider.GetPaths(Model);
|
||||
IEnumerable<ODataPath> allPaths = _pathProvider.GetPaths(Model, Settings);
|
||||
foreach (var path in allPaths)
|
||||
{
|
||||
if ((path.Kind == ODataPathKind.Operation && !Settings.EnableOperationPath) ||
|
||||
|
|
|
@ -3,10 +3,12 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Vocabularies;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Edm
|
||||
{
|
||||
|
@ -38,8 +40,9 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
/// Generate the list of <see cref="ODataPath"/> based on the given <see cref="IEdmModel"/>.
|
||||
/// </summary>
|
||||
/// <param name="model">The Edm model.</param>
|
||||
/// <param name="settings">The conversion settings.</param>
|
||||
/// <returns>The collection of built <see cref="ODataPath"/>.</returns>
|
||||
public virtual IEnumerable<ODataPath> GetPaths(IEdmModel model)
|
||||
public virtual IEnumerable<ODataPath> GetPaths(IEdmModel model, OpenApiConvertSettings settings)
|
||||
{
|
||||
if (model == null || model.EntityContainer == null)
|
||||
{
|
||||
|
@ -67,7 +70,7 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
}
|
||||
|
||||
// bound operations
|
||||
RetrieveBoundOperationPaths();
|
||||
RetrieveBoundOperationPaths(settings);
|
||||
|
||||
// unbound operations
|
||||
foreach (IEdmOperationImport import in _model.EntityContainer.OperationImports())
|
||||
|
@ -338,7 +341,7 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
/// <summary>
|
||||
/// Retrieve all bounding <see cref="IEdmOperation"/>.
|
||||
/// </summary>
|
||||
private void RetrieveBoundOperationPaths()
|
||||
private void RetrieveBoundOperationPaths(OpenApiConvertSettings convertSettings)
|
||||
{
|
||||
foreach (var edmOperation in _model.GetAllElements().OfType<IEdmOperation>().Where(e => e.IsBound))
|
||||
{
|
||||
|
@ -396,10 +399,17 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
}
|
||||
|
||||
// 3. Search for derived
|
||||
if (AppendBoundOperationOnDerived(edmOperation, isCollection, bindingEntityType))
|
||||
if (AppendBoundOperationOnDerived(edmOperation, isCollection, bindingEntityType, convertSettings))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// 4. Search for derived generated navigation property
|
||||
if (AppendBoundOperationOnDerivedNavigationPropertyPath(edmOperation, isCollection, bindingEntityType, convertSettings))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -477,7 +487,11 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
return found;
|
||||
}
|
||||
|
||||
private bool AppendBoundOperationOnDerived(IEdmOperation edmOperation, bool isCollection, IEdmEntityType bindingEntityType)
|
||||
private bool AppendBoundOperationOnDerived(
|
||||
IEdmOperation edmOperation,
|
||||
bool isCollection,
|
||||
IEdmEntityType bindingEntityType,
|
||||
OpenApiConvertSettings convertSettings)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
|
@ -488,6 +502,14 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
{
|
||||
foreach (var ns in baseNavigationSource)
|
||||
{
|
||||
if (HasUnsatisfiedDerivedTypeConstraint(
|
||||
ns as IEdmVocabularyAnnotatable,
|
||||
baseType,
|
||||
convertSettings))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isCollection)
|
||||
{
|
||||
if (ns is IEdmEntitySet)
|
||||
|
@ -523,5 +545,84 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
return found;
|
||||
}
|
||||
|
||||
private bool HasUnsatisfiedDerivedTypeConstraint(
|
||||
IEdmVocabularyAnnotatable annotatable,
|
||||
IEdmEntityType baseType,
|
||||
OpenApiConvertSettings convertSettings)
|
||||
{
|
||||
return convertSettings.RequireDerivedTypesConstraintForBoundOperations &&
|
||||
!(_model.GetCollection(annotatable, "Org.OData.Validation.V1.DerivedTypeConstraint") ?? Enumerable.Empty<string>())
|
||||
.Any(c => c.Equals(baseType.FullName(), StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
private bool AppendBoundOperationOnDerivedNavigationPropertyPath(
|
||||
IEdmOperation edmOperation,
|
||||
bool isCollection,
|
||||
IEdmEntityType bindingEntityType,
|
||||
OpenApiConvertSettings convertSettings)
|
||||
{
|
||||
bool found = false;
|
||||
bool isEscapedFunction = _model.IsUrlEscapeFunction(edmOperation);
|
||||
|
||||
foreach (var baseType in bindingEntityType.FindAllBaseTypes())
|
||||
{
|
||||
if (_allNavigationPropertyPaths.TryGetValue(baseType, out IList<ODataPath> paths))
|
||||
{
|
||||
foreach (var path in paths)
|
||||
{
|
||||
if (path.Kind == ODataPathKind.Ref)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var npSegment = path.Segments.Last(s => s is ODataNavigationPropertySegment)
|
||||
as ODataNavigationPropertySegment;
|
||||
if (npSegment == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isLastKeySegment = path.LastSegment is ODataKeySegment;
|
||||
|
||||
if (isCollection)
|
||||
{
|
||||
if (isLastKeySegment)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (npSegment.NavigationProperty.TargetMultiplicity() != EdmMultiplicity.Many)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!isLastKeySegment && npSegment.NavigationProperty.TargetMultiplicity() ==
|
||||
EdmMultiplicity.Many)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (HasUnsatisfiedDerivedTypeConstraint(
|
||||
npSegment.NavigationProperty as IEdmVocabularyAnnotatable,
|
||||
baseType,
|
||||
convertSettings))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ODataPath newPath = path.Clone();
|
||||
newPath.Push(new ODataTypeCastSegment(bindingEntityType));
|
||||
newPath.Push(new ODataOperationSegment(edmOperation, isEscapedFunction));
|
||||
AppendPath(newPath);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -161,6 +161,13 @@ namespace Microsoft.OpenApi.OData
|
|||
/// </summary>
|
||||
public bool ShowSchemaExamples { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets a value indicating whether or not to require the
|
||||
/// Validation.DerivedTypeConstraint to be applied to NavigationSources
|
||||
/// to bind operations of derived types to them.
|
||||
/// </summary>
|
||||
public bool RequireDerivedTypesConstraintForBoundOperations { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets/sets a value indicating whether or not to show the root path of the described API.
|
||||
/// </summary>
|
||||
|
@ -197,6 +204,7 @@ namespace Microsoft.OpenApi.OData
|
|||
EnableDerivedTypesReferencesForRequestBody = this.EnableDerivedTypesReferencesForRequestBody,
|
||||
RoutePathPrefixProvider = this.RoutePathPrefixProvider,
|
||||
ShowLinks = this.ShowLinks,
|
||||
RequireDerivedTypesConstraintForBoundOperations = this.RequireDerivedTypesConstraintForBoundOperations,
|
||||
ShowSchemaExamples = this.ShowSchemaExamples,
|
||||
ShowRootPath = this.ShowRootPath,
|
||||
PathProvider = this.PathProvider
|
||||
|
|
|
@ -71,6 +71,9 @@
|
|||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<None Include="..\..\.editorconfig">
|
||||
<Link>.editorconfig</Link>
|
||||
</None>
|
||||
<None Include="packages.config" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
|
|
|
@ -74,22 +74,29 @@ namespace OoasUtil
|
|||
/// Set the output to expect all derived types in request bodies.
|
||||
/// </summary>
|
||||
public bool? DerivedTypesReferencesForRequestBody { get; private set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Set the output to expose pagination for collections.
|
||||
/// </summary>
|
||||
public bool? EnablePagination { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// tSet the output to use unqualified calls for bound operations.
|
||||
/// Set the output to use unqualified calls for bound operations.
|
||||
/// </summary>
|
||||
public bool? EnableUnqualifiedCall { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// tDisable examples in the schema.
|
||||
/// Disable examples in the schema.
|
||||
/// </summary>
|
||||
public bool? DisableSchemaExamples { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets a value indicating whether or not to require the
|
||||
/// Validation.DerivedTypeConstraint to be applied to NavigationSources
|
||||
/// to bind operations of derived types to them.
|
||||
/// </summary>
|
||||
public bool? RequireDerivedTypesConstraint { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Process the arguments.
|
||||
/// </summary>
|
||||
|
@ -186,6 +193,14 @@ namespace OoasUtil
|
|||
}
|
||||
break;
|
||||
|
||||
case "--requireDerivedTypesConstraint":
|
||||
case "-rdt":
|
||||
if (!ProcessRequireDerivedTypesConstraint(true))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case "--enablepagination":
|
||||
case "-p":
|
||||
if (!ProcessEnablePagination(true))
|
||||
|
@ -248,6 +263,11 @@ namespace OoasUtil
|
|||
DerivedTypesReferencesForRequestBody = false;
|
||||
}
|
||||
|
||||
if (RequireDerivedTypesConstraint == null)
|
||||
{
|
||||
RequireDerivedTypesConstraint = false;
|
||||
}
|
||||
|
||||
if (EnablePagination == null)
|
||||
{
|
||||
EnablePagination = false;
|
||||
|
@ -345,6 +365,19 @@ namespace OoasUtil
|
|||
return true;
|
||||
}
|
||||
|
||||
private bool ProcessRequireDerivedTypesConstraint(bool requireDerivedTypesConstraint)
|
||||
{
|
||||
if (RequireDerivedTypesConstraint != null)
|
||||
{
|
||||
Console.WriteLine("[Error:] Multiple [--requireDerivedTypesConstraint|-rdt] are not allowed.\n");
|
||||
PrintUsage();
|
||||
return false;
|
||||
}
|
||||
|
||||
RequireDerivedTypesConstraint = requireDerivedTypesConstraint;
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool ProcessEnablePagination(bool enablePagination)
|
||||
{
|
||||
if (EnablePagination != null)
|
||||
|
@ -445,6 +478,7 @@ namespace OoasUtil
|
|||
sb.Append(" --keyassegment|-k\t\t\tSet the output to use key-as-segment style URLs.\n");
|
||||
sb.Append(" --derivedtypesreferencesforresponses|-drs\t\t\tSet the output to produce all derived types in responses.\n");
|
||||
sb.Append(" --derivedtypesreferencesforrequestbody|-drq\t\t\tSet the output to expect all derived types in request bodies.\n");
|
||||
sb.Append(" --requireDerivedTypesConstraint|-rdt\t\t\tSet the output to require derived type constraint to bind Operations.\n");
|
||||
sb.Append(" --enablepagination|-p\t\t\tSet the output to expose pagination for collections.\n");
|
||||
sb.Append(" --enableunqualifiedcall|-u\t\t\tSet the output to use unqualified calls for bound operations.\n");
|
||||
sb.Append(" --disableschemaexamples|-x\t\t\tDisable examples in the schema.\n");
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace OoasUtil
|
|||
EnableKeyAsSegment = processer.KeyAsSegment,
|
||||
EnableDerivedTypesReferencesForResponses = processer.DerivedTypesReferencesForResponses.Value,
|
||||
EnableDerivedTypesReferencesForRequestBody = processer.DerivedTypesReferencesForRequestBody.Value,
|
||||
RequireDerivedTypesConstraintForBoundOperations = processer.RequireDerivedTypesConstraint.Value,
|
||||
EnablePagination = processer.EnablePagination.Value,
|
||||
EnableUnqualifiedCall = processer.EnableUnqualifiedCall.Value,
|
||||
ShowSchemaExamples = !processer.DisableSchemaExamples.Value,
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
using Microsoft.OData.Edm.Validation;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
||||
|
@ -23,9 +25,10 @@ namespace Microsoft.OpenApi.OData.Edm.Tests
|
|||
// Arrange
|
||||
IEdmModel model = new EdmModel();
|
||||
ODataPathProvider provider = new ODataPathProvider();
|
||||
var settings = new OpenApiConvertSettings();
|
||||
|
||||
// Act
|
||||
var paths = provider.GetPaths(model);
|
||||
var paths = provider.GetPaths(model, settings);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(paths);
|
||||
|
@ -37,25 +40,174 @@ namespace Microsoft.OpenApi.OData.Edm.Tests
|
|||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.GraphBetaModel;
|
||||
var settings = new OpenApiConvertSettings();
|
||||
ODataPathProvider provider = new ODataPathProvider();
|
||||
|
||||
// Act
|
||||
var paths = provider.GetPaths(model);
|
||||
var paths = provider.GetPaths(model, settings);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(paths);
|
||||
Assert.Equal(4887, paths.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetPathsForGraphBetaModelWithDerivedTypesConstraintReturnsAllPaths()
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.GraphBetaModel;
|
||||
ODataPathProvider provider = new ODataPathProvider();
|
||||
var settings = new OpenApiConvertSettings
|
||||
{
|
||||
RequireDerivedTypesConstraintForBoundOperations = true
|
||||
};
|
||||
|
||||
// Act
|
||||
var paths = provider.GetPaths(model, settings);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(paths);
|
||||
Assert.Equal(4544, paths.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetPathsForInheritanceModelWithoutDerivedTypesConstraintReturnsMore()
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = GetInheritanceModel(string.Empty);
|
||||
ODataPathProvider provider = new ODataPathProvider();
|
||||
var settings = new OpenApiConvertSettings();
|
||||
|
||||
// Act
|
||||
var paths = provider.GetPaths(model, settings);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(paths);
|
||||
Assert.Equal(3, paths.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetPathsForInheritanceModelWithDerivedTypesConstraintNoAnnotationReturnsFewer()
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = GetInheritanceModel(string.Empty);
|
||||
ODataPathProvider provider = new ODataPathProvider();
|
||||
var settings = new OpenApiConvertSettings
|
||||
{
|
||||
RequireDerivedTypesConstraintForBoundOperations = true
|
||||
};
|
||||
|
||||
// Act
|
||||
var paths = provider.GetPaths(model, settings);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(paths);
|
||||
Assert.Equal(2, paths.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetPathsForInheritanceModelWithDerivedTypesConstraintWithAnnotationReturnsMore()
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = GetInheritanceModel(@"
|
||||
<Annotation Term=""Org.OData.Validation.V1.DerivedTypeConstraint"">
|
||||
<Collection>
|
||||
<String>NS.Customer</String>
|
||||
<String>NS.NiceCustomer</String>
|
||||
</Collection>
|
||||
</Annotation>");
|
||||
ODataPathProvider provider = new ODataPathProvider();
|
||||
var settings = new OpenApiConvertSettings
|
||||
{
|
||||
RequireDerivedTypesConstraintForBoundOperations = true
|
||||
};
|
||||
|
||||
// Act
|
||||
var paths = provider.GetPaths(model, settings);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(3, paths.Count());
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
// Super useful for debugging tests.
|
||||
private string ListToString(IEnumerable<ODataPath> paths)
|
||||
{
|
||||
return string.Join(Environment.NewLine,
|
||||
paths.Select(p => string.Join("/", p.Segments.Select(s => s.Identifier))));
|
||||
}
|
||||
#endif
|
||||
|
||||
[Fact]
|
||||
public void GetPathsForNavPropModelWithoutDerivedTypesConstraintReturnsMore()
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = GetNavPropModel(string.Empty);
|
||||
ODataPathProvider provider = new ODataPathProvider();
|
||||
var settings = new OpenApiConvertSettings();
|
||||
|
||||
// Act
|
||||
var paths = provider.GetPaths(model, settings);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(paths);
|
||||
Assert.Equal(4, paths.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetPathsForNavPropModelWithDerivedTypesConstraintNoAnnotationReturnsFewer()
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = GetNavPropModel(string.Empty);
|
||||
ODataPathProvider provider = new ODataPathProvider();
|
||||
var settings = new OpenApiConvertSettings
|
||||
{
|
||||
RequireDerivedTypesConstraintForBoundOperations = true
|
||||
};
|
||||
|
||||
// Act
|
||||
var paths = provider.GetPaths(model, settings);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(paths);
|
||||
Assert.Equal(3, paths.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetPathsForNavPropModelWithDerivedTypesConstraintWithAnnotationReturnsMore()
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = GetNavPropModel(@"
|
||||
<Annotation Term=""Org.OData.Validation.V1.DerivedTypeConstraint"">
|
||||
<Collection>
|
||||
<String>NS.Customer</String>
|
||||
<String>NS.NiceCustomer</String>
|
||||
</Collection>
|
||||
</Annotation>");
|
||||
ODataPathProvider provider = new ODataPathProvider();
|
||||
var settings = new OpenApiConvertSettings
|
||||
{
|
||||
RequireDerivedTypesConstraintForBoundOperations = true
|
||||
};
|
||||
|
||||
// Act
|
||||
var paths = provider.GetPaths(model, settings);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(paths);
|
||||
Assert.Equal(4, paths.Count());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetPathsForSingleEntitySetWorks()
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = GetEdmModel("", "");
|
||||
ODataPathProvider provider = new ODataPathProvider();
|
||||
var settings = new OpenApiConvertSettings();
|
||||
|
||||
// Act
|
||||
var paths = provider.GetPaths(model);
|
||||
var paths = provider.GetPaths(model, settings);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(paths);
|
||||
|
@ -69,9 +221,10 @@ namespace Microsoft.OpenApi.OData.Edm.Tests
|
|||
// Arrange
|
||||
IEdmModel model = GetEdmModel("", @"<Singleton Name=""Me"" Type=""NS.Customer"" />");
|
||||
ODataPathProvider provider = new ODataPathProvider();
|
||||
var settings = new OpenApiConvertSettings();
|
||||
|
||||
// Act
|
||||
var paths = provider.GetPaths(model);
|
||||
var paths = provider.GetPaths(model, settings);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(paths);
|
||||
|
@ -90,9 +243,10 @@ namespace Microsoft.OpenApi.OData.Edm.Tests
|
|||
</Function>";
|
||||
IEdmModel model = GetEdmModel(boundFunction, "");
|
||||
ODataPathProvider provider = new ODataPathProvider();
|
||||
var settings = new OpenApiConvertSettings();
|
||||
|
||||
// Act
|
||||
var paths = provider.GetPaths(model);
|
||||
var paths = provider.GetPaths(model, settings);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(paths);
|
||||
|
@ -111,9 +265,10 @@ namespace Microsoft.OpenApi.OData.Edm.Tests
|
|||
</Action>";
|
||||
IEdmModel model = GetEdmModel(boundAction, "");
|
||||
ODataPathProvider provider = new ODataPathProvider();
|
||||
var settings = new OpenApiConvertSettings();
|
||||
|
||||
// Act
|
||||
var paths = provider.GetPaths(model);
|
||||
var paths = provider.GetPaths(model, settings);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(paths);
|
||||
|
@ -137,9 +292,10 @@ namespace Microsoft.OpenApi.OData.Edm.Tests
|
|||
IEdmModel model = GetEdmModel(boundAction, unbounds);
|
||||
|
||||
ODataPathProvider provider = new ODataPathProvider();
|
||||
var settings = new OpenApiConvertSettings();
|
||||
|
||||
// Act
|
||||
var paths = provider.GetPaths(model);
|
||||
var paths = provider.GetPaths(model, settings);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(paths);
|
||||
|
@ -165,9 +321,10 @@ namespace Microsoft.OpenApi.OData.Edm.Tests
|
|||
IEdmModel model = GetEdmModel(entityType, entitySet);
|
||||
|
||||
ODataPathProvider provider = new ODataPathProvider();
|
||||
var settings = new OpenApiConvertSettings();
|
||||
|
||||
// Act
|
||||
var paths = provider.GetPaths(model);
|
||||
var paths = provider.GetPaths(model, settings);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(paths);
|
||||
|
@ -196,9 +353,10 @@ namespace Microsoft.OpenApi.OData.Edm.Tests
|
|||
string entitySet = @"<EntitySet Name=""Orders"" EntityType=""NS.Order"" />";
|
||||
IEdmModel model = GetEdmModel(entityType, entitySet);
|
||||
ODataPathProvider provider = new ODataPathProvider();
|
||||
var settings = new OpenApiConvertSettings();
|
||||
|
||||
// Act
|
||||
var paths = provider.GetPaths(model);
|
||||
var paths = provider.GetPaths(model, settings);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(paths);
|
||||
|
@ -220,9 +378,10 @@ namespace Microsoft.OpenApi.OData.Edm.Tests
|
|||
// Arrange
|
||||
IEdmModel model = GetEdmModel(hasStream, streamPropName);
|
||||
ODataPathProvider provider = new ODataPathProvider();
|
||||
var settings = new OpenApiConvertSettings();
|
||||
|
||||
// Act
|
||||
var paths = provider.GetPaths(model);
|
||||
var paths = provider.GetPaths(model,settings);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(paths);
|
||||
|
@ -250,7 +409,7 @@ namespace Microsoft.OpenApi.OData.Edm.Tests
|
|||
|
||||
private static IEdmModel GetEdmModel(string schemaElement, string containerElement)
|
||||
{
|
||||
string template = @"<?xml version=""1.0"" encoding=""utf-16""?>
|
||||
string template = $@"<?xml version=""1.0"" encoding=""utf-16""?>
|
||||
<Schema Namespace=""NS"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
|
||||
<EntityType Name=""Customer"">
|
||||
<Key>
|
||||
|
@ -258,15 +417,76 @@ namespace Microsoft.OpenApi.OData.Edm.Tests
|
|||
</Key>
|
||||
<Property Name=""ID"" Type=""Edm.Int32"" Nullable=""false"" />
|
||||
</EntityType>
|
||||
{0}
|
||||
{schemaElement}
|
||||
<EntityContainer Name =""Default"">
|
||||
<EntitySet Name=""Customers"" EntityType=""NS.Customer"" />
|
||||
{1}
|
||||
{containerElement}
|
||||
</EntityContainer>
|
||||
</Schema>";
|
||||
string schema = string.Format(template, schemaElement, containerElement);
|
||||
bool parsed = SchemaReader.TryParse(new XmlReader[] { XmlReader.Create(new StringReader(schema)) }, out IEdmModel parsedModel, out _);
|
||||
Assert.True(parsed);
|
||||
return GetEdmModel(template);
|
||||
}
|
||||
|
||||
private static IEdmModel GetInheritanceModel(string annotation)
|
||||
{
|
||||
string template = $@"<?xml version=""1.0"" encoding=""utf-16""?>
|
||||
<Schema Namespace=""NS"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
|
||||
<EntityType Name=""Customer"">
|
||||
<Key>
|
||||
<PropertyRef Name=""ID"" />
|
||||
</Key>
|
||||
<Property Name=""ID"" Type=""Edm.Int32"" Nullable=""false"" />
|
||||
</EntityType>
|
||||
<EntityType Name=""NiceCustomer"" BaseType=""NS.Customer"">
|
||||
<Property Name=""Other"" Type=""Edm.Int32"" Nullable=""true"" />
|
||||
</EntityType>
|
||||
<Action Name=""Ack"" IsBound=""true"" >
|
||||
<Parameter Name = ""bindingParameter"" Type=""NS.NiceCustomer"" />
|
||||
</Action>
|
||||
<EntityContainer Name =""Default"">
|
||||
<EntitySet Name=""Customers"" EntityType=""NS.Customer"">
|
||||
{annotation}
|
||||
</EntitySet>
|
||||
</EntityContainer>
|
||||
</Schema>";
|
||||
return GetEdmModel(template);
|
||||
}
|
||||
|
||||
private static IEdmModel GetNavPropModel(string annotation)
|
||||
{
|
||||
string template = $@"<?xml version=""1.0"" encoding=""utf-16""?>
|
||||
<Schema Namespace=""NS"" xmlns=""http://docs.oasis-open.org/odata/ns/edm"">
|
||||
<EntityType Name=""Root"">
|
||||
<Key>
|
||||
<PropertyRef Name=""ID"" />
|
||||
</Key>
|
||||
<Property Name=""ID"" Type=""Edm.Int32"" Nullable=""false"" />
|
||||
<NavigationProperty Name=""Customers"" Type=""Collection(NS.Customer)"" ContainsTarget=""true"">
|
||||
{annotation}
|
||||
</NavigationProperty>
|
||||
</EntityType>
|
||||
<EntityType Name=""Customer"">
|
||||
<Key>
|
||||
<PropertyRef Name=""ID"" />
|
||||
</Key>
|
||||
<Property Name=""ID"" Type=""Edm.Int32"" Nullable=""false"" />
|
||||
</EntityType>
|
||||
<EntityType Name=""NiceCustomer"" BaseType=""NS.Customer"">
|
||||
<Property Name=""Other"" Type=""Edm.Int32"" Nullable=""true"" />
|
||||
</EntityType>
|
||||
<Action Name=""Ack"" IsBound=""true"" >
|
||||
<Parameter Name = ""bindingParameter"" Type=""NS.NiceCustomer"" />
|
||||
</Action>
|
||||
<EntityContainer Name =""Default"">
|
||||
<Singleton Name=""Root"" Type=""NS.Root"" />
|
||||
</EntityContainer>
|
||||
</Schema>";
|
||||
return GetEdmModel(template);
|
||||
}
|
||||
|
||||
private static IEdmModel GetEdmModel(string schema)
|
||||
{
|
||||
bool parsed = SchemaReader.TryParse(new XmlReader[] { XmlReader.Create(new StringReader(schema)) }, out IEdmModel parsedModel, out IEnumerable<EdmError> errors);
|
||||
Assert.True(parsed, $"Parse failure. {string.Join(Environment.NewLine, errors.Select(e => e.ToString()))}");
|
||||
return parsedModel;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue