using System;
using System.Threading;
using System.Threading.Tasks;
using NSubstitute;
using NUnit.Framework;
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
using ShareeBike.Services.BluetoothLock;
using ShareeBike.Services.Geolocation;
using ShareeBike.Repository.Request;
using ShareeBike.Model.Connector;
using static ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Command.StartReservationCommand;
using ShareeBike.Model;
using ShareeBike.Repository.Exception;
namespace SharedBusinessLogic.Tests.Model.Bikes.BikeInfoNS.BikeNS.Command
{
[TestFixture]
public class TestStartReservationCommand
{
///
/// Use case: Start reservation.
/// Final state: Reservation started successfully
///
[Test]
public async Task TestStartReservation()
{
var bike = Substitute.For();
var connector = Substitute.For();
var listener = Substitute.For();
await InvokeAsync(
bike,
() => true, // isConnectedDelegate
(isConnected) => connector,
listener);
await connector.Command.DoReserve(Arg.Any());
// Verify behavior
Received.InOrder(async () =>
{
listener.ReportStep(Step.ReserveBike);
await connector.Command.DoReserve(bike);
});
}
///
/// Use case: Start reservation.
/// Final state: Reservation failed.
///
[Test]
public void TestStartReservationNoWebException()
{
var bike = Substitute.For();
var connector = Substitute.For();
var listener = Substitute.For();
bike.LockInfo.State.Returns(LockingState.Closed);
connector.Command.DoReserve(Arg.Any()).Returns(x
=> throw new WebConnectFailureException("Context info.", new System.Exception("hoppla")));
Assert.That(
async () => await InvokeAsync(
bike,
() => false, // isConnectedDelegate
(isConnected) => connector,
listener),
Throws.InstanceOf());
// Verify behavior
Received.InOrder(async () =>
{
listener.ReportStep(Step.ReserveBike);
await connector.Command.DoReserve(bike);
await listener.ReportStateAsync(State.WebConnectFailed, "Context info.");
});
}
///
/// Use case: Start reservation.
/// Final state: Reservation failed.
///
[Test]
public void TestStartReservationGeneralException()
{
var bike = Substitute.For();
var connector = Substitute.For();
var listener = Substitute.For();
connector.Command.DoReserve(Arg.Any()).Returns(x
=> throw new Exception("Context info."));
Assert.That(
async () => await InvokeAsync(
bike,
() => true, // isConnectedDelegate
(isConnected) => connector,
listener),
Throws.InstanceOf());
// Verify behavior
Received.InOrder(async () =>
{
listener.ReportStep(Step.ReserveBike);
await connector.Command.DoReserve(bike);
await listener.ReportStateAsync(State.GeneralStartReservationError, "Context info.");
});
}
///
/// Use case: Start reservation.
/// Final state: Reservation failed.
///
[Test]
[Ignore("Exception needs to be initialized correctly.")]
public void TestStartReservationTooManyBikesException()
{
var bike = Substitute.For();
var connector = Substitute.For();
var listener = Substitute.For();
bike.Id.Returns("1543");
BookingDeclinedException.IsBookingDeclined("Too many bikes", out BookingDeclinedException bookingDeclinedException);
bookingDeclinedException.MaxBikesCount.Returns(3);
connector.Command.DoReserve(Arg.Any()).Returns(x
=> throw bookingDeclinedException);
Assert.That(
async () => await InvokeAsync(
bike,
() => true, // isConnectedDelegate
(isConnected) => connector,
listener),
Throws.InstanceOf());
// Verify behavior
Received.InOrder(async () =>
{
listener.ReportStep(Step.ReserveBike);
await connector.Command.DoReserve(bike);
await listener.ReportStateAsync(State.TooManyBikesError, "Too many bikes");
});
}
}
}