From da88280bbc62a39a0706ac8d26c1a3bbf3415028 Mon Sep 17 00:00:00 2001 From: Harrison Ulrich Date: Sun, 7 Feb 2016 19:10:13 -0600 Subject: [PATCH 1/2] Updated EnableQuery filter to check if return type is a collection --- .editorconfig | 7 ++++ Swashbuckle.OData.Tests/Fixtures/GetTests.cs | 40 +++++++++++++++++++ .../Descriptions/ODataSwaggerUtilities.cs | 23 +++++++---- Swashbuckle.OData/EnableQueryFilter.cs | 22 +++++++++- 4 files changed, 83 insertions(+), 9 deletions(-) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..05936bb --- /dev/null +++ b/.editorconfig @@ -0,0 +1,7 @@ +; Top-most EditorConfig file +root = true + +; 4-column space indention +[*.cs] +indent_style = space +indent_size = 4 diff --git a/Swashbuckle.OData.Tests/Fixtures/GetTests.cs b/Swashbuckle.OData.Tests/Fixtures/GetTests.cs index 9914e44..6811d19 100644 --- a/Swashbuckle.OData.Tests/Fixtures/GetTests.cs +++ b/Swashbuckle.OData.Tests/Fixtures/GetTests.cs @@ -62,6 +62,46 @@ public async Task It_has_all_optional_odata_query_parameters() } } + [Test] + public async Task It_has_collection_odata_query_parameters() + { + using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(CustomersController)))) + { + // Arrange + var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress); + + // Act + var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1"); + + // Assert + PathItem pathItem; + swaggerDocument.paths.TryGetValue("/odata/Customers", out pathItem); + pathItem.get.parameters.Where(parameter => parameter.name.StartsWith("$")).Should().HaveCount(7); + + await ValidationUtils.ValidateSwaggerJson(); + } + } + + [Test] + public async Task It_has_single_entity_odata_query_parameters() + { + using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(CustomersController)))) + { + // Arrange + var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress); + + // Act + var swaggerDocument = await httpClient.GetJsonAsync("swagger/docs/v1"); + + // Assert + PathItem pathItem; + swaggerDocument.paths.TryGetValue("/odata/Customers({Id})", out pathItem); + pathItem.get.parameters.Where(parameter => parameter.name.StartsWith("$")).Should().HaveCount(2); + + await ValidationUtils.ValidateSwaggerJson(); + } + } + [Test] public async Task It_has_a_parameter_with_a_name_equal_to_the_path_name() { diff --git a/Swashbuckle.OData/Descriptions/ODataSwaggerUtilities.cs b/Swashbuckle.OData/Descriptions/ODataSwaggerUtilities.cs index e46c9ea..268b14e 100644 --- a/Swashbuckle.OData/Descriptions/ODataSwaggerUtilities.cs +++ b/Swashbuckle.OData/Descriptions/ODataSwaggerUtilities.cs @@ -35,7 +35,7 @@ public static PathItem CreateSwaggerPathForEntitySet(IEdmEntitySet entitySet) .OperationId(entitySet.Name + "_Get") .Description("Returns the EntitySet " + entitySet.Name) .Tags(entitySet.Name) - .Parameters(AddQueryOptionParameters(new List())) + .Parameters(AddQueryOptionParametersForEntitySet(new List())) .Responses(new Dictionary().Response("200", "EntitySet " + entitySet.Name, entitySet.Type).DefaultErrorResponse()), post = new Operation() .Summary("Post a new entity to EntitySet " + entitySet.Name) @@ -48,7 +48,7 @@ public static PathItem CreateSwaggerPathForEntitySet(IEdmEntitySet entitySet) }; } - public static IList AddQueryOptionParameters(IList parameterList) + public static IList AddQueryOptionParametersForEntitySet(IList parameterList) { return parameterList .Parameter("$expand", "query", "Expands related entities inline.", "string", false) @@ -60,12 +60,19 @@ public static IList AddQueryOptionParameters(IList paramet .Parameter("$count", "query", "Includes a count of the matching results in the response.", "boolean", false); } - /// - /// Create the Swagger path for the Edm entity. - /// - /// The entity set. - /// - public static PathItem CreateSwaggerPathForEntity(IEdmEntitySet entitySet) + public static IList AddQueryOptionParametersForEntity(IList parameterList) + { + return parameterList + .Parameter("$expand", "query", "Expands related entities inline.", "string", false) + .Parameter("$select", "query", "Selects which properties to include in the response.", "string", false); + } + + /// + /// Create the Swagger path for the Edm entity. + /// + /// The entity set. + /// + public static PathItem CreateSwaggerPathForEntity(IEdmEntitySet entitySet) { Contract.Requires(entitySet != null); Contract.Ensures(Contract.Result() != null); diff --git a/Swashbuckle.OData/EnableQueryFilter.cs b/Swashbuckle.OData/EnableQueryFilter.cs index c6cb1dd..43e5041 100644 --- a/Swashbuckle.OData/EnableQueryFilter.cs +++ b/Swashbuckle.OData/EnableQueryFilter.cs @@ -5,6 +5,8 @@ using System.Web.OData; using Swashbuckle.OData.Descriptions; using Swashbuckle.Swagger; +using System.Web.Http; +using System; namespace Swashbuckle.OData { @@ -21,7 +23,9 @@ public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescrip if (HasEnableQueryAttribute(apiDescription) && !HasAnyQueryOptionParameters(operation)) { - operation.parameters = ODataSwaggerUtilities.AddQueryOptionParameters(operation.parameters ?? new List()); + operation.parameters = ReturnsCollection(apiDescription) + ? ODataSwaggerUtilities.AddQueryOptionParametersForEntitySet(operation.parameters ?? new List()) + : ODataSwaggerUtilities.AddQueryOptionParametersForEntity(operation.parameters ?? new List()); } } @@ -36,5 +40,21 @@ private static bool HasEnableQueryAttribute(ApiDescription apiDescription) Contract.Assume(httpActionDescriptor != null); return httpActionDescriptor.GetCustomAttributes().Any(); } + + private static bool ReturnsCollection(ApiDescription apiDescription) + { + var httpActionDescriptor = apiDescription.ActionDescriptor; + Contract.Assume(httpActionDescriptor != null); + + Type returnType = httpActionDescriptor.ReturnType; + + var responseTypeAttr = httpActionDescriptor.GetCustomAttributes().FirstOrDefault(); + if (responseTypeAttr != null) + returnType = responseTypeAttr.ResponseType; + + return returnType.IsCollection(); + } + + } } \ No newline at end of file From 3b252a61b022f3a44d9884d769e79f9e367f5f61 Mon Sep 17 00:00:00 2001 From: Harrison Ulrich Date: Sun, 7 Feb 2016 23:42:44 -0600 Subject: [PATCH 2/2] tabs --- .../Descriptions/ODataSwaggerUtilities.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Swashbuckle.OData/Descriptions/ODataSwaggerUtilities.cs b/Swashbuckle.OData/Descriptions/ODataSwaggerUtilities.cs index 268b14e..74fdf68 100644 --- a/Swashbuckle.OData/Descriptions/ODataSwaggerUtilities.cs +++ b/Swashbuckle.OData/Descriptions/ODataSwaggerUtilities.cs @@ -67,12 +67,12 @@ public static IList AddQueryOptionParametersForEntity(IList - /// Create the Swagger path for the Edm entity. - /// - /// The entity set. - /// - public static PathItem CreateSwaggerPathForEntity(IEdmEntitySet entitySet) + /// + /// Create the Swagger path for the Edm entity. + /// + /// The entity set. + /// + public static PathItem CreateSwaggerPathForEntity(IEdmEntitySet entitySet) { Contract.Requires(entitySet != null); Contract.Ensures(Contract.Result() != null);