mirror of
https://github.com/DrMboga/WotBlitzStatisticsBlazor.git
synced 2026-10-24 20:00:05 +02:00
feat: Blazor tests added
This commit is contained in:
1 parent
b4378b643b
commit
c60f622989
7 files changed
+309
-21
No files matched your search
@@ -0,0 +1,30 @@
|
|||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
|
||||||
|
namespace WotBlitzStatisticsPro.Blazor.Tests
|
||||||
|
{
|
||||||
|
public class MockNavigationManager: NavigationManager
|
||||||
|
{
|
||||||
|
public int NavigationCount { get; private set; } = 0;
|
||||||
|
|
||||||
|
public MockNavigationManager()
|
||||||
|
{
|
||||||
|
Initialize("https://unit-test.example/", "https://unit-test.example/bla-bla");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override void NavigateToCore(string uri, bool forceLoad)
|
||||||
|
{
|
||||||
|
if (uri == "/")
|
||||||
|
{
|
||||||
|
Uri = BaseUri;
|
||||||
|
}
|
||||||
|
else if (uri.StartsWith("/") && uri.Length > 1)
|
||||||
|
{
|
||||||
|
Uri = $"{BaseUri}{uri.Substring(1)}";
|
||||||
|
}
|
||||||
|
NotifyLocationChanged(false);
|
||||||
|
|
||||||
|
NavigationCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
-21
@@ -1,41 +1,28 @@
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Bunit;
|
using Bunit;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using MediatR;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using Radzen;
|
|
||||||
using WotBlitzStatisticsPro.Blazor.Messages;
|
using WotBlitzStatisticsPro.Blazor.Messages;
|
||||||
using WotBlitzStatisticsPro.Blazor.Services;
|
|
||||||
using WotBlitzStatisticsPro.Blazor.Shared;
|
using WotBlitzStatisticsPro.Blazor.Shared;
|
||||||
|
|
||||||
namespace WotBlitzStatisticsPro.Blazor.Tests
|
namespace WotBlitzStatisticsPro.Blazor.Tests.Pages
|
||||||
{
|
{
|
||||||
public class MainLayoutTest: TestContextWrapper
|
public class MainLayoutTest: TestContextBase
|
||||||
{
|
{
|
||||||
private readonly Mock<IMediator> _mediatorMock = new();
|
|
||||||
private readonly Mock<ISearchDialogService> _searchServiceMock = new();
|
|
||||||
private IRenderedComponent<MainLayout> _component;
|
private IRenderedComponent<MainLayout> _component;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
TestContext = new Bunit.TestContext();
|
_component = TestContext?.RenderComponent<MainLayout>();
|
||||||
TestContext.Services.AddSingleton(_mediatorMock.Object);
|
|
||||||
|
|
||||||
TestContext.Services.AddSingleton<DialogService>();
|
|
||||||
TestContext.Services.AddSingleton(_searchServiceMock.Object);
|
|
||||||
TestContext.Services.AddLocalization();
|
|
||||||
|
|
||||||
_component = TestContext.RenderComponent<MainLayout>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void ShouldFireMediatorEventEachTimeWhenLanguageChanged()
|
public void ShouldFireMediatorEventEachTimeWhenLanguageChanged()
|
||||||
{
|
{
|
||||||
// =====================================
|
// =====================================
|
||||||
// Hint for css lookup
|
// Hint for css selector
|
||||||
/*
|
/*
|
||||||
By.css('.classname') // get by class name
|
By.css('.classname') // get by class name
|
||||||
By.css('input[type=radio]') // get input by type radio
|
By.css('input[type=radio]') // get input by type radio
|
||||||
@@ -57,13 +44,10 @@ By.css('.parent .child') // get child who has a parent
|
|||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
elements[i].Click();
|
elements[i].Click();
|
||||||
_mediatorMock.Verify(m => m.Publish(
|
MediatorMock.Verify(m => m.Publish(
|
||||||
It.Is<ChangeCurrentCultureMessage>(m => m.CultureName == expectedLanguages[0]),
|
It.Is<ChangeCurrentCultureMessage>(m => m.CultureName == expectedLanguages[0]),
|
||||||
It.IsAny<CancellationToken>()), Times.Once);
|
It.IsAny<CancellationToken>()), Times.Once);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[TearDown]
|
|
||||||
public void TearDown() => TestContext?.Dispose();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using AngleSharp.Dom;
|
||||||
|
using Bunit;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using WotBlitzStatisticsPro.Blazor.Messages;
|
||||||
|
using WotBlitzStatisticsPro.Blazor.Model;
|
||||||
|
using WotBlitzStatisticsPro.Blazor.Shared;
|
||||||
|
using Index = WotBlitzStatisticsPro.Blazor.Pages.Index;
|
||||||
|
|
||||||
|
namespace WotBlitzStatisticsPro.Blazor.Tests.Pages
|
||||||
|
{
|
||||||
|
public class NavMenuAndIndexPageTests: TestContextBase
|
||||||
|
{
|
||||||
|
public enum ComponentType
|
||||||
|
{
|
||||||
|
NavMenu,
|
||||||
|
Index
|
||||||
|
}
|
||||||
|
|
||||||
|
private IRenderedComponent<NavMenu> _navMenuComponent;
|
||||||
|
private IRefreshableElementCollection<IElement> _navMenuElements;
|
||||||
|
private IRenderedComponent<Index> _indexComponent;
|
||||||
|
private IRefreshableElementCollection<IElement> _indexButtons;
|
||||||
|
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_navMenuComponent = TestContext?.RenderComponent<NavMenu>();
|
||||||
|
_indexComponent = TestContext?.RenderComponent<Index>();
|
||||||
|
|
||||||
|
_navMenuElements = _navMenuComponent?.FindAll(".rz-navigation-item");
|
||||||
|
_navMenuElements.Should().NotBeNull();
|
||||||
|
_navMenuElements?.Count.Should().Be(4);
|
||||||
|
|
||||||
|
_indexButtons = _indexComponent?.FindAll(".rz-button");
|
||||||
|
_indexButtons.Should().NotBeNull();
|
||||||
|
_indexButtons?.Count.Should().Be(3);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void MavMenuShouldNavigateToRootWhenHomePressed()
|
||||||
|
{
|
||||||
|
var homeElement = _navMenuElements[0];
|
||||||
|
homeElement.Should().NotBeNull();
|
||||||
|
|
||||||
|
homeElement.Click();
|
||||||
|
|
||||||
|
NavigationManagerMock.Uri.Should().Be(NavigationManagerMock.BaseUri);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(ComponentType.NavMenu)]
|
||||||
|
[TestCase(ComponentType.Index)]
|
||||||
|
public void ShouldFireLoginMediatorEventWhenElementClicked(ComponentType componentType)
|
||||||
|
{
|
||||||
|
var targetElement = componentType switch
|
||||||
|
{
|
||||||
|
ComponentType.NavMenu => _navMenuElements[1],
|
||||||
|
ComponentType.Index => _indexButtons[0],
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(componentType), componentType, null)
|
||||||
|
};
|
||||||
|
targetElement.Click();
|
||||||
|
|
||||||
|
MediatorMock.Verify(m => m.Publish(It.IsAny<LoginToWgMessage>(), It.IsAny<CancellationToken>()), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(ComponentType.NavMenu)]
|
||||||
|
[TestCase(ComponentType.Index)]
|
||||||
|
public void ShouldFireOpenPlayerSearchMediatorEventWhenElementClicked(ComponentType componentType)
|
||||||
|
{
|
||||||
|
var targetElement = componentType switch
|
||||||
|
{
|
||||||
|
ComponentType.NavMenu => _navMenuElements[2],
|
||||||
|
ComponentType.Index => _indexButtons[1],
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(componentType), componentType, null)
|
||||||
|
};
|
||||||
|
targetElement.Click();
|
||||||
|
|
||||||
|
MediatorMock.Verify(m => m.Publish(
|
||||||
|
It.Is<OpenSearchDialogMessage>(m => m.Type == DialogType.FindPlayer),
|
||||||
|
It.IsAny<CancellationToken>()), Times.Once);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(ComponentType.NavMenu)]
|
||||||
|
[TestCase(ComponentType.Index)]
|
||||||
|
public void ShouldFireOpenClansSearchMediatorEventWhenElementClicked(ComponentType componentType)
|
||||||
|
{
|
||||||
|
var targetElement = componentType switch
|
||||||
|
{
|
||||||
|
ComponentType.NavMenu => _navMenuElements[3],
|
||||||
|
ComponentType.Index => _indexButtons[2],
|
||||||
|
_ => throw new ArgumentOutOfRangeException(nameof(componentType), componentType, null)
|
||||||
|
};
|
||||||
|
targetElement.Click();
|
||||||
|
|
||||||
|
MediatorMock.Verify(m => m.Publish(
|
||||||
|
It.Is<OpenSearchDialogMessage>(m => m.Type == DialogType.FindClan),
|
||||||
|
It.IsAny<CancellationToken>()), Times.Once);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using Bunit;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using WotBlitzStatisticsPro.Blazor.Model;
|
||||||
|
using WotBlitzStatisticsPro.Blazor.Pages;
|
||||||
|
|
||||||
|
namespace WotBlitzStatisticsPro.Blazor.Tests.Pages
|
||||||
|
{
|
||||||
|
public class SearchDialogTests: TestContextBase
|
||||||
|
{
|
||||||
|
private IRenderedComponent<SearchDialog> _component;
|
||||||
|
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_component = TestContext?.RenderComponent<SearchDialog>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[TestCase(DialogType.FindPlayer)]
|
||||||
|
[TestCase(DialogType.FindClan)]
|
||||||
|
[Ignore("Search component is not implemented yet")]
|
||||||
|
public void ShouldRedirectToAppropriatePageWhenOkButtonClicked(DialogType dialogType)
|
||||||
|
{
|
||||||
|
// Find OK button by CSS and click
|
||||||
|
// Check OpenPlayerInfoMessage with appropriate accountId/clanId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Bunit;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using WotBlitzStatisticsPro.Blazor.Messages;
|
||||||
|
using WotBlitzStatisticsPro.Blazor.Model;
|
||||||
|
using WotBlitzStatisticsPro.Blazor.Services;
|
||||||
|
using TestContext = Bunit.TestContext;
|
||||||
|
|
||||||
|
namespace WotBlitzStatisticsPro.Blazor.Tests.Services
|
||||||
|
{
|
||||||
|
public class LocalStorageServiceTests
|
||||||
|
{
|
||||||
|
private TestContext _testContext;
|
||||||
|
private BunitJSInterop _jsRuntimeMock;
|
||||||
|
protected MockNavigationManager _navigationManagerMock;
|
||||||
|
|
||||||
|
private LocalStorageService _localStorageService;
|
||||||
|
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_navigationManagerMock = new MockNavigationManager();
|
||||||
|
|
||||||
|
_testContext = new TestContext();
|
||||||
|
_jsRuntimeMock = _testContext.JSInterop;
|
||||||
|
_jsRuntimeMock.Setup<string>("localStorage.getItem", UserSettings.UserSettingsLocalStorageKey).SetResult(string.Empty);
|
||||||
|
var localStorageSetItemHandler = _jsRuntimeMock.SetupVoid("localStorage.setItem", _ => true);
|
||||||
|
localStorageSetItemHandler.SetVoidResult();
|
||||||
|
|
||||||
|
_localStorageService = new LocalStorageService(_jsRuntimeMock.JSRuntime, _navigationManagerMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task ShouldInvokeJsLocalStorageSetWithAppropriateDataOnChangeCurrentCulture()
|
||||||
|
{
|
||||||
|
string cultureName = "fake-CL";
|
||||||
|
|
||||||
|
await _localStorageService.Handle(new ChangeCurrentCultureMessage(cultureName), CancellationToken.None);
|
||||||
|
|
||||||
|
_jsRuntimeMock.Invocations.Count.Should().Be(2);
|
||||||
|
var jsInvocations = _jsRuntimeMock.Invocations.ToArray();
|
||||||
|
jsInvocations[0].Identifier.Should().Be("localStorage.getItem");
|
||||||
|
jsInvocations[1].Identifier.Should().Be("localStorage.setItem");
|
||||||
|
|
||||||
|
var args = jsInvocations[1].Arguments;
|
||||||
|
args.Should().NotBeNull();
|
||||||
|
args.Count.Should().Be(2);
|
||||||
|
args[0].Should().Be("user-settings");
|
||||||
|
args[1].Should().Be($"{{\"Culture\":\"{cultureName}\"}}");
|
||||||
|
|
||||||
|
_navigationManagerMock.NavigationCount.Should().Be(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void TearDown() => _testContext?.Dispose();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using FluentAssertions;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using WotBlitzStatisticsPro.Blazor.Messages;
|
||||||
|
using WotBlitzStatisticsPro.Blazor.Services;
|
||||||
|
|
||||||
|
namespace WotBlitzStatisticsPro.Blazor.Tests.Services
|
||||||
|
{
|
||||||
|
public class NavigatorInterceptorTests
|
||||||
|
{
|
||||||
|
private NavigationMessagesInterceptor _service;
|
||||||
|
private MockNavigationManager _navigationManager;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
_navigationManager = new MockNavigationManager();
|
||||||
|
_service = new NavigationMessagesInterceptor(_navigationManager);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task ShouldNavigateToAppropriateLinkWhenOpenPlayerInfoMessageArrived()
|
||||||
|
{
|
||||||
|
int accountId = 42;
|
||||||
|
var message = new OpenPlayerInfoMessage(accountId, false);
|
||||||
|
|
||||||
|
await _service.Handle(message, CancellationToken.None);
|
||||||
|
|
||||||
|
_navigationManager.Uri.Should().Be($"{_navigationManager.BaseUri}player/{accountId}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
using Bunit;
|
||||||
|
using MediatR;
|
||||||
|
using Microsoft.AspNetCore.Components;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Moq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using Radzen;
|
||||||
|
using WotBlitzStatisticsPro.Blazor.Services;
|
||||||
|
|
||||||
|
namespace WotBlitzStatisticsPro.Blazor.Tests
|
||||||
|
{
|
||||||
|
public class TestContextBase: TestContextWrapper
|
||||||
|
{
|
||||||
|
protected Mock<IMediator> MediatorMock;
|
||||||
|
protected Mock<ISearchDialogService> SearchServiceMock;
|
||||||
|
protected MockNavigationManager NavigationManagerMock;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
protected void Init()
|
||||||
|
{
|
||||||
|
MediatorMock = new();
|
||||||
|
SearchServiceMock = new();
|
||||||
|
NavigationManagerMock = new();
|
||||||
|
|
||||||
|
TestContext = new Bunit.TestContext();
|
||||||
|
TestContext.Services.AddSingleton(MediatorMock.Object);
|
||||||
|
TestContext.Services.AddLocalization();
|
||||||
|
|
||||||
|
TestContext.Services.AddSingleton<DialogService>();
|
||||||
|
TestContext.Services.AddSingleton(SearchServiceMock.Object);
|
||||||
|
|
||||||
|
|
||||||
|
TestContext.Services.AddSingleton<NavigationManager>(NavigationManagerMock);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void TearDown() => TestContext?.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user