mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2025-07-07 20:16:44 +02:00
Version 3.0.381
This commit is contained in:
parent
f963c0a219
commit
3a363acf3a
1525 changed files with 60589 additions and 125098 deletions
|
@ -0,0 +1,491 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using ShareeBike.Model.Connector;
|
||||
using ShareeBike.Model.State;
|
||||
using ShareeBike.Repository.Request;
|
||||
using ShareeBike.Services.BluetoothLock;
|
||||
using ShareeBike.Services.BluetoothLock.Tdo;
|
||||
using ShareeBike.Services.Geolocation;
|
||||
using Geolocation = ShareeBike.Services.Geolocation.Geolocation;
|
||||
using static ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock.Command.CloseCommand;
|
||||
using NSubstitute.ExceptionExtensions;
|
||||
using ShareeBike.Services.BluetoothLock.Exception;
|
||||
using ShareeBike.Repository.Exception;
|
||||
using Newtonsoft.Json;
|
||||
using ShareeBike.Repository.Response;
|
||||
using ShareeBike.ViewModel;
|
||||
|
||||
namespace SharedBusinessLogic.Tests.Model.Bikes.BikeInfoNS.BluetoothLock.Command
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCloseCommand
|
||||
{
|
||||
/// <summary>
|
||||
/// Use case: Close lock
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestClose()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var geolocation = Substitute.For<IGeolocationService>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<ICloseCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>()).Returns(new Geolocation.Builder { Latitude = 47.99, Longitude = 7.78 }.Build());
|
||||
|
||||
locks[0].CloseAsync()
|
||||
.Returns(Task.FromResult((LockitLockingState?)LockitLockingState.Closed)); // Return lock state indicating success
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
bike.LockInfo.State.Returns(LockingState.Open);
|
||||
|
||||
await InvokeAsync<TestCloseCommand>(
|
||||
bike,
|
||||
geolocation,
|
||||
locks,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnected) => connector,
|
||||
listener, null);
|
||||
|
||||
// Verify that location is kept because bike might be returned later.
|
||||
Assert.That(
|
||||
bike.LockInfo.Location.Latitude,
|
||||
Is.EqualTo(47.99).Within(0.001));
|
||||
Assert.That(
|
||||
bike.LockInfo.Location.Longitude,
|
||||
Is.EqualTo(7.78).Within(0.001));
|
||||
|
||||
Assert.That(
|
||||
bike.LockInfo.State,
|
||||
Is.EqualTo(LockingState.Closed));
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.StartingQueryingLocation);
|
||||
await geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>());
|
||||
listener.Received().ReportStep(Step.ClosingLock);
|
||||
await locks.Received()[0].CloseAsync(); // Lock must be closed
|
||||
listener.Received().ReportStep(Step.WaitStopPollingQueryLocation);
|
||||
listener.Received().ReportStep(Step.QueryLocationTerminated);
|
||||
await connector.Command.UpdateLockingStateAsync(bike, Arg.Is<LocationDto>(x => x.Latitude == 47.99 && x.Longitude == 7.78));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestCloseGeolocationServiceGetAsyncFails()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var geolocation = Substitute.For<IGeolocationService>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<ICloseCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
var startOfTest = DateTime.Now;
|
||||
|
||||
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>()).Throws(new Exception("Ups no location..."));
|
||||
|
||||
locks[0].CloseAsync()
|
||||
.Returns(Task.FromResult((LockitLockingState?)LockitLockingState.Closed)); // Return lock state indicating success
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
|
||||
await InvokeAsync<TestCloseCommand>(
|
||||
bike,
|
||||
geolocation,
|
||||
locks,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnected) => connector,
|
||||
listener, null);
|
||||
|
||||
// Verify that location is kept because bike might be returned later.
|
||||
Assert.That(
|
||||
bike.LockInfo.Location,
|
||||
Is.Null);
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.StartingQueryingLocation);
|
||||
await geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>());
|
||||
await listener.Received().ReportStateAsync(State.StartGeolocationException, "Ups no location...");
|
||||
listener.Received().ReportStep(Step.ClosingLock);
|
||||
await locks.Received()[0].CloseAsync(); // Lock must be closed
|
||||
await connector.Command.UpdateLockingStateAsync(bike, Arg.Any<LocationDto>());
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCloseCloseFailsOutOfReachException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var geolocation = Substitute.For<IGeolocationService>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<ICloseCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>()).Returns(new Geolocation.Builder { Latitude = 47.99, Longitude = 7.78 }.Build());
|
||||
|
||||
locks[0].CloseAsync()
|
||||
.Returns<Task<LockitLockingState?>>(x => throw new OutOfReachException());
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
bike.LockInfo.State.Returns(LockingState.Open);
|
||||
|
||||
Assert.That(
|
||||
async () => await InvokeAsync<TestCloseCommand>(
|
||||
bike,
|
||||
geolocation,
|
||||
locks,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnected) => connector,
|
||||
listener, null),
|
||||
Throws.InstanceOf<OutOfReachException>());
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.StartingQueryingLocation);
|
||||
await geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>());
|
||||
listener.Received().ReportStep(Step.ClosingLock);
|
||||
await locks.Received()[0].CloseAsync(); // Lock must be closed
|
||||
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));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCloseCloseFailsCouldntCloseMovingException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var geolocation = Substitute.For<IGeolocationService>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<ICloseCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>()).Returns(new Geolocation.Builder { Latitude = 47.99, Longitude = 7.78 }.Build());
|
||||
|
||||
locks[0].CloseAsync()
|
||||
.Returns<Task<LockitLockingState?>>(x => throw new CouldntCloseMovingException());
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
bike.LockInfo.State.Returns(LockingState.Open);
|
||||
|
||||
Assert.That(
|
||||
async () => await InvokeAsync<TestCloseCommand>(
|
||||
bike, geolocation, locks, () => true, (isConnected) => connector, listener, null),
|
||||
Throws.InstanceOf<CouldntCloseMovingException>());
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.StartingQueryingLocation);
|
||||
await geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>());
|
||||
listener.Received().ReportStep(Step.ClosingLock);
|
||||
await locks.Received()[0].CloseAsync(); // Lock must be closed
|
||||
await listener.Received().ReportStateAsync(State.CouldntCloseMovingError, "The process is motion sensitive. Step close to the lock, do not move, and try again.");
|
||||
await connector.Command.UpdateLockingStateAsync(bike, Arg.Is<LocationDto>(x => x.Latitude == 47.99 && x.Longitude == 7.78));
|
||||
});
|
||||
|
||||
Assert.That(
|
||||
bike.LockInfo.State,
|
||||
Is.EqualTo(LockingState.Open));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCloseCloseFailsCouldntCloseBoltBlockedException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var geolocation = Substitute.For<IGeolocationService>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<ICloseCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>()).Returns(new Geolocation.Builder { Latitude = 47.99, Longitude = 7.78 }.Build());
|
||||
|
||||
locks[0].CloseAsync()
|
||||
.Returns<Task<LockitLockingState?>>(x => throw new CouldntCloseBoltBlockedException());
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
bike.LockInfo.State.Returns(LockingState.Open);
|
||||
|
||||
Assert.That(
|
||||
async () => await InvokeAsync<TestCloseCommand>(bike, geolocation, locks, () => true, (isConnected) => connector, listener, null),
|
||||
Throws.InstanceOf<CouldntCloseBoltBlockedException>());
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.StartingQueryingLocation);
|
||||
await geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>());
|
||||
listener.Received().ReportStep(Step.ClosingLock);
|
||||
await locks.Received()[0].CloseAsync(); // Lock must be closed
|
||||
await listener.Received().ReportStateAsync(State.CouldntCloseBoltBlockedError, "Lock bolt is blocked. Make sure that no spoke or any other obstacle prevents the lock from closing and try again.");
|
||||
await connector.Command.UpdateLockingStateAsync(bike, Arg.Is<LocationDto>(x => x.Latitude == 47.99 && x.Longitude == 7.78));
|
||||
});
|
||||
|
||||
Assert.That(
|
||||
bike.LockInfo.State,
|
||||
Is.EqualTo(LockingState.UnknownFromHardwareError));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCloseCloseFailsCouldntCloseBoltBlockedExceptionOpen()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var geolocation = Substitute.For<IGeolocationService>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<ICloseCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>()).Returns(new Geolocation.Builder { Latitude = 47.99, Longitude = 7.78 }.Build());
|
||||
|
||||
locks[0].CloseAsync()
|
||||
.Returns<Task<LockitLockingState?>>(x => throw new CouldntCloseBoltBlockedException(LockingState.Open));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
bike.LockInfo.State.Returns(LockingState.Open);
|
||||
|
||||
Assert.That(
|
||||
async () => await InvokeAsync<TestCloseCommand>(bike, geolocation, locks, () => true, (isConnected) => connector, listener, null),
|
||||
Throws.InstanceOf<CouldntCloseBoltBlockedException>());
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.StartingQueryingLocation);
|
||||
await geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>());
|
||||
listener.Received().ReportStep(Step.ClosingLock);
|
||||
await locks.Received()[0].CloseAsync(); // Lock must be closed
|
||||
await listener.Received().ReportStateAsync(State.CouldntCloseBoltBlockedError, "Lock bolt is blocked. Make sure that no spoke or any other obstacle prevents the lock from closing and try again.");
|
||||
await connector.Command.UpdateLockingStateAsync(bike, Arg.Is<LocationDto>(x => x.Latitude == 47.99 && x.Longitude == 7.78));
|
||||
});
|
||||
|
||||
Assert.That(
|
||||
bike.LockInfo.State,
|
||||
Is.EqualTo(LockingState.Open));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCloseCloseFailsCouldntCloseInconsistentState()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var geolocation = Substitute.For<IGeolocationService>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<ICloseCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>()).Returns(new Geolocation.Builder { Latitude = 47.99, Longitude = 7.78 }.Build());
|
||||
|
||||
locks[0].CloseAsync()
|
||||
.Returns<Task<LockitLockingState?>>(x => throw new CouldntCloseInconsistentStateExecption(LockitLockingState.Unknown.GetLockingState()));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
bike.LockInfo.State.Returns(LockingState.Open);
|
||||
|
||||
Assert.That(
|
||||
async () => await InvokeAsync<TestCloseCommand>(bike, geolocation, locks, () => true, (isConnected) => connector, listener, null),
|
||||
Throws.InstanceOf<CouldntCloseInconsistentStateExecption>());
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.StartingQueryingLocation);
|
||||
await geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>());
|
||||
listener.Received().ReportStep(Step.ClosingLock);
|
||||
await locks.Received()[0].CloseAsync(); // Lock must be closed
|
||||
await listener.Received().ReportStateAsync(State.GeneralCloseError, "Lock reports unknown bold position. Lock could be closed or open. Please try again or contact customer support.");
|
||||
await connector.Command.UpdateLockingStateAsync(bike, Arg.Is<LocationDto>(x => x.Latitude == 47.99 && x.Longitude == 7.78));
|
||||
});
|
||||
|
||||
Assert.That(
|
||||
bike.LockInfo.State,
|
||||
Is.EqualTo(LockingState.UnknownFromHardwareError));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCloseCloseFailsException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocationService>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<ICloseCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>()).Returns(new Geolocation.Builder { Latitude = 47.99, Longitude = 7.78 }.Build());
|
||||
|
||||
locks[0].CloseAsync()
|
||||
.Returns<Task<LockitLockingState?>>(x => throw new Exception("Exception message."));
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
|
||||
|
||||
Assert.That(
|
||||
async () => await InvokeAsync<TestCloseCommand>(bike, geolocation, locks, () => true, (isConnected) => connector, listener, null),
|
||||
Throws.InstanceOf<Exception>());
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.StartingQueryingLocation);
|
||||
await geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>());
|
||||
listener.Received().ReportStep(Step.ClosingLock);
|
||||
await locks.Received()[0].CloseAsync(); // Lock must be closed
|
||||
await listener.ReportStateAsync(State.GeneralCloseError, "Exception message.");
|
||||
await connector.Command.UpdateLockingStateAsync(bike, Arg.Is<LocationDto>(x => x.Latitude == 47.99 && x.Longitude == 7.78));
|
||||
});
|
||||
|
||||
Assert.That(
|
||||
bike.LockInfo.State,
|
||||
Is.EqualTo(LockingState.UnknownDisconnected));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestCloseWaitGeolocationServiceGetAsyncFails()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocationService>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<ICloseCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
locks[0].CloseAsync()
|
||||
.Returns(LockitLockingState.Closed); // Return lock state indicating success
|
||||
|
||||
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>()).Returns(Task.FromException<IGeolocation>(new Exception("Ups, some error...")));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
|
||||
await InvokeAsync<TestCloseCommand>(bike, geolocation, locks, () => true, (isConnected) => connector, listener, null);
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.StartingQueryingLocation);
|
||||
await geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>());
|
||||
listener.Received().ReportStep(Step.ClosingLock);
|
||||
await locks.Received()[0].CloseAsync(); // Lock must be closed
|
||||
listener.Received().ReportStep(Step.WaitStopPollingQueryLocation);
|
||||
await listener.Received().ReportStateAsync(State.WaitGeolocationException, "Ups, some error...");
|
||||
listener.Received().ReportStep(Step.QueryLocationTerminated);
|
||||
await connector.Command.UpdateLockingStateAsync(bike, Arg.Any<LocationDto>());
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task TestCloseUpdateLockingStateFailsWebConnectFailureException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocationService>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<ICloseCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
locks[0].CloseAsync()
|
||||
.Returns(LockitLockingState.Closed); // Return lock state indicating success
|
||||
|
||||
connector.Command.UpdateLockingStateAsync(bike, Arg.Any<LocationDto>()).Returns(x => throw new WebConnectFailureException("Context info.", new System.Exception("hoppla")));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
|
||||
await InvokeAsync<TestCloseCommand>(bike, geolocation, locks, () => true, (isConnected) => connector, listener, null);
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.StartingQueryingLocation);
|
||||
await geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>());
|
||||
listener.Received().ReportStep(Step.ClosingLock);
|
||||
await locks.Received()[0].CloseAsync(); // Lock must be closed
|
||||
await connector.Command.UpdateLockingStateAsync(bike, Arg.Any<LocationDto>());
|
||||
await listener.ReportStateAsync(State.WebConnectFailed, "Context info.");
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestCloseUpdateLockingStateFailsResponseException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocationService>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<ICloseCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
locks[0].CloseAsync()
|
||||
.Returns(LockitLockingState.Closed); // Return lock state indicating success
|
||||
|
||||
connector.Command.UpdateLockingStateAsync(bike, Arg.Any<LocationDto>()).Returns(x =>
|
||||
throw new ReturnBikeException(JsonConvert.DeserializeObject<DoReturnResponse>(@"{ ""response_text"" : ""Some invalid data received!""}"), "Outer message."));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
|
||||
await InvokeAsync<TestCloseCommand>(bike, geolocation, locks, () => true, (isConnected) => connector, listener, null);
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.StartingQueryingLocation);
|
||||
await geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>());
|
||||
listener.Received().ReportStep(Step.ClosingLock);
|
||||
await locks.Received()[0].CloseAsync(); // Lock must be closed
|
||||
await connector.Command.UpdateLockingStateAsync(bike, Arg.Any<LocationDto>());
|
||||
await listener.ReportStateAsync(State.ResponseIsInvalid, "Outer message.");
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task TestCloseUpdateLockingStateFailsException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var geolocation = Substitute.For<IGeolocationService>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<ICloseCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
locks[0].CloseAsync()
|
||||
.Returns(LockitLockingState.Closed); // Return lock state indicating success
|
||||
|
||||
connector.Command.UpdateLockingStateAsync(bike, Arg.Any<LocationDto>()).Returns(x => throw new Exception("Exception message."));
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
|
||||
await InvokeAsync<TestCloseCommand>(bike, geolocation, locks, () => true, (isConnected) => connector, listener, null);
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.StartingQueryingLocation);
|
||||
await geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>());
|
||||
listener.Received().ReportStep(Step.ClosingLock);
|
||||
await locks.Received()[0].CloseAsync(); // Lock must be closed
|
||||
await connector.Command.UpdateLockingStateAsync(bike, Arg.Any<LocationDto>());
|
||||
await listener.ReportStateAsync(State.BackendUpdateFailed, "Exception message.");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
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));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
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.DisconnectCommand;
|
||||
using ShareeBike.Services.BluetoothLock.Exception;
|
||||
|
||||
namespace SharedBusinessLogic.Tests.Model.Bikes.BikeInfoNS.BluetoothLock.Command
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestDisconnectCommand
|
||||
{
|
||||
/// <summary>
|
||||
/// Use case: Disconnect lock
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestDisconnect()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<IDisconnectCommandListener>();
|
||||
|
||||
bike.LockInfo.Id.Returns(0);
|
||||
bike.LockInfo.State.Returns(LockingState.Closed);
|
||||
|
||||
await locks.DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>());
|
||||
|
||||
await InvokeAsync<TestDisconnectCommand>(
|
||||
bike,
|
||||
locks,
|
||||
listener);
|
||||
|
||||
Assert.That(
|
||||
bike.LockInfo.State,
|
||||
Is.EqualTo(LockingState.UnknownDisconnected));
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.DisconnectLock);
|
||||
await locks.DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>());
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use case: Disconnect lock
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestDisconnectException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<IDisconnectCommandListener>();
|
||||
|
||||
bike.LockInfo.Id.Returns(0);
|
||||
bike.LockInfo.State.Returns(LockingState.Closed);
|
||||
|
||||
locks.DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>())
|
||||
.Returns<Task>(x => throw new Exception("exception"));
|
||||
|
||||
await InvokeAsync<TestDisconnectCommand>(
|
||||
bike,
|
||||
locks,
|
||||
listener);
|
||||
|
||||
Assert.That(
|
||||
bike.LockInfo.State,
|
||||
Is.EqualTo(LockingState.Closed));
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.DisconnectLock);
|
||||
await locks.DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>());
|
||||
await listener.Received().ReportStateAsync(State.GeneralDisconnectError,"exception");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,329 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using ShareeBike.Model.Connector;
|
||||
using ShareeBike.Model.State;
|
||||
using ShareeBike.Repository.Request;
|
||||
using ShareeBike.Services.BluetoothLock;
|
||||
using ShareeBike.Services.BluetoothLock.Tdo;
|
||||
using static ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock.Command.OpenCommand;
|
||||
using ShareeBike.Services.BluetoothLock.Exception;
|
||||
using ShareeBike.Repository.Exception;
|
||||
using Newtonsoft.Json;
|
||||
using ShareeBike.Repository.Response;
|
||||
using ShareeBike.ViewModel;
|
||||
|
||||
namespace SharedBusinessLogic.Tests.Model.Bikes.BikeInfoNS.BluetoothLock.Command
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestOpenCommand
|
||||
{
|
||||
/// <summary>
|
||||
/// Use case: Open lock
|
||||
/// </summary>
|
||||
[Test]
|
||||
public async Task TestOpen()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<IOpenCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
bike.LockInfo.State.Returns(LockingState.Closed);
|
||||
|
||||
locks[0].OpenAsync()
|
||||
.Returns(Task.FromResult((LockitLockingState?)LockitLockingState.Open)); // Return lock state indicating success
|
||||
|
||||
await InvokeAsync<TestOpenCommand>(
|
||||
bike,
|
||||
locks,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnected) => connector,
|
||||
listener, null);
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.OpeningLock);
|
||||
await locks.Received()[0].OpenAsync(); // Lock must be open
|
||||
listener.Received().ReportStep(Step.GetLockInfos);
|
||||
listener.Received().ReportStep(Step.WaitStopPolling);
|
||||
listener.Received().ReportStep(Step.UpdateLockingState);
|
||||
await connector.Command.UpdateLockingStateAsync(bike);
|
||||
});
|
||||
|
||||
Assert.That(
|
||||
bike.LockInfo.State,
|
||||
Is.EqualTo(LockingState.Open));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestOpenOpenFailsOutOfReachException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<IOpenCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
bike.LockInfo.State.Returns(LockingState.Closed);
|
||||
|
||||
locks[0].OpenAsync()
|
||||
.Returns<Task<LockitLockingState?>>(x => throw new OutOfReachException());
|
||||
|
||||
Assert.That(
|
||||
async () => await InvokeAsync<TestOpenCommand>(
|
||||
bike,
|
||||
locks,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnected) => connector,
|
||||
listener, null),
|
||||
Throws.InstanceOf<OutOfReachException>());
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.OpeningLock);
|
||||
await locks.Received()[0].OpenAsync(); // Lock must be open
|
||||
await listener.ReportStateAsync(State.OutOfReachError, "Exception of type 'ShareeBike.Services.BluetoothLock.Exception.OutOfReachException' was thrown.");
|
||||
});
|
||||
|
||||
Assert.That(
|
||||
bike.LockInfo.State,
|
||||
Is.EqualTo(LockingState.UnknownDisconnected));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestOpenOpenFailsBoltStatusUnknownException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<IOpenCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
bike.LockInfo.State.Returns(LockingState.Closed);
|
||||
|
||||
locks[0].OpenAsync()
|
||||
.Returns<Task<LockitLockingState?>>(x => throw new CouldntOpenBoldStatusIsUnknownException());
|
||||
|
||||
Assert.That(
|
||||
async () => await InvokeAsync<TestOpenCommand>(
|
||||
bike,
|
||||
locks,
|
||||
() => true, // isConnectedDelegate
|
||||
(isConnected) => connector,
|
||||
listener, null),
|
||||
Throws.InstanceOf<CouldntOpenBoldStatusIsUnknownException>());
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.OpeningLock);
|
||||
await locks.Received()[0].OpenAsync(); // Lock must be open
|
||||
await listener.ReportStateAsync(State.CouldntOpenBoldStatusIsUnknownError, "Position of lock bolt is unknown. Lock could be closed or open. Please try again or contact customer support.");
|
||||
listener.Received().ReportStep(Step.GetLockInfos);
|
||||
listener.Received().ReportStep(Step.UpdateLockingState);
|
||||
});
|
||||
|
||||
Assert.That(
|
||||
bike.LockInfo.State,
|
||||
Is.EqualTo(LockingState.UnknownFromHardwareError));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void TestOpenOpenFailsCouldntOpenBoltBlockedException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<IOpenCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
bike.LockInfo.State.Returns(LockingState.Closed);
|
||||
|
||||
locks[0].OpenAsync()
|
||||
.Returns<Task<LockitLockingState?>>(x => throw new CouldntOpenBoldIsBlockedException());
|
||||
|
||||
Assert.That(
|
||||
async () => await InvokeAsync<TestOpenCommand>(bike, locks, () => true, (isConnected) => connector, listener, null),
|
||||
Throws.InstanceOf<CouldntOpenBoldIsBlockedException>());
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.OpeningLock);
|
||||
await locks.Received()[0].OpenAsync(); // Lock must be open
|
||||
await listener.ReportStateAsync(State.CouldntOpenBoldIsBlockedError, "Lock bolt is blocked. Make sure that no spoke presses against the lock bolt and try again.");
|
||||
listener.Received().ReportStep(Step.GetLockInfos);
|
||||
listener.Received().ReportStep(Step.UpdateLockingState);
|
||||
});
|
||||
|
||||
Assert.That(
|
||||
bike.LockInfo.State,
|
||||
Is.EqualTo(LockingState.UnknownFromHardwareError));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestOpenOpenFailsCouldntOpenInconsistentStateException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<IOpenCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
bike.LockInfo.State.Returns(LockingState.Closed);
|
||||
|
||||
locks[0].OpenAsync()
|
||||
.Returns<Task<LockitLockingState?>>(x => throw new CouldntOpenInconsistentStateExecption(LockitLockingState.Closed.GetLockingState()));
|
||||
|
||||
Assert.That(
|
||||
async () => await InvokeAsync<TestOpenCommand>(bike, locks, () => true, (isConnected) => connector, listener, null),
|
||||
Throws.InstanceOf<CouldntOpenInconsistentStateExecption>());
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.OpeningLock);
|
||||
await locks.Received()[0].OpenAsync(); // Lock must be open
|
||||
await listener.ReportStateAsync(State.CouldntOpenInconsistentStateError, "Unexpected locking state \"Closed\" detected after sending open command. Please try again or contact customer support.");
|
||||
listener.Received().ReportStep(Step.GetLockInfos);
|
||||
listener.Received().ReportStep(Step.UpdateLockingState);
|
||||
});
|
||||
|
||||
Assert.That(
|
||||
bike.LockInfo.State,
|
||||
Is.EqualTo(LockingState.Closed));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestOpenOpenFailsException()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<IOpenCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
locks[0].OpenAsync()
|
||||
.Returns<Task<LockitLockingState?>>(x => throw new Exception("Exception message."));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked);
|
||||
bike.LockInfo.State.Returns(LockingState.Closed);
|
||||
|
||||
Assert.That(
|
||||
async () => await InvokeAsync<TestOpenCommand>(bike, locks, () => true, (isConnected) => connector, listener, null),
|
||||
Throws.InstanceOf<Exception>());
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.OpeningLock);
|
||||
await locks.Received()[0].OpenAsync(); // Lock must be open
|
||||
await listener.ReportStateAsync(State.GeneralOpenError, "Exception message.");
|
||||
listener.Received().ReportStep(Step.GetLockInfos);
|
||||
listener.Received().ReportStep(Step.UpdateLockingState);
|
||||
});
|
||||
|
||||
Assert.That(
|
||||
bike.LockInfo.State,
|
||||
Is.EqualTo(LockingState.UnknownDisconnected));
|
||||
}
|
||||
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task TestOpenUpdateLockingStateFailsWebConnectFailure()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<IOpenCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
connector.Command.UpdateLockingStateAsync(bike, Arg.Any<LocationDto>()).Returns(x => throw new WebConnectFailureException("Context info.", new System.Exception("hoppla")));
|
||||
|
||||
await InvokeAsync<TestOpenCommand>(bike, locks, () => true, (isConnected) => connector, listener, null);
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.OpeningLock);
|
||||
await locks.Received()[0].OpenAsync(); // Lock must be open
|
||||
listener.Received().ReportStep(Step.GetLockInfos);
|
||||
listener.Received().ReportStep(Step.WaitStopPolling);
|
||||
listener.Received().ReportStep(Step.UpdateLockingState);
|
||||
await listener.ReportStateAsync(State.WebConnectFailed, "Context info.");
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestOpenUpdateLockingStateFailsInvalidResponse()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<IOpenCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
connector.Command.UpdateLockingStateAsync(bike, Arg.Any<LocationDto>()).Returns(x =>
|
||||
throw new ReturnBikeException(JsonConvert.DeserializeObject<DoReturnResponse>(@"{ ""response_text"" : ""Some invalid data received!""}"), "Outer message."));
|
||||
|
||||
await InvokeAsync<TestOpenCommand>(bike, locks, () => true, (isConnected) => connector, listener, null);
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.OpeningLock);
|
||||
await locks.Received()[0].OpenAsync(); // Lock must be open
|
||||
listener.Received().ReportStep(Step.GetLockInfos);
|
||||
listener.Received().ReportStep(Step.WaitStopPolling);
|
||||
listener.Received().ReportStep(Step.UpdateLockingState);
|
||||
await listener.ReportStateAsync(State.ResponseIsInvalid, "Outer message.");
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestOpenUpdateLockingStateFails()
|
||||
{
|
||||
var bike = Substitute.For<IBikeInfoMutable>();
|
||||
var connector = Substitute.For<IConnector>();
|
||||
var command = Substitute.For<ICommand>();
|
||||
var locks = Substitute.For<ILocksService>();
|
||||
var listener = Substitute.For<IOpenCommandListener>();
|
||||
var viewUpdateManager = Substitute.For<IPollingUpdateTaskManager>();
|
||||
|
||||
locks[0].OpenAsync()
|
||||
.Returns(LockitLockingState.Open); // Return lock state indicating success
|
||||
|
||||
connector.Command.UpdateLockingStateAsync(bike).Returns(x => throw new Exception("Exception message."));
|
||||
|
||||
await InvokeAsync<TestOpenCommand>(bike, locks, () => true, (isConnected) => connector, listener, null);
|
||||
|
||||
// Verify behavior
|
||||
Received.InOrder(async () =>
|
||||
{
|
||||
listener.Received().ReportStep(Step.OpeningLock);
|
||||
await locks.Received()[0].OpenAsync(); // Lock must be open
|
||||
listener.Received().ReportStep(Step.GetLockInfos);
|
||||
listener.Received().ReportStep(Step.WaitStopPolling);
|
||||
listener.Received().ReportStep(Step.UpdateLockingState);
|
||||
await connector.Command.UpdateLockingStateAsync(bike);
|
||||
await listener.ReportStateAsync(State.BackendUpdateFailed, "Exception message.");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
using System;
|
||||
using NUnit.Framework;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.BikeNS;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.DriveNS;
|
||||
using ShareeBike.Model.State;
|
||||
|
||||
namespace SharedBusinessLogic.Tests.Fixtures.ObjectTests.Bike.BluetoothLock
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestBikeInfo
|
||||
{
|
||||
[Test]
|
||||
public void TestCtorCopyNull() =>
|
||||
Assert.Throws<ArgumentException>(
|
||||
() => new BikeInfo(null, null),
|
||||
"Verify that no unspecific reference not set to... exception is thrown");
|
||||
|
||||
[Test]
|
||||
public void TestCtorAvailable()
|
||||
{
|
||||
Assert.That(new BikeInfo(new ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new DriveMutable(), ShareeBike.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "13").Id, Is.EqualTo("12"));
|
||||
Assert.That(new BikeInfo(new ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new DriveMutable(), ShareeBike.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "13").StationId, Is.EqualTo("13"));
|
||||
Assert.That(new BikeInfo(new ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new DriveMutable(), ShareeBike.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "13").State.Value, Is.EqualTo(InUseStateEnum.Disposable));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCtorAvailableBikeNull()
|
||||
{
|
||||
Assert.That(
|
||||
() => new BikeInfo(
|
||||
null,
|
||||
new DriveMutable(),
|
||||
ShareeBike.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
|
||||
5200544,
|
||||
new Guid("00000000-0000-0000-0000-000000000001"),
|
||||
"13"),
|
||||
Throws.ArgumentNullException);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCtorRequested()
|
||||
{
|
||||
Assert.That(new BikeInfo(new ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new DriveMutable(), ShareeBike.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", "13", null, null, dateTimeProvider: () => new DateTime(2019, 1, 1), false /*isDemo*/, null /*group*/).Id, Is.EqualTo("12"));
|
||||
Assert.That(new BikeInfo(new ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new DriveMutable(), ShareeBike.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", "13", null, null, dateTimeProvider: () => new DateTime(2019, 1, 1), false /*isDemo*/, null /*group*/).LockInfo.Id, Is.EqualTo(112));
|
||||
Assert.That(new BikeInfo(new ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new DriveMutable(), ShareeBike.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", "13", null, null, dateTimeProvider: () => new DateTime(2019, 1, 1), false /*isDemo*/, null /*group*/).State.Value, Is.EqualTo(InUseStateEnum.Reserved));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCtorRequestedBikeNull()
|
||||
{
|
||||
Assert.That(
|
||||
() => new BikeInfo(
|
||||
null,
|
||||
new DriveMutable(),
|
||||
ShareeBike.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
|
||||
112,
|
||||
new Guid(),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new DateTime(2020, 1, 1),
|
||||
"a@b",
|
||||
"13",
|
||||
null,
|
||||
null,
|
||||
dateTimeProvider: () => new DateTime(2019, 1, 1),
|
||||
false /*isDemo*/,
|
||||
null /*group*/),
|
||||
Throws.ArgumentNullException);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCtorBooked()
|
||||
{
|
||||
Assert.That(new BikeInfo(new ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new DriveMutable(), ShareeBike.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", "13", null /*operator uri*/).Id, Is.EqualTo("12"));
|
||||
Assert.That(new BikeInfo(new ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new DriveMutable(), ShareeBike.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", "13", null /*operator uri*/).LockInfo.Id, Is.EqualTo(112));
|
||||
Assert.That(new BikeInfo(new ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new DriveMutable(), ShareeBike.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", "13", null /*operator uri*/).State.Value, Is.EqualTo(InUseStateEnum.Booked));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCtorBookedNull()
|
||||
{
|
||||
Assert.That(
|
||||
() => new BikeInfo(
|
||||
null,
|
||||
new DriveMutable(),
|
||||
ShareeBike.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
|
||||
112,
|
||||
new Guid(),
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
new DateTime(2020, 1, 1),
|
||||
"a@b",
|
||||
"13",
|
||||
null /*operator uri*/),
|
||||
Throws.ArgumentNullException);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
using System;
|
||||
using NSubstitute;
|
||||
using NUnit.Framework;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.DriveNS;
|
||||
using ShareeBike.Model.Connector;
|
||||
using ShareeBike.Services.BluetoothLock;
|
||||
using ShareeBike.Services.Geolocation;
|
||||
using ShareeBike.ViewModel;
|
||||
|
||||
namespace SharedBusinessLogic.Tests.Model.Bike.BluetoothLock
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestBikeInfoMutalbe
|
||||
{
|
||||
[Test]
|
||||
public void TestCtor()
|
||||
{
|
||||
Assert.That(
|
||||
new BikeInfoMutable(
|
||||
Substitute.For<IGeolocationService>(),
|
||||
Substitute.For<ILocksService>(),
|
||||
() => false /* not connected */,
|
||||
(_) => Substitute.For<IConnector>(),
|
||||
() => Substitute.For<IPollingUpdateTaskManager>(),
|
||||
new ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo(
|
||||
new ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Bike(
|
||||
"MyBikeId",
|
||||
ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.LockModel.ILockIt),
|
||||
new DriveMutable(),
|
||||
ShareeBike.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
|
||||
42,
|
||||
new Guid(),
|
||||
"17"),
|
||||
"My Station Name").StationName,
|
||||
Is.EqualTo("My Station Name"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestToString()
|
||||
{
|
||||
Assert.That(
|
||||
new BikeInfoMutable(
|
||||
Substitute.For<IGeolocationService>(),
|
||||
Substitute.For<ILocksService>(),
|
||||
() => false /* not connected */,
|
||||
(_) => Substitute.For<IConnector>(),
|
||||
() => Substitute.For<IPollingUpdateTaskManager>(),
|
||||
new ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo(
|
||||
new ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.Bike(
|
||||
"MyBikeId",
|
||||
ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.LockModel.ILockIt,
|
||||
ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.WheelType.Trike,
|
||||
ShareeBike.Model.Bikes.BikeInfoNS.BikeNS.TypeOfBike.Cargo),
|
||||
new DriveMutable(),
|
||||
ShareeBike.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
|
||||
42,
|
||||
new Guid(),
|
||||
"17"),
|
||||
"My Station Name").ToString(),
|
||||
Is.EqualTo("Id=MyBikeId;type=Cargo;state=Disposable;Lock id=42"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestCtorBikeNull()
|
||||
{
|
||||
Assert.That(
|
||||
() => new BikeInfoMutable(
|
||||
Substitute.For<IGeolocationService>(),
|
||||
Substitute.For<ILocksService>(),
|
||||
() => false /* not connected */,
|
||||
(_) => Substitute.For<IConnector>(),
|
||||
() => Substitute.For<IPollingUpdateTaskManager>(),
|
||||
null,
|
||||
"My Station Name"),
|
||||
Throws.ArgumentNullException);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,173 @@
|
|||
using System;
|
||||
using NUnit.Framework;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
namespace SharedBusinessLogic.Tests.Fixtures.ObjectTests.Bike.BluetoothLock
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestLockInfo
|
||||
{
|
||||
[Test]
|
||||
public void TestCtor()
|
||||
{
|
||||
Assert.That(
|
||||
new LockInfo.Builder { Id = 123 }.Build().State, Is.EqualTo(LockingState.UnknownDisconnected));
|
||||
|
||||
Assert.That(
|
||||
new LockInfo.Builder { Id = 123 }.Build().Id, Is.EqualTo(123));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEquals()
|
||||
{
|
||||
Assert.That(new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build() == new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build(), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEqualsFalse_Id()
|
||||
{
|
||||
Assert.That(new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build() == new LockInfo.Builder
|
||||
{
|
||||
Id = 3,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build(), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEqualsFalse_Guid()
|
||||
{
|
||||
Assert.That(new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build() == new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("1000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build(), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEqualsFalse_Seed()
|
||||
{
|
||||
Assert.That(new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build() == new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 5, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build(), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEqualsFalse_UserKey()
|
||||
{
|
||||
Assert.That(new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build() == new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 9, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build(), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEqualsFalse_AdminKey()
|
||||
{
|
||||
Assert.That(new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build() == new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 11, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build(), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestEqualsFalse_LockingState()
|
||||
{
|
||||
Assert.That(new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Closed
|
||||
}.Build() == new LockInfo.Builder
|
||||
{
|
||||
Id = 2,
|
||||
Guid = new Guid("0000f00d-1212-efde-1523-785fef13d123"),
|
||||
Seed = new byte[] { 1, 2 },
|
||||
UserKey = new byte[] { 7, 2 },
|
||||
AdminKey = new byte[] { 2, 1 },
|
||||
State = LockingState.Open
|
||||
}.Build(), Is.False);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using ShareeBike.Services.BluetoothLock.Tdo;
|
||||
|
||||
namespace SharedBusinessLogic.Tests.Fixtures.ObjectTests.Bike.BluetoothLock
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestLockInfoHelper
|
||||
{
|
||||
[Test]
|
||||
public void TestUpdateById_State()
|
||||
{
|
||||
var locksInfo = new List<LockInfo> {
|
||||
new LockInfo.Builder { Id = 12, Seed = new byte[] { 3, 5 }, UserKey = new byte[] {2, 1 }, State = LockingState.UnknownFromHardwareError }.Build(),
|
||||
new LockInfo.Builder { Id = 14, Seed = new byte[] { 3, 1 }, UserKey = new byte[] {2, 7 }, State = LockingState.Open }.Build(),
|
||||
new LockInfo.Builder { Id = 3, Seed = new byte[] { 1, 5 }, UserKey = new byte[] {2, 9 }, State = LockingState.Closed }.Build(),
|
||||
};
|
||||
|
||||
var locksInfoTdo = new List<LockInfoTdo> {
|
||||
new LockInfoTdo.Builder { Id =14, State = LockitLockingState.Closed}.Build()
|
||||
};
|
||||
|
||||
var resultList = locksInfo.UpdateById(locksInfoTdo);
|
||||
|
||||
var result = resultList.FirstOrDefault(x => x.Id == 14);
|
||||
Assert.That(result, Is.Not.Null, "Target element was removed.");
|
||||
Assert.That(result.State, Is.EqualTo(LockingState.Closed));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestUpdateById_Guid()
|
||||
{
|
||||
var locksInfo = new List<LockInfo> {
|
||||
new LockInfo.Builder { Id = 12, Seed = new byte[] { 3, 5 }, UserKey = new byte[] {2, 1 }, State = LockingState.UnknownFromHardwareError }.Build(),
|
||||
new LockInfo.Builder { Id = 14, Seed = new byte[] { 3, 1 }, UserKey = new byte[] {2, 7 }, State = LockingState.Open }.Build(),
|
||||
new LockInfo.Builder { Id = 3, Seed = new byte[] { 1, 5 }, UserKey = new byte[] {2, 9 }, State = LockingState.Closed }.Build(),
|
||||
};
|
||||
|
||||
var locksInfoTdo = new List<LockInfoTdo> {
|
||||
new LockInfoTdo.Builder { Id =14, Guid = new System.Guid("00000000-0000-0000-0000-e57e6b9aee16"), State = LockitLockingState.Open}.Build()
|
||||
};
|
||||
|
||||
var resultList = locksInfo.UpdateById(locksInfoTdo);
|
||||
|
||||
var result = resultList.FirstOrDefault(x => x.Id == 14);
|
||||
Assert.That(result, Is.Not.Null, "Target element was removed.");
|
||||
Assert.That(result.Guid, Is.EqualTo(new Guid("00000000-0000-0000-0000-e57e6b9aee16")));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using ShareeBike.Services.Geolocation;
|
||||
|
||||
namespace SharedBusinessLogic.Tests.Fixtures.ObjectTests.Bike.BluetoothLock
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestLockInfoMutable
|
||||
{
|
||||
[Test]
|
||||
public void TestCtor()
|
||||
{
|
||||
var lockInfo = new LockInfoMutable(
|
||||
1,
|
||||
new Guid("00000000-0000-0000-0000-e57e6b9aee16"),
|
||||
new byte[] { 1, 2, 3 }, // User key
|
||||
new byte[] { 1, 23 }, // Admin key
|
||||
new byte[] { 1, 12 }, // Seed
|
||||
LockingState.Closed);
|
||||
|
||||
Assert.That(lockInfo.Id, Is.EqualTo(1));
|
||||
Assert.That(lockInfo.Guid, Is.EqualTo(new Guid("00000000-0000-0000-0000-e57e6b9aee16")));
|
||||
Assert.That((new byte[] { 1, 2, 3 }).SequenceEqual(lockInfo.UserKey), Is.True);
|
||||
Assert.That((new byte[] { 1, 23 }).SequenceEqual(lockInfo.AdminKey), Is.True);
|
||||
Assert.That((new byte[] { 1, 12 }).SequenceEqual(lockInfo.Seed), Is.True);
|
||||
Assert.That(lockInfo.State, Is.EqualTo(LockingState.Closed));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestSetGuid()
|
||||
{
|
||||
var lockInfo = new LockInfoMutable(1, new Guid(), new byte[] { 1, 2, 3 }, new byte[] { 1, 23 }, new byte[] { 1, 12 }, LockingState.Closed);
|
||||
|
||||
lockInfo.Guid = new Guid("00000000-0000-0000-0000-e57e6b9aee16");
|
||||
Assert.That(lockInfo.Guid, Is.EqualTo(new Guid("00000000-0000-0000-0000-e57e6b9aee16")));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLoad()
|
||||
{
|
||||
|
||||
var lockInfo = new LockInfoMutable(
|
||||
2,
|
||||
new Guid(),
|
||||
new byte[] { 5, 4 }, // User key
|
||||
new byte[] { 14, 223 }, // Admin key
|
||||
new byte[] { 3, 4, 5 }, // Seed
|
||||
LockingState.Closed);
|
||||
|
||||
lockInfo.Load(
|
||||
1,
|
||||
new Guid("00000000-0000-0000-0000-e57e6b9aee16"),
|
||||
new byte[] { 1, 12 }, // Seed
|
||||
new byte[] { 1, 2, 3 }, // User key)
|
||||
new byte[] { 1, 23 });
|
||||
|
||||
Assert.That(lockInfo.Id, Is.EqualTo(1));
|
||||
Assert.That(lockInfo.Guid, Is.EqualTo(new Guid("00000000-0000-0000-0000-e57e6b9aee16")));
|
||||
Assert.That((new byte[] { 1, 2, 3 }).SequenceEqual(lockInfo.UserKey), Is.True);
|
||||
Assert.That((new byte[] { 1, 23 }).SequenceEqual(lockInfo.AdminKey), Is.True);
|
||||
Assert.That((new byte[] { 1, 12 }).SequenceEqual(lockInfo.Seed), Is.True);
|
||||
Assert.That(lockInfo.State, Is.EqualTo(LockingState.Closed));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLastLockingStateChange()
|
||||
=> Assert.That(
|
||||
new LockInfoMutable(1, new Guid(), null, null, null, LockingState.Open, () => new DateTime(2023, 03, 13)).LastLockingStateChange,
|
||||
Is.Null);
|
||||
|
||||
[Test]
|
||||
public void TestLastLockingStateChangeCangeCtor()
|
||||
{
|
||||
var lockInfo = new LockInfoMutable(1, new Guid(), null, null, null, LockingState.Open, () => new DateTime(2023, 03, 13));
|
||||
|
||||
lockInfo.State = LockingState.Closed;
|
||||
|
||||
Assert.That(
|
||||
lockInfo.LastLockingStateChange,
|
||||
Is.EqualTo(new DateTime(2023, 03, 13)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLocationCtor()
|
||||
=> Assert.That(
|
||||
new LockInfoMutable(1, new Guid(), null, null, null, LockingState.Open, () => new DateTime(2023, 03, 13)).Location,
|
||||
Is.Null);
|
||||
|
||||
[Test]
|
||||
public void TestLocation()
|
||||
{
|
||||
var lockInfo = new LockInfoMutable(1, new Guid(), null, null, null, LockingState.Open, () => new DateTime(2023, 03, 13));
|
||||
|
||||
lockInfo.Location = new Geolocation.Builder { Latitude = 47.99, Longitude = 7.78}.Build();
|
||||
|
||||
// Verify that location is kept because bike might be returned later.
|
||||
Assert.That(
|
||||
lockInfo.Location.Latitude,
|
||||
Is.EqualTo(47.99).Within(0.001));
|
||||
Assert.That(
|
||||
lockInfo.Location.Longitude,
|
||||
Is.EqualTo(7.78).Within(0.001));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLocationStateChange()
|
||||
{
|
||||
var lockInfo = new LockInfoMutable(1, new Guid(), null, null, null, LockingState.Open, () => new DateTime(2023, 03, 13));
|
||||
|
||||
lockInfo.Location = new Geolocation.Builder { Latitude = 47.99, Longitude = 7.78 }.Build();
|
||||
|
||||
lockInfo.State = LockingState.Closed;
|
||||
|
||||
// Verify that location is kept because bike might be returned later.
|
||||
Assert.That(
|
||||
lockInfo.Location,
|
||||
Is.Null);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue