From 296deea3494941e26fb79c5794ab44fef40bdc0d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 9 Jul 2025 07:27:12 +0000 Subject: [PATCH 01/10] Initial plan From 93b15d62694274e90fbad9ebc1d6a03634e9254a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 9 Jul 2025 07:36:45 +0000 Subject: [PATCH 02/10] Add validation to prevent NotFound and NotFoundPage being set simultaneously Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- .../Components/src/PublicAPI.Unshipped.txt | 2 +- .../Components/src/Routing/Router.cs | 7 +- .../Components/test/Routing/RouterTest.cs | 70 +++++++++++++++++++ 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/src/Components/Components/src/PublicAPI.Unshipped.txt b/src/Components/Components/src/PublicAPI.Unshipped.txt index dc07b8afddac..f5e0f10aad7d 100644 --- a/src/Components/Components/src/PublicAPI.Unshipped.txt +++ b/src/Components/Components/src/PublicAPI.Unshipped.txt @@ -1,7 +1,7 @@ #nullable enable *REMOVED*Microsoft.AspNetCore.Components.ResourceAsset.ResourceAsset(string! url, System.Collections.Generic.IReadOnlyList? properties) -> void Microsoft.AspNetCore.Components.ResourceAsset.ResourceAsset(string! url, System.Collections.Generic.IReadOnlyList? properties = null) -> void -Microsoft.AspNetCore.Components.Routing.Router.NotFoundPage.get -> System.Type! +Microsoft.AspNetCore.Components.Routing.Router.NotFoundPage.get -> System.Type? Microsoft.AspNetCore.Components.Routing.Router.NotFoundPage.set -> void Microsoft.AspNetCore.Components.Infrastructure.ComponentsMetricsServiceCollectionExtensions Microsoft.AspNetCore.Components.NavigationManager.OnNotFound -> System.EventHandler! diff --git a/src/Components/Components/src/Routing/Router.cs b/src/Components/Components/src/Routing/Router.cs index eedff373f656..79a48ec9f973 100644 --- a/src/Components/Components/src/Routing/Router.cs +++ b/src/Components/Components/src/Routing/Router.cs @@ -77,7 +77,7 @@ static readonly IReadOnlyDictionary _emptyParametersDictionary /// [Parameter] [DynamicallyAccessedMembers(LinkerFlags.Component)] - public Type NotFoundPage { get; set; } = default!; + public Type? NotFoundPage { get; set; } /// /// Gets or sets the content to display when a match is found for the requested route. @@ -141,6 +141,11 @@ public async Task SetParametersAsync(ParameterView parameters) throw new InvalidOperationException($"The {nameof(Router)} component requires a value for the parameter {nameof(Found)}."); } + if (NotFound != null && NotFoundPage != null) + { + throw new InvalidOperationException($"The {nameof(Router)} component cannot have both {nameof(NotFound)} and {nameof(NotFoundPage)} parameters set. Use either {nameof(NotFound)} render fragment or {nameof(NotFoundPage)} component type, but not both."); + } + if (NotFoundPage != null) { if (!typeof(IComponent).IsAssignableFrom(NotFoundPage)) diff --git a/src/Components/Components/test/Routing/RouterTest.cs b/src/Components/Components/test/Routing/RouterTest.cs index f393a2edccf0..76aece62db60 100644 --- a/src/Components/Components/test/Routing/RouterTest.cs +++ b/src/Components/Components/test/Routing/RouterTest.cs @@ -265,6 +265,73 @@ await _renderer.Dispatcher.InvokeAsync(() => Assert.Equal("Not found", renderedFrame.TextContent); } + [Fact] + public async Task ThrowsIfBothNotFoundAndNotFoundPageAreSet() + { + // Arrange + var parameters = new Dictionary + { + { nameof(Router.AppAssembly), typeof(RouterTest).Assembly }, + { nameof(Router.NotFound), (RenderFragment)(builder => builder.AddContent(0, "Custom content")) }, + { nameof(Router.NotFoundPage), typeof(TestNotFoundPageComponent) }, + }; + + // Act & Assert + var exception = await Assert.ThrowsAsync(async () => + await _renderer.Dispatcher.InvokeAsync(() => + _router.SetParametersAsync(ParameterView.FromDictionary(parameters)))); + + Assert.Contains("cannot have both NotFound and NotFoundPage parameters set", exception.Message); + } + + [Fact] + public async Task UsesNotFoundPageIfSpecified() + { + // Arrange + _navigationManager.NotifyLocationChanged("https://www.example.com/subdir/nonexistent", false); + var parameters = new Dictionary + { + { nameof(Router.AppAssembly), typeof(RouterTest).Assembly }, + { nameof(Router.NotFoundPage), typeof(TestNotFoundPageComponent) }, + }; + + // Act + await _renderer.Dispatcher.InvokeAsync(() => + _router.SetParametersAsync(ParameterView.FromDictionary(parameters))); + + // Assert + var batch = _renderer.Batches.First(); + var renderedFrame = batch.ReferenceFrames.Skip(1).First(); // Skip the RouteView frame + Assert.Equal(RenderTreeFrameType.Attribute, renderedFrame.FrameType); + Assert.Equal(nameof(RouteView.RouteData), renderedFrame.AttributeName); + var routeData = (RouteData)renderedFrame.AttributeValue; + Assert.Equal(typeof(TestNotFoundPageComponent), routeData.PageType); + } + + [Fact] + public async Task UsesNotFoundPageOverNotFound() + { + // Arrange - This test verifies that if only NotFoundPage is set (not both), it takes precedence over default + _navigationManager.NotifyLocationChanged("https://www.example.com/subdir/nonexistent", false); + var parameters = new Dictionary + { + { nameof(Router.AppAssembly), typeof(RouterTest).Assembly }, + { nameof(Router.NotFoundPage), typeof(TestNotFoundPageComponent) }, + }; + + // Act + await _renderer.Dispatcher.InvokeAsync(() => + _router.SetParametersAsync(ParameterView.FromDictionary(parameters))); + + // Assert + var batch = _renderer.Batches.First(); + var renderedFrame = batch.ReferenceFrames.Skip(1).First(); // Skip the RouteView frame + Assert.Equal(RenderTreeFrameType.Attribute, renderedFrame.FrameType); + Assert.Equal(nameof(RouteView.RouteData), renderedFrame.AttributeName); + var routeData = (RouteData)renderedFrame.AttributeValue; + Assert.Equal(typeof(TestNotFoundPageComponent), routeData.PageType); + } + internal class TestNavigationManager : NavigationManager { public TestNavigationManager() => @@ -306,4 +373,7 @@ public class MatchAnythingComponent : ComponentBase { } [Route("a/b/c")] public class MultiSegmentRouteComponent : ComponentBase { } + + [Route("/not-found")] + public class TestNotFoundPageComponent : ComponentBase { } } From 935a879a3d506e318631560c060abcbc4843dd1c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 9 Jul 2025 07:53:09 +0000 Subject: [PATCH 03/10] Remove all tests as requested - keep only validation logic Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- .../Components/test/Routing/RouterTest.cs | 70 ------------------- 1 file changed, 70 deletions(-) diff --git a/src/Components/Components/test/Routing/RouterTest.cs b/src/Components/Components/test/Routing/RouterTest.cs index 76aece62db60..f393a2edccf0 100644 --- a/src/Components/Components/test/Routing/RouterTest.cs +++ b/src/Components/Components/test/Routing/RouterTest.cs @@ -265,73 +265,6 @@ await _renderer.Dispatcher.InvokeAsync(() => Assert.Equal("Not found", renderedFrame.TextContent); } - [Fact] - public async Task ThrowsIfBothNotFoundAndNotFoundPageAreSet() - { - // Arrange - var parameters = new Dictionary - { - { nameof(Router.AppAssembly), typeof(RouterTest).Assembly }, - { nameof(Router.NotFound), (RenderFragment)(builder => builder.AddContent(0, "Custom content")) }, - { nameof(Router.NotFoundPage), typeof(TestNotFoundPageComponent) }, - }; - - // Act & Assert - var exception = await Assert.ThrowsAsync(async () => - await _renderer.Dispatcher.InvokeAsync(() => - _router.SetParametersAsync(ParameterView.FromDictionary(parameters)))); - - Assert.Contains("cannot have both NotFound and NotFoundPage parameters set", exception.Message); - } - - [Fact] - public async Task UsesNotFoundPageIfSpecified() - { - // Arrange - _navigationManager.NotifyLocationChanged("https://www.example.com/subdir/nonexistent", false); - var parameters = new Dictionary - { - { nameof(Router.AppAssembly), typeof(RouterTest).Assembly }, - { nameof(Router.NotFoundPage), typeof(TestNotFoundPageComponent) }, - }; - - // Act - await _renderer.Dispatcher.InvokeAsync(() => - _router.SetParametersAsync(ParameterView.FromDictionary(parameters))); - - // Assert - var batch = _renderer.Batches.First(); - var renderedFrame = batch.ReferenceFrames.Skip(1).First(); // Skip the RouteView frame - Assert.Equal(RenderTreeFrameType.Attribute, renderedFrame.FrameType); - Assert.Equal(nameof(RouteView.RouteData), renderedFrame.AttributeName); - var routeData = (RouteData)renderedFrame.AttributeValue; - Assert.Equal(typeof(TestNotFoundPageComponent), routeData.PageType); - } - - [Fact] - public async Task UsesNotFoundPageOverNotFound() - { - // Arrange - This test verifies that if only NotFoundPage is set (not both), it takes precedence over default - _navigationManager.NotifyLocationChanged("https://www.example.com/subdir/nonexistent", false); - var parameters = new Dictionary - { - { nameof(Router.AppAssembly), typeof(RouterTest).Assembly }, - { nameof(Router.NotFoundPage), typeof(TestNotFoundPageComponent) }, - }; - - // Act - await _renderer.Dispatcher.InvokeAsync(() => - _router.SetParametersAsync(ParameterView.FromDictionary(parameters))); - - // Assert - var batch = _renderer.Batches.First(); - var renderedFrame = batch.ReferenceFrames.Skip(1).First(); // Skip the RouteView frame - Assert.Equal(RenderTreeFrameType.Attribute, renderedFrame.FrameType); - Assert.Equal(nameof(RouteView.RouteData), renderedFrame.AttributeName); - var routeData = (RouteData)renderedFrame.AttributeValue; - Assert.Equal(typeof(TestNotFoundPageComponent), routeData.PageType); - } - internal class TestNavigationManager : NavigationManager { public TestNavigationManager() => @@ -373,7 +306,4 @@ public class MatchAnythingComponent : ComponentBase { } [Route("a/b/c")] public class MultiSegmentRouteComponent : ComponentBase { } - - [Route("/not-found")] - public class TestNotFoundPageComponent : ComponentBase { } } From 4bef8cc28e9b210c7c8a23a2186a8f048e679a2f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 9 Jul 2025 08:26:16 +0000 Subject: [PATCH 04/10] Replace exception with warning logging for NotFound/NotFoundPage validation Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- .../Components/src/Routing/Router.cs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/Components/Components/src/Routing/Router.cs b/src/Components/Components/src/Routing/Router.cs index 79a48ec9f973..7a5599fcefb3 100644 --- a/src/Components/Components/src/Routing/Router.cs +++ b/src/Components/Components/src/Routing/Router.cs @@ -70,6 +70,7 @@ static readonly IReadOnlyDictionary _emptyParametersDictionary /// Gets or sets the content to display when no match is found for the requested route. /// [Parameter] + [Obsolete("NotFound is deprecated. Use NotFoundPage instead.")] public RenderFragment NotFound { get; set; } /// @@ -141,13 +142,14 @@ public async Task SetParametersAsync(ParameterView parameters) throw new InvalidOperationException($"The {nameof(Router)} component requires a value for the parameter {nameof(Found)}."); } - if (NotFound != null && NotFoundPage != null) - { - throw new InvalidOperationException($"The {nameof(Router)} component cannot have both {nameof(NotFound)} and {nameof(NotFoundPage)} parameters set. Use either {nameof(NotFound)} render fragment or {nameof(NotFoundPage)} component type, but not both."); - } - if (NotFoundPage != null) { +#pragma warning disable CS0618 // Type or member is obsolete + if (NotFound != null) + { + Log.BothNotFoundParametersSet(_logger); + } +#pragma warning restore CS0618 // Type or member is obsolete if (!typeof(IComponent).IsAssignableFrom(NotFoundPage)) { throw new InvalidOperationException($"The type {NotFoundPage.FullName} " + @@ -406,10 +408,12 @@ private void RenderNotFound() new RouteData(NotFoundPage, _emptyParametersDictionary)); builder.CloseComponent(); } +#pragma warning disable CS0618 // Type or member is obsolete else if (NotFound != null) { NotFound(builder); } +#pragma warning restore CS0618 // Type or member is obsolete else { DefaultNotFoundContent(builder); @@ -434,6 +438,7 @@ async Task IHandleAfterRender.OnAfterRenderAsync() private static partial class Log { +#pragma warning disable CS0618 // Type or member is obsolete [LoggerMessage(1, LogLevel.Debug, $"Displaying {nameof(NotFound)} because path '{{Path}}' with base URI '{{BaseUri}}' does not match any component route", EventName = "DisplayingNotFound")] internal static partial void DisplayingNotFound(ILogger logger, string path, string baseUri); @@ -445,5 +450,9 @@ private static partial class Log [LoggerMessage(4, LogLevel.Debug, $"Displaying {nameof(NotFound)} on request", EventName = "DisplayingNotFoundOnRequest")] internal static partial void DisplayingNotFound(ILogger logger); +#pragma warning restore CS0618 // Type or member is obsolete + + [LoggerMessage(5, LogLevel.Warning, "Both NotFound and NotFoundPage parameters are set on Router component. NotFoundPage is preferred and NotFound will be deprecated. Consider using only NotFoundPage.", EventName = "BothNotFoundParametersSet")] + internal static partial void BothNotFoundParametersSet(ILogger logger); } } From c5e0c46f56144e98accbc88c492fd664ffa891b6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 9 Jul 2025 10:34:05 +0000 Subject: [PATCH 05/10] Disable CS0618 obsolete warnings for RouterTest.cs Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- src/Components/Components/test/Routing/RouterTest.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Components/Components/test/Routing/RouterTest.cs b/src/Components/Components/test/Routing/RouterTest.cs index f393a2edccf0..4514a96d5bcb 100644 --- a/src/Components/Components/test/Routing/RouterTest.cs +++ b/src/Components/Components/test/Routing/RouterTest.cs @@ -1,6 +1,8 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +#pragma warning disable CS0618 // Type or member is obsolete + using System.Reflection; using Microsoft.AspNetCore.Components.RenderTree; using Microsoft.AspNetCore.Components.Test.Helpers; From aa545628048cbcee638e03b0a1f31da766d76c8e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 9 Jul 2025 12:30:02 +0000 Subject: [PATCH 06/10] Add unit test for warning when both NotFound and NotFoundPage are set Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- .../Components/test/Routing/RouterTest.cs | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/src/Components/Components/test/Routing/RouterTest.cs b/src/Components/Components/test/Routing/RouterTest.cs index 4514a96d5bcb..3c860656db49 100644 --- a/src/Components/Components/test/Routing/RouterTest.cs +++ b/src/Components/Components/test/Routing/RouterTest.cs @@ -267,6 +267,43 @@ await _renderer.Dispatcher.InvokeAsync(() => Assert.Equal("Not found", renderedFrame.TextContent); } + [Fact] + public async Task LogsWarningWhenBothNotFoundAndNotFoundPageAreSet() + { + // Arrange + var logger = new TestLogger(); + var services = new ServiceCollection(); + services.AddSingleton(new TestLoggerFactory(logger)); + services.AddSingleton(_navigationManager); + services.AddSingleton(); + services.AddSingleton(); + var serviceProvider = services.BuildServiceProvider(); + + var renderer = new TestRenderer(serviceProvider); + renderer.ShouldHandleExceptions = true; + var router = (Router)renderer.InstantiateComponent(); + router.AppAssembly = Assembly.GetExecutingAssembly(); + router.Found = routeData => (builder) => builder.AddContent(0, $"Rendering route matching {routeData.PageType}"); + renderer.AssignRootComponentId(router); + + var parameters = new Dictionary + { + { nameof(Router.AppAssembly), typeof(RouterTest).Assembly }, + { nameof(Router.NotFound), (RenderFragment)(builder => builder.AddContent(0, "Custom not found")) }, + { nameof(Router.NotFoundPage), typeof(NotFoundTestComponent) } + }; + + // Act + await renderer.Dispatcher.InvokeAsync(() => + router.SetParametersAsync(ParameterView.FromDictionary(parameters))); + + // Assert + var warningLogs = logger.LogEntries.Where(entry => entry.LogLevel == LogLevel.Warning).ToList(); + Assert.Single(warningLogs); + Assert.Contains("Both NotFound and NotFoundPage parameters are set on Router component", warningLogs[0].Message); + Assert.Contains("NotFoundPage is preferred and NotFound will be deprecated", warningLogs[0].Message); + } + internal class TestNavigationManager : NavigationManager { public TestNavigationManager() => @@ -308,4 +345,51 @@ public class MatchAnythingComponent : ComponentBase { } [Route("a/b/c")] public class MultiSegmentRouteComponent : ComponentBase { } + + [Route("not-found")] + public class NotFoundTestComponent : ComponentBase { } + + public class TestLogger : ILogger + { + public List LogEntries { get; } = new List(); + + public IDisposable BeginScope(TState state) => null; + + public bool IsEnabled(LogLevel logLevel) => true; + + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) + { + LogEntries.Add(new LogEntry + { + LogLevel = logLevel, + EventId = eventId, + Message = formatter(state, exception), + Exception = exception + }); + } + } + + public class LogEntry + { + public LogLevel LogLevel { get; set; } + public EventId EventId { get; set; } + public string Message { get; set; } + public Exception Exception { get; set; } + } + + public class TestLoggerFactory : ILoggerFactory + { + private readonly ILogger _logger; + + public TestLoggerFactory(ILogger logger) + { + _logger = logger; + } + + public void AddProvider(ILoggerProvider provider) { } + + public ILogger CreateLogger(string categoryName) => _logger; + + public void Dispose() { } + } } From c10c0d4cfc4e7a8c9e5fbe5482bbb000e79b6694 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 15 Jul 2025 08:06:28 +0000 Subject: [PATCH 07/10] Change warning to throwing exception for NotFound/NotFoundPage validation Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- .../Components/src/Routing/Router.cs | 5 +---- .../Components/test/Routing/RouterTest.cs | 19 ++++++++----------- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/Components/Components/src/Routing/Router.cs b/src/Components/Components/src/Routing/Router.cs index 7a5599fcefb3..2bec7fdd24d3 100644 --- a/src/Components/Components/src/Routing/Router.cs +++ b/src/Components/Components/src/Routing/Router.cs @@ -147,7 +147,7 @@ public async Task SetParametersAsync(ParameterView parameters) #pragma warning disable CS0618 // Type or member is obsolete if (NotFound != null) { - Log.BothNotFoundParametersSet(_logger); + throw new InvalidOperationException("Both NotFound and NotFoundPage parameters are set on Router component. NotFoundPage is preferred and NotFound will be deprecated. Consider using only NotFoundPage."); } #pragma warning restore CS0618 // Type or member is obsolete if (!typeof(IComponent).IsAssignableFrom(NotFoundPage)) @@ -451,8 +451,5 @@ private static partial class Log [LoggerMessage(4, LogLevel.Debug, $"Displaying {nameof(NotFound)} on request", EventName = "DisplayingNotFoundOnRequest")] internal static partial void DisplayingNotFound(ILogger logger); #pragma warning restore CS0618 // Type or member is obsolete - - [LoggerMessage(5, LogLevel.Warning, "Both NotFound and NotFoundPage parameters are set on Router component. NotFoundPage is preferred and NotFound will be deprecated. Consider using only NotFoundPage.", EventName = "BothNotFoundParametersSet")] - internal static partial void BothNotFoundParametersSet(ILogger logger); } } diff --git a/src/Components/Components/test/Routing/RouterTest.cs b/src/Components/Components/test/Routing/RouterTest.cs index 3c860656db49..96d7b9dea109 100644 --- a/src/Components/Components/test/Routing/RouterTest.cs +++ b/src/Components/Components/test/Routing/RouterTest.cs @@ -268,12 +268,11 @@ await _renderer.Dispatcher.InvokeAsync(() => } [Fact] - public async Task LogsWarningWhenBothNotFoundAndNotFoundPageAreSet() + public async Task ThrowsExceptionWhenBothNotFoundAndNotFoundPageAreSet() { // Arrange - var logger = new TestLogger(); var services = new ServiceCollection(); - services.AddSingleton(new TestLoggerFactory(logger)); + services.AddSingleton(NullLoggerFactory.Instance); services.AddSingleton(_navigationManager); services.AddSingleton(); services.AddSingleton(); @@ -293,15 +292,13 @@ public async Task LogsWarningWhenBothNotFoundAndNotFoundPageAreSet() { nameof(Router.NotFoundPage), typeof(NotFoundTestComponent) } }; - // Act - await renderer.Dispatcher.InvokeAsync(() => - router.SetParametersAsync(ParameterView.FromDictionary(parameters))); + // Act & Assert + var exception = await Assert.ThrowsAsync(async () => + await renderer.Dispatcher.InvokeAsync(() => + router.SetParametersAsync(ParameterView.FromDictionary(parameters)))); - // Assert - var warningLogs = logger.LogEntries.Where(entry => entry.LogLevel == LogLevel.Warning).ToList(); - Assert.Single(warningLogs); - Assert.Contains("Both NotFound and NotFoundPage parameters are set on Router component", warningLogs[0].Message); - Assert.Contains("NotFoundPage is preferred and NotFound will be deprecated", warningLogs[0].Message); + Assert.Contains("Both NotFound and NotFoundPage parameters are set on Router component", exception.Message); + Assert.Contains("NotFoundPage is preferred and NotFound will be deprecated", exception.Message); } internal class TestNavigationManager : NavigationManager From 0712e4c3423d7c777493b5c50234e5eccdfc2280 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Tue, 15 Jul 2025 08:20:32 +0000 Subject: [PATCH 08/10] Fix test assets and clean up test code as requested Co-authored-by: ilonatommy <32700855+ilonatommy@users.noreply.github.com> --- .../Components/test/Routing/RouterTest.cs | 43 ------------------- .../RazorComponents/App.razor | 26 ++++++++--- .../Components.WasmMinimal/Routes.razor | 26 ++++++++--- 3 files changed, 38 insertions(+), 57 deletions(-) diff --git a/src/Components/Components/test/Routing/RouterTest.cs b/src/Components/Components/test/Routing/RouterTest.cs index 96d7b9dea109..460444b919ca 100644 --- a/src/Components/Components/test/Routing/RouterTest.cs +++ b/src/Components/Components/test/Routing/RouterTest.cs @@ -346,47 +346,4 @@ public class MultiSegmentRouteComponent : ComponentBase { } [Route("not-found")] public class NotFoundTestComponent : ComponentBase { } - public class TestLogger : ILogger - { - public List LogEntries { get; } = new List(); - - public IDisposable BeginScope(TState state) => null; - - public bool IsEnabled(LogLevel logLevel) => true; - - public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) - { - LogEntries.Add(new LogEntry - { - LogLevel = logLevel, - EventId = eventId, - Message = formatter(state, exception), - Exception = exception - }); - } - } - - public class LogEntry - { - public LogLevel LogLevel { get; set; } - public EventId EventId { get; set; } - public string Message { get; set; } - public Exception Exception { get; set; } - } - - public class TestLoggerFactory : ILoggerFactory - { - private readonly ILogger _logger; - - public TestLoggerFactory(ILogger logger) - { - _logger = logger; - } - - public void AddProvider(ILoggerProvider provider) { } - - public ILogger CreateLogger(string categoryName) => _logger; - - public void Dispose() { } - } } diff --git a/src/Components/test/testassets/Components.TestServer/RazorComponents/App.razor b/src/Components/test/testassets/Components.TestServer/RazorComponents/App.razor index 2219da3955d2..d2adde64c256 100644 --- a/src/Components/test/testassets/Components.TestServer/RazorComponents/App.razor +++ b/src/Components/test/testassets/Components.TestServer/RazorComponents/App.razor @@ -30,13 +30,25 @@ - - - - - -

There's nothing here

-
+ @if (NotFoundPageType != null) + { + + + + + + + } + else + { + + + + + +

There's nothing here

+
+ }