File: SSRRenderModeBoundaryTest.cs
Web Access
Project: src\src\Components\Endpoints\test\Microsoft.AspNetCore.Components.Endpoints.Tests.csproj (Microsoft.AspNetCore.Components.Endpoints.Tests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Http;
 
namespace Microsoft.AspNetCore.Components.Endpoints;
 
public class SSRRenderModeBoundaryTest
{
    // While most aspects of SSRRenderModeBoundary are only interesting to test E2E,
    // the configuration validation aspect is better covered as unit tests because
    // otherwise we would need many different E2E test app configurations.
 
    [Fact]
    public void DoesNotAssertAboutConfiguredRenderModesOnUnknownEndpoints()
    {
        // Arrange: an endpoint with no ConfiguredRenderModesMetadata
        var httpContext = new DefaultHttpContext();
        httpContext.SetEndpoint(new Endpoint(null, new EndpointMetadataCollection(), null));
 
        // Act/Assert: no exception means we're OK
        new SSRRenderModeBoundary(httpContext, typeof(TestComponent), new InteractiveServerRenderMode());
        new SSRRenderModeBoundary(httpContext, typeof(TestComponent), new InteractiveWebAssemblyRenderMode());
        new SSRRenderModeBoundary(httpContext, typeof(TestComponent), new InteractiveAutoRenderMode());
    }
 
    [Fact]
    public void ThrowsIfServerRenderModeUsedAndNotConfigured()
    {
        // Arrange
        var httpContext = new DefaultHttpContext();
        PrepareEndpoint(httpContext, new WebAssemblyRenderModeSubclass());
 
        // Act/Assert
        var ex = Assert.Throws<InvalidOperationException>(() => new SSRRenderModeBoundary(
            httpContext, typeof(TestComponent), new ServerRenderModeSubclass()));
        Assert.Contains($"A component of type '{typeof(TestComponent)}' has render mode '{nameof(ServerRenderModeSubclass)}'", ex.Message);
        Assert.Contains($"add a call to 'AddInteractiveServerRenderMode'", ex.Message);
    }
 
    [Fact]
    public void ThrowsIfWebAssemblyRenderModeUsedAndNotConfigured()
    {
        // Arrange
        var httpContext = new DefaultHttpContext();
        PrepareEndpoint(httpContext, new ServerRenderModeSubclass());
 
        // Act/Assert
        var ex = Assert.Throws<InvalidOperationException>(() => new SSRRenderModeBoundary(
            httpContext, typeof(TestComponent), new WebAssemblyRenderModeSubclass()));
        Assert.Contains($"A component of type '{typeof(TestComponent)}' has render mode '{nameof(WebAssemblyRenderModeSubclass)}'", ex.Message);
        Assert.Contains($"add a call to 'AddInteractiveWebAssemblyRenderMode'", ex.Message);
    }
 
    [Fact]
    public void ThrowsIfAutoRenderModeUsedAndServerNotConfigured()
    {
        // Arrange
        var httpContext = new DefaultHttpContext();
        PrepareEndpoint(httpContext, new WebAssemblyRenderModeSubclass());
 
        // Act/Assert
        var ex = Assert.Throws<InvalidOperationException>(() => new SSRRenderModeBoundary(
            httpContext, typeof(TestComponent), new AutoRenderModeSubclass()));
        Assert.Contains($"A component of type '{typeof(TestComponent)}' has render mode '{nameof(AutoRenderModeSubclass)}'", ex.Message);
        Assert.Contains($"add a call to 'AddInteractiveServerRenderMode'", ex.Message);
    }
 
    [Fact]
    public void ThrowsIfAutoRenderModeUsedAndWebAssemblyNotConfigured()
    {
        // Arrange
        var httpContext = new DefaultHttpContext();
        PrepareEndpoint(httpContext, new ServerRenderModeSubclass());
 
        // Act/Assert
        var ex = Assert.Throws<InvalidOperationException>(() => new SSRRenderModeBoundary(
            httpContext, typeof(TestComponent), new AutoRenderModeSubclass()));
        Assert.Contains($"A component of type '{typeof(TestComponent)}' has render mode '{nameof(AutoRenderModeSubclass)}'", ex.Message);
        Assert.Contains($"add a call to 'AddInteractiveWebAssemblyRenderMode'", ex.Message);
    }
 
    private static void PrepareEndpoint(HttpContext httpContext, params IComponentRenderMode[] configuredModes)
    {
        httpContext.SetEndpoint(new Endpoint(null, new EndpointMetadataCollection(
            new ConfiguredRenderModesMetadata(configuredModes)), null));
    }
 
    class TestComponent : IComponent
    {
        public void Attach(RenderHandle renderHandle)
            => throw new NotImplementedException();
 
        public Task SetParametersAsync(ParameterView parameters)
            => throw new NotImplementedException();
    }
 
    class ServerRenderModeSubclass : InteractiveServerRenderMode { }
    class WebAssemblyRenderModeSubclass : InteractiveWebAssemblyRenderMode { }
    class AutoRenderModeSubclass : InteractiveAutoRenderMode { }
}