Skip to content

FakeNavigationManager sets "Uri" property too early #1647

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
ayyron-dev opened this issue Jan 14, 2025 · 1 comment
Closed

FakeNavigationManager sets "Uri" property too early #1647

ayyron-dev opened this issue Jan 14, 2025 · 1 comment

Comments

@ayyron-dev
Copy link
Contributor

ayyron-dev commented Jan 14, 2025

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:

@linkdotnet
Copy link
Collaborator

That is definitely a bug. The Uri shouldn't be changed if the navigation is prevented.

At least I can't think of a good reason, why. So feel free to file a PR, that is very welcome!

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants