sharee.bike-App/SharedBusinessLogic.Tests/Model/Bikes/BikeInfoNS/BluetoothLock/Command/TestConnectCommand.cs
2024-04-09 12:53:23 +02:00

132 lines
4.9 KiB
C#

using System;
using System.Threading.Tasks;
using NSubstitute;
using NUnit.Framework;
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
using ShareeBike.Services.BluetoothLock;
using ShareeBike.Services.BluetoothLock.Tdo;
using static ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock.Command.ConnectAndGetStateCommand;
using ShareeBike.Services.BluetoothLock.Exception;
using ShareeBike.Repository.Exception;
namespace SharedBusinessLogic.Tests.Model.Bikes.BikeInfoNS.BluetoothLock.Command
{
[TestFixture]
public class TestConnectCommand
{
/// <summary>
/// Use case: Connect lock
/// </summary>
[Test]
public async Task TestConnect()
{
var bike = Substitute.For<IBikeInfoMutable>();
var locks = Substitute.For<ILocksService>();
var listener = Substitute.For<IConnectAndGetStateCommandListener>();
bike.LockInfo.Id.Returns(0);
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected);
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>())
.Returns(Task.FromResult(new LockInfoTdo.Builder { State = LockitLockingState.Closed }.Build())); // Return lock state indicating success
await InvokeAsync<TestConnectCommand>(
bike,
locks,
listener);
Assert.That(
bike.LockInfo.State,
Is.EqualTo(LockingState.Closed));
// Verify behavior
Received.InOrder(async () =>
{
listener.Received().ReportStep(Step.ConnectLock);
await locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>());
listener.Received().ReportStep(Step.GetLockingState);
});
}
/// <summary>
/// Use case: Connect lock, lock out of reach
/// </summary>
[Test]
public void TestConnectOutOfReachException()
{
var bike = Substitute.For<IBikeInfoMutable>();
var locks = Substitute.For<ILocksService>();
var listener = Substitute.For<IConnectAndGetStateCommandListener>();
var timeOuts = Substitute.For<ITimeOutProvider>();
bike.LockInfo.Id.Returns(0);
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected);
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>())
.Returns<LockInfoTdo>(x => throw new OutOfReachException()); // Return exception
locks.TimeOut.Returns(timeOuts);
Assert.That(
async () => await InvokeAsync<TestConnectCommand>(
bike,
locks,
listener),
Throws.InstanceOf<OutOfReachException>());
// Verify behavior
Received.InOrder(async () =>
{
listener.Received().ReportStep(Step.ConnectLock);
await locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>());
await listener.Received().ReportStateAsync(State.OutOfReachError, "Exception of type 'ShareeBike.Services.BluetoothLock.Exception.OutOfReachException' was thrown.");
});
Assert.That(
bike.LockInfo.State,
Is.EqualTo(LockingState.UnknownDisconnected));
}
/// <summary>
/// Use case: Connect lock
/// </summary>
[Test]
public void TestConnectException()
{
var bike = Substitute.For<IBikeInfoMutable>();
var locks = Substitute.For<ILocksService>();
var listener = Substitute.For<IConnectAndGetStateCommandListener>();
var timeOuts = Substitute.For<ITimeOutProvider>();
bike.Id.Returns("0");
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected);
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>())
.Returns<LockInfoTdo>(x => throw new Exception("Ups...")); // Return exception
locks.TimeOut.Returns(timeOuts);
Assert.That(
async () => await InvokeAsync<TestConnectCommand>(
bike,
locks,
listener),
Throws.InstanceOf<Exception>());
// Verify behavior
Received.InOrder(async () =>
{
listener.Received().ReportStep(Step.ConnectLock);
await locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>());
await listener.Received().ReportStateAsync(State.GeneralConnectLockError, "Please step as close as possible to the bike lock and try again.");
await locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>());
await listener.Received().ReportStateAsync(State.GeneralConnectLockError, "Your mobile device still does not connect to the bike lock. Please restart the app or even your mobile device and repeat the process.");
await locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>());
await listener.Received().ReportStateAsync(State.GeneralConnectLockError, "It is still not possible to establish a connection between your mobile device and the bike lock. Please contact customer support!\r\n\r\nAlternative:\r\n1. close app,\r\n2. press the button at the top of the lock briefly and release it as soon as it starts flashing,\r\n3. make sure that the lock is completely closed and remains closed.\r\n4. send e-mail to operator (otherwise your chargeable rental will continue!): Please include problem description, bike-id and drop-off station.");
});
Assert.That(
bike.LockInfo.State,
Is.EqualTo(LockingState.UnknownDisconnected));
}
}
}