// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Linq; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Xunit; namespace Microsoft.AspNetCore.Routing { // Integration tests for GetXyzByRouteValues. These are basic because important behavioral details // are covered elsewhere. // // Does not cover template processing in detail, those scenarios are validated by TemplateBinderTests // and DefaultLinkGeneratorProcessTemplateTest // // Does not cover the RouteValuesAddressScheme in detail. see RouteValuesAddressSchemeTest public class LinkGeneratorRouteValuesAddressExtensionsTest : LinkGeneratorTestBase { [Fact] public void GetPathByRouteValues_WithHttpContext_UsesAmbientValues() { // Arrange var endpoint1 = EndpointFactory.CreateRouteEndpoint( "Home/Index/{id}", defaults: new { controller = "Home", action = "Index", }, metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) }); var endpoint2 = EndpointFactory.CreateRouteEndpoint( "Home/Index/{id?}", defaults: new { controller = "Home", action = "Index", }, metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) }); var linkGenerator = CreateLinkGenerator(endpoint1, endpoint2); var context = new EndpointSelectorContext() { RouteValues = new RouteValueDictionary(new { action = "Index", }) }; var httpContext = CreateHttpContext(); httpContext.Features.Set(context); httpContext.Request.PathBase = new PathString("/Foo/Bar?encodeme?"); // Act var path = linkGenerator.GetPathByRouteValues( httpContext, routeName: null, values: new RouteValueDictionary(new { controller = "Home", query = "some?query" }), fragment: new FragmentString("#Fragment?"), options: new LinkOptions() { AppendTrailingSlash = true, }); // Assert Assert.Equal("/Foo/Bar%3Fencodeme%3F/Home/Index/?query=some%3Fquery#Fragment?", path); } [Fact] public void GetPathByRouteValues_WithoutHttpContext_WithPathBaseAndFragment() { // Arrange var endpoint1 = EndpointFactory.CreateRouteEndpoint( "Home/Index/{id}", defaults: new { controller = "Home", action = "Index", }, metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) }); var endpoint2 = EndpointFactory.CreateRouteEndpoint( "Home/Index/{id?}", defaults: new { controller = "Home", action = "Index", }, metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) }); var linkGenerator = CreateLinkGenerator(endpoint1, endpoint2); // Act var path = linkGenerator.GetPathByRouteValues( routeName: null, values: new RouteValueDictionary(new { controller = "Home", action = "Index", query = "some?query" }), new PathString("/Foo/Bar?encodeme?"), new FragmentString("#Fragment?"), new LinkOptions() { AppendTrailingSlash = true, }); // Assert Assert.Equal("/Foo/Bar%3Fencodeme%3F/Home/Index/?query=some%3Fquery#Fragment?", path); } [Fact] public void GetPathByRouteValues_WithHttpContext_WithPathBaseAndFragment() { // Arrange var endpoint1 = EndpointFactory.CreateRouteEndpoint( "Home/Index/{id}", defaults: new { controller = "Home", action = "Index", }, metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) }); var endpoint2 = EndpointFactory.CreateRouteEndpoint( "Home/Index/{id?}", defaults: new { controller = "Home", action = "Index", }, metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) }); var linkGenerator = CreateLinkGenerator(endpoint1, endpoint2); var httpContext = CreateHttpContext(); httpContext.Request.PathBase = new PathString("/Foo/Bar?encodeme?"); // Act var path = linkGenerator.GetPathByRouteValues( httpContext, routeName: null, values: new RouteValueDictionary(new { controller = "Home", action = "Index", query = "some?query" }), fragment: new FragmentString("#Fragment?"), options: new LinkOptions() { AppendTrailingSlash = true, }); // Assert Assert.Equal("/Foo/Bar%3Fencodeme%3F/Home/Index/?query=some%3Fquery#Fragment?", path); } [Fact] public void GetUriByRouteValues_WithoutHttpContext_WithPathBaseAndFragment() { // Arrange var endpoint1 = EndpointFactory.CreateRouteEndpoint( "Home/Index/{id}", defaults: new { controller = "Home", action = "Index", }, metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) }); var endpoint2 = EndpointFactory.CreateRouteEndpoint( "Home/Index/{id?}", defaults: new { controller = "Home", action = "Index", }, metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) }); var linkGenerator = CreateLinkGenerator(endpoint1, endpoint2); // Act var path = linkGenerator.GetUriByRouteValues( routeName: null, values: new RouteValueDictionary(new { controller = "Home", action = "Index", query = "some?query" }), "http", new HostString("example.com"), new PathString("/Foo/Bar?encodeme?"), new FragmentString("#Fragment?"), new LinkOptions() { AppendTrailingSlash = true, }); // Assert Assert.Equal("http://example.com/Foo/Bar%3Fencodeme%3F/Home/Index/?query=some%3Fquery#Fragment?", path); } [Fact] public void GetUriByRouteValues_WithHttpContext_WithPathBaseAndFragment() { // Arrange var endpoint1 = EndpointFactory.CreateRouteEndpoint( "Home/Index/{id}", defaults: new { controller = "Home", action = "Index", }, metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) }); var endpoint2 = EndpointFactory.CreateRouteEndpoint( "Home/Index/{id?}", defaults: new { controller = "Home", action = "Index", }, metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) }); var linkGenerator = CreateLinkGenerator(endpoint1, endpoint2); var httpContext = CreateHttpContext(); httpContext.Request.Scheme = "http"; httpContext.Request.Host = new HostString("example.com"); httpContext.Request.PathBase = new PathString("/Foo/Bar?encodeme?"); // Act var uri = linkGenerator.GetUriByRouteValues( httpContext, routeName: null, values: new RouteValueDictionary(new { controller = "Home", action = "Index", query = "some?query" }), fragment: new FragmentString("#Fragment?"), options: new LinkOptions() { AppendTrailingSlash = true, }); // Assert Assert.Equal("http://example.com/Foo/Bar%3Fencodeme%3F/Home/Index/?query=some%3Fquery#Fragment?", uri); } [Fact] public void GetUriByRouteValues_WithHttpContext_CanUseAmbientValues() { // Arrange var endpoint1 = EndpointFactory.CreateRouteEndpoint( "Home/Index/{id}", defaults: new { controller = "Home", action = "Index", }, metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) }); var endpoint2 = EndpointFactory.CreateRouteEndpoint( "Home/Index/{id?}", defaults: new { controller = "Home", action = "Index", }, metadata: new[] { new RouteValuesAddressMetadata(new RouteValueDictionary(new { controller = "Home", action = "Index", })) }); var linkGenerator = CreateLinkGenerator(endpoint1, endpoint2); var httpContext = CreateHttpContext(new { controller = "Home", }); httpContext.Request.Scheme = "http"; httpContext.Request.Host = new HostString("example.com"); httpContext.Request.PathBase = new PathString("/Foo/Bar?encodeme?"); // Act var uri = linkGenerator.GetUriByRouteValues( httpContext, routeName: null, values: new RouteValueDictionary(new { action = "Index", query = "some?query" }), fragment: new FragmentString("#Fragment?"), options: new LinkOptions() { AppendTrailingSlash = true, }); // Assert Assert.Equal("http://example.com/Foo/Bar%3Fencodeme%3F/Home/Index/?query=some%3Fquery#Fragment?", uri); } } }