diff --git a/src/Microsoft.OpenApi.OData.Reader/Microsoft.OpenAPI.OData.Reader.csproj b/src/Microsoft.OpenApi.OData.Reader/Microsoft.OpenAPI.OData.Reader.csproj
index 7effe22e..be061bdc 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Microsoft.OpenAPI.OData.Reader.csproj
+++ b/src/Microsoft.OpenApi.OData.Reader/Microsoft.OpenAPI.OData.Reader.csproj
@@ -15,23 +15,13 @@
netstandard2.0
Microsoft.OpenApi.OData
true
- 1.0.11
+ 1.1.0-preview1
This package contains the codes you need to convert OData CSDL to Open API Document of Model.
© Microsoft Corporation. All rights reserved.
Microsoft OpenApi OData EDM
https://github.com/Microsoft/OpenAPI.NET.OData
-- Fixes reading restriction annotations for entity types defining navigation properties #220
-- Enables configuring appending bound operations on derived types #221
-- Add error ranges for OData actions when ErrorResponsesAsDefault is set to false #218
-- Fixes missing bound operations on some navigation property paths #201
-- Provides support for using success status code range 2XX #153
-- Fixes request body and response representation for ref POST and PUT operations #228
-- Adds discriminator object to complex types which have derived types #233
-- Lists all the derived types of a type in discriminator mapping #240
-- Adds @odata.type property and makes this a required property in schemas that have discriminator objects #243
-- Appends `@odata.type` property to all derived types schemas #248
-- Represent nullable references within anyOf correctly #190
+- Fixes response schemas of actions and functions that return a collection to contain the nextLink property #231
Microsoft.OpenApi.OData.Reader
..\..\tool\Microsoft.OpenApi.OData.snk
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EdmActionOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EdmActionOperationHandler.cs
index bcbc883c..77cd097a 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/EdmActionOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EdmActionOperationHandler.cs
@@ -35,6 +35,16 @@ protected override void SetRequestBody(OpenApiOperation operation)
protected override void SetExtensions(OpenApiOperation operation)
{
operation.Extensions.Add(Constants.xMsDosOperationType, new OpenApiString("action"));
+ if (Context.Settings.EnablePagination && EdmOperation.ReturnType?.TypeKind() == EdmTypeKind.Collection)
+ {
+ OpenApiObject extension = new OpenApiObject
+ {
+ { "nextLinkName", new OpenApiString("@odata.nextLink")},
+ { "operationName", new OpenApiString(Context.Settings.PageableOperationName)}
+ };
+
+ operation.Extensions.Add(Constants.xMsPageable, extension);
+ }
base.SetExtensions(operation);
}
}
diff --git a/src/Microsoft.OpenApi.OData.Reader/Operation/EdmFunctionOperationHandler.cs b/src/Microsoft.OpenApi.OData.Reader/Operation/EdmFunctionOperationHandler.cs
index 4cbf0525..c1134f8d 100644
--- a/src/Microsoft.OpenApi.OData.Reader/Operation/EdmFunctionOperationHandler.cs
+++ b/src/Microsoft.OpenApi.OData.Reader/Operation/EdmFunctionOperationHandler.cs
@@ -27,6 +27,16 @@ internal class EdmFunctionOperationHandler : EdmOperationOperationHandler
protected override void SetExtensions(OpenApiOperation operation)
{
operation.Extensions.Add(Constants.xMsDosOperationType, new OpenApiString("function"));
+ if (Context.Settings.EnablePagination && EdmOperation.ReturnType?.TypeKind() == EdmTypeKind.Collection)
+ {
+ OpenApiObject extension = new OpenApiObject
+ {
+ { "nextLinkName", new OpenApiString("@odata.nextLink")},
+ { "operationName", new OpenApiString(Context.Settings.PageableOperationName)}
+ };
+
+ operation.Extensions.Add(Constants.xMsPageable, extension);
+ }
base.SetExtensions(operation);
}
}
diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EdmActionOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EdmActionOperationHandlerTests.cs
index ed8fd1fa..a4e93bb6 100644
--- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EdmActionOperationHandlerTests.cs
+++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EdmActionOperationHandlerTests.cs
@@ -54,7 +54,7 @@ public void CreateOperationForEdmActionReturnsCorrectOperation()
}
[Fact]
- public void CreateOperationForEdmActionReturnsCorrectOperationHierarhicalClass()
+ public void CreateOperationForEdmActionReturnsCorrectOperationHierarchicalClass()
{
// Arrange
IEdmModel model = EdmModelHelper.ContractServiceModel;
@@ -296,5 +296,44 @@ public void OperationRestrictionsTermWorksToCreateOperationForEdmAction(bool ena
Assert.Empty(operation.Security);
}
}
+
+ [Theory]
+ [InlineData("getMailTips", true)] // returns collection
+ [InlineData("getMailTips", false)] // returns collection
+ [InlineData("findMeetingTimes", true)] // does not return collection
+ public void CreateOperationForEdmActionWithCollectionReturnTypeContainsXMsPageableExtension(string actionName, bool enablePagination)
+ {
+ // Arrange
+ IEdmModel model = EdmModelHelper.GraphBetaModel;
+ OpenApiConvertSettings settings = new()
+ {
+ EnableOperationId = true,
+ EnablePagination = enablePagination
+ };
+ ODataContext context = new(model, settings);
+ IEdmAction action = model.SchemaElements.OfType()
+ .First(x => x.Name == actionName &&
+ x.FindParameter("bindingParameter").Type.Definition.ToString() == "microsoft.graph.user");
+ IEdmEntityContainer container = model.SchemaElements.OfType().First();
+ IEdmEntitySet users = container.FindEntitySet("users");
+ IEdmEntityType user = model.SchemaElements.OfType().First(x => x.Name == "user");
+
+ ODataPath path = new(new ODataNavigationSourceSegment(users),
+ new ODataKeySegment(user),
+ new ODataOperationSegment(action));
+
+ // Act
+ var operation = _operationHandler.CreateOperation(context, path);
+
+ // Assert
+ if (enablePagination && action.ReturnType.IsCollection())
+ {
+ Assert.True(operation.Extensions.ContainsKey(Common.Constants.xMsPageable));
+ }
+ else
+ {
+ Assert.False(operation.Extensions.ContainsKey(Common.Constants.xMsPageable));
+ }
+ }
}
}
diff --git a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EdmFunctionOperationHandlerTests.cs b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EdmFunctionOperationHandlerTests.cs
index 5edb1fd9..3542a580 100644
--- a/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EdmFunctionOperationHandlerTests.cs
+++ b/test/Microsoft.OpenAPI.OData.Reader.Tests/Operation/EdmFunctionOperationHandlerTests.cs
@@ -112,7 +112,7 @@ public void CreateOperationForEdmFunctionReturnsCorrectOperation(bool useHTTPSta
}
[Fact]
- public void CreateOperationForEdmFunctionReturnsCorrectOperationHierarhicalClass()
+ public void CreateOperationForEdmFunctionReturnsCorrectOperationHierarchicalClass()
{
// Arrange
IEdmModel model = EdmModelHelper.ContractServiceModel;
@@ -408,5 +408,42 @@ public void OperationRestrictionsTermWorksToCreateOperationForEdmFunction(bool e
Assert.Empty(operation.Security);
}
}
+
+ [Theory]
+ [InlineData("getUserArchivedPrintJobs", true)] // returns collection
+ [InlineData("getUserArchivedPrintJobs", false)] // returns collection
+ [InlineData("managedDeviceEnrollmentAbandonmentSummary", true)] // does not return collection
+ public void CreateOperationForEdmFunctionWithCollectionReturnTypeContainsXMsPageableExtension(string functionName, bool enablePagination)
+ {
+ // Arrange
+ IEdmModel model = EdmModelHelper.GraphBetaModel;
+ OpenApiConvertSettings settings = new()
+ {
+ EnableOperationId = true,
+ EnablePagination = enablePagination
+ };
+ ODataContext context = new(model, settings);
+ IEdmFunction function = model.SchemaElements.OfType()
+ .First(x => x.Name == functionName &&
+ x.FindParameter("bindingParameter").Type.Definition.ToString() == "microsoft.graph.reportRoot");
+ IEdmEntityContainer container = model.SchemaElements.OfType().First();
+ IEdmSingleton reports = container.FindSingleton("reports");
+
+ ODataPath path = new(new ODataNavigationSourceSegment(reports),
+ new ODataOperationSegment(function));
+
+ // Act
+ var operation = _operationHandler.CreateOperation(context, path);
+
+ // Assert
+ if (enablePagination && function.ReturnType.IsCollection())
+ {
+ Assert.True(operation.Extensions.ContainsKey(Common.Constants.xMsPageable));
+ }
+ else
+ {
+ Assert.False(operation.Extensions.ContainsKey(Common.Constants.xMsPageable));
+ }
+ }
}
}