Skip to content

Commit

Permalink
Fix AcceptedAtRoute link generation and add tests (dotnet#46724)
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesNK authored Feb 18, 2023
1 parent c8a77ae commit 320c6a6
Show file tree
Hide file tree
Showing 7 changed files with 31 additions and 22 deletions.
2 changes: 1 addition & 1 deletion src/Http/Http.Results/src/AcceptedAtRoute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public Task ExecuteAsync(HttpContext httpContext)
ArgumentNullException.ThrowIfNull(httpContext);

var linkGenerator = httpContext.RequestServices.GetRequiredService<LinkGenerator>();
var url = linkGenerator.GetUriByAddress(
var url = linkGenerator.GetUriByRouteValues(
httpContext,
RouteName,
RouteValues,
Expand Down
2 changes: 1 addition & 1 deletion src/Http/Http.Results/src/AcceptedAtRouteOfT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public Task ExecuteAsync(HttpContext httpContext)
ArgumentNullException.ThrowIfNull(httpContext);

var linkGenerator = httpContext.RequestServices.GetRequiredService<LinkGenerator>();
var url = linkGenerator.GetUriByAddress(
var url = linkGenerator.GetUriByRouteValues(
httpContext,
RouteName,
RouteValues,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ public async Task ExecuteResultAsync_SetsStatusCodeAndLocationHeader(object valu
// Assert
Assert.Equal(StatusCodes.Status202Accepted, httpContext.Response.StatusCode);
Assert.Equal(expectedUrl, httpContext.Response.Headers["Location"]);
Assert.Equal(new RouteValueDictionary(values), linkGenerator.RouteValuesAddress.ExplicitValues);
}

[Fact]
Expand Down
1 change: 1 addition & 0 deletions src/Http/Http.Results/test/AcceptedAtRouteResultTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public async Task ExecuteResultAsync_SetsStatusCodeAndLocationHeader(object valu
// Assert
Assert.Equal(StatusCodes.Status202Accepted, httpContext.Response.StatusCode);
Assert.Equal(expectedUrl, httpContext.Response.Headers["Location"]);
Assert.Equal(new RouteValueDictionary(values), linkGenerator.RouteValuesAddress.ExplicitValues);
}

[Fact]
Expand Down
18 changes: 9 additions & 9 deletions src/Http/Http.Results/test/CreatedAtRouteOfTResultTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ public async Task CreatedAtRouteResult_ReturnsStatusCode_SetsLocationHeader(obje
{
// Arrange
var expectedUrl = "testAction";
var httpContext = GetHttpContext(expectedUrl);
var linkGenerator = new TestLinkGenerator { Url = expectedUrl };
var httpContext = GetHttpContext(linkGenerator);

// Act
var result = new CreatedAtRoute<object>(routeName: null, routeValues: values, value: null);
Expand All @@ -66,13 +67,15 @@ public async Task CreatedAtRouteResult_ReturnsStatusCode_SetsLocationHeader(obje
// Assert
Assert.Equal(StatusCodes.Status201Created, httpContext.Response.StatusCode);
Assert.Equal(expectedUrl, httpContext.Response.Headers["Location"]);
Assert.Equal(new RouteValueDictionary(values), linkGenerator.RouteValuesAddress.ExplicitValues);
}

[Fact]
public async Task CreatedAtRouteResult_ThrowsOnNullUrl()
{
// Arrange
var httpContext = GetHttpContext(expectedUrl: null);
var linkGenerator = new TestLinkGenerator();
var httpContext = GetHttpContext(linkGenerator);

var result = new CreatedAtRoute<object>(
routeName: null,
Expand Down Expand Up @@ -173,23 +176,20 @@ private static void PopulateMetadata<TResult>(MethodInfo method, EndpointBuilder

private record Todo(int Id, string Title);

private static HttpContext GetHttpContext(string expectedUrl)
private static HttpContext GetHttpContext(LinkGenerator linkGenerator)
{
var httpContext = new DefaultHttpContext();
httpContext.Request.PathBase = new PathString("");
httpContext.Response.Body = new MemoryStream();
httpContext.RequestServices = CreateServices(expectedUrl);
httpContext.RequestServices = CreateServices(linkGenerator);
return httpContext;
}

private static IServiceProvider CreateServices(string expectedUrl)
private static IServiceProvider CreateServices(LinkGenerator linkGenerator)
{
var services = new ServiceCollection();
services.AddSingleton<ILoggerFactory, NullLoggerFactory>();
services.AddSingleton<LinkGenerator>(new TestLinkGenerator
{
Url = expectedUrl
});
services.AddSingleton<LinkGenerator>(linkGenerator);

return services.BuildServiceProvider();
}
Expand Down
18 changes: 9 additions & 9 deletions src/Http/Http.Results/test/CreatedAtRouteResultTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ public async Task CreatedAtRouteResult_ReturnsStatusCode_SetsLocationHeader(obje
{
// Arrange
var expectedUrl = "testAction";
var httpContext = GetHttpContext(expectedUrl);
var linkGenerator = new TestLinkGenerator { Url = expectedUrl };
var httpContext = GetHttpContext(linkGenerator);

// Act
var result = new CreatedAtRoute(routeName: null, routeValues: values);
Expand All @@ -49,13 +50,15 @@ public async Task CreatedAtRouteResult_ReturnsStatusCode_SetsLocationHeader(obje
// Assert
Assert.Equal(StatusCodes.Status201Created, httpContext.Response.StatusCode);
Assert.Equal(expectedUrl, httpContext.Response.Headers["Location"]);
Assert.Equal(new RouteValueDictionary(values), linkGenerator.RouteValuesAddress.ExplicitValues);
}

[Fact]
public async Task CreatedAtRouteResult_ThrowsOnNullUrl()
{
// Arrange
var httpContext = GetHttpContext(expectedUrl: null);
var linkGenerator = new TestLinkGenerator();
var httpContext = GetHttpContext(linkGenerator);

var result = new CreatedAtRoute(
routeName: null,
Expand Down Expand Up @@ -119,23 +122,20 @@ public void CreatedAtRouteResult_Implements_IValueHttpResult_Correctly()
private static void PopulateMetadata<TResult>(MethodInfo method, EndpointBuilder builder)
where TResult : IEndpointMetadataProvider => TResult.PopulateMetadata(method, builder);

private static HttpContext GetHttpContext(string expectedUrl)
private static HttpContext GetHttpContext(LinkGenerator linkGenerator)
{
var httpContext = new DefaultHttpContext();
httpContext.Request.PathBase = new PathString("");
httpContext.Response.Body = new MemoryStream();
httpContext.RequestServices = CreateServices(expectedUrl);
httpContext.RequestServices = CreateServices(linkGenerator);
return httpContext;
}

private static IServiceProvider CreateServices(string expectedUrl)
private static IServiceProvider CreateServices(LinkGenerator linkGenerator)
{
var services = new ServiceCollection();
services.AddSingleton<ILoggerFactory, NullLoggerFactory>();
services.AddSingleton<LinkGenerator>(new TestLinkGenerator
{
Url = expectedUrl
});
services.AddSingleton<LinkGenerator>(linkGenerator);

return services.BuildServiceProvider();
}
Expand Down
11 changes: 9 additions & 2 deletions src/Http/Http.Results/test/TestLinkGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace Microsoft.AspNetCore.Http.HttpResults;
internal sealed class TestLinkGenerator : LinkGenerator
{
public string Url { get; set; }
public RouteValuesAddress RouteValuesAddress { get; set; }

public override string GetPathByAddress<TAddress>(HttpContext httpContext, TAddress address, RouteValueDictionary values, RouteValueDictionary ambientValues = null, PathString? pathBase = null, FragmentString fragment = default, LinkOptions options = null)
{
Expand All @@ -20,8 +21,14 @@ public override string GetPathByAddress<TAddress>(TAddress address, RouteValueDi
}

public override string GetUriByAddress<TAddress>(HttpContext httpContext, TAddress address, RouteValueDictionary values, RouteValueDictionary ambientValues = null, string scheme = null, HostString? host = null, PathString? pathBase = null, FragmentString fragment = default, LinkOptions options = null)
=> Url;
=> AssertAddressAndReturnUrl(address);

public override string GetUriByAddress<TAddress>(TAddress address, RouteValueDictionary values, string scheme, HostString host, PathString pathBase = default, FragmentString fragment = default, LinkOptions options = null)
=> Url;
=> AssertAddressAndReturnUrl(address);

private string AssertAddressAndReturnUrl<TAddress>(TAddress address)
{
RouteValuesAddress = Assert.IsType<RouteValuesAddress>(address);
return Url;
}
}

0 comments on commit 320c6a6

Please sign in to comment.