using System;
using NSubstitute;
using NUnit.Framework;
using ShareeBike.Model.Bikes.BikeInfoNS.CopriLock;
using ShareeBike.Model.Connector;
using ShareeBike.Model.Device;
using ShareeBike.Model.User;
using ShareeBike.Repository.Exception;
using ShareeBike.View;
using ShareeBike.ViewModel;
using ShareeBike.ViewModel.Bikes;
using ShareeBike.ViewModel.Bikes.Bike.CopriLock.RequestHandler;
namespace SharedBusinessLogic.Tests.ViewModel.Bikes.Bike.CopriLock.RequestHandler
{
[TestFixture]
public class TestBookedClosed
{
///
/// Use case: Try to open lock.
/// Final state: Bike remains locked and stays booked.
///
[Test]
public void TestOpenLockOpenLockAsyncFailsWebConnectFailureException()
{
var bike = Substitute.For();
var connector = Substitute.For();
var command = Substitute.For();
var pollingManager = Substitute.For();
var viewService = Substitute.For();
var bikesViewModel = Substitute.For();
var activeUser = Substitute.For();
var handler = new BookedClosed(
bike,
() => true, // isConnectedDelegate
(isConnected) => connector,
() => pollingManager,
Substitute.For(),
viewService,
bikesViewModel,
activeUser);
bike.Id.Returns("0");
bike.LockInfo.State.Returns(LockingState.Closed); // Locking state does not change.
connector.Command.OpenLockAsync(bike).Returns(x => throw new WebConnectFailureException("Context info", new Exception("Tst")));
bike.State.Value.Returns(ShareeBike.Model.State.InUseStateEnum.Booked); // State remains booked because opening failed.
var subsequent = handler.HandleRequestOption2().Result;
// 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.ActionText = "Lock is opening. Please wait until it is completely open.";
connector.Command.OpenLockAsync(bike); // Booking must be performed
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert(
"Connection to booking system not possible.",
"A stable Internet connection is required. Connect to WIFI or to mobile network and activate mobile data. Try again.",
"OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartAsync(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state after action
Assert.That(
subsequent.ButtonText,
Is.EqualTo("BookedClosed"));
Assert.That(
subsequent.IsButtonVisible,
Is.False);
Assert.That(
subsequent.LockitButtonText,
Is.EqualTo("Open lock"));
Assert.That(
subsequent.IsLockitButtonVisible,
Is.True);
}
///
/// Use case: Try to open lock.
/// Final state: Bike remains locked and stays booked.
///
[Test]
public void TestOpenLockOpenLockAsyncFailsException()
{
var bike = Substitute.For();
var connector = Substitute.For();
var command = Substitute.For();
var pollingManager = Substitute.For();
var viewService = Substitute.For();
var bikesViewModel = Substitute.For();
var activeUser = Substitute.For();
var handler = new BookedClosed(
bike,
() => true, // isConnectedDelegate
(isConnected) => connector,
() => pollingManager,
Substitute.For(),
viewService,
bikesViewModel,
activeUser);
bike.Id.Returns("0");
bike.LockInfo.State.Returns(LockingState.Closed); // Locking state does not change.
connector.Command.OpenLockAsync(bike).Returns(x => throw new Exception("Some error", new Exception("Inner exception")));
bike.State.Value.Returns(ShareeBike.Model.State.InUseStateEnum.Booked); // State remains booked because opening failed.
var subsequent = handler.HandleRequestOption2().Result;
// 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.ActionText = "Lock is opening. Please wait until it is completely open.";
connector.Command.OpenLockAsync(bike); // Booking must be performed
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert(
"Lock could not be opened!",
"Some error",
"OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartAsync(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state after action
Assert.That(
subsequent.ButtonText,
Is.EqualTo("BookedClosed"));
Assert.That(
subsequent.IsButtonVisible,
Is.False);
Assert.That(
subsequent.LockitButtonText,
Is.EqualTo("Open lock"));
Assert.That(
subsequent.IsLockitButtonVisible,
Is.True);
}
///
/// Use case: Open lock.
/// Final state: Lock is opened and bike remains booked.
///
[Test]
public void TestOpenLock()
{
var bike = Substitute.For();
var connector = Substitute.For();
var command = Substitute.For();
var pollingManager = Substitute.For();
var viewService = Substitute.For();
var bikesViewModel = Substitute.For();
var activeUser = Substitute.For();
var handler = new BookedClosed(
bike,
() => true, // isConnectedDelegate
(isConnected) => connector,
() => pollingManager,
Substitute.For(),
viewService,
bikesViewModel,
activeUser);
bike.Id.Returns("0");
bike.LockInfo.State.Returns(LockingState.Open); // After opening, lock state is open.
bike.State.Value.Returns(ShareeBike.Model.State.InUseStateEnum.Booked); // After Booking and opening, state is booked.
var subsequent = handler.HandleRequestOption2().Result;
// 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.ActionText = "Lock is opening. Please wait until it is completely open.";
connector.Command.OpenLockAsync(bike); // Booking must be performed
bikesViewModel.ActionText = "Updating...";
pollingManager.StartAsync(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state
Assert.That(
subsequent.ButtonText,
Is.EqualTo("BookedOpen"));
Assert.That(
subsequent.IsButtonVisible,
Is.False);
Assert.That(
subsequent.LockitButtonText,
Is.EqualTo("Open lock"));
Assert.That(
subsequent.IsLockitButtonVisible,
Is.True);
}
}
}