Skip to content

Commit

Permalink
Updated EnableQuery filter to check if return type is a collection
Browse files Browse the repository at this point in the history
  • Loading branch information
bigred8982 committed Feb 8, 2016
1 parent e933dc0 commit da88280
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 9 deletions.
7 changes: 7 additions & 0 deletions .editorconfig
@@ -0,0 +1,7 @@
; Top-most EditorConfig file
root = true

; 4-column space indention
[*.cs]
indent_style = space
indent_size = 4
40 changes: 40 additions & 0 deletions Swashbuckle.OData.Tests/Fixtures/GetTests.cs
Expand Up @@ -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<SwaggerDocument>("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<SwaggerDocument>("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()
{
Expand Down
23 changes: 15 additions & 8 deletions Swashbuckle.OData/Descriptions/ODataSwaggerUtilities.cs
Expand Up @@ -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<Parameter>()))
.Parameters(AddQueryOptionParametersForEntitySet(new List<Parameter>()))
.Responses(new Dictionary<string, Response>().Response("200", "EntitySet " + entitySet.Name, entitySet.Type).DefaultErrorResponse()),
post = new Operation()
.Summary("Post a new entity to EntitySet " + entitySet.Name)
Expand All @@ -48,7 +48,7 @@ public static PathItem CreateSwaggerPathForEntitySet(IEdmEntitySet entitySet)
};
}

public static IList<Parameter> AddQueryOptionParameters(IList<Parameter> parameterList)
public static IList<Parameter> AddQueryOptionParametersForEntitySet(IList<Parameter> parameterList)
{
return parameterList
.Parameter("$expand", "query", "Expands related entities inline.", "string", false)
Expand All @@ -60,12 +60,19 @@ public static IList<Parameter> AddQueryOptionParameters(IList<Parameter> paramet
.Parameter("$count", "query", "Includes a count of the matching results in the response.", "boolean", false);
}

/// <summary>
/// Create the Swagger path for the Edm entity.
/// </summary>
/// <param name="entitySet">The entity set.</param>
/// <returns></returns>
public static PathItem CreateSwaggerPathForEntity(IEdmEntitySet entitySet)
public static IList<Parameter> AddQueryOptionParametersForEntity(IList<Parameter> 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);
}

/// <summary>
/// Create the Swagger path for the Edm entity.
/// </summary>
/// <param name="entitySet">The entity set.</param>
/// <returns></returns>
public static PathItem CreateSwaggerPathForEntity(IEdmEntitySet entitySet)
{
Contract.Requires(entitySet != null);
Contract.Ensures(Contract.Result<PathItem>() != null);
Expand Down
22 changes: 21 additions & 1 deletion Swashbuckle.OData/EnableQueryFilter.cs
Expand Up @@ -5,6 +5,8 @@
using System.Web.OData;
using Swashbuckle.OData.Descriptions;
using Swashbuckle.Swagger;
using System.Web.Http;
using System;

namespace Swashbuckle.OData
{
Expand All @@ -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<Parameter>());
operation.parameters = ReturnsCollection(apiDescription)
? ODataSwaggerUtilities.AddQueryOptionParametersForEntitySet(operation.parameters ?? new List<Parameter>())
: ODataSwaggerUtilities.AddQueryOptionParametersForEntity(operation.parameters ?? new List<Parameter>());
}
}

Expand All @@ -36,5 +40,21 @@ private static bool HasEnableQueryAttribute(ApiDescription apiDescription)
Contract.Assume(httpActionDescriptor != null);
return httpActionDescriptor.GetCustomAttributes<EnableQueryAttribute>().Any();
}

private static bool ReturnsCollection(ApiDescription apiDescription)
{
var httpActionDescriptor = apiDescription.ActionDescriptor;
Contract.Assume(httpActionDescriptor != null);

Type returnType = httpActionDescriptor.ReturnType;

var responseTypeAttr = httpActionDescriptor.GetCustomAttributes<ResponseTypeAttribute>().FirstOrDefault();
if (responseTypeAttr != null)
returnType = responseTypeAttr.ResponseType;

return returnType.IsCollection();
}


}
}

0 comments on commit da88280

Please sign in to comment.