Skip to content
This repository was archived by the owner on Nov 27, 2018. It is now read-only.

Commit

Permalink
[Fixes #324] Default parameters are not taken into account on attribu…
Browse files Browse the repository at this point in the history
…te routing
  • Loading branch information
javiercn committed Aug 17, 2016
1 parent a1ee754 commit ffa0ee5
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/Microsoft.AspNetCore.Routing/Tree/TreeRouteBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ private void AddEntryToTree(UrlMatchingTree tree, InboundRouteEntry entry)
continue;
}

if (part.IsParameter && (part.IsOptional || part.IsCatchAll))
if (part.IsParameter && (part.IsOptional || part.IsCatchAll || part.DefaultValue != null))
{
current.Matches.Add(new InboundMatch() { Entry = entry, TemplateMatcher = matcher });
}
Expand Down
148 changes: 148 additions & 0 deletions test/Microsoft.AspNetCore.Routing.Tests/Tree/TreeRouterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using Microsoft.Extensions.WebEncoders.Testing;
using Moq;
using Xunit;
using Xunit.Extensions;

namespace Microsoft.AspNetCore.Routing.Tree
{
Expand Down Expand Up @@ -125,6 +126,153 @@ public async Task TreeRouter_RouteAsync_MatchesRouteWithTheRightLength(string ur
Assert.Equal(expectedRouteGroup, context.RouteData.Values["test_route_group"]);
}

public static TheoryData<string, object[]> MatchesRoutesWithDefaultsData =>
new TheoryData<string, object[]>
{
{ "/", new object[] { "1", "2", "3", "4" } },
{ "/a", new object[] { "a", "2", "3", "4" } },
{ "/a/b", new object[] { "a", "b", "3", "4" } },
{ "/a/b/c", new object[] { "a", "b", "c", "4" } },
{ "/a/b/c/d", new object[] { "a", "b", "c", "d" } }
};

[Theory]
[MemberData(nameof(MatchesRoutesWithDefaultsData))]
public async Task TreeRouter_RouteAsync_MatchesRoutesWithDefaults(string url, object[] routeValues)
{
// Arrange
var routes = new[] {
"{parameter1=1}/{parameter2=2}/{parameter3=3}/{parameter4=4}",
};

var expectedRouteGroup = CreateRouteGroup(0, "{parameter1=1}/{parameter2=2}/{parameter3=3}/{parameter4=4}");
var routeValueKeys = new[] { "parameter1", "parameter2", "parameter3", "parameter4" };
var expectedRouteValues = new RouteValueDictionary();
for (int i = 0; i < routeValueKeys.Length; i++)
{
expectedRouteValues.Add(routeValueKeys[i], routeValues[i]);
}

var builder = CreateBuilder();

// We setup the route entries in reverse order of precedence to ensure that when we
// try to route the request, the route with a higher precedence gets tried first.
foreach (var template in routes.Reverse())
{
MapInboundEntry(builder, template);
}

var route = builder.Build();

var context = CreateRouteContext(url);

// Act
await route.RouteAsync(context);

// Assert
Assert.Equal(expectedRouteGroup, context.RouteData.Values["test_route_group"]);
foreach (var entry in expectedRouteValues)
{
var data = Assert.Single(context.RouteData.Values, v => v.Key == entry.Key);
Assert.Equal(entry.Value, data.Value);
}
}

public static TheoryData<string, object[]> MatchesConstrainedRoutesWithDefaultsData =>
new TheoryData<string, object[]>
{
{ "/", new object[] { "1", "2", "3", "4" } },
{ "/10", new object[] { "10", "2", "3", "4" } },
{ "/10/11", new object[] { "10", "11", "3", "4" } },
{ "/10/11/12", new object[] { "10", "11", "12", "4" } },
{ "/10/11/12/13", new object[] { "10", "11", "12", "13" } }
};

[Theory]
[MemberData(nameof(MatchesConstrainedRoutesWithDefaultsData))]
public async Task TreeRouter_RouteAsync_MatchesConstrainedRoutesWithDefaults(string url, object[] routeValues)
{
// Arrange
var routes = new[] {
"{parameter1:int=1}/{parameter2:int=2}/{parameter3:int=3}/{parameter4:int=4}",
};

var expectedRouteGroup = CreateRouteGroup(0, "{parameter1:int=1}/{parameter2:int=2}/{parameter3:int=3}/{parameter4:int=4}");
var routeValueKeys = new[] { "parameter1", "parameter2", "parameter3", "parameter4" };
var expectedRouteValues = new RouteValueDictionary();
for (int i = 0; i < routeValueKeys.Length; i++)
{
expectedRouteValues.Add(routeValueKeys[i], routeValues[i]);
}

var builder = CreateBuilder();

// We setup the route entries in reverse order of precedence to ensure that when we
// try to route the request, the route with a higher precedence gets tried first.
foreach (var template in routes.Reverse())
{
MapInboundEntry(builder, template);
}

var route = builder.Build();

var context = CreateRouteContext(url);

// Act
await route.RouteAsync(context);

// Assert
Assert.Equal(expectedRouteGroup, context.RouteData.Values["test_route_group"]);
foreach (var entry in expectedRouteValues)
{
var data = Assert.Single(context.RouteData.Values, v => v.Key == entry.Key);
Assert.Equal(entry.Value, data.Value);
}
}

[Fact]
public async Task TreeRouter_RouteAsync_MatchesCatchAllRoutesWithDefaults()
{
// Arrange
var routes = new[] {
"{parameter1=1}/{parameter2=2}/{parameter3=3}/{*parameter4=4}",
};
var url = "/a/b/c";
var routeValues = new[] { "a", "b", "c", "4" };

var expectedRouteGroup = CreateRouteGroup(0, "{parameter1=1}/{parameter2=2}/{parameter3=3}/{*parameter4=4}");
var routeValueKeys = new[] { "parameter1", "parameter2", "parameter3", "parameter4" };
var expectedRouteValues = new RouteValueDictionary();
for (int i = 0; i < routeValueKeys.Length; i++)
{
expectedRouteValues.Add(routeValueKeys[i], routeValues[i]);
}

var builder = CreateBuilder();

// We setup the route entries in reverse order of precedence to ensure that when we
// try to route the request, the route with a higher precedence gets tried first.
foreach (var template in routes.Reverse())
{
MapInboundEntry(builder, template);
}

var route = builder.Build();

var context = CreateRouteContext(url);

// Act
await route.RouteAsync(context);

// Assert
Assert.Equal(expectedRouteGroup, context.RouteData.Values["test_route_group"]);
foreach (var entry in expectedRouteValues)
{
var data = Assert.Single(context.RouteData.Values, v => v.Key == entry.Key);
Assert.Equal(entry.Value, data.Value);
}
}

[Fact]
public async Task TreeRouter_RouteAsync_DoesNotMatchShorterUrl()
{
Expand Down

0 comments on commit ffa0ee5

Please sign in to comment.