File: Dashboard\DashboardServiceHostTests.cs
Web Access
Project: src\tests\Aspire.Hosting.Tests\Aspire.Hosting.Tests.csproj (Aspire.Hosting.Tests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Net;
using Aspire.Hosting.Dashboard;
 
namespace Aspire.Hosting.Tests.Dashboard;
 
[Trait("Partition", "3")]
public class DashboardServiceHostTests
{
    [Theory]
    [InlineData(null, false, "https")]
    [InlineData(null, true, "http")]
    [InlineData("https://localhost:5001", false, "https")]
    [InlineData("http://localhost:5000", true, "http")]
    [InlineData("http://localhost:5000", false, "http")] // Explicit URI scheme wins regardless of allowUnsecuredTransport. Should never happen because of validation.
    public void ResolveScheme_ReturnsExpectedScheme(string? uriString, bool allowUnsecuredTransport, string expectedScheme)
    {
        var uri = uriString is not null ? new Uri(uriString) : null;
 
        var scheme = DashboardServiceHost.ResolveScheme(configuredUri: uri, allowUnsecuredTransport: allowUnsecuredTransport);
 
        Assert.Equal(expectedScheme, scheme);
    }
 
    [Fact]
    public void ResolveEndpoint_NullUri_BindsToLoopbackPort0()
    {
        var result = DashboardServiceHost.ResolveEndpoint(configuredUri: null, randomizePorts: false, allowUnsecuredTransport: false);
 
        Assert.Equal(IPAddress.Loopback, result.BindAddress);
        Assert.Equal(0, result.Port);
        Assert.False(result.UseListenLocalhost);
        Assert.Equal("https", result.Scheme);
    }
 
    [Theory]
    [InlineData("http://127.0.0.1:5000", false, "127.0.0.1", 5000, false)]
    [InlineData("https://127.0.0.1:5001", false, "127.0.0.1", 5001, false)]
    [InlineData("http://[::1]:5000", false, "::1", 5000, false)]
    [InlineData("https://[::1]:0", false, "::1", 0, false)]
    public void ResolveEndpoint_IpLoopback_BindsToExactAddress(string uriString, bool randomizePorts, string expectedHost, int expectedPort, bool expectedUseLocalhost)
    {
        var uri = new Uri(uriString);
 
        var result = DashboardServiceHost.ResolveEndpoint(uri, randomizePorts, allowUnsecuredTransport: false);
 
        Assert.Equal(IPAddress.Parse(expectedHost), result.BindAddress);
        Assert.Equal(expectedPort, result.Port);
        Assert.Equal(expectedUseLocalhost, result.UseListenLocalhost);
    }
 
    [Theory]
    [InlineData("http://localhost:5000", false, 5000, true)]
    [InlineData("http://localhost:5000", true, 0, false)] // randomizePorts overrides to port 0, falls back from ListenLocalhost
    [InlineData("http://localhost:0", false, 0, false)] // port 0 already dynamic, falls back from ListenLocalhost
    [InlineData("http://localhost:0", true, 0, false)] // port 0 + randomize, still dynamic
    public void ResolveEndpoint_Localhost_BindsCorrectly(string uriString, bool randomizePorts, int expectedPort, bool expectedUseLocalhost)
    {
        var uri = new Uri(uriString);
 
        var result = DashboardServiceHost.ResolveEndpoint(uri, randomizePorts, allowUnsecuredTransport: true);
 
        Assert.Equal(expectedPort, result.Port);
        Assert.Equal(expectedUseLocalhost, result.UseListenLocalhost);
    }
 
    [Theory]
    [InlineData("http://127.0.0.1:5000", true, 0)]
    [InlineData("http://[::1]:5000", true, 0)]
    [InlineData("http://127.0.0.1:0", true, 0)] // port 0 stays 0
    [InlineData("http://[::1]:0", true, 0)] // port 0 stays 0
    [InlineData("http://127.0.0.1:5000", false, 5000)] // randomize off, port preserved
    [InlineData("http://[::1]:5000", false, 5000)]
    public void ResolveEndpoint_RandomizePorts_OverridesNonZeroPort(string uriString, bool randomizePorts, int expectedPort)
    {
        var uri = new Uri(uriString);
 
        var result = DashboardServiceHost.ResolveEndpoint(uri, randomizePorts, allowUnsecuredTransport: true);
 
        Assert.Equal(expectedPort, result.Port);
    }
 
    [Fact]
    public void ResolveEndpoint_NonLoopbackAddress_Throws()
    {
        var uri = new Uri("http://192.168.1.1:5000");
 
        Assert.Throws<ArgumentException>(() => DashboardServiceHost.ResolveEndpoint(uri, randomizePorts: false, allowUnsecuredTransport: true));
    }
}