| 
1 | 1 | // Licensed to the .NET Foundation under one or more agreements.  | 
2 | 2 | // The .NET Foundation licenses this file to you under the MIT license.  | 
3 | 3 | 
 
  | 
 | 4 | +using System;  | 
4 | 5 | using System.Text.Encodings.Web;  | 
5 | 6 | using System.Text.Json;  | 
6 | 7 | using System.Text.RegularExpressions;  | 
 | 8 | +using Microsoft.AspNetCore.Builder;  | 
7 | 9 | using Microsoft.AspNetCore.Components.Endpoints.Forms;  | 
8 | 10 | using Microsoft.AspNetCore.Components.Endpoints.Tests.TestComponents;  | 
9 | 11 | using Microsoft.AspNetCore.Components.Forms;  | 
 | 
12 | 14 | using Microsoft.AspNetCore.Components.Reflection;  | 
13 | 15 | using Microsoft.AspNetCore.Components.Rendering;  | 
14 | 16 | using Microsoft.AspNetCore.Components.RenderTree;  | 
 | 17 | +using Microsoft.AspNetCore.Components.Routing;  | 
15 | 18 | using Microsoft.AspNetCore.Components.Test.Helpers;  | 
16 | 19 | using Microsoft.AspNetCore.Components.Web;  | 
17 | 20 | using Microsoft.AspNetCore.DataProtection;  | 
@@ -934,6 +937,28 @@ await renderer.PrerenderComponentAsync(  | 
934 | 937 |         Assert.Equal("http://localhost/redirect", ctx.Response.Headers.Location);  | 
935 | 938 |     }  | 
936 | 939 | 
 
  | 
 | 940 | +    [Fact]  | 
 | 941 | +    public async Task Renderer_WhenNoNotFoundPathProvided_Throws()  | 
 | 942 | +    {  | 
 | 943 | +        // Arrange  | 
 | 944 | +        var httpContext = GetHttpContext();  | 
 | 945 | +        var responseMock = new Mock<IHttpResponseFeature>();  | 
 | 946 | +        responseMock.Setup(r => r.HasStarted).Returns(true);  | 
 | 947 | +        responseMock.Setup(r => r.Headers).Returns(new HeaderDictionary());  | 
 | 948 | +        httpContext.Features.Set(responseMock.Object);  | 
 | 949 | +        var renderer = GetEndpointHtmlRenderer();  | 
 | 950 | +        httpContext.Items[nameof(StatusCodePagesOptions)] = null; // simulate missing re-execution route  | 
 | 951 | + | 
 | 952 | +        var component = new NotFoundComponent();  | 
 | 953 | +        var id = renderer.AssignRootComponentId(component);  | 
 | 954 | +        var exception = await Assert.ThrowsAsync<InvalidOperationException>(async () =>  | 
 | 955 | +            await renderer.SetNotFoundResponseAsync(httpContext, new NotFoundEventArgs(""))  | 
 | 956 | +        );  | 
 | 957 | +        string expectedError = "The NotFoundPage route must be specified or re-execution middleware has to be set to render NotFoundPage when the response has started.";  | 
 | 958 | + | 
 | 959 | +        Assert.Equal(expectedError, exception.Message);  | 
 | 960 | +    }  | 
 | 961 | + | 
937 | 962 |     [Fact]  | 
938 | 963 |     public async Task CanRender_AsyncComponent()  | 
939 | 964 |     {  | 
@@ -1802,6 +1827,12 @@ protected override void ProcessPendingRender()  | 
1802 | 1827 |             _rendererIsStopped = true;  | 
1803 | 1828 |             base.SignalRendererToFinishRendering();  | 
1804 | 1829 |         }  | 
 | 1830 | + | 
 | 1831 | +        public async Task SetNotFoundResponseAsync(HttpContext httpContext, NotFoundEventArgs args)  | 
 | 1832 | +        {  | 
 | 1833 | +            SetHttpContext(httpContext);  | 
 | 1834 | +            await SetNotFoundResponseAsync(httpContext.Request.PathBase, args);  | 
 | 1835 | +        }  | 
1805 | 1836 |     }  | 
1806 | 1837 | 
 
  | 
1807 | 1838 |     private HttpContext GetHttpContext(HttpContext context = null)  | 
 | 
0 commit comments