Skip to content
Browse files

RouteDefaults specs for Web API

  • Loading branch information...
1 parent 907df42 commit 10c419483974f5f79c49a57e0adf18f9ffa6162d @kamranayub committed
View
2 src/AttributeRouting.Specs/AttributeRouting.Specs.csproj
@@ -134,8 +134,10 @@
<Compile Include="Steps\SharedSteps.cs" />
<Compile Include="Steps\StandardUsageSteps.cs" />
<Compile Include="Subjects\BugFixesController.cs" />
+ <Compile Include="Subjects\Http\RouteAreasControllers.cs" />
<Compile Include="Subjects\Http\RouteConstraintsController.cs" />
<Compile Include="Subjects\Http\RouteConventionsController.cs" />
+ <Compile Include="Subjects\Http\RouteDefaultsController.cs" />
<Compile Include="Subjects\Http\StandardUsageController.cs" />
<Compile Include="Subjects\LowercaseUrlController.cs" />
<Compile Include="Subjects\RouteAreasControllers.cs" />
View
19 src/AttributeRouting.Specs/Features/RouteAreas.feature
@@ -7,25 +7,40 @@ Scenario: Generating area routes
When I fetch the routes for the Areas controller's Index action
Then the route url is "Area/Index"
And the data token for "area" is "Area"
+ When I fetch the routes for the HttpAreas controller's Get action
+ Then the route url is "ApiArea/Get"
+ And the data token for "area" is "ApiArea"
Scenario: Generating area routes when route urls specify a duplicate area prefix
When I fetch the routes for the Areas controller's DuplicatePrefix action
Then the route url is "Area/DuplicatePrefix"
+ When I fetch the routes for the HttpAreas controller's DuplicatePrefix action
+ Then the route url is "ApiArea/DuplicatePrefix"
Scenario: Generating absolute routes when a route area is defined
When I fetch the routes for the Areas controller's Absolute action
Then the route url is "AreaAbsolute"
+ When I fetch the routes for the HttpAreas controller's Absolute action
+ Then the route url is "ApiAreaAbsolute"
Scenario: Generating area routes when route url starts with the area prefix
When I fetch the routes for the Areas controller's RouteBeginsWithAreaName action
Then the route url is "Area/Areas"
+ When I fetch the routes for the HttpAreas controller's RouteBeginsWithAreaName action
+ Then the route url is "ApiArea/ApiAreas"
Scenario: Generating area routes with an explicit area url
When I fetch the routes for the ExplicitAreaUrl controller's Index action
Then the route url is "ExplicitArea/Index"
And the data token for "area" is "Area"
-
+ When I fetch the routes for the HttpExplicitAreaUrl controller's Get action
+ Then the route url is "ApiExplicitArea/Get"
+ And the data token for "area" is "ApiArea"
+
Scenario: Generating area routes with an explicit area url when route urls specify a duplicate area prefix
When I fetch the routes for the ExplicitAreaUrl controller's DuplicatePrefix action
Then the route url is "ExplicitArea/DuplicatePrefix"
- And the data token for "area" is "Area"
+ And the data token for "area" is "Area"
+ When I fetch the routes for the HttpExplicitAreaUrl controller's DuplicatePrefix action
+ Then the route url is "ApiExplicitArea/DuplicatePrefix"
+ And the data token for "area" is "ApiArea"
View
65 src/AttributeRouting.Specs/Features/RouteAreas.feature.cs
@@ -87,6 +87,12 @@ public virtual void GeneratingAreaRoutes()
testRunner.Then("the route url is \"Area/Index\"");
#line 9
testRunner.And("the data token for \"area\" is \"Area\"");
+#line 10
+ testRunner.When("I fetch the routes for the HttpAreas controller\'s Get action");
+#line 11
+ testRunner.Then("the route url is \"ApiArea/Get\"");
+#line 12
+ testRunner.And("the data token for \"area\" is \"ApiArea\"");
#line hidden
this.ScenarioCleanup();
}
@@ -96,14 +102,18 @@ public virtual void GeneratingAreaRoutes()
public virtual void GeneratingAreaRoutesWhenRouteUrlsSpecifyADuplicateAreaPrefix()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Generating area routes when route urls specify a duplicate area prefix", ((string[])(null)));
-#line 11
+#line 14
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 12
+#line 15
testRunner.When("I fetch the routes for the Areas controller\'s DuplicatePrefix action");
-#line 13
+#line 16
testRunner.Then("the route url is \"Area/DuplicatePrefix\"");
+#line 17
+ testRunner.When("I fetch the routes for the HttpAreas controller\'s DuplicatePrefix action");
+#line 18
+ testRunner.Then("the route url is \"ApiArea/DuplicatePrefix\"");
#line hidden
this.ScenarioCleanup();
}
@@ -113,14 +123,18 @@ public virtual void GeneratingAreaRoutesWhenRouteUrlsSpecifyADuplicateAreaPrefix
public virtual void GeneratingAbsoluteRoutesWhenARouteAreaIsDefined()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Generating absolute routes when a route area is defined", ((string[])(null)));
-#line 15
+#line 20
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 16
+#line 21
testRunner.When("I fetch the routes for the Areas controller\'s Absolute action");
-#line 17
+#line 22
testRunner.Then("the route url is \"AreaAbsolute\"");
+#line 23
+ testRunner.When("I fetch the routes for the HttpAreas controller\'s Absolute action");
+#line 24
+ testRunner.Then("the route url is \"ApiAreaAbsolute\"");
#line hidden
this.ScenarioCleanup();
}
@@ -130,14 +144,18 @@ public virtual void GeneratingAbsoluteRoutesWhenARouteAreaIsDefined()
public virtual void GeneratingAreaRoutesWhenRouteUrlStartsWithTheAreaPrefix()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Generating area routes when route url starts with the area prefix", ((string[])(null)));
-#line 19
+#line 26
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 20
+#line 27
testRunner.When("I fetch the routes for the Areas controller\'s RouteBeginsWithAreaName action");
-#line 21
+#line 28
testRunner.Then("the route url is \"Area/Areas\"");
+#line 29
+ testRunner.When("I fetch the routes for the HttpAreas controller\'s RouteBeginsWithAreaName action");
+#line 30
+ testRunner.Then("the route url is \"ApiArea/ApiAreas\"");
#line hidden
this.ScenarioCleanup();
}
@@ -147,16 +165,22 @@ public virtual void GeneratingAreaRoutesWhenRouteUrlStartsWithTheAreaPrefix()
public virtual void GeneratingAreaRoutesWithAnExplicitAreaUrl()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Generating area routes with an explicit area url", ((string[])(null)));
-#line 23
+#line 32
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 24
+#line 33
testRunner.When("I fetch the routes for the ExplicitAreaUrl controller\'s Index action");
-#line 25
+#line 34
testRunner.Then("the route url is \"ExplicitArea/Index\"");
-#line 26
+#line 35
testRunner.And("the data token for \"area\" is \"Area\"");
+#line 36
+ testRunner.When("I fetch the routes for the HttpExplicitAreaUrl controller\'s Get action");
+#line 37
+ testRunner.Then("the route url is \"ApiExplicitArea/Get\"");
+#line 38
+ testRunner.And("the data token for \"area\" is \"ApiArea\"");
#line hidden
this.ScenarioCleanup();
}
@@ -168,16 +192,23 @@ public virtual void GeneratingAreaRoutesWithAnExplicitAreaUrlWhenRouteUrlsSpecif
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Generating area routes with an explicit area url when route urls specify a duplic" +
"ate area prefix", ((string[])(null)));
-#line 28
+#line 40
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 29
+#line 41
testRunner.When("I fetch the routes for the ExplicitAreaUrl controller\'s DuplicatePrefix action");
-#line 30
+#line 42
testRunner.Then("the route url is \"ExplicitArea/DuplicatePrefix\"");
-#line 31
+#line 43
testRunner.And("the data token for \"area\" is \"Area\"");
+#line 44
+ testRunner.When("I fetch the routes for the HttpExplicitAreaUrl controller\'s DuplicatePrefix actio" +
+ "n");
+#line 45
+ testRunner.Then("the route url is \"ApiExplicitArea/DuplicatePrefix\"");
+#line 46
+ testRunner.And("the data token for \"area\" is \"ApiArea\"");
#line hidden
this.ScenarioCleanup();
}
View
6 src/AttributeRouting.Specs/Features/RouteDefaults.feature
@@ -5,16 +5,19 @@ Background:
Scenario: Route default specified with an attribute
When I fetch the routes for the RouteDefaults controller's Index action
+ And I fetch the routes for the HttpRouteDefaults controller's Get action
Then the default for "p1" is "variable"
Scenario: Route default specified inline
When I fetch the routes for the RouteDefaults controller's InlineDefaults action
+ And I fetch the routes for the HttpRouteDefaults controller's InlineDefaults action
Then the route url is "InlineDefaults/{hello}/{goodnight}"
Then the default for "hello" is "sun"
Then the default for "goodnight" is "moon"
Scenario: Optional parameters specified with a url parameter token
When I fetch the routes for the RouteDefaults controller's Optionals action
+ And I fetch the routes for the HttpRouteDefaults controller's Optionals action
Then the route url is "Optionals/{p1}/{p2}/{p3}"
And the parameter "p1" is optional
And the parameter "p2" is optional
@@ -22,5 +25,8 @@ Scenario: Optional parameters specified with a url parameter token
Scenario: Multiple routes with different defaults
When I fetch the routes for the RouteDefaults controller's MultipleRoutes action
+ And I fetch the routes for the HttpRouteDefaults controller's MultipleRoutes action
Then the route named "MultipleDefaults1" has a default for "p1" of "first"
And the route named "MultipleDefaults2" has a default for "p1" of "second"
+ And the route named "ApiMultipleDefaults1" has a default for "p1" of "first"
+ And the route named "ApiMultipleDefaults2" has a default for "p1" of "second"
View
42 src/AttributeRouting.Specs/Features/RouteDefaults.feature.cs
@@ -84,6 +84,8 @@ public virtual void RouteDefaultSpecifiedWithAnAttribute()
#line 7
testRunner.When("I fetch the routes for the RouteDefaults controller\'s Index action");
#line 8
+ testRunner.And("I fetch the routes for the HttpRouteDefaults controller\'s Get action");
+#line 9
testRunner.Then("the default for \"p1\" is \"variable\"");
#line hidden
this.ScenarioCleanup();
@@ -94,17 +96,19 @@ public virtual void RouteDefaultSpecifiedWithAnAttribute()
public virtual void RouteDefaultSpecifiedInline()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Route default specified inline", ((string[])(null)));
-#line 10
+#line 11
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 11
- testRunner.When("I fetch the routes for the RouteDefaults controller\'s InlineDefaults action");
#line 12
- testRunner.Then("the route url is \"InlineDefaults/{hello}/{goodnight}\"");
+ testRunner.When("I fetch the routes for the RouteDefaults controller\'s InlineDefaults action");
#line 13
- testRunner.Then("the default for \"hello\" is \"sun\"");
+ testRunner.And("I fetch the routes for the HttpRouteDefaults controller\'s InlineDefaults action");
#line 14
+ testRunner.Then("the route url is \"InlineDefaults/{hello}/{goodnight}\"");
+#line 15
+ testRunner.Then("the default for \"hello\" is \"sun\"");
+#line 16
testRunner.Then("the default for \"goodnight\" is \"moon\"");
#line hidden
this.ScenarioCleanup();
@@ -115,19 +119,21 @@ public virtual void RouteDefaultSpecifiedInline()
public virtual void OptionalParametersSpecifiedWithAUrlParameterToken()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Optional parameters specified with a url parameter token", ((string[])(null)));
-#line 16
+#line 18
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 17
+#line 19
testRunner.When("I fetch the routes for the RouteDefaults controller\'s Optionals action");
-#line 18
+#line 20
+ testRunner.And("I fetch the routes for the HttpRouteDefaults controller\'s Optionals action");
+#line 21
testRunner.Then("the route url is \"Optionals/{p1}/{p2}/{p3}\"");
-#line 19
+#line 22
testRunner.And("the parameter \"p1\" is optional");
-#line 20
+#line 23
testRunner.And("the parameter \"p2\" is optional");
-#line 21
+#line 24
testRunner.And("the parameter \"p3\" is optional");
#line hidden
this.ScenarioCleanup();
@@ -138,16 +144,22 @@ public virtual void OptionalParametersSpecifiedWithAUrlParameterToken()
public virtual void MultipleRoutesWithDifferentDefaults()
{
TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Multiple routes with different defaults", ((string[])(null)));
-#line 23
+#line 26
this.ScenarioSetup(scenarioInfo);
#line 3
this.FeatureBackground();
-#line 24
+#line 27
testRunner.When("I fetch the routes for the RouteDefaults controller\'s MultipleRoutes action");
-#line 25
+#line 28
+ testRunner.And("I fetch the routes for the HttpRouteDefaults controller\'s MultipleRoutes action");
+#line 29
testRunner.Then("the route named \"MultipleDefaults1\" has a default for \"p1\" of \"first\"");
-#line 26
+#line 30
testRunner.And("the route named \"MultipleDefaults2\" has a default for \"p1\" of \"second\"");
+#line 31
+ testRunner.And("the route named \"ApiMultipleDefaults1\" has a default for \"p1\" of \"first\"");
+#line 32
+ testRunner.And("the route named \"ApiMultipleDefaults2\" has a default for \"p1\" of \"second\"");
#line hidden
this.ScenarioCleanup();
}
View
4 src/AttributeRouting.Specs/Features/StandardUsage.feature
@@ -22,10 +22,10 @@ Scenario Outline: Generating routes for an action method
| | AnyVerb | AnyVerb |
Scenario Outline: Generating routes for an API controller
- When I fetch the routes for the ApiStandardUsage controller's <action> action
+ When I fetch the routes for the HttpStandardUsage controller's <action> action
Then the route is constrained to <method> requests
And the route url is "<url>"
- And the default for "controller" is "ApiStandardUsage"
+ And the default for "controller" is "HttpStandardUsage"
And the default for "action" is "<action>"
And the namespace is "AttributeRouting.Specs.Subjects.Http"
View
4 src/AttributeRouting.Specs/Features/StandardUsage.feature.cs
@@ -121,13 +121,13 @@ public virtual void GeneratingRoutesForAnAPIController(string method, string act
#line 3
this.FeatureBackground();
#line 25
- testRunner.When(string.Format("I fetch the routes for the ApiStandardUsage controller\'s {0} action", action));
+ testRunner.When(string.Format("I fetch the routes for the HttpStandardUsage controller\'s {0} action", action));
#line 26
testRunner.Then(string.Format("the route is constrained to {0} requests", method));
#line 27
testRunner.And(string.Format("the route url is \"{0}\"", url));
#line 28
- testRunner.And("the default for \"controller\" is \"ApiStandardUsage\"");
+ testRunner.And("the default for \"controller\" is \"HttpStandardUsage\"");
#line 29
testRunner.And(string.Format("the default for \"action\" is \"{0}\"", action));
#line 30
View
21 src/AttributeRouting.Specs/Steps/RouteDefaultsSteps.cs
@@ -1,4 +1,5 @@
using System.Linq;
+using System.Web.Http;
using System.Web.Mvc;
using AttributeRouting.Framework;
using AttributeRouting.Web.Mvc.Framework;
@@ -13,23 +14,27 @@ public class RouteDefaultsSteps
[Then(@"the parameter ""(.*?)"" is optional")]
public void ThenTheParameterIsOptional(string name)
{
- var route = ScenarioContext.Current.GetFetchedRoutes().First();
+ var routes = ScenarioContext.Current.GetFetchedRoutes();
- Assert.That(route, Is.Not.Null);
- Assert.That(route.Defaults[name], Is.EqualTo(UrlParameter.Optional));
+ foreach (var route in routes) {
+ Assert.That(route, Is.Not.Null);
+ Assert.That(route.Defaults[name], Is.EqualTo(UrlParameter.Optional).Or.EqualTo(RouteParameter.Optional));
+ }
}
[Then(@"the route named ""(.*)"" has a default for ""(.*)"" of ""?(.*?)""?")]
public void ThenTheRouteNamedHasADefaultForOf(string routeName, string key, string value)
{
- var route = ScenarioContext.Current.GetFetchedRoutes().Cast<AttributeRoute>().SingleOrDefault(r => r.Container.RouteName == routeName);
+ var routes = ScenarioContext.Current.GetFetchedRouteContainers().Where(c => c.RouteName == routeName);
- Assert.That(route, Is.Not.Null);
+ foreach (var route in routes) {
+ Assert.That(route, Is.Not.Null);
- var routeDefault = route.Defaults[key];
+ var routeDefault = route.Defaults[key];
- Assert.That(routeDefault, Is.Not.Null);
- Assert.That(routeDefault.ToString(), Is.EqualTo(value));
+ Assert.That(routeDefault, Is.Not.Null);
+ Assert.That(routeDefault.ToString(), Is.EqualTo(value));
+ }
}
}
}
View
49 src/AttributeRouting.Specs/Subjects/Http/RouteAreasControllers.cs
@@ -0,0 +1,49 @@
+using System.Web.Http;
+using AttributeRouting.Web.Http;
+
+namespace AttributeRouting.Specs.Subjects.Http
+{
+ [RouteArea("ApiArea")]
+ public class HttpAreasController : ApiController
+ {
+ [GET("Get")]
+ public string Get()
+ {
+ return "";
+ }
+
+ [GET("ApiArea/DuplicatePrefix")]
+ public string DuplicatePrefix()
+ {
+ return "";
+ }
+
+ [GET("ApiAreaAbsolute", IsAbsoluteUrl = true)]
+ public string Absolute()
+ {
+ return "";
+ }
+
+ [GET("ApiAreas")]
+ public string RouteBeginsWithAreaName()
+ {
+ return "";
+ }
+ }
+
+ [RouteArea("ApiArea", AreaUrl = "ApiExplicitArea")]
+ public class HttpExplicitAreaUrlController : ApiController
+ {
+ [GET("Get")]
+ public string Get()
+ {
+ return "";
+ }
+
+ [GET("ApiExplicitArea/DuplicatePrefix")]
+ public string DuplicatePrefix()
+ {
+ return "";
+ }
+ }
+}
View
36 src/AttributeRouting.Specs/Subjects/Http/RouteDefaultsController.cs
@@ -0,0 +1,36 @@
+using System.Web.Http;
+using AttributeRouting.Web.Http;
+
+namespace AttributeRouting.Specs.Subjects.Http
+{
+ public class HttpRouteDefaultsController : ApiController
+ {
+ [GET("Default/{p1}")]
+ [RouteDefault("p1", "variable")]
+ public string Get()
+ {
+ return "";
+ }
+
+ [GET("InlineDefaults/{hello=sun}/{goodnight=moon}")]
+ public string InlineDefaults()
+ {
+ return "";
+ }
+
+ [GET("Optionals/{p1?}/{?p2}/{?p3?}")]
+ public string Optionals(string p1, string p2, string p3)
+ {
+ return "";
+ }
+
+ [GET("MultipleDefaults/1/{p1}", RouteName = "ApiMultipleDefaults1")]
+ [GET("MultipleDefaults/2/{p1}", RouteName = "ApiMultipleDefaults2")]
+ [RouteDefault("p1", "first", ForRouteNamed = "ApiMultipleDefaults1")]
+ [RouteDefault("p1", "second", ForRouteNamed = "ApiMultipleDefaults2")]
+ public string MultipleRoutes()
+ {
+ return "";
+ }
+ }
+}
View
2 src/AttributeRouting.Specs/Subjects/Http/StandardUsageController.cs
@@ -4,7 +4,7 @@
namespace AttributeRouting.Specs.Subjects.Http
{
- public class ApiStandardUsageController : ApiController
+ public class HttpStandardUsageController : ApiController
{
[GET("api")]
public string Get()
View
8 src/AttributeRouting.Web.Http.SelfHost/Framework/AttributeRouteContainer.cs
@@ -44,5 +44,13 @@ public class AttributeRouteContainer : AttributeRouteContainerBase<AttributeRout
get { return Route.Constraints; }
set { throw new NotImplementedException("WebAPI HttpRoute.Constraints has no setter."); }
}
+
+ /// <summary>
+ /// Defaults dictionary
+ /// </summary>
+ public override IDictionary<string, object> Defaults {
+ get { return Route.Defaults; }
+ set { throw new NotImplementedException("WebAPI HttpRoute.Constraints has no setter."); }
+ }
}
}
View
8 src/AttributeRouting.Web.Http.WebHost/Framework/AttributeRouteContainer.cs
@@ -41,5 +41,13 @@ public class AttributeRouteContainer : AttributeRouteContainerBase<AttributeRout
get { return Route.Constraints; }
set { Route.Constraints = new RouteValueDictionary(value); }
}
+
+ /// <summary>
+ /// Defaults dictionary
+ /// </summary>
+ public override IDictionary<string, object> Defaults {
+ get { return Route.Defaults; }
+ set { Route.Defaults = new RouteValueDictionary(value); }
+ }
}
}
View
8 src/AttributeRouting.Web.Mvc/Framework/AttributeRouteContainer.cs
@@ -40,5 +40,13 @@ public class AttributeRouteContainer : AttributeRouteContainerBase<AttributeRout
get { return Route.Constraints; }
set { Route.Constraints = new RouteValueDictionary(value); }
}
+
+ /// <summary>
+ /// Defaults dictionary
+ /// </summary>
+ public override IDictionary<string, object> Defaults {
+ get { return Route.Defaults; }
+ set { Route.Defaults = new RouteValueDictionary(value); }
+ }
}
}
View
5 src/AttributeRouting/Framework/AttributeRouteContainerBase.cs
@@ -47,5 +47,10 @@ public abstract class AttributeRouteContainerBase<TRoute> : IAttributeRouteConta
/// Constraints dictionary
/// </summary>
public abstract IDictionary<string, object> Constraints { get; set; }
+
+ /// <summary>
+ /// Defaults dictionary
+ /// </summary>
+ public abstract IDictionary<string, object> Defaults { get; set; }
}
}
View
5 src/AttributeRouting/Framework/IAttributeRouteContainer.cs
@@ -36,5 +36,10 @@ public interface IAttributeRouteContainer {
/// Constraints dictionary
/// </summary>
IDictionary<string, object> Constraints { get; set; }
+
+ /// <summary>
+ /// Defaults dictionary
+ /// </summary>
+ IDictionary<string, object> Defaults { get; set; }
}
}

0 comments on commit 10c4194

Please sign in to comment.
Something went wrong with that request. Please try again.