Skip to content

Commit

Permalink
Merge pull request #4 from markvincze/handle-route-query
Browse files Browse the repository at this point in the history
Handle query segments of the route templates
  • Loading branch information
markvincze committed Sep 23, 2017
2 parents ab22f43 + 4a9734e commit 7ede98a
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 23 deletions.
5 changes: 3 additions & 2 deletions src/Stubbery/RequestMatching/IRouteMatcher.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;

namespace Stubbery.RequestMatching
{
internal interface IRouteMatcher
{
RouteValueDictionary Match(string routeTemplate, string requestPath);
RouteValueDictionary Match(string routeTemplate, string requestPath, IQueryCollection query);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public bool Match(HttpContext context)
{
var routeMatcher = new RouteMatcher();

var result = routeMatcher.Match(route, context.Request.Path);
var result = routeMatcher.Match(route, context.Request.Path, context.Request.Query);

if (result != null)
{
Expand Down
44 changes: 33 additions & 11 deletions src/Stubbery/RequestMatching/RouteMatcher.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,47 @@
using Microsoft.AspNetCore.Routing;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.AspNetCore.Routing.Template;
using Microsoft.AspNetCore.WebUtilities;

namespace Stubbery.RequestMatching
{
internal class RouteMatcher : IRouteMatcher
{
public RouteValueDictionary Match(string routeTemplate, string requestPath)
public RouteValueDictionary Match(string routeTemplate, string requestPath, IQueryCollection query)
{
// The TemplateParser can only parse the route part, and not the query string.
// If the template provided by the user also has a query string, we separate that and match it manually.
var regex = new Regex(@"(.*)(\?[^{}]*$)");
var match = regex.Match(routeTemplate);
if (match.Success)
{
var queryString = match.Groups[2].Value;
routeTemplate = match.Groups[1].Value;

var queryInTemplate = QueryHelpers.ParseQuery(queryString);

if (!query.All(arg => queryInTemplate.ContainsKey(arg.Key.TrimStart('?')) &&
queryInTemplate[arg.Key.TrimStart('?')] == arg.Value))
{
return null;
}
}

var template = TemplateParser.Parse(routeTemplate);

var matcher = new TemplateMatcher(template, GetDefaults(template));

var values = new RouteValueDictionary();
if(matcher.TryMatch(requestPath, values))
{
return values;
}
else
{
return null;
}
var values = new RouteValueDictionary();
if (matcher.TryMatch(requestPath, values))
{
return values;
}
else
{
return null;
}
}

private RouteValueDictionary GetDefaults(RouteTemplate parsedTemplate)
Expand Down
9 changes: 1 addition & 8 deletions src/Stubbery/RequestMatching/SetupResponseParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,7 @@ public async Task SendResponseAsync(HttpContext httpContext)

foreach (var header in Headers)
{
//if (httpContext.Response.Headers.ContainsKey(header.Key))
//{
httpContext.Response.Headers[header.Key] = header.Value;
//}
//else
//{
// httpContext.Response.Headers.Add(header.Key, header.Value);
//}
httpContext.Response.Headers[header.Key] = header.Value;
}

var routeValues = httpContext.GetRouteValues();
Expand Down
2 changes: 1 addition & 1 deletion src/Stubbery/Stubbery.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<PropertyGroup>
<Description>Library for creating Api stubs in .NET.</Description>
<Copyright>Copyright � Mark Vincze 2016</Copyright>
<VersionPrefix>1.2.4</VersionPrefix>
<VersionPrefix>1.2.5</VersionPrefix>
<Authors>Mark Vincze</Authors>
<TargetFrameworks>netstandard1.3;net451</TargetFrameworks>
<DebugType>full</DebugType>
Expand Down
33 changes: 33 additions & 0 deletions test/Stubbery.IntegrationTests/RouteConditionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,38 @@ public async Task Route_MultipleRoutesOneIsEqual_ResultReturned()
Assert.Equal("testresponse", resultString);
}
}

[Fact]
public async Task Route_RouteIncludesMatchingQuery_ResultReturned()
{
using (var sut = new ApiStub())
{
sut.Get("/testget?foo=bar", (req, args) => "testresponse");

sut.Start();

var result = await httpClient.GetAsync(new UriBuilder(new Uri(sut.Address)) { Path = "/testget", Query = "?foo=bar" }.Uri);

var resultString = await result.Content.ReadAsStringAsync();

Assert.Equal(HttpStatusCode.OK, result.StatusCode);
Assert.Equal("testresponse", resultString);
}
}

[Fact]
public async Task Route_RouteIncludesNotMatchingQuery_NotFoundReturned()
{
using (var sut = new ApiStub())
{
sut.Get("/testget?foo=bar", (req, args) => "testresponse");

sut.Start();

var result = await httpClient.GetAsync(new UriBuilder(new Uri(sut.Address)) { Path = "/testget", Query = "?foo=qux" }.Uri);

Assert.Equal(HttpStatusCode.NotFound, result.StatusCode);
}
}
}
}

0 comments on commit 7ede98a

Please sign in to comment.