using System.Threading.Tasks; using NSubstitute; using NUnit.Framework; using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock; using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock.Command; using ShareeBike.Model.Connector; using ShareeBike.Model.State; using ShareeBike.Services.BluetoothLock; using ShareeBike.View; using ShareeBike.ViewModel; using ShareeBike.ViewModel.Bikes; using ShareeBike.ViewModel.Bikes.Bike.BluetoothLock; using ShareeBike.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler; using OpenCommand = ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock.Command.OpenCommand; namespace SharedBusinessLogic.Tests.ViewModel.Bikes.Bike.BluetoothLock { [TestFixture] public class TestOpenLockActionViewModel { /// /// Use case: Open lock. /// Final state: Occupied open /// [Test] public async Task TestOpenLock() { var bike = Substitute.For(); var connector = Substitute.For(); var command = Substitute.For(); var locks = Substitute.For(); var pollingManager = Substitute.For(); var viewService = Substitute.For(); var bikesViewModel = Substitute.For(); var listener = Substitute.For(); var openLockActionViewModel = new OpenLockActionViewModel( bike, () => pollingManager, viewService, bikesViewModel); bike.Id.Returns("0"); bike.OpenLockAsync(Arg.Any(), Arg.Any()).Returns(x => { // Add calls to ReportStep which IBikeInfoMutable implementation would do. openLockActionViewModel.ReportStep(OpenCommand.Step.OpeningLock); openLockActionViewModel.ReportStep(OpenCommand.Step.GetLockInfos); openLockActionViewModel.ReportStep(OpenCommand.Step.UpdateLockingState); return Task.CompletedTask; }); bike.State.Value.Returns(InUseStateEnum.Booked); // Request handler factory queries state to create appropriate request handler object. bike.LockInfo.State.Returns(LockingState.Open); // Request handler factory queries lock state to create appropriate request handler object. await openLockActionViewModel.OpenLockAsync(); // Verify behavior Received.InOrder(() => { bikesViewModel.Received(1).IsIdle = false; // GUI must be locked bikesViewModel.ActionText = "One moment please..."; pollingManager.StopAsync(); // Polling must be stopped before any COPR and lock service action bikesViewModel.StartRentalProcess(Arg.Is( x => x.BikeId == "0" && x.State == CurrentRentalProcess.OpenLock && x.StepIndex == 1 && x.Result == CurrentStepStatus.None)); //ClosingLock & GetLockInfos bikesViewModel.ActionText = "The lock bolt moves through the spokes of the rear wheel."; //UpdateLockingState bikesViewModel.ActionText = "Updating lock state..."; bikesViewModel.RentalProcess.Result = CurrentStepStatus.Succeeded; bikesViewModel.ActionText = "One moment please..."; pollingManager.StartAsync(); // polling must be restarted again bikesViewModel.ActionText = string.Empty; bikesViewModel.RentalProcess.State = CurrentRentalProcess.None; bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked return; }); } } }