From 7ba0cd5c4d395f3355a4e13bc27fd0ee2d75cb7f Mon Sep 17 00:00:00 2001 From: Marc-Antoine Soucy Date: Tue, 23 Apr 2024 09:12:44 -0400 Subject: [PATCH] fix: pr comments --- .../KillSwitch/KillSwitchService.cs | 21 +++++++- .../ForceUpdate/ForceUpdatesShould.cs | 25 +-------- .../FunctionalTestBase.cs | 25 +++++++++ .../KillSwitch/KillSwitchShould.cs | 54 ++----------------- 4 files changed, 50 insertions(+), 75 deletions(-) diff --git a/src/app/ApplicationTemplate.Business/KillSwitch/KillSwitchService.cs b/src/app/ApplicationTemplate.Business/KillSwitch/KillSwitchService.cs index 4b959553..c865f37f 100644 --- a/src/app/ApplicationTemplate.Business/KillSwitch/KillSwitchService.cs +++ b/src/app/ApplicationTemplate.Business/KillSwitch/KillSwitchService.cs @@ -1,25 +1,42 @@ using System; using System.Reactive.Linq; using ApplicationTemplate.DataAccess; +using Microsoft.Extensions.Logging; namespace ApplicationTemplate.Business; /// /// Implementation of the IKillSwitchService. /// -public class KillSwitchService : IKillSwitchService +public class KillSwitchService : IKillSwitchService, IDisposable { private readonly IKillSwitchRepository _killSwitchRepository; + private readonly ILogger _logger; + private readonly IDisposable _subscription; /// /// Initializes a new instance of the class. /// /// The . - public KillSwitchService(IKillSwitchRepository killSwitchRepository) + /// The . + public KillSwitchService(IKillSwitchRepository killSwitchRepository, ILogger logger) { _killSwitchRepository = killSwitchRepository; + _logger = logger; + + _subscription = _killSwitchRepository.ObserveKillSwitchActivation() + .Subscribe(isActive => + { + _logger.LogInformation("Kill switch is now {isActive}", isActive); + }); } /// public IObservable ObserveKillSwitchActivation() => _killSwitchRepository.ObserveKillSwitchActivation(); + + /// + public void Dispose() + { + _subscription.Dispose(); + } } diff --git a/src/app/ApplicationTemplate.Tests.Functional/ForceUpdate/ForceUpdatesShould.cs b/src/app/ApplicationTemplate.Tests.Functional/ForceUpdate/ForceUpdatesShould.cs index b0c34c87..fd043659 100644 --- a/src/app/ApplicationTemplate.Tests.Functional/ForceUpdate/ForceUpdatesShould.cs +++ b/src/app/ApplicationTemplate.Tests.Functional/ForceUpdate/ForceUpdatesShould.cs @@ -1,6 +1,5 @@ using System.Linq; using System.Reactive.Linq; -using System.Threading; using System.Threading.Tasks; using ApplicationTemplate.DataAccess; @@ -26,17 +25,7 @@ public async Task RedirectTheAppToForceUpdatePage() // This will raise the update required event. minimumVersionReposiory.CheckMinimumVersion(); - var timeoutTask = Task.Delay(1000); - - // Waits for the navigation to be completed, we need the StartWith in case the navigation already finished before we started observing. - var navTask = sectionNavigator.ObserveCurrentState() - .Where(x => x.LastRequestState != NavigatorRequestState.Processing - // This sometimes takes longer, so we need to need to make sure - && x.GetCurrentOrNextViewModelType() == typeof(ForcedUpdatePageViewModel)) - // The CancellationToken is so that this returns a task. - .FirstAsync(CancellationToken.None); - - await Task.WhenAny(navTask, timeoutTask); + await WaitForNavigation(viewModelType: typeof(ForcedUpdatePageViewModel), isDestination: true); // Assert ActiveViewModel.Should().BeOfType(); @@ -57,17 +46,7 @@ public async Task DisableTheBackButton() // This will raise the update required event. minimumVersionReposiory.CheckMinimumVersion(); - var timeoutTask = Task.Delay(1000); - - // Waits for the navigation to be completed, we need the StartWith in case the navigation already finished before we started observing. - var navTask = sectionNavigator.ObserveCurrentState() - .Where(x => x.LastRequestState != NavigatorRequestState.Processing - // This sometimes takes longer, so we need to need to make sure - && x.GetCurrentOrNextViewModelType() == typeof(ForcedUpdatePageViewModel)) - // The CancellationToken is so that this returns a task. - .FirstAsync(CancellationToken.None); - - await Task.WhenAny(navTask, timeoutTask); + await WaitForNavigation(viewModelType: typeof(ForcedUpdatePageViewModel), isDestination: true); NavigateBackUsingHardwareButton(); diff --git a/src/app/ApplicationTemplate.Tests.Functional/FunctionalTestBase.cs b/src/app/ApplicationTemplate.Tests.Functional/FunctionalTestBase.cs index 94ed7347..3e6500e4 100644 --- a/src/app/ApplicationTemplate.Tests.Functional/FunctionalTestBase.cs +++ b/src/app/ApplicationTemplate.Tests.Functional/FunctionalTestBase.cs @@ -1,5 +1,7 @@ using System.Collections.Generic; using System.Reactive.Concurrency; +using System.Reactive.Linq; +using System.Threading; using System.Threading.Tasks; using ApplicationTemplate.DataAccess; using Chinook.BackButtonManager; @@ -127,6 +129,29 @@ public void NavigateBackUsingHardwareButton() _backButtonSource.RaiseBackRequested(); } + /// + /// Waits for navigation out of or to a specific ViewModel type to be completed. + /// This is for when you cannot let the test continue until the navigation is completed. + /// It should be used when you know that the navigation is going to happen. + /// + /// The type of viewmodel we are navigating to or from. + /// Whether the viewmodel is the destination or the origin. + protected async Task WaitForNavigation(Type viewModelType, bool isDestination) + { + var sectionNavigator = GetService(); + + var timeoutTask = Task.Delay(1000); + + // Waits for the navigation to be completed, we need the StartWith in case the navigation already finished before we started observing. + var navTask = sectionNavigator.ObserveCurrentState() + .Where(x => x.LastRequestState != NavigatorRequestState.Processing + && (x.GetCurrentOrNextViewModelType() == viewModelType) == isDestination) + // The CancellationToken is so that this returns a task. + .FirstAsync(CancellationToken.None); + + await Task.WhenAny(navTask, timeoutTask); + } + /// /// Configures the services required for functional testing. /// diff --git a/src/app/ApplicationTemplate.Tests.Functional/KillSwitch/KillSwitchShould.cs b/src/app/ApplicationTemplate.Tests.Functional/KillSwitch/KillSwitchShould.cs index fde1aae8..ad555267 100644 --- a/src/app/ApplicationTemplate.Tests.Functional/KillSwitch/KillSwitchShould.cs +++ b/src/app/ApplicationTemplate.Tests.Functional/KillSwitch/KillSwitchShould.cs @@ -2,7 +2,6 @@ using System.Reactive.Linq; using System.Threading.Tasks; using System.Reactive.Subjects; -using System.Threading; using ApplicationTemplate.DataAccess; using ApplicationTemplate.Tests; using Microsoft.Extensions.Hosting; @@ -26,22 +25,11 @@ public async Task NavigateToKillSwitchPageWhenTheKillSwitchIsActivated() { // Arrange var vm = await this.ReachLoginPage(); - var sectionNavigator = GetService(); // Act _killSwitchActivatedSubject.OnNext(true); - var timeoutTask = Task.Delay(1000); - - // Waits for the navigation to be completed, we need the StartWith in case the navigation already finished before we started observing. - var navTask = sectionNavigator.ObserveCurrentState() - .Where(x => x.LastRequestState != NavigatorRequestState.Processing - // This sometimes takes longer, so we need to need to make sure - && x.GetCurrentOrNextViewModelType() == typeof(KillSwitchPageViewModel)) - // The CancellationToken is so that this returns a task. - .FirstAsync(CancellationToken.None); - - await Task.WhenAny(navTask, timeoutTask); + await WaitForNavigation(viewModelType: typeof(KillSwitchPageViewModel), isDestination: true); // Assert ActiveViewModel.Should().BeOfType(); @@ -60,17 +48,7 @@ public async Task DisableTheBackButton() // Act _killSwitchActivatedSubject.OnNext(true); - var timeoutTask = Task.Delay(1000); - - // Waits for the navigation to be completed, we need the StartWith in case the navigation already finished before we started observing. - var navTask = sectionNavigator.ObserveCurrentState() - .Where(x => x.LastRequestState != NavigatorRequestState.Processing - // This sometimes takes longer, so we need to need to make sure - && x.GetCurrentOrNextViewModelType() == typeof(KillSwitchPageViewModel)) - // The CancellationToken is so that this returns a task. - .FirstAsync(CancellationToken.None); - - await Task.WhenAny(navTask, timeoutTask); + await WaitForNavigation(viewModelType: typeof(KillSwitchPageViewModel), isDestination: true); // Navigate back using the hardware button. NavigateBackUsingHardwareButton(); @@ -93,44 +71,20 @@ public async Task NavigateBackWhenTheKillSwitchIsDeactivated() { // Arrange var vm = await this.ReachLoginPage(); - var sectionNavigator = GetService(); - var killSwitchRepository = GetService(); // Act _killSwitchActivatedSubject.OnNext(true); - var timeoutTask = Task.Delay(5000); - - // Waits for the navigation to be completed, we need the StartWith in case the navigation already finished before we started observing. - var navTask = sectionNavigator.ObserveCurrentState() - .Where(x => x.LastRequestState != NavigatorRequestState.Processing - // This sometimes takes longer, so we need to need to make sure - && x.GetCurrentOrNextViewModelType() == typeof(KillSwitchPageViewModel)) - // The CancellationToken is so that this returns a task. - .FirstAsync(CancellationToken.None); - - await Task.WhenAny(navTask, timeoutTask); + await WaitForNavigation(viewModelType: typeof(KillSwitchPageViewModel), isDestination: true); _killSwitchActivatedSubject.OnNext(false); - var timeoutTask2 = Task.Delay(1000); - - // Waits for the navigation to be completed, we need the StartWith in case the navigation already finished before we started observing. - var navTask2 = sectionNavigator.ObserveCurrentState() - .Where(x => x.LastRequestState != NavigatorRequestState.Processing - // This sometimes takes longer, so we need to need to make sure - && x.GetCurrentOrNextViewModelType() != typeof(KillSwitchPageViewModel)) - // The CancellationToken is so that this returns a task. - .FirstAsync(CancellationToken.None); - - await Task.WhenAny(navTask2, timeoutTask2); + await WaitForNavigation(viewModelType: typeof(KillSwitchPageViewModel), isDestination: false); // Assert ActiveViewModel.Should().NotBeOfType(); } - - /// protected override void ConfigureHost(IHostBuilder hostBuilder) {