refactor the operation handler
This commit is contained in:
parent
009ca7fef3
commit
0f8b01df3e
|
@ -0,0 +1,32 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Common
|
||||
{
|
||||
internal static class CryptographyExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Calculates the MD5 hash for the given string.
|
||||
/// </summary>
|
||||
/// <returns>A 32 char long hash.</returns>
|
||||
public static string GetHashMd5(this string input)
|
||||
{
|
||||
Utils.CheckArgumentNull(input, nameof(input));
|
||||
|
||||
var hasher = new MD5CryptoServiceProvider();
|
||||
var inputBytes = Encoding.UTF8.GetBytes(input);
|
||||
var hashBytes = hasher.ComputeHash(inputBytes);
|
||||
var hash = new StringBuilder();
|
||||
foreach (var b in hashBytes)
|
||||
{
|
||||
hash.Append(string.Format("{0:x2}", b));
|
||||
}
|
||||
return hash.ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,6 +3,9 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Common;
|
||||
|
||||
|
@ -31,6 +34,40 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
public override ODataSegmentKind Kind => ODataSegmentKind.OperationImport;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string GetPathItemName(OpenApiConvertSettings settings) => OperationImport.Name;
|
||||
public override string GetPathItemName(OpenApiConvertSettings settings)
|
||||
{
|
||||
Utils.CheckArgumentNull(settings, nameof(settings));
|
||||
|
||||
if (OperationImport.IsFunctionImport())
|
||||
{
|
||||
return FunctionImportName(OperationImport as IEdmFunctionImport, settings);
|
||||
}
|
||||
|
||||
return OperationImport.Name;
|
||||
}
|
||||
|
||||
private string FunctionImportName(IEdmFunctionImport functionImport, OpenApiConvertSettings settings)
|
||||
{
|
||||
StringBuilder functionName = new StringBuilder(functionImport.Name);
|
||||
functionName.Append("(");
|
||||
|
||||
// Structured or collection-valued parameters are represented as a parameter alias in the path template
|
||||
// and the parameters array contains a Parameter Object for the parameter alias as a query option of type string.
|
||||
IEdmFunction function = functionImport.Function;
|
||||
functionName.Append(String.Join(",", function.Parameters.Select(p =>
|
||||
{
|
||||
if (p.Type.IsStructured() || p.Type.IsCollection())
|
||||
{
|
||||
return p.Name + "=@" + p.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
return p.Name + "={" + p.Name + "}";
|
||||
}
|
||||
})));
|
||||
|
||||
functionName.Append(")");
|
||||
return functionName.ToString();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,6 +36,8 @@ namespace Microsoft.OpenApi.OData.Edm
|
|||
/// <inheritdoc />
|
||||
public override string GetPathItemName(OpenApiConvertSettings settings)
|
||||
{
|
||||
Utils.CheckArgumentNull(settings, nameof(settings));
|
||||
|
||||
if (Operation.IsFunction())
|
||||
{
|
||||
return FunctionName(Operation as IEdmFunction, settings);
|
||||
|
|
|
@ -143,6 +143,62 @@ namespace Microsoft.OpenApi.OData.Generator
|
|||
return parameters;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create key parameters for the <see cref="ODataKeySegment"/>.
|
||||
/// </summary>
|
||||
/// <param name="keySegment">The key segment.</param>
|
||||
/// <returns>The created the list of <see cref="OpenApiParameter"/>.</returns>
|
||||
public static IList<OpenApiParameter> CreateKeyParameters(this ODataContext context, ODataKeySegment keySegment)
|
||||
{
|
||||
Utils.CheckArgumentNull(context, nameof(context));
|
||||
Utils.CheckArgumentNull(keySegment, nameof(keySegment));
|
||||
|
||||
IList<OpenApiParameter> parameters = new List<OpenApiParameter>();
|
||||
IEdmEntityType entityType = keySegment.EntityType;
|
||||
|
||||
IList<IEdmStructuralProperty> keys = entityType.Key().ToList();
|
||||
if (keys.Count() == 1)
|
||||
{
|
||||
string keyName = keys.First().Name;
|
||||
if (context.Settings.PrefixEntityTypeNameBeforeKey)
|
||||
{
|
||||
keyName = entityType.Name + "-" + keys.First().Name;
|
||||
}
|
||||
|
||||
OpenApiParameter parameter = new OpenApiParameter
|
||||
{
|
||||
Name = keyName,
|
||||
In = ParameterLocation.Path,
|
||||
Required = true,
|
||||
Description = "key: " + keyName,
|
||||
Schema = context.CreateEdmTypeSchema(keys.First().Type)
|
||||
};
|
||||
|
||||
parameter.Extensions.Add(Constants.xMsKeyType, new OpenApiString(entityType.Name));
|
||||
parameters.Add(parameter);
|
||||
}
|
||||
else
|
||||
{
|
||||
// append key parameter
|
||||
foreach (var keyProperty in entityType.Key())
|
||||
{
|
||||
OpenApiParameter parameter = new OpenApiParameter
|
||||
{
|
||||
Name = keyProperty.Name,
|
||||
In = ParameterLocation.Path,
|
||||
Required = true,
|
||||
Description = "key: " + keyProperty.Name,
|
||||
Schema = context.CreateEdmTypeSchema(keyProperty.Type)
|
||||
};
|
||||
|
||||
parameter.Extensions.Add(Constants.xMsKeyType, new OpenApiString(entityType.Name));
|
||||
parameters.Add(parameter);
|
||||
}
|
||||
}
|
||||
|
||||
return parameters;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create the $top parameter.
|
||||
/// </summary>
|
||||
|
|
|
@ -35,12 +35,24 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
/// <inheritdoc/>
|
||||
protected override void SetBasicInfo(OpenApiOperation operation)
|
||||
{
|
||||
operation.Summary = "Invoke " + (EdmOperationImport.IsActionImport() ? "action " : "function ") + EdmOperationImport.Name;
|
||||
operation.Summary = "Invoke " + (EdmOperationImport.IsActionImport() ? "actionImport " : "functionImport ") + EdmOperationImport.Name;
|
||||
|
||||
if (Context.Settings.OperationId)
|
||||
{
|
||||
string key = "OperationImport." + EdmOperationImport.Name;
|
||||
operation.OperationId += "OperationImport." + Context.GetIndex(key) + "-" + Utils.UpperFirstChar(EdmOperationImport.Name);
|
||||
|
||||
if (EdmOperationImport.IsActionImport())
|
||||
{
|
||||
operation.OperationId = "OperationImport." + EdmOperationImport.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
ODataOperationImportSegment operationImportSegment = Path.LastSegment as ODataOperationImportSegment;
|
||||
string pathItemName = operationImportSegment.GetPathItemName(Context.Settings);
|
||||
string md5 = pathItemName.GetHashMd5();
|
||||
operation.OperationId = "OperationImport." + EdmOperationImport.Name + "." + md5.Substring(8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.Any;
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
@ -57,9 +58,32 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
// OperationId
|
||||
if (Context.Settings.OperationId)
|
||||
{
|
||||
string key = NavigationSource.Name + "-" + Utils.UpperFirstChar(EdmOperation.Name);
|
||||
int index = Context.GetIndex(key);
|
||||
operation.OperationId = NavigationSource.Name + "." + index + "-" + Utils.UpperFirstChar(EdmOperation.Name);
|
||||
StringBuilder operationId = new StringBuilder(NavigationSource.Name);
|
||||
if (HasTypeCast)
|
||||
{
|
||||
ODataTypeCastSegment typeCast = Path.Segments.FirstOrDefault(s => s is ODataTypeCastSegment) as ODataTypeCastSegment;
|
||||
operationId.Append(".");
|
||||
operationId.Append(typeCast.EntityType.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
operationId.Append(".");
|
||||
operationId.Append(NavigationSource.EntityType().Name);
|
||||
}
|
||||
|
||||
operationId.Append(".");
|
||||
operationId.Append(EdmOperation.Name);
|
||||
if (EdmOperation.IsAction())
|
||||
{
|
||||
operation.OperationId = operationId.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
ODataOperationSegment operationSegment = Path.LastSegment as ODataOperationSegment;
|
||||
string pathItemName = operationSegment.GetPathItemName(Context.Settings);
|
||||
string md5 = pathItemName.GetHashMd5();
|
||||
operation.OperationId = operationId.Append(".").Append(md5.Substring(8)).ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,19 +105,6 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
protected override void SetParameters(OpenApiOperation operation)
|
||||
{
|
||||
base.SetParameters(operation);
|
||||
/*
|
||||
IEdmSingleton singleton = NavigationSource as IEdmSingleton;
|
||||
if (singleton == null && EdmOperation.IsBound)
|
||||
{
|
||||
IEdmOperationParameter bindingParameter = EdmOperation.Parameters.FirstOrDefault();
|
||||
if (bindingParameter != null &&
|
||||
!bindingParameter.Type.IsCollection() && // bound to a single entity
|
||||
bindingParameter.Type.IsEntity())
|
||||
{
|
||||
operation.Parameters = Context.CreateKeyParameters(bindingParameter
|
||||
.Type.AsEntity().EntityDefinition());
|
||||
}
|
||||
}*/
|
||||
|
||||
if (EdmOperation.IsFunction())
|
||||
{
|
||||
|
|
|
@ -36,11 +36,6 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
prefix = "List";
|
||||
}
|
||||
|
||||
/*
|
||||
string key = NavigationSource.Name + "." + NavigationProperty.Name + "-" + prefix + Utils.UpperFirstChar(NavigationProperty.ToEntityType().Name);
|
||||
int index = Context.GetIndex(key);
|
||||
operation.OperationId = NavigationSource.Name + "." + NavigationProperty.Name + index + "-" + prefix + Utils.UpperFirstChar(NavigationProperty.ToEntityType().Name);
|
||||
*/
|
||||
operation.OperationId = GetOperationId(prefix);
|
||||
}
|
||||
}
|
||||
|
@ -88,10 +83,10 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
operation.Parameters = new List<OpenApiParameter>();
|
||||
}
|
||||
|
||||
if (NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
|
||||
if (!LastSegmentIsKeySegment && NavigationProperty.TargetMultiplicity() == EdmMultiplicity.Many)
|
||||
{
|
||||
// The parameters array contains Parameter Objects for system query options allowed for this entity set,
|
||||
// and it does not list system query options not allowed for this entity set.
|
||||
// Need to verify that TopSupported or others should be applyed to navigaiton source.
|
||||
// So, how about for the navigation property.
|
||||
OpenApiParameter parameter = Context.CreateTop(NavigationProperty);
|
||||
if (parameter != null)
|
||||
{
|
||||
|
|
|
@ -28,6 +28,11 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
/// </summary>
|
||||
protected IEdmNavigationSource NavigationSource { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the navigation path.
|
||||
/// </summary>
|
||||
protected string NavigationPropertyPath { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a bool value indicating whether the last segment is a key segment.
|
||||
/// </summary>
|
||||
|
@ -48,6 +53,9 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
}
|
||||
NavigationProperty = npSegment.NavigationProperty;
|
||||
|
||||
NavigationPropertyPath = string.Join("/",
|
||||
path.Segments.OfType<ODataNavigationPropertySegment>().Select(p => p.NavigationProperty.Name));
|
||||
|
||||
base.Initialize(context, path);
|
||||
}
|
||||
|
||||
|
@ -87,7 +95,6 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
string name = string.Join(".", items);
|
||||
OpenApiTag tag = new OpenApiTag
|
||||
{
|
||||
// Name = NavigationSource.Name + "." + NavigationProperty.ToEntityType().Name,
|
||||
Name = name
|
||||
};
|
||||
tag.Extensions.Add(Constants.xMsTocType, new OpenApiString("page"));
|
||||
|
@ -109,16 +116,6 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
ODataNavigationPropertySegment npSegment = segment as ODataNavigationPropertySegment;
|
||||
if (npSegment != null)
|
||||
{
|
||||
/*
|
||||
if (npSegment.NavigationProperty == NavigationProperty)
|
||||
{
|
||||
items.Add(prefix + Utils.UpperFirstChar(NavigationProperty.ToEntityType().Name));
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
items.Add(segment.Name);
|
||||
}*/
|
||||
if (segment == lastpath)
|
||||
{
|
||||
items.Add(prefix + Utils.UpperFirstChar(npSegment.NavigationProperty.Name));
|
||||
|
|
|
@ -31,10 +31,6 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
if (Context.Settings.OperationId)
|
||||
{
|
||||
string prefix = "Update";
|
||||
//string key = NavigationSource.Name + "." + NavigationProperty.Name + "-" + prefix + Utils.UpperFirstChar(NavigationProperty.ToEntityType().Name);
|
||||
// int index = Context.GetIndex(key);
|
||||
// operation.OperationId = NavigationSource.Name + "." + NavigationProperty.Name + index + "-" + prefix + Utils.UpperFirstChar(NavigationProperty.ToEntityType().Name);
|
||||
|
||||
operation.OperationId = GetOperationId(prefix);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,11 +31,6 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
if (Context.Settings.OperationId)
|
||||
{
|
||||
string prefix = "Create";
|
||||
/*
|
||||
string key = NavigationSource.Name + "." + NavigationProperty.Name + "-" + prefix + Utils.UpperFirstChar(NavigationProperty.ToEntityType().Name);
|
||||
int index = Context.GetIndex(key);
|
||||
operation.OperationId = NavigationSource.Name + "." + NavigationProperty.Name + index + "-" + prefix + Utils.UpperFirstChar(NavigationProperty.ToEntityType().Name);
|
||||
*/
|
||||
operation.OperationId = GetOperationId(prefix);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -112,7 +112,7 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
{
|
||||
foreach (ODataKeySegment keySegment in Path.OfType<ODataKeySegment>())
|
||||
{
|
||||
foreach (var p in Context.CreateKeyParameters(keySegment.EntityType))
|
||||
foreach (var p in Context.CreateKeyParameters(keySegment))
|
||||
{
|
||||
operation.Parameters.Add(p);
|
||||
}
|
||||
|
|
|
@ -46,7 +46,6 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
base.SetParameters(operation);
|
||||
|
||||
operation.Parameters = new List<OpenApiParameter>();
|
||||
IEdmEntityType entityType = Singleton.EntityType();
|
||||
|
||||
// $select
|
||||
OpenApiParameter parameter = Context.CreateSelect(Singleton);
|
||||
|
|
|
@ -38,7 +38,9 @@ namespace Microsoft.OpenApi.OData.Operation
|
|||
{
|
||||
Name = Singleton.Name + "." + Singleton.EntityType().Name,
|
||||
};
|
||||
|
||||
tag.Extensions.Add(Constants.xMsTocType, new OpenApiString("page"));
|
||||
|
||||
operation.Tags.Add(tag);
|
||||
|
||||
Context.AppendTag(tag);
|
||||
|
|
|
@ -97,16 +97,16 @@ namespace Microsoft.OpenApi.OData.Reader.Capabilities.Tests
|
|||
|
||||
private static IEdmModel GetEdmModel(string template, EdmVocabularyAnnotationSerializationLocation location)
|
||||
{
|
||||
string countAnnotation = @"<Annotation Term=""Org.OData.Capabilities.V1.TopSupported"" Bool=""false"" />";
|
||||
string topAnnotation = @"<Annotation Term=""Org.OData.Capabilities.V1.TopSupported"" Bool=""false"" />";
|
||||
|
||||
if (location == EdmVocabularyAnnotationSerializationLocation.OutOfLine)
|
||||
{
|
||||
countAnnotation = string.Format(template, countAnnotation);
|
||||
return CapabilitiesModelHelper.GetEdmModelOutline(countAnnotation);
|
||||
topAnnotation = string.Format(template, topAnnotation);
|
||||
return CapabilitiesModelHelper.GetEdmModelOutline(topAnnotation);
|
||||
}
|
||||
else
|
||||
{
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(countAnnotation);
|
||||
return CapabilitiesModelHelper.GetEdmModelTypeInline(topAnnotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,13 +11,19 @@ namespace Microsoft.OpenApi.OData.Edm.Tests
|
|||
{
|
||||
public class ODataOperationImportSegmentTests
|
||||
{
|
||||
private IEdmOperationImport _operationImport;
|
||||
private IEdmOperationImport _actionImport;
|
||||
private IEdmOperationImport _functionImport;
|
||||
|
||||
public ODataOperationImportSegmentTests()
|
||||
{
|
||||
IEdmEntityContainer container = new EdmEntityContainer("NS", "default");
|
||||
IEdmAction action = new EdmAction("NS", "MyAction", null);
|
||||
_operationImport = new EdmActionImport(container, "MyAction", action);
|
||||
_actionImport = new EdmActionImport(container, "MyAction", action);
|
||||
|
||||
EdmFunction function = new EdmFunction("NS", "MyFunction", EdmCoreModel.Instance.GetString(false), false, null, false);
|
||||
function.AddParameter("firstName", EdmCoreModel.Instance.GetString(false));
|
||||
function.AddParameter("lastName", EdmCoreModel.Instance.GetString(false));
|
||||
_functionImport = new EdmFunctionImport(container, "MyFunction", function);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -31,17 +37,17 @@ namespace Microsoft.OpenApi.OData.Edm.Tests
|
|||
public void CtorSetOperationImportProperty()
|
||||
{
|
||||
// Arrange & Act
|
||||
var segment = new ODataOperationImportSegment(_operationImport);
|
||||
var segment = new ODataOperationImportSegment(_actionImport);
|
||||
|
||||
// Assert
|
||||
Assert.Same(_operationImport, segment.OperationImport);
|
||||
Assert.Same(_actionImport, segment.OperationImport);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetEntityTypeThrowsNotImplementedException()
|
||||
{
|
||||
// Arrange & Act
|
||||
var segment = new ODataOperationImportSegment(_operationImport);
|
||||
var segment = new ODataOperationImportSegment(_actionImport);
|
||||
|
||||
// Assert
|
||||
Assert.Throws<NotImplementedException>(() => segment.EntityType);
|
||||
|
@ -51,20 +57,31 @@ namespace Microsoft.OpenApi.OData.Edm.Tests
|
|||
public void KindPropertyReturnsOperationImportEnumMember()
|
||||
{
|
||||
// Arrange & Act
|
||||
var segment = new ODataOperationImportSegment(_operationImport);
|
||||
var segment = new ODataOperationImportSegment(_actionImport);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(ODataSegmentKind.OperationImport, segment.Kind);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetPathItemNameReturnsCorrectOperationImportLiteral()
|
||||
public void GetPathItemNameReturnsCorrectActionImportLiteral()
|
||||
{
|
||||
// Arrange & Act
|
||||
var segment = new ODataOperationImportSegment(_operationImport);
|
||||
var segment = new ODataOperationImportSegment(_actionImport);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("MyAction", segment.GetPathItemName(new OpenApiConvertSettings()));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetPathItemNameReturnsCorrectFunctionImportLiteral()
|
||||
{
|
||||
// Arrange & Act
|
||||
var segment = new ODataOperationImportSegment(_functionImport);
|
||||
|
||||
// Assert
|
||||
Assert.Equal("MyFunction(firstName={firstName},lastName={lastName})",
|
||||
segment.GetPathItemName(new OpenApiConvertSettings()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
|
||||
// Assert
|
||||
Assert.NotNull(operation);
|
||||
Assert.Equal("Invoke action ResetDataSource", operation.Summary);
|
||||
Assert.Equal("Invoke actionImport ResetDataSource", operation.Summary);
|
||||
Assert.NotNull(operation.Tags);
|
||||
|
||||
Assert.NotNull(operation.Parameters);
|
||||
|
@ -42,5 +42,47 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.Equal(2, operation.Responses.Count);
|
||||
Assert.Equal(new string[] { "204", "default" }, operation.Responses.Select(e => e.Key));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateOperationForEdmActionReturnsCorrectOperationId(bool enableOperationId)
|
||||
{
|
||||
// Arrange
|
||||
EdmModel model = new EdmModel();
|
||||
EdmEntityType customer = new EdmEntityType("NS", "Customer");
|
||||
customer.AddKeys(customer.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
|
||||
model.AddElement(customer);
|
||||
EdmAction action = new EdmAction("NS", "MyAction", EdmCoreModel.Instance.GetString(false), false, null);
|
||||
action.AddParameter("param", EdmCoreModel.Instance.GetString(false));
|
||||
model.AddElement(action);
|
||||
EdmEntityContainer container = new EdmEntityContainer("NS", "Default");
|
||||
EdmEntitySet customers = new EdmEntitySet(container, "Customers", customer);
|
||||
EdmActionImport actionImport = new EdmActionImport(container, "MyAction", action);
|
||||
model.AddElement(container);
|
||||
|
||||
OpenApiConvertSettings settings = new OpenApiConvertSettings
|
||||
{
|
||||
OperationId = enableOperationId
|
||||
};
|
||||
ODataContext context = new ODataContext(model, settings);
|
||||
|
||||
ODataPath path = new ODataPath(new ODataOperationImportSegment(actionImport));
|
||||
|
||||
// Act
|
||||
var operation = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(operation);
|
||||
|
||||
if (enableOperationId)
|
||||
{
|
||||
Assert.Equal("OperationImport.MyAction", operation.OperationId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Null(operation.OperationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,5 +48,96 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.Equal(2, operation.Responses.Count);
|
||||
Assert.Equal(new string[] { "204", "default" }, operation.Responses.Select(e => e.Key));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateOperationForEdmActionReturnsCorrectOperationId(bool enableOperationId)
|
||||
{
|
||||
// Arrange
|
||||
EdmModel model = new EdmModel();
|
||||
EdmEntityType customer = new EdmEntityType("NS", "Customer");
|
||||
customer.AddKeys(customer.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
|
||||
model.AddElement(customer);
|
||||
EdmAction action = new EdmAction("NS", "MyAction", EdmCoreModel.Instance.GetString(false), true, null);
|
||||
action.AddParameter("entity", new EdmEntityTypeReference(customer, false));
|
||||
action.AddParameter("param", EdmCoreModel.Instance.GetString(false));
|
||||
model.AddElement(action);
|
||||
EdmEntityContainer container = new EdmEntityContainer("NS", "Default");
|
||||
EdmEntitySet customers = new EdmEntitySet(container, "Customers", customer);
|
||||
model.AddElement(container);
|
||||
|
||||
OpenApiConvertSettings settings = new OpenApiConvertSettings
|
||||
{
|
||||
OperationId = enableOperationId
|
||||
};
|
||||
ODataContext context = new ODataContext(model, settings);
|
||||
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(customers),
|
||||
new ODataKeySegment(customer),
|
||||
new ODataOperationSegment(action));
|
||||
|
||||
// Act
|
||||
var operation = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(operation);
|
||||
|
||||
if (enableOperationId)
|
||||
{
|
||||
Assert.Equal("Customers.Customer.MyAction", operation.OperationId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Null(operation.OperationId);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateOperationForEdmActionWithTypeCastReturnsCorrectOperationId(bool enableOperationId)
|
||||
{
|
||||
// Arrange
|
||||
EdmModel model = new EdmModel();
|
||||
EdmEntityType customer = new EdmEntityType("NS", "Customer");
|
||||
customer.AddKeys(customer.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
|
||||
model.AddElement(customer);
|
||||
EdmEntityType vipCustomer = new EdmEntityType("NS", "VipCustomer", customer);
|
||||
model.AddElement(vipCustomer);
|
||||
EdmAction action = new EdmAction("NS", "MyAction", EdmCoreModel.Instance.GetString(false), true, null);
|
||||
action.AddParameter("entity", new EdmEntityTypeReference(vipCustomer, false));
|
||||
action.AddParameter("param", EdmCoreModel.Instance.GetString(false));
|
||||
model.AddElement(action);
|
||||
EdmEntityContainer container = new EdmEntityContainer("NS", "Default");
|
||||
EdmEntitySet customers = new EdmEntitySet(container, "Customers", customer);
|
||||
model.AddElement(container);
|
||||
|
||||
OpenApiConvertSettings settings = new OpenApiConvertSettings
|
||||
{
|
||||
OperationId = enableOperationId
|
||||
};
|
||||
ODataContext context = new ODataContext(model, settings);
|
||||
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(customers),
|
||||
new ODataKeySegment(customer),
|
||||
new ODataTypeCastSegment(vipCustomer),
|
||||
new ODataOperationSegment(action));
|
||||
|
||||
// Act
|
||||
var operation = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(operation);
|
||||
|
||||
if (enableOperationId)
|
||||
{
|
||||
Assert.Equal("Customers.VipCustomer.MyAction", operation.OperationId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Null(operation.OperationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
|
||||
// Assert
|
||||
Assert.NotNull(operation);
|
||||
Assert.Equal("Invoke function GetPersonWithMostFriends", operation.Summary);
|
||||
Assert.Equal("Invoke functionImport GetPersonWithMostFriends", operation.Summary);
|
||||
Assert.NotNull(operation.Tags);
|
||||
var tag = Assert.Single(operation.Tags);
|
||||
Assert.Equal("People", tag.Name);
|
||||
|
@ -43,5 +43,47 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.Equal(2, operation.Responses.Count);
|
||||
Assert.Equal(new string[] { "200", "default" }, operation.Responses.Select(e => e.Key));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateOperationForEdmFunctionImportReturnsCorrectOperationId(bool enableOperationId)
|
||||
{
|
||||
// Arrange
|
||||
EdmModel model = new EdmModel();
|
||||
EdmEntityType customer = new EdmEntityType("NS", "Customer");
|
||||
customer.AddKeys(customer.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
|
||||
model.AddElement(customer);
|
||||
EdmFunction function = new EdmFunction("NS", "MyFunction", EdmCoreModel.Instance.GetString(false), false, null, false);
|
||||
function.AddParameter("entity", new EdmEntityTypeReference(customer, false));
|
||||
function.AddParameter("param", EdmCoreModel.Instance.GetString(false));
|
||||
model.AddElement(function);
|
||||
EdmEntityContainer container = new EdmEntityContainer("NS", "Default");
|
||||
EdmFunctionImport functionImport = new EdmFunctionImport(container, "MyFunction", function);
|
||||
model.AddElement(container);
|
||||
|
||||
OpenApiConvertSettings settings = new OpenApiConvertSettings
|
||||
{
|
||||
OperationId = enableOperationId
|
||||
};
|
||||
ODataContext context = new ODataContext(model, settings);
|
||||
|
||||
ODataPath path = new ODataPath(new ODataOperationImportSegment(functionImport));
|
||||
|
||||
// Act
|
||||
var operation = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(operation);
|
||||
|
||||
if (enableOperationId)
|
||||
{
|
||||
Assert.Equal("OperationImport.MyFunction.a5ea52712c5e17e3bd081e4f", operation.OperationId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Null(operation.OperationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,8 +3,12 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
using Microsoft.OData.Edm.Validation;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
@ -48,5 +52,96 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.Equal(2, operation.Responses.Count);
|
||||
Assert.Equal(new string[] { "200", "default" }, operation.Responses.Select(e => e.Key));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateOperationForEdmFunctionReturnsCorrectOperationId(bool enableOperationId)
|
||||
{
|
||||
// Arrange
|
||||
EdmModel model = new EdmModel();
|
||||
EdmEntityType customer = new EdmEntityType("NS", "Customer");
|
||||
customer.AddKeys(customer.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
|
||||
model.AddElement(customer);
|
||||
EdmFunction function = new EdmFunction("NS", "MyFunction", EdmCoreModel.Instance.GetString(false), true, null, false);
|
||||
function.AddParameter("entity", new EdmEntityTypeReference(customer, false));
|
||||
function.AddParameter("param", EdmCoreModel.Instance.GetString(false));
|
||||
model.AddElement(function);
|
||||
EdmEntityContainer container = new EdmEntityContainer("NS", "Default");
|
||||
EdmEntitySet customers = new EdmEntitySet(container, "Customers", customer);
|
||||
model.AddElement(container);
|
||||
|
||||
OpenApiConvertSettings settings = new OpenApiConvertSettings
|
||||
{
|
||||
OperationId = enableOperationId
|
||||
};
|
||||
ODataContext context = new ODataContext(model, settings);
|
||||
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(customers),
|
||||
new ODataKeySegment(customer),
|
||||
new ODataOperationSegment(function));
|
||||
|
||||
// Act
|
||||
var operation = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(operation);
|
||||
|
||||
if (enableOperationId)
|
||||
{
|
||||
Assert.Equal("Customers.Customer.MyFunction.2c7bd5b91474cb963a16e394", operation.OperationId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Null(operation.OperationId);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateOperationForEdmFunctionWithTypeCastReturnsCorrectOperationId(bool enableOperationId)
|
||||
{
|
||||
// Arrange
|
||||
EdmModel model = new EdmModel();
|
||||
EdmEntityType customer = new EdmEntityType("NS", "Customer");
|
||||
customer.AddKeys(customer.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32));
|
||||
model.AddElement(customer);
|
||||
EdmEntityType vipCustomer = new EdmEntityType("NS", "VipCustomer", customer);
|
||||
model.AddElement(vipCustomer);
|
||||
EdmFunction function = new EdmFunction("NS", "MyFunction", EdmCoreModel.Instance.GetString(false), true, null, false);
|
||||
function.AddParameter("entity", new EdmEntityTypeReference(vipCustomer, false));
|
||||
function.AddParameter("param", EdmCoreModel.Instance.GetString(false));
|
||||
model.AddElement(function);
|
||||
EdmEntityContainer container = new EdmEntityContainer("NS", "Default");
|
||||
EdmEntitySet customers = new EdmEntitySet(container, "Customers", customer);
|
||||
model.AddElement(container);
|
||||
|
||||
OpenApiConvertSettings settings = new OpenApiConvertSettings
|
||||
{
|
||||
OperationId = enableOperationId
|
||||
};
|
||||
ODataContext context = new ODataContext(model, settings);
|
||||
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(customers),
|
||||
new ODataKeySegment(customer),
|
||||
new ODataTypeCastSegment(vipCustomer),
|
||||
new ODataOperationSegment(function));
|
||||
|
||||
// Act
|
||||
var operation = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(operation);
|
||||
|
||||
if (enableOperationId)
|
||||
{
|
||||
Assert.Equal("Customers.VipCustomer.MyFunction.2c7bd5b91474cb963a16e394", operation.OperationId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Null(operation.OperationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Operation.Tests
|
||||
|
@ -15,13 +14,19 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
{
|
||||
private EntityDeleteOperationHandler _operationHandler = new EntityDeleteOperationHandler();
|
||||
|
||||
[Fact]
|
||||
public void CreateEntityDeleteOperationReturnsCorrectOperation()
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateEntityDeleteOperationReturnsCorrectOperation(bool enableOperationId)
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.BasicEdmModel;
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("People");
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmModel model = EntitySetGetOperationHandlerTests.GetEdmModel("");
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Customers");
|
||||
OpenApiConvertSettings settings = new OpenApiConvertSettings
|
||||
{
|
||||
OperationId = enableOperationId
|
||||
};
|
||||
ODataContext context = new ODataContext(model, settings);
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(entitySet), new ODataKeySegment(entitySet.EntityType()));
|
||||
|
||||
// Act
|
||||
|
@ -29,10 +34,10 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
|
||||
// Assert
|
||||
Assert.NotNull(delete);
|
||||
Assert.Equal("Delete entity from People", delete.Summary);
|
||||
Assert.Equal("Delete entity from Customers", delete.Summary);
|
||||
Assert.NotNull(delete.Tags);
|
||||
var tag = Assert.Single(delete.Tags);
|
||||
Assert.Equal("People.Person", tag.Name);
|
||||
Assert.Equal("Customers.Customer", tag.Name);
|
||||
|
||||
Assert.NotNull(delete.Parameters);
|
||||
Assert.Equal(2, delete.Parameters.Count);
|
||||
|
@ -42,6 +47,15 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.NotNull(delete.Responses);
|
||||
Assert.Equal(2, delete.Responses.Count);
|
||||
Assert.Equal(new[] { "204", "default" }, delete.Responses.Select(r => r.Key));
|
||||
|
||||
if (enableOperationId)
|
||||
{
|
||||
Assert.Equal("Customers.Customer.DeleteCustomer", delete.OperationId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Null(delete.OperationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
// 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.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Operation.Tests
|
||||
|
@ -15,13 +15,19 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
{
|
||||
private EntityGetOperationHandler _operationHandler = new EntityGetOperationHandler();
|
||||
|
||||
[Fact]
|
||||
public void CreateEntityGetOperationReturnsCorrectOperation()
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateEntityGetOperationReturnsCorrectOperation(bool enableOperationId)
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.BasicEdmModel;
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("People");
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmModel model = EntitySetGetOperationHandlerTests.GetEdmModel("");
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Customers");
|
||||
OpenApiConvertSettings settings = new OpenApiConvertSettings
|
||||
{
|
||||
OperationId = enableOperationId
|
||||
};
|
||||
ODataContext context = new ODataContext(model, settings);
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(entitySet), new ODataKeySegment(entitySet.EntityType()));
|
||||
|
||||
// Act
|
||||
|
@ -29,10 +35,10 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
|
||||
// Assert
|
||||
Assert.NotNull(get);
|
||||
Assert.Equal("Get entity from People by key", get.Summary);
|
||||
Assert.Equal("Get entity from Customers by key", get.Summary);
|
||||
Assert.NotNull(get.Tags);
|
||||
var tag = Assert.Single(get.Tags);
|
||||
Assert.Equal("People.Person", tag.Name);
|
||||
Assert.Equal("Customers.Customer", tag.Name);
|
||||
|
||||
Assert.NotNull(get.Parameters);
|
||||
Assert.Equal(3, get.Parameters.Count);
|
||||
|
@ -41,6 +47,85 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.NotNull(get.Responses);
|
||||
Assert.Equal(2, get.Responses.Count);
|
||||
Assert.Equal(new[] { "200", "default" }, get.Responses.Select(r => r.Key));
|
||||
|
||||
if (enableOperationId)
|
||||
{
|
||||
Assert.Equal("Customers.Customer.GetCustomer", get.OperationId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Null(get.OperationId);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false, true)]
|
||||
[InlineData(false, false)]
|
||||
[InlineData(true, true)]
|
||||
[InlineData(true, false)]
|
||||
public void CreateEntityGetOperationReturnsParameterForExpandRestrictions(bool hasRestriction, bool expandable)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.ExpandRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Expandable"" Bool=""{0}"" />
|
||||
</Record>
|
||||
</Annotation>", expandable);
|
||||
|
||||
// Act & Assert
|
||||
VerifyParameter(annotation, hasRestriction, expandable, "$expand");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false, "Recursive")]
|
||||
[InlineData(false, "Single")]
|
||||
[InlineData(false, "None")]
|
||||
[InlineData(true, "Recursive")]
|
||||
[InlineData(true, "Single")]
|
||||
[InlineData(true, "None")]
|
||||
public void CreateEntityGetOperationReturnsParameterForNavigationRestrictions(bool hasRestriction, string navigability)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.NavigationRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Navigability"">
|
||||
<EnumMember>Org.OData.Capabilities.V1.NavigationType/{0}</EnumMember >
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>", navigability);
|
||||
|
||||
// Act & Assert
|
||||
VerifyParameter(annotation, hasRestriction, navigability == "None" ? false : true, "$select");
|
||||
}
|
||||
|
||||
private void VerifyParameter(string annotation, bool hasRestriction, bool supported, string queryOption)
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EntitySetGetOperationHandlerTests.GetEdmModel(hasRestriction ? annotation : "");
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmEntitySet customers = model.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(customers); // guard
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(customers), new ODataKeySegment(customers.EntityType()));
|
||||
|
||||
// Act
|
||||
var get = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(get);
|
||||
|
||||
Assert.NotNull(get.Parameters);
|
||||
if (!hasRestriction || supported)
|
||||
{
|
||||
Assert.Equal(3, get.Parameters.Count);
|
||||
Assert.Contains(queryOption, get.Parameters.Select(p => p.Name));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Equal(2, get.Parameters.Count);
|
||||
Assert.DoesNotContain(queryOption, get.Parameters.Select(p => p.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Operation.Tests
|
||||
|
@ -15,13 +14,19 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
{
|
||||
private EntityPatchOperationHandler _operationHandler = new EntityPatchOperationHandler();
|
||||
|
||||
[Fact]
|
||||
public void CreateEntityPatchOperationReturnsCorrectOperation()
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateEntityPatchOperationReturnsCorrectOperation(bool enableOperationId)
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.BasicEdmModel;
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("People");
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmModel model = EntitySetGetOperationHandlerTests.GetEdmModel("");
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Customers");
|
||||
OpenApiConvertSettings settings = new OpenApiConvertSettings
|
||||
{
|
||||
OperationId = enableOperationId
|
||||
};
|
||||
ODataContext context = new ODataContext(model, settings);
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(entitySet), new ODataKeySegment(entitySet.EntityType()));
|
||||
|
||||
// Act
|
||||
|
@ -29,10 +34,10 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
|
||||
// Assert
|
||||
Assert.NotNull(patch);
|
||||
Assert.Equal("Update entity in People", patch.Summary);
|
||||
Assert.Equal("Update entity in Customers", patch.Summary);
|
||||
Assert.NotNull(patch.Tags);
|
||||
var tag = Assert.Single(patch.Tags);
|
||||
Assert.Equal("People.Person", tag.Name);
|
||||
Assert.Equal("Customers.Customer", tag.Name);
|
||||
|
||||
Assert.NotNull(patch.Parameters);
|
||||
Assert.Equal(1, patch.Parameters.Count);
|
||||
|
@ -42,6 +47,15 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.NotNull(patch.Responses);
|
||||
Assert.Equal(2, patch.Responses.Count);
|
||||
Assert.Equal(new[] { "204", "default" }, patch.Responses.Select(r => r.Key));
|
||||
|
||||
if (enableOperationId)
|
||||
{
|
||||
Assert.Equal("Customers.Customer.UpdateCustomer", patch.OperationId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Null(patch.OperationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,14 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
using Microsoft.OData.Edm.Validation;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Operation.Tests
|
||||
|
@ -14,13 +19,19 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
{
|
||||
private EntitySetGetOperationHandler _operationHandler = new EntitySetGetOperationHandler();
|
||||
|
||||
[Fact]
|
||||
public void CreateEntitySetGetOperationReturnsCorrectOperation()
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateEntitySetGetOperationReturnsCorrectOperation(bool enableOperationId)
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.BasicEdmModel;
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("People");
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmModel model = GetEdmModel("");
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Customers");
|
||||
OpenApiConvertSettings settings = new OpenApiConvertSettings
|
||||
{
|
||||
OperationId = enableOperationId
|
||||
};
|
||||
ODataContext context = new ODataContext(model, settings);
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(entitySet));
|
||||
|
||||
// Act
|
||||
|
@ -31,13 +42,240 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.Equal("Get entities from " + entitySet.Name, get.Summary);
|
||||
Assert.NotNull(get.Tags);
|
||||
var tag = Assert.Single(get.Tags);
|
||||
Assert.Equal("People.Person", tag.Name);
|
||||
Assert.Equal("Customers.Customer", tag.Name);
|
||||
|
||||
Assert.NotNull(get.Parameters);
|
||||
Assert.Equal(8, get.Parameters.Count);
|
||||
|
||||
Assert.NotNull(get.Responses);
|
||||
Assert.Equal(2, get.Responses.Count);
|
||||
|
||||
if (enableOperationId)
|
||||
{
|
||||
Assert.Equal("Customers.Customer.ListCustomer", get.OperationId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Null(get.OperationId);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false, true)]
|
||||
[InlineData(false, false)]
|
||||
[InlineData(true, true)]
|
||||
[InlineData(true, false)]
|
||||
public void CreateEntitySetGetOperationReturnsParameterForTopSupportedRestrictions(bool hasRestriction, bool supported)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"<Annotation Term=""Org.OData.Capabilities.V1.TopSupported"" Bool=""{0}"" />", supported);
|
||||
|
||||
// Act & Assert
|
||||
VerifyParameter(annotation, hasRestriction, supported, "top");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false, true)]
|
||||
[InlineData(false, false)]
|
||||
[InlineData(true, true)]
|
||||
[InlineData(true, false)]
|
||||
public void CreateEntitySetGetOperationReturnsParameterForSkipSupportedRestrictions(bool hasRestriction, bool supported)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"<Annotation Term=""Org.OData.Capabilities.V1.SkipSupported"" Bool=""{0}"" />", supported);
|
||||
|
||||
// Act & Assert
|
||||
VerifyParameter(annotation, hasRestriction, supported, "skip");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false, true)]
|
||||
[InlineData(false, false)]
|
||||
[InlineData(true, true)]
|
||||
[InlineData(true, false)]
|
||||
public void CreateEntitySetGetOperationReturnsParameterForSearchRestrictions(bool hasRestriction, bool searchable)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.SearchRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Searchable"" Bool=""{0}"" />
|
||||
</Record>
|
||||
</Annotation>", searchable);
|
||||
|
||||
// Act & Assert
|
||||
VerifyParameter(annotation, hasRestriction, searchable, "search");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false, true)]
|
||||
[InlineData(false, false)]
|
||||
[InlineData(true, true)]
|
||||
[InlineData(true, false)]
|
||||
public void CreateEntitySetGetOperationReturnsParameterForFilterRestrictions(bool hasRestriction, bool filterable)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.FilterRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Filterable"" Bool=""{0}"" />
|
||||
</Record>
|
||||
</Annotation>", filterable);
|
||||
|
||||
// Act & Assert
|
||||
VerifyParameter(annotation, hasRestriction, filterable, "filter");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false, true)]
|
||||
[InlineData(false, false)]
|
||||
[InlineData(true, true)]
|
||||
[InlineData(true, false)]
|
||||
public void CreateEntitySetGetOperationReturnsParameterForCountRestrictions(bool hasRestriction, bool countable)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.CountRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Countable"" Bool=""{0}"" />
|
||||
</Record>
|
||||
</Annotation>", countable);
|
||||
|
||||
// Act & Assert
|
||||
VerifyParameter(annotation, hasRestriction, countable, "count");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false, true)]
|
||||
[InlineData(false, false)]
|
||||
[InlineData(true, true)]
|
||||
[InlineData(true, false)]
|
||||
public void CreateEntitySetGetOperationReturnsParameterForSortRestrictions(bool hasRestriction, bool sortable)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.SortRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Sortable"" Bool=""{0}"" />
|
||||
</Record>
|
||||
</Annotation>", sortable);
|
||||
|
||||
// Act & Assert
|
||||
VerifyParameter(annotation, hasRestriction, sortable, "$orderby", false);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false, true)]
|
||||
[InlineData(false, false)]
|
||||
[InlineData(true, true)]
|
||||
[InlineData(true, false)]
|
||||
public void CreateEntitySetGetOperationReturnsParameterForExpandRestrictions(bool hasRestriction, bool expandable)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.ExpandRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Expandable"" Bool=""{0}"" />
|
||||
</Record>
|
||||
</Annotation>", expandable);
|
||||
|
||||
// Act & Assert
|
||||
VerifyParameter(annotation, hasRestriction, expandable, "$expand", false);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false, "Recursive")]
|
||||
[InlineData(false, "Single")]
|
||||
[InlineData(false, "None")]
|
||||
[InlineData(true, "Recursive")]
|
||||
[InlineData(true, "Single")]
|
||||
[InlineData(true, "None")]
|
||||
public void CreateEntitySetGetOperationReturnsParameterForNavigationRestrictions(bool hasRestriction, string navigability)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.NavigationRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Navigability"">
|
||||
<EnumMember>Org.OData.Capabilities.V1.NavigationType/{0}</EnumMember >
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>", navigability);
|
||||
|
||||
// Act & Assert
|
||||
VerifyParameter(annotation, hasRestriction, navigability == "None" ? false : true, "$select", false);
|
||||
}
|
||||
|
||||
public static IEdmModel GetEdmModel(string annotation)
|
||||
{
|
||||
const string template = @"<edmx:Edmx Version=""4.0"" xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx"">
|
||||
<edmx:DataServices>
|
||||
<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>
|
||||
<EntityContainer Name =""Default"">
|
||||
<EntitySet Name=""Customers"" EntityType=""NS.Customer"" />
|
||||
</EntityContainer>
|
||||
<Annotations Target=""NS.Default/Customers"">
|
||||
{0}
|
||||
</Annotations>
|
||||
</Schema>
|
||||
</edmx:DataServices>
|
||||
</edmx:Edmx>";
|
||||
string modelText = string.Format(template, annotation);
|
||||
|
||||
IEdmModel model;
|
||||
IEnumerable<EdmError> errors;
|
||||
|
||||
bool result = CsdlReader.TryParse(XElement.Parse(modelText).CreateReader(), out model, out errors);
|
||||
Assert.True(result);
|
||||
return model;
|
||||
}
|
||||
|
||||
private void VerifyParameter(string annotation, bool hasRestriction, bool supported, string queryOption, bool isReference = true)
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = GetEdmModel(hasRestriction ? annotation : "");
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmEntitySet customers = model.EntityContainer.FindEntitySet("Customers");
|
||||
Assert.NotNull(customers); // guard
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(customers));
|
||||
|
||||
// Act
|
||||
var get = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(get);
|
||||
|
||||
Assert.NotNull(get.Parameters);
|
||||
if (!hasRestriction || supported)
|
||||
{
|
||||
Assert.Equal(8, get.Parameters.Count);
|
||||
if (isReference)
|
||||
{
|
||||
Assert.Contains(queryOption, get.Parameters.Select(p => p.Reference?.Id));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Contains(queryOption, get.Parameters.Select(p => p.Name));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Equal(7, get.Parameters.Count);
|
||||
if (isReference)
|
||||
{
|
||||
Assert.DoesNotContain(queryOption, get.Parameters.Select(p => p.Reference?.Id));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.DoesNotContain(queryOption, get.Parameters.Select(p => p.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Operation.Tests
|
||||
|
@ -14,13 +13,19 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
{
|
||||
private EntitySetPostOperationHandler _operationHandler = new EntitySetPostOperationHandler();
|
||||
|
||||
[Fact]
|
||||
public void CreateEntitySetPostOperationReturnsCorrectOperation()
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateEntitySetPostOperationReturnsCorrectOperation(bool enableOperationId)
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.BasicEdmModel;
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("People");
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmModel model = EntitySetGetOperationHandlerTests.GetEdmModel("");
|
||||
IEdmEntitySet entitySet = model.EntityContainer.FindEntitySet("Customers");
|
||||
OpenApiConvertSettings settings = new OpenApiConvertSettings
|
||||
{
|
||||
OperationId = enableOperationId
|
||||
};
|
||||
ODataContext context = new ODataContext(model, settings);
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(entitySet));
|
||||
|
||||
// Act
|
||||
|
@ -31,13 +36,22 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.Equal("Add new entity to " + entitySet.Name, post.Summary);
|
||||
Assert.NotNull(post.Tags);
|
||||
var tag = Assert.Single(post.Tags);
|
||||
Assert.Equal("People.Person", tag.Name);
|
||||
Assert.Equal("Customers.Customer", tag.Name);
|
||||
|
||||
Assert.Empty(post.Parameters);
|
||||
Assert.NotNull(post.RequestBody);
|
||||
|
||||
Assert.NotNull(post.Responses);
|
||||
Assert.Equal(2, post.Responses.Count);
|
||||
|
||||
if (enableOperationId)
|
||||
{
|
||||
Assert.Equal("Customers.Customer.CreateCustomer", post.OperationId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Null(post.OperationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,12 +15,18 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
{
|
||||
private NavigationPropertyGetOperationHandler _operationHandler = new NavigationPropertyGetOperationHandler();
|
||||
|
||||
[Fact]
|
||||
public void CreateNavigationGetOperationReturnsCorrectOperation()
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateNavigationGetOperationReturnsCorrectOperation(bool enableOperationId)
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.TripServiceModel;
|
||||
ODataContext context = new ODataContext(model);
|
||||
OpenApiConvertSettings settings = new OpenApiConvertSettings
|
||||
{
|
||||
OperationId = enableOperationId
|
||||
};
|
||||
ODataContext context = new ODataContext(model, settings);
|
||||
IEdmEntitySet people = model.EntityContainer.FindEntitySet("People");
|
||||
Assert.NotNull(people);
|
||||
|
||||
|
@ -45,6 +51,15 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
|
||||
Assert.Equal(2, operation.Responses.Count);
|
||||
Assert.Equal(new string[] { "200", "default" }, operation.Responses.Select(e => e.Key));
|
||||
|
||||
if (enableOperationId)
|
||||
{
|
||||
Assert.Equal("People.ListTrips", operation.OperationId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Null(operation.OperationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,12 +15,18 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
{
|
||||
private NavigationPropertyPatchOperationHandler _operationHandler = new NavigationPropertyPatchOperationHandler();
|
||||
|
||||
[Fact]
|
||||
public void CreateNavigationPatchOperationReturnsCorrectOperation()
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateNavigationPatchOperationReturnsCorrectOperation(bool enableOperationId)
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.TripServiceModel;
|
||||
ODataContext context = new ODataContext(model);
|
||||
OpenApiConvertSettings settings = new OpenApiConvertSettings
|
||||
{
|
||||
OperationId = enableOperationId
|
||||
};
|
||||
ODataContext context = new ODataContext(model, settings);
|
||||
IEdmEntitySet people = model.EntityContainer.FindEntitySet("People");
|
||||
Assert.NotNull(people);
|
||||
|
||||
|
@ -46,6 +52,15 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
|
||||
Assert.Equal(2, operation.Responses.Count);
|
||||
Assert.Equal(new string[] { "204", "default" }, operation.Responses.Select(e => e.Key));
|
||||
|
||||
if (enableOperationId)
|
||||
{
|
||||
Assert.Equal("People.UpdateBestFriend", operation.OperationId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Null(operation.OperationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,12 +15,18 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
{
|
||||
private NavigationPropertyPostOperationHandler _operationHandler = new NavigationPropertyPostOperationHandler();
|
||||
|
||||
[Fact]
|
||||
public void CreateNavigationPostOperationReturnsCorrectOperation()
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateNavigationPostOperationReturnsCorrectOperation(bool enableOperationId)
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.TripServiceModel;
|
||||
ODataContext context = new ODataContext(model);
|
||||
OpenApiConvertSettings settings = new OpenApiConvertSettings
|
||||
{
|
||||
OperationId = enableOperationId
|
||||
};
|
||||
ODataContext context = new ODataContext(model, settings);
|
||||
IEdmEntitySet people = model.EntityContainer.FindEntitySet("People");
|
||||
Assert.NotNull(people);
|
||||
|
||||
|
@ -46,6 +52,15 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
|
||||
Assert.Equal(2, operation.Responses.Count);
|
||||
Assert.Equal(new string[] { "201", "default" }, operation.Responses.Select(e => e.Key));
|
||||
|
||||
if (enableOperationId)
|
||||
{
|
||||
Assert.Equal("People.CreateTrips", operation.OperationId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Null(operation.OperationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,10 +3,14 @@
|
|||
// Licensed under the MIT License (MIT). See LICENSE in the repo root for license information.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OData.Edm.Csdl;
|
||||
using Microsoft.OData.Edm.Validation;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Operation.Tests
|
||||
|
@ -15,13 +19,19 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
{
|
||||
private SingletonGetOperationHandler _operationHandler = new SingletonGetOperationHandler();
|
||||
|
||||
[Fact]
|
||||
public void CreateSingletonGetOperationReturnsCorrectOperation()
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateSingletonGetOperationReturnsCorrectOperation(bool enableOperationId)
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.BasicEdmModel;
|
||||
IEdmModel model = GetEdmModel("");
|
||||
IEdmSingleton singleton = model.EntityContainer.FindSingleton("Me");
|
||||
ODataContext context = new ODataContext(model);
|
||||
OpenApiConvertSettings settings = new OpenApiConvertSettings
|
||||
{
|
||||
OperationId = enableOperationId
|
||||
};
|
||||
ODataContext context = new ODataContext(model, settings);
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(singleton));
|
||||
|
||||
// Act
|
||||
|
@ -32,7 +42,7 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.Equal("Get Me", get.Summary);
|
||||
Assert.NotNull(get.Tags);
|
||||
var tag = Assert.Single(get.Tags);
|
||||
Assert.Equal("Me.Person", tag.Name);
|
||||
Assert.Equal("Me.Customer", tag.Name);
|
||||
|
||||
Assert.NotNull(get.Parameters);
|
||||
Assert.Equal(2, get.Parameters.Count);
|
||||
|
@ -42,6 +52,115 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.NotNull(get.Responses);
|
||||
Assert.Equal(2, get.Responses.Count);
|
||||
Assert.Equal(new[] { "200", "default" }, get.Responses.Select(r => r.Key));
|
||||
|
||||
if (enableOperationId)
|
||||
{
|
||||
Assert.Equal("Me.Customer.GetCustomer", get.OperationId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Null(get.OperationId);
|
||||
}
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false, true)]
|
||||
[InlineData(false, false)]
|
||||
[InlineData(true, true)]
|
||||
[InlineData(true, false)]
|
||||
public void CreateSingletonSetGetOperationReturnsParameterForExpandRestrictions(bool hasRestriction, bool expandable)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.ExpandRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Expandable"" Bool=""{0}"" />
|
||||
</Record>
|
||||
</Annotation>", expandable);
|
||||
|
||||
// Act & Assert
|
||||
VerifyParameter(annotation, hasRestriction, expandable, "$expand");
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false, "Recursive")]
|
||||
[InlineData(false, "Single")]
|
||||
[InlineData(false, "None")]
|
||||
[InlineData(true, "Recursive")]
|
||||
[InlineData(true, "Single")]
|
||||
[InlineData(true, "None")]
|
||||
public void CreateSingletonGetOperationReturnsParameterForNavigationRestrictions(bool hasRestriction, string navigability)
|
||||
{
|
||||
// Arrange
|
||||
string annotation = String.Format(@"
|
||||
<Annotation Term=""Org.OData.Capabilities.V1.NavigationRestrictions"">
|
||||
<Record>
|
||||
<PropertyValue Property=""Navigability"">
|
||||
<EnumMember>Org.OData.Capabilities.V1.NavigationType/{0}</EnumMember >
|
||||
</PropertyValue>
|
||||
</Record>
|
||||
</Annotation>", navigability);
|
||||
|
||||
// Act & Assert
|
||||
VerifyParameter(annotation, hasRestriction, navigability == "None" ? false : true, "$select");
|
||||
}
|
||||
|
||||
public static IEdmModel GetEdmModel(string annotation)
|
||||
{
|
||||
const string template = @"<edmx:Edmx Version=""4.0"" xmlns:edmx=""http://docs.oasis-open.org/odata/ns/edmx"">
|
||||
<edmx:DataServices>
|
||||
<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>
|
||||
<EntityContainer Name =""Default"">
|
||||
<Singleton Name=""Me"" Type=""NS.Customer"" />
|
||||
</EntityContainer>
|
||||
<Annotations Target=""NS.Default/Me"">
|
||||
{0}
|
||||
</Annotations>
|
||||
</Schema>
|
||||
</edmx:DataServices>
|
||||
</edmx:Edmx>";
|
||||
string modelText = string.Format(template, annotation);
|
||||
|
||||
IEdmModel model;
|
||||
IEnumerable<EdmError> errors;
|
||||
|
||||
bool result = CsdlReader.TryParse(XElement.Parse(modelText).CreateReader(), out model, out errors);
|
||||
Assert.True(result);
|
||||
return model;
|
||||
}
|
||||
|
||||
private void VerifyParameter(string annotation, bool hasRestriction, bool supported, string queryOption)
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = GetEdmModel(hasRestriction ? annotation : "");
|
||||
ODataContext context = new ODataContext(model);
|
||||
IEdmSingleton me = model.EntityContainer.FindSingleton("Me");
|
||||
Assert.NotNull(me); // guard
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(me));
|
||||
|
||||
// Act
|
||||
var get = _operationHandler.CreateOperation(context, path);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(get);
|
||||
|
||||
Assert.NotNull(get.Parameters);
|
||||
if (!hasRestriction || supported)
|
||||
{
|
||||
Assert.Equal(2, get.Parameters.Count);
|
||||
Assert.Contains(queryOption, get.Parameters.Select(p => p.Name));
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Equal(1, get.Parameters.Count);
|
||||
Assert.DoesNotContain(queryOption, get.Parameters.Select(p => p.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
using System.Linq;
|
||||
using Microsoft.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Edm;
|
||||
using Microsoft.OpenApi.OData.Tests;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.OpenApi.OData.Operation.Tests
|
||||
|
@ -15,13 +14,19 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
{
|
||||
private SingletonPatchOperationHandler _operationHandler = new SingletonPatchOperationHandler();
|
||||
|
||||
[Fact]
|
||||
public void CreateSingletonPatchOperationReturnsCorrectOperation()
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public void CreateSingletonPatchOperationReturnsCorrectOperation(bool enableOperationId)
|
||||
{
|
||||
// Arrange
|
||||
IEdmModel model = EdmModelHelper.BasicEdmModel;
|
||||
IEdmModel model = SingletonGetOperationHandlerTests.GetEdmModel("");
|
||||
IEdmSingleton singleton = model.EntityContainer.FindSingleton("Me");
|
||||
ODataContext context = new ODataContext(model);
|
||||
OpenApiConvertSettings settings = new OpenApiConvertSettings
|
||||
{
|
||||
OperationId = enableOperationId
|
||||
};
|
||||
ODataContext context = new ODataContext(model, settings);
|
||||
ODataPath path = new ODataPath(new ODataNavigationSourceSegment(singleton));
|
||||
|
||||
// Act
|
||||
|
@ -32,7 +37,7 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.Equal("Update Me", patch.Summary);
|
||||
Assert.NotNull(patch.Tags);
|
||||
var tag = Assert.Single(patch.Tags);
|
||||
Assert.Equal("Me.Person", tag.Name);
|
||||
Assert.Equal("Me.Customer", tag.Name);
|
||||
|
||||
Assert.Empty(patch.Parameters);
|
||||
Assert.NotNull(patch.RequestBody);
|
||||
|
@ -40,6 +45,15 @@ namespace Microsoft.OpenApi.OData.Operation.Tests
|
|||
Assert.NotNull(patch.Responses);
|
||||
Assert.Equal(2, patch.Responses.Count);
|
||||
Assert.Equal(new[] { "204", "default" }, patch.Responses.Select(r => r.Key));
|
||||
|
||||
if (enableOperationId)
|
||||
{
|
||||
Assert.Equal("Me.Customer.UpdateCustomer", patch.OperationId);
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.Null(patch.OperationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace Microsoft.OpenApi.OData.PathItem.Tests
|
|||
.OperationImports().FirstOrDefault(o => o.Name == operationImport);
|
||||
Assert.NotNull(edmOperationImport); // guard
|
||||
string expectSummary = "Invoke " +
|
||||
(edmOperationImport.IsActionImport() ? "action " : "function ") + operationImport;
|
||||
(edmOperationImport.IsActionImport() ? "actionImport " : "functionImport ") + operationImport;
|
||||
ODataPath path = new ODataPath(new ODataOperationImportSegment(edmOperationImport));
|
||||
|
||||
// Act
|
||||
|
|
|
@ -362,7 +362,7 @@
|
|||
"People.Functions"
|
||||
],
|
||||
"summary": "Invoke function GetFavoriteAirline",
|
||||
"operationId": "People.0-GetFavoriteAirline",
|
||||
"operationId": "People.Person.GetFavoriteAirline.1c526eb64c7a82083ebab0f2",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "UserName",
|
||||
|
@ -404,7 +404,7 @@
|
|||
"People.Functions"
|
||||
],
|
||||
"summary": "Invoke function GetFriendsTrips",
|
||||
"operationId": "People.0-GetFriendsTrips",
|
||||
"operationId": "People.Person.GetFriendsTrips.9b42e09ab8ef6d73b88be6e9",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "UserName",
|
||||
|
@ -457,7 +457,7 @@
|
|||
"People.Functions"
|
||||
],
|
||||
"summary": "Invoke function UpdatePersonLastName",
|
||||
"operationId": "People.0-UpdatePersonLastName",
|
||||
"operationId": "People.Person.UpdatePersonLastName.e4ea38792d2cfa3aa5bab91b",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "UserName",
|
||||
|
@ -503,7 +503,7 @@
|
|||
"People.Actions"
|
||||
],
|
||||
"summary": "Invoke action ShareTrip",
|
||||
"operationId": "People.0-ShareTrip",
|
||||
"operationId": "People.Person.ShareTrip",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "UserName",
|
||||
|
@ -1462,7 +1462,7 @@
|
|||
"NewComePeople.Functions"
|
||||
],
|
||||
"summary": "Invoke function GetFavoriteAirline",
|
||||
"operationId": "NewComePeople.0-GetFavoriteAirline",
|
||||
"operationId": "NewComePeople.Person.GetFavoriteAirline.1c526eb64c7a82083ebab0f2",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "UserName",
|
||||
|
@ -1504,7 +1504,7 @@
|
|||
"NewComePeople.Functions"
|
||||
],
|
||||
"summary": "Invoke function GetFriendsTrips",
|
||||
"operationId": "NewComePeople.0-GetFriendsTrips",
|
||||
"operationId": "NewComePeople.Person.GetFriendsTrips.9b42e09ab8ef6d73b88be6e9",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "UserName",
|
||||
|
@ -1557,7 +1557,7 @@
|
|||
"NewComePeople.Functions"
|
||||
],
|
||||
"summary": "Invoke function UpdatePersonLastName",
|
||||
"operationId": "NewComePeople.0-UpdatePersonLastName",
|
||||
"operationId": "NewComePeople.Person.UpdatePersonLastName.e4ea38792d2cfa3aa5bab91b",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "UserName",
|
||||
|
@ -1603,7 +1603,7 @@
|
|||
"NewComePeople.Actions"
|
||||
],
|
||||
"summary": "Invoke action ShareTrip",
|
||||
"operationId": "NewComePeople.0-ShareTrip",
|
||||
"operationId": "NewComePeople.Person.ShareTrip",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "UserName",
|
||||
|
@ -1755,7 +1755,7 @@
|
|||
"Me.Functions"
|
||||
],
|
||||
"summary": "Invoke function GetFavoriteAirline",
|
||||
"operationId": "Me.0-GetFavoriteAirline",
|
||||
"operationId": "Me.Person.GetFavoriteAirline.1c526eb64c7a82083ebab0f2",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
|
@ -1785,7 +1785,7 @@
|
|||
"Me.Functions"
|
||||
],
|
||||
"summary": "Invoke function GetFriendsTrips",
|
||||
"operationId": "Me.0-GetFriendsTrips",
|
||||
"operationId": "Me.Person.GetFriendsTrips.9b42e09ab8ef6d73b88be6e9",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "userName",
|
||||
|
@ -1828,7 +1828,7 @@
|
|||
"Me.Functions"
|
||||
],
|
||||
"summary": "Invoke function UpdatePersonLastName",
|
||||
"operationId": "Me.0-UpdatePersonLastName",
|
||||
"operationId": "Me.Person.UpdatePersonLastName.e4ea38792d2cfa3aa5bab91b",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "lastName",
|
||||
|
@ -1864,7 +1864,7 @@
|
|||
"Me.Actions"
|
||||
],
|
||||
"summary": "Invoke action ShareTrip",
|
||||
"operationId": "Me.0-ShareTrip",
|
||||
"operationId": "Me.Person.ShareTrip",
|
||||
"requestBody": {
|
||||
"description": "Action parameters",
|
||||
"content": {
|
||||
|
@ -1898,13 +1898,13 @@
|
|||
"x-ms-docs-operation-type": "action"
|
||||
}
|
||||
},
|
||||
"/GetPersonWithMostFriends": {
|
||||
"/GetPersonWithMostFriends()": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"People"
|
||||
],
|
||||
"summary": "Invoke function GetPersonWithMostFriends",
|
||||
"operationId": "OperationImport.0-GetPersonWithMostFriends",
|
||||
"summary": "Invoke functionImport GetPersonWithMostFriends",
|
||||
"operationId": "OperationImport.GetPersonWithMostFriends.de8b4a5ab51ba6c8c254fe80",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
|
@ -1928,13 +1928,13 @@
|
|||
"x-ms-docs-operation-type": "functionImport"
|
||||
}
|
||||
},
|
||||
"/GetNearestAirport": {
|
||||
"/GetNearestAirport(lat={lat},lon={lon})": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"Airports"
|
||||
],
|
||||
"summary": "Invoke function GetNearestAirport",
|
||||
"operationId": "OperationImport.0-GetNearestAirport",
|
||||
"summary": "Invoke functionImport GetNearestAirport",
|
||||
"operationId": "OperationImport.GetNearestAirport.6896b1324a4eff76ad9867a0",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "lat",
|
||||
|
@ -2011,8 +2011,8 @@
|
|||
"tags": [
|
||||
"ResetDataSource"
|
||||
],
|
||||
"summary": "Invoke action ResetDataSource",
|
||||
"operationId": "OperationImport.0-ResetDataSource",
|
||||
"summary": "Invoke actionImport ResetDataSource",
|
||||
"operationId": "OperationImport.ResetDataSource",
|
||||
"responses": {
|
||||
"204": {
|
||||
"description": "Success"
|
||||
|
|
|
@ -251,7 +251,7 @@ paths:
|
|||
tags:
|
||||
- People.Functions
|
||||
summary: Invoke function GetFavoriteAirline
|
||||
operationId: People.0-GetFavoriteAirline
|
||||
operationId: People.Person.GetFavoriteAirline.1c526eb64c7a82083ebab0f2
|
||||
parameters:
|
||||
- name: UserName
|
||||
in: path
|
||||
|
@ -277,7 +277,7 @@ paths:
|
|||
tags:
|
||||
- People.Functions
|
||||
summary: Invoke function GetFriendsTrips
|
||||
operationId: People.0-GetFriendsTrips
|
||||
operationId: People.Person.GetFriendsTrips.9b42e09ab8ef6d73b88be6e9
|
||||
parameters:
|
||||
- name: UserName
|
||||
in: path
|
||||
|
@ -310,7 +310,7 @@ paths:
|
|||
tags:
|
||||
- People.Functions
|
||||
summary: Invoke function UpdatePersonLastName
|
||||
operationId: People.0-UpdatePersonLastName
|
||||
operationId: People.Person.UpdatePersonLastName.e4ea38792d2cfa3aa5bab91b
|
||||
parameters:
|
||||
- name: UserName
|
||||
in: path
|
||||
|
@ -340,7 +340,7 @@ paths:
|
|||
tags:
|
||||
- People.Actions
|
||||
summary: Invoke action ShareTrip
|
||||
operationId: People.0-ShareTrip
|
||||
operationId: People.Person.ShareTrip
|
||||
parameters:
|
||||
- name: UserName
|
||||
in: path
|
||||
|
@ -981,7 +981,7 @@ paths:
|
|||
tags:
|
||||
- NewComePeople.Functions
|
||||
summary: Invoke function GetFavoriteAirline
|
||||
operationId: NewComePeople.0-GetFavoriteAirline
|
||||
operationId: NewComePeople.Person.GetFavoriteAirline.1c526eb64c7a82083ebab0f2
|
||||
parameters:
|
||||
- name: UserName
|
||||
in: path
|
||||
|
@ -1007,7 +1007,7 @@ paths:
|
|||
tags:
|
||||
- NewComePeople.Functions
|
||||
summary: Invoke function GetFriendsTrips
|
||||
operationId: NewComePeople.0-GetFriendsTrips
|
||||
operationId: NewComePeople.Person.GetFriendsTrips.9b42e09ab8ef6d73b88be6e9
|
||||
parameters:
|
||||
- name: UserName
|
||||
in: path
|
||||
|
@ -1040,7 +1040,7 @@ paths:
|
|||
tags:
|
||||
- NewComePeople.Functions
|
||||
summary: Invoke function UpdatePersonLastName
|
||||
operationId: NewComePeople.0-UpdatePersonLastName
|
||||
operationId: NewComePeople.Person.UpdatePersonLastName.e4ea38792d2cfa3aa5bab91b
|
||||
parameters:
|
||||
- name: UserName
|
||||
in: path
|
||||
|
@ -1070,7 +1070,7 @@ paths:
|
|||
tags:
|
||||
- NewComePeople.Actions
|
||||
summary: Invoke action ShareTrip
|
||||
operationId: NewComePeople.0-ShareTrip
|
||||
operationId: NewComePeople.Person.ShareTrip
|
||||
parameters:
|
||||
- name: UserName
|
||||
in: path
|
||||
|
@ -1176,7 +1176,7 @@ paths:
|
|||
tags:
|
||||
- Me.Functions
|
||||
summary: Invoke function GetFavoriteAirline
|
||||
operationId: Me.0-GetFavoriteAirline
|
||||
operationId: Me.Person.GetFavoriteAirline.1c526eb64c7a82083ebab0f2
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
|
@ -1194,7 +1194,7 @@ paths:
|
|||
tags:
|
||||
- Me.Functions
|
||||
summary: Invoke function GetFriendsTrips
|
||||
operationId: Me.0-GetFriendsTrips
|
||||
operationId: Me.Person.GetFriendsTrips.9b42e09ab8ef6d73b88be6e9
|
||||
parameters:
|
||||
- name: userName
|
||||
in: path
|
||||
|
@ -1220,7 +1220,7 @@ paths:
|
|||
tags:
|
||||
- Me.Functions
|
||||
summary: Invoke function UpdatePersonLastName
|
||||
operationId: Me.0-UpdatePersonLastName
|
||||
operationId: Me.Person.UpdatePersonLastName.e4ea38792d2cfa3aa5bab91b
|
||||
parameters:
|
||||
- name: lastName
|
||||
in: path
|
||||
|
@ -1243,7 +1243,7 @@ paths:
|
|||
tags:
|
||||
- Me.Actions
|
||||
summary: Invoke action ShareTrip
|
||||
operationId: Me.0-ShareTrip
|
||||
operationId: Me.Person.ShareTrip
|
||||
requestBody:
|
||||
description: Action parameters
|
||||
content:
|
||||
|
@ -1265,12 +1265,12 @@ paths:
|
|||
default:
|
||||
$ref: '#/components/responses/error'
|
||||
x-ms-docs-operation-type: action
|
||||
/GetPersonWithMostFriends:
|
||||
/GetPersonWithMostFriends():
|
||||
get:
|
||||
tags:
|
||||
- People
|
||||
summary: Invoke function GetPersonWithMostFriends
|
||||
operationId: OperationImport.0-GetPersonWithMostFriends
|
||||
summary: Invoke functionImport GetPersonWithMostFriends
|
||||
operationId: OperationImport.GetPersonWithMostFriends.de8b4a5ab51ba6c8c254fe80
|
||||
responses:
|
||||
'200':
|
||||
description: Success
|
||||
|
@ -1283,12 +1283,12 @@ paths:
|
|||
default:
|
||||
$ref: '#/components/responses/error'
|
||||
x-ms-docs-operation-type: functionImport
|
||||
/GetNearestAirport:
|
||||
'/GetNearestAirport(lat={lat},lon={lon})':
|
||||
get:
|
||||
tags:
|
||||
- Airports
|
||||
summary: Invoke function GetNearestAirport
|
||||
operationId: OperationImport.0-GetNearestAirport
|
||||
summary: Invoke functionImport GetNearestAirport
|
||||
operationId: OperationImport.GetNearestAirport.6896b1324a4eff76ad9867a0
|
||||
parameters:
|
||||
- name: lat
|
||||
in: path
|
||||
|
@ -1330,8 +1330,8 @@ paths:
|
|||
post:
|
||||
tags:
|
||||
- ResetDataSource
|
||||
summary: Invoke action ResetDataSource
|
||||
operationId: OperationImport.0-ResetDataSource
|
||||
summary: Invoke actionImport ResetDataSource
|
||||
operationId: OperationImport.ResetDataSource
|
||||
responses:
|
||||
'204':
|
||||
description: Success
|
||||
|
|
Loading…
Reference in a new issue