Skip to content

Commit

Permalink
Add prefix parameters to swagger operation
Browse files Browse the repository at this point in the history
Operations on Entities were missing the prefix parameters. This would
cause an unbound variable exception if you had a route prefix and a
function or action bound to an entity.
  • Loading branch information
vantubbe committed Oct 5, 2016
1 parent 85c25df commit c617506
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 2 deletions.
44 changes: 44 additions & 0 deletions Swashbuckle.OData.Tests/Fixtures/FunctionTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
using Owin;
using Swashbuckle.Swagger;
using SwashbuckleODataSample.Models;
using System.Web.Http.Routing.Constraints;
using System.Web.Http;

namespace Swashbuckle.OData.Tests
{
Expand Down Expand Up @@ -196,6 +198,34 @@ public async Task It_supports_unbound_functions()
}
}

[Test]
public async Task It_supports_a_function_bound_to_an_entity_using_route_param()
{
Action<HttpConfiguration> configAction = config =>
{
// Define a route to a controller class that contains functions
var route = config.MapODataServiceRoute("FunctionsODataRouteWithParam", "odata/v1/{intParam}", GetFunctionsEdmModel());
route.Constraints.Add("intParam", new IntRouteConstraint());
};

using (WebApp.Start(HttpClientUtils.BaseAddress, appBuilder => Configuration(appBuilder, typeof(ProductsV1Controller),configAction)))
{
// Arrange
var httpClient = HttpClientUtils.GetHttpClient(HttpClientUtils.BaseAddress);

// Act
var swaggerDocument = await httpClient.GetJsonAsync<SwaggerDocument>("swagger/docs/v1");

// Assert
PathItem pathItem;
swaggerDocument.paths.TryGetValue("/odata/v1/{intParam}/Products({Id})/Default.GetPriceRank()", out pathItem);
pathItem.Should().NotBeNull();
pathItem.get.Should().NotBeNull();

await ValidationUtils.ValidateSwaggerJson();
}
}

private static void Configuration(IAppBuilder appBuilder, Type targetController)
{
var config = appBuilder.GetStandardHttpConfig(targetController);
Expand All @@ -210,6 +240,20 @@ private static void Configuration(IAppBuilder appBuilder, Type targetController)
config.EnsureInitialized();
}

private static void Configuration(IAppBuilder appBuilder, Type targetController, Action<HttpConfiguration> configAction)
{
var config = appBuilder.GetStandardHttpConfig(targetController);

var controllerSelector = new UnitTestODataVersionControllerSelector(config, targetController);
config.Services.Replace(typeof(IHttpControllerSelector), controllerSelector);

configAction(config);

controllerSelector.RouteVersionSuffixMapping.Add("FunctionsODataRoute", "V1");

config.EnsureInitialized();
}

private static IEdmModel GetFunctionsEdmModel()
{
ODataModelBuilder builder = new ODataConventionModelBuilder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ private static IEnumerable<SwaggerRoute> GenerateOperationRoutes(ODataRoute oDat
var entityType = (IEdmEntityType)boundType;
var edmEntitySets = oDataRoute.GetEdmModel().EntityContainer.EntitySets();
Contract.Assume(edmEntitySets != null);
routes.AddRange(edmEntitySets.Where(es => es.GetEntityType().Equals(entityType)).Select(entitySet => new SwaggerRoute(ODataSwaggerUtilities.GetPathForOperationOfEntity(operation, entitySet), oDataRoute, ODataSwaggerUtilities.CreateSwaggerPathForOperationOfEntity(operation, entitySet))));
routes.AddRange(edmEntitySets.Where(es => es.GetEntityType().Equals(entityType)).Select(entitySet => new SwaggerRoute(ODataSwaggerUtilities.GetPathForOperationOfEntity(operation, entitySet), oDataRoute, ODataSwaggerUtilities.CreateSwaggerPathForOperationOfEntity(operation, entitySet, oDataRoute))));
}
else if (boundType.TypeKind == EdmTypeKind.Collection)
{
Expand Down
3 changes: 2 additions & 1 deletion Swashbuckle.OData/Descriptions/ODataSwaggerUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ private static void AddSwaggerParametersForAction(List<Parameter> swaggerParamet
/// <param name="operation">The Edm operation.</param>
/// <param name="entitySet">The entity set.</param>
/// <returns></returns>
public static PathItem CreateSwaggerPathForOperationOfEntity(IEdmOperation operation, IEdmEntitySet entitySet)
public static PathItem CreateSwaggerPathForOperationOfEntity(IEdmOperation operation, IEdmEntitySet entitySet, ODataRoute oDataRoute)
{
Contract.Requires(operation != null);
Contract.Requires(entitySet != null);
Expand Down Expand Up @@ -424,6 +424,7 @@ public static PathItem CreateSwaggerPathForOperationOfEntity(IEdmOperation opera
var swaggerOperation = new Operation()
.Summary("Call operation " + operation.Name)
.Description("Call operation " + operation.Name)
.Parameters(AddRoutePrefixParameters(oDataRoute))
.Tags(entitySet.Name, isFunction ? "Function" : "Action");

if (swaggerParameters.Count > 0)
Expand Down

0 comments on commit c617506

Please sign in to comment.