Skip to content

FakeNavigationManager sets "Uri" property too early #1647

@ayyron-dev

Description

@ayyron-dev

Describe the bug

I would love to try submitting a PR if the maintainers agree this should be changed.

In FakeNavigationManager.NavigateToCore() the Uri is being set regardless of whether or not handlers prevented navigation.

Example:
Testing this component:

@using Microsoft.AspNetCore.Components.Routing
@inject NavigationManager nav
@implements IDisposable

<h3>Navigation</h3>
<button id="clickable" @onclick=@(() => nav.NavigateTo("/some-path"))></button>

@code {
    IDisposable? _navRegistration;

    protected override void OnInitialized()
    {
        nav.NavigateTo("/original-path");
        _navRegistration = nav.RegisterLocationChangingHandler(LocationChangingHandler);
    }

    private async ValueTask LocationChangingHandler(LocationChangingContext arg)
    {
        arg.PreventNavigation();
    }

    private void UnregisterLocationChangingHandler()
    {
        _navRegistration?.Dispose();
        _navRegistration = null;
    }

    void IDisposable.Dispose()
    {
        UnregisterLocationChangingHandler();
    }
}

With this test:

@inherits TestContext

@code {

	[Fact]
	public void PreventNavigation()
	{
		// Arrange
		var cut = Render(@<Navigation />);
		var navigationManager = Services.GetRequiredService<NavigationManager>();

		// Assert we're at the starting Uri
		Assert.Equal(new Uri(new(navigationManager.BaseUri), "/original-path").AbsoluteUri, navigationManager.Uri);

		// Act -> click the button to navigate
		var button = cut.Find("#clickable");
		button.Click();

		// Assert the path remains the original path as navigation was prevented
		Assert.Equal(new Uri(new(navigationManager.BaseUri), "/original-path").AbsoluteUri, navigationManager.Uri);
	}
}

Results in this output:

[xUnit.net 00:00:01.26]     BUnitExamples.Tests.NavigationTests.PreventNavigation [FAIL]
[xUnit.net 00:00:01.27]       Assert.Equal() Failure: Strings differ
[xUnit.net 00:00:01.27]                                   ↓ (pos 17)
[xUnit.net 00:00:01.27]       Expected: "http://localhost/original-path"
[xUnit.net 00:00:01.27]       Actual:   "http://localhost/some-path"
[xUnit.net 00:00:01.27]                                   ↑ (pos 17)
[xUnit.net 00:00:01.27]       Stack Trace:
[xUnit.net 00:00:01.27]         C:\Users\XXXXXX\source\repos\BUnitExamples\BUnitExamples.Tests\NavigationTests.razor(20,0): at BUnitExamples.Tests.NavigationTests.PreventNavigation()
[xUnit.net 00:00:01.27]            at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
[xUnit.net 00:00:01.27]            at System.Reflection.MethodInvoker.Invoke(Object obj, IntPtr* args, BindingFlags invokeAttr)
[xUnit.net 00:00:01.27]   Finished:    BUnitExamples.Tests

Expected behavior:
I would have expected the test to pass. But both line #83 and line #95 are setting the Uri property before it checks if navigation should be prevented. The History Stack is correct, but I would have expected the FakeNavigationManager to behave more like the WebAssemblyNavigationManager

Version info:

  • bUnit version: 1.34.0
  • .NET Runtime and Blazor version: net7.0 (Mcrosoft.NETCore.App 7.0.20)
  • OS type and version: Windows 11 Version 23H2

Additional context:

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions