Search code examples
c#unit-testingasp.net-coredotnet-httpclientasp.net-core-2.1

How do I test an https redirect in ASP.NET Core?


Recently, I came up with unit tests for checking some redirect rules of my ASP.NET Core 2.1 application:

[Fact(DisplayName = "lowercase path")]
public async Task LowercaseRedirect()
{
    var result = await this.Client.GetAsync("/BLOG/");
    Assert.EndsWith("/blog/", result.RequestMessage.RequestUri.PathAndQuery, StringComparison.InvariantCulture);
}

[Fact(DisplayName = "add missing slash")]
public async Task SlashRedirect()
{
    var result = await this.Client.GetAsync("/blog");
    Assert.EndsWith("/blog/", result.RequestMessage.RequestUri.PathAndQuery, StringComparison.InvariantCulture);
}

FYI: I am currently injecting the WebApplicationFactory<TEntryPoint> into my test class, which I use to create my HttpClient.

But now I am curious how to check if the https redirect is working. Any ideas how to accomplish that? Thanks in advance :)


Solution

  • For UseHttpsRedirection, a port must be available for the middleware to redirect to HTTPS. If no port is available, redirection to HTTPS does not occur.

    The HTTPS port can be specified by any of the following setting:

    • HttpsRedirectionOptions.HttpsPort
    • The ASPNETCORE_HTTPS_PORT environment variable.
    • In development, an HTTPS url in launchsettings.json.
    • An HTTPS url configured directly on Kestrel or HttpSys.

    Reference:UseHttpsRedirection

    To test for UseHttpsRedirection, specify the https port. You could follow steps below:

    1. Configure WebApplicationFactory with https_port

      public class UnitTest1 : IClassFixture<WebApplicationFactory<CoreHttps.Startup>>
      {
          private readonly WebApplicationFactory<CoreHttps.Startup> _factory;
      
      public UnitTest1(WebApplicationFactory<CoreHttps.Startup> factory)
      {
          _factory = factory.WithWebHostBuilder(builder => builder
              .UseStartup<Startup>()
              .UseSetting("https_port", "8080")); 
      }
      
    2. For default, the request url is http://localhost/, check the request url if client did not auto redirect.

      [Theory]
      [InlineData("/Home")]
      public async Task HttpsRedirectionWithoutAutoRedirect(string url)
      {
          // Arrange
          var client = _factory.CreateClient(new WebApplicationFactoryClientOptions
                                  {
                                      AllowAutoRedirect = false
                                  });
          // Act
          var response = await client.GetAsync(url);
          // Assert
          Assert.Equal(HttpStatusCode.RedirectKeepVerb, response.StatusCode);
          Assert.StartsWith("http://localhost/",
              response.RequestMessage.RequestUri.AbsoluteUri);
      
          Assert.StartsWith("https://localhost:8080/",
              response.Headers.Location.OriginalString);
      }
      
    3. check the request url if the request is auto redirect.

      [Theory]
      [InlineData("/Home")]
      public async Task HttpsRedirectionWithAutoRedirect(string url)
      {
          // Arrange
          var client = _factory.CreateClient();
          // Act
          var response = await client.GetAsync(url);
      
          // Assert
          Assert.Equal(HttpStatusCode.OK, response.StatusCode);
          Assert.StartsWith("https://localhost:8080/",
              response.RequestMessage.RequestUri.AbsoluteUri);
      }