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)
{