mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2024-11-16 23:26:26 +01:00
203 lines
6.8 KiB
C#
203 lines
6.8 KiB
C#
using System;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using NSubstitute;
|
|
using NSubstitute.ExceptionExtensions;
|
|
using NUnit.Framework;
|
|
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
|
|
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock.Command;
|
|
using TINK.Model.Connector;
|
|
using TINK.Model.Device;
|
|
using TINK.Model.State;
|
|
using TINK.Model.User;
|
|
using TINK.Services.BluetoothLock;
|
|
using TINK.Services.Geolocation;
|
|
using static TINK.Model.Bikes.BikeInfoNS.BluetoothLock.Command.GetLockedLocationCommand;
|
|
|
|
namespace TestShareeLib.Model.Bikes.BikeInfoNS.BluetoothLock.Command
|
|
{
|
|
public class TestGetBikeLocationCommand
|
|
{
|
|
/// <summary>
|
|
/// Use case: End rental.
|
|
/// Final state: Booked, lock state unknown.
|
|
/// </summary>
|
|
/// <remarks> Replaces test TestReturnOutOfReach which was removed for sharee.bike version ~3.0.362. </remarks>
|
|
[Test]
|
|
public void TestReturnLastGeolocatonNullLockOutOfReach()
|
|
{
|
|
var bike = Substitute.For<IBikeInfoMutable>();
|
|
var geolocation = Substitute.For<IGeolocationService>();
|
|
var locks = Substitute.For<ILocksService>();
|
|
var listener = Substitute.For<IGetLockedLocationCommandListener>();
|
|
|
|
bike.Id.Returns("0");
|
|
|
|
bike.LockInfo.Location.Returns((IGeolocation)null); // When locking bike geolocation was not available.
|
|
|
|
locks[0].GetDeviceState().Returns(DeviceState.Disconnected); // Simulate bike out of reach.
|
|
|
|
locks.DisconnectAsync(0, Arg.Any<Guid>()).Returns(LockingState.UnknownDisconnected); // Simulate disconnecting.
|
|
|
|
bike.State.Value.Returns(InUseStateEnum.Booked);
|
|
|
|
Assert.That(
|
|
async () => await InvokeAsync<TestGetBikeLocationCommand>(
|
|
bike,
|
|
geolocation,
|
|
locks,
|
|
listener: listener),
|
|
Throws.TypeOf<Exception>());
|
|
|
|
// Verify behavior
|
|
Received.InOrder(() =>
|
|
{
|
|
listener.ReportStep(Step.StartingQueryLocation);
|
|
var location = bike.LockInfo.Location;
|
|
locks[0].GetDeviceState();
|
|
listener.ReportStateAsync(State.DisconnetedNoLocationError, "");
|
|
listener.ReportStep(Step.DisconnectingLockOnDisconnectedNoLocationError);
|
|
locks.DisconnectAsync(0, Arg.Any<Guid>());
|
|
listener.ReportStateAsync(State.QueryLocationSucceeded, "");
|
|
});
|
|
|
|
Assert.That(
|
|
bike.LockInfo.State,
|
|
Is.EqualTo(LockingState.UnknownDisconnected));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use case: End rental.
|
|
/// Final state: Booked, lock state unknown.
|
|
/// </summary>
|
|
/// <remarks>Replaces test TestReturnLockInReachNoGeolocation which was removed for sharee.bike older ~ 3.0.362.</remarks>
|
|
[Test]
|
|
public void TestReturnStartGetGeolocationException()
|
|
{
|
|
var bike = Substitute.For<IBikeInfoMutable>();
|
|
var geolocation = Substitute.For<IGeolocationService>();
|
|
var locks = Substitute.For<ILocksService>();
|
|
var listener = Substitute.For<IGetLockedLocationCommandListener>();
|
|
|
|
bike.Id.Returns("0");
|
|
|
|
bike.LockInfo.Location.Returns((IGeolocation)null); // When locking bike geolocation was not available.
|
|
|
|
locks[0].GetDeviceState().Returns(DeviceState.Connected); // Simulate bike in reach.
|
|
|
|
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>()).Throws(new Exception("Ups...")); // Simulate error when starting query for geolocation.
|
|
|
|
bike.State.Value.Returns(InUseStateEnum.Booked); // Booking state does not change.
|
|
|
|
bike.LockInfo.State.Returns(LockingState.Closed); // Locking state does not change.
|
|
|
|
var subsequent = InvokeAsync<TestGetBikeLocationCommand>(
|
|
bike,
|
|
geolocation,
|
|
locks,
|
|
listener: listener);
|
|
|
|
// Verify behavior
|
|
Received.InOrder(async () =>
|
|
{
|
|
listener.ReportStep(Step.StartingQueryLocation);
|
|
locks[0].GetDeviceState();
|
|
await geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>());
|
|
await listener.ReportStateAsync(State.QueryLocationFailed, "Ups...");
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// Use case: End rental.
|
|
/// Final state: Booked, lock state unknown.
|
|
/// </summary>
|
|
[Test]
|
|
public void TestReturnGetGeolocationException()
|
|
{
|
|
var bike = Substitute.For<IBikeInfoMutable>();
|
|
var geolocation = Substitute.For<IGeolocationService>();
|
|
var locks = Substitute.For<ILocksService>();
|
|
var listener = Substitute.For<IGetLockedLocationCommandListener>();
|
|
|
|
bike.Id.Returns("0");
|
|
|
|
bike.LockInfo.Location.Returns((IGeolocation)null); // When locking bike geolocation was not available.
|
|
|
|
locks[0].GetDeviceState().Returns(DeviceState.Connected); // Simulate bike in reach.
|
|
|
|
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>())
|
|
.Returns(Task.FromException<IGeolocation>(new Exception("Ups..."))); // Simulate error starting query for geolocation.
|
|
|
|
bike.State.Value.Returns(InUseStateEnum.Booked); // Booking state does not change.
|
|
|
|
bike.LockInfo.State.Returns(LockingState.Closed); // Locking state does not change.
|
|
|
|
Assert.That(
|
|
async () => await InvokeAsync<TestGetBikeLocationCommand>(
|
|
bike,
|
|
geolocation,
|
|
locks,
|
|
listener: listener),
|
|
Throws.TypeOf<Exception>());
|
|
|
|
// Verify behavior
|
|
Received.InOrder(async () =>
|
|
{
|
|
listener.ReportStep(Step.StartingQueryLocation);
|
|
locks[0].GetDeviceState();
|
|
await geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>());
|
|
await listener.ReportStateAsync(State.QueryLocationFailed, "Ups...");
|
|
});
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
/// Use case: End rental.
|
|
/// Final state: Disposable closed
|
|
/// </summary>
|
|
[Test]
|
|
public async Task TestReturnLockInReach()
|
|
{
|
|
var bike = Substitute.For<IBikeInfoMutable>();
|
|
var geolocation = Substitute.For<IGeolocationService>();
|
|
var locks = Substitute.For<ILocksService>();
|
|
var listener = Substitute.For<IGetLockedLocationCommandListener>();
|
|
|
|
bike.LockInfo.Location.Returns((IGeolocation)null);
|
|
|
|
bike.Id.Returns("0");
|
|
|
|
locks[0].GetDeviceState().Returns(DeviceState.Connected); // Simulate bike in reach. If bike is out of reach bluetooth state changes to unknown.
|
|
|
|
var location = Substitute.For<IGeolocation>();
|
|
location.Latitude.Returns(7);
|
|
location.Longitude.Returns(9);
|
|
location.Timestamp.Returns(DateTimeOffset.MinValue);
|
|
|
|
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>()).Returns(Task.FromResult(
|
|
location
|
|
)); ;
|
|
|
|
var lockingLocation = await InvokeAsync<TestGetBikeLocationCommand>(
|
|
bike,
|
|
geolocation,
|
|
locks,
|
|
() => DateTime.MinValue,
|
|
listener);
|
|
|
|
Assert.That(lockingLocation.Latitude, Is.EqualTo(7));
|
|
Assert.That(lockingLocation.Longitude, Is.EqualTo(9));
|
|
|
|
// Verify behavior
|
|
Received.InOrder(async () =>
|
|
{
|
|
listener.ReportStep(Step.StartingQueryLocation);
|
|
var dummyLoc = bike.LockInfo.Location; // Check if location was available when closing lock.
|
|
locks[0].GetDeviceState(); // Check if bike is connected.
|
|
await geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>()); // Query current location.
|
|
await listener.ReportStateAsync(State.QueryLocationSucceeded, string.Empty);
|
|
});
|
|
}
|
|
}
|
|
}
|