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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions