Version 3.0.362

This commit is contained in:
Anja 2023-04-05 15:02:10 +02:00
parent cba4da9357
commit 4ff3307997
128 changed files with 3954 additions and 3193 deletions

View file

@ -0,0 +1,160 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
using TestFramework.Model.User.Account;
using TINK.Model.Bikes.BikeInfoNS.BikeNS;
using TINK.Model.State;
using TINK.Model.User;
using TINK.Model.User.Account;
using TINK.Repository;
using TINK.ViewModel.Bikes.Bike;
using static TINK.Repository.CopriCallsMemory;
namespace UITest.Fixtures.ViewModel
{
public class TestBikeViewModel
{
private class BikeInfoMutable : TINK.Model.Bikes.BikeInfoNS.BC.BikeInfoMutable
{
public BikeInfoMutable(
string id,
LockModel lockModel,
bool pisDemo = false,
IEnumerable<string> group = null,
WheelType? wheelType = null,
TypeOfBike? typeOfBike = null,
string description = null,
string stationId = null,
string stationName = null,
Uri operatorUri = null,
Func<DateTime> dateTimeProvider = null,
IStateInfo stateInfo = null) : base(
new Bike(id, lockModel, wheelType, typeOfBike, description),
new TINK.Model.Bikes.BikeInfoNS.DriveNS.Drive(),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
pisDemo,
group,
stationId,
stationName,
operatorUri,
null,
dateTimeProvider,
stateInfo)
{
}
}
/// <summary>
/// Tests base class functionaltiy by using child.
/// </summary>
public static BikeViewModelBase TestStateText_LoggedIn_Reserved(Func<TINK.Model.Bikes.BikeInfoNS.BC.BikeInfoMutable, User, BikeViewModelBase> p_oFactory)
{
var l_oBike = new BikeInfoMutable(
"2",
LockModel.ILockIt,
false,
new List<string> { "TINK" },
WheelType.Trike,
TypeOfBike.Cargo,
"Test description",
"3",
"Radstation",
null,
() => new DateTime(1980, 1, 1)); // Now time stamp
// Update state from Copri.
l_oBike.State.Load(
InUseStateEnum.Reserved, // Copri acknowledges state reserved.
new DateTime(1980, 1, 1), // Date when bike was booked.
"ragu@gnu-systems.de"); // Owner from Copri.
var l_oStoreMock = new StoreMock(new Account("ragu@gnu-systems.de", "123456789" /* password */, false, "987654321" /* session cookie */, new List<string> { "TINK" }));
var l_oUser = new User(
l_oStoreMock,
l_oStoreMock.Load().Result,
"123456789");
// Verify prerequisites
Assert.AreEqual(InUseStateEnum.Reserved, l_oBike.State.Value);
Assert.IsTrue(l_oUser.IsLoggedIn);
Assert.AreEqual(l_oBike.State.MailAddress, l_oUser.Mail);
// Do not update from Copri
var l_oViewModel = p_oFactory(l_oBike, l_oUser);
return l_oViewModel;
}
/// <summary>
/// Tests base class functionaltiy by using child.
/// </summary>
public static BikeViewModelBase TestStateText_LoggedIn_ReservedWithCopriConnect(Func<TINK.Model.Bikes.BikeInfoNS.BC.BikeInfoMutable, User, BikeViewModelBase> p_oFactory)
{
var l_oBike = new BikeInfoMutable(
"2",
LockModel.ILockIt,
false,
new List<string> { "TINK" },
WheelType.Trike,
TypeOfBike.Cargo,
"Test description",
"3",
"Radstation",
null,
() => (new DateTime(1980, 1, 1)).Add(new TimeSpan(0, 8, 0)));
// Update state from Copri.
l_oBike.State.Load(
InUseStateEnum.Reserved, // Copri acknowledges state reserved.
new DateTime(1980, 1, 1),
"ragu@gnu-systems.de", // Owner from Copri.
"4asdfA"); // Reservation code from Copri
var l_oStoreMock = new StoreMock(new Account("ragu@gnu-systems.de", "123456789" /* password */, false, "987654321" /* session cookie */, new List<string> { "TINK" }));
var l_oUser = new User(
l_oStoreMock, // Mocks account store functionality.
l_oStoreMock.Load().Result,
"123456789");
// Verify prerequisites
Assert.AreEqual(InUseStateEnum.Reserved, l_oBike.State.Value);
Assert.IsTrue(l_oUser.IsLoggedIn);
Assert.AreEqual(l_oBike.State.MailAddress, l_oUser.Mail);
var l_oViewModel = p_oFactory(l_oBike, l_oUser); // Bikes collection mock.
return l_oViewModel;
}
/// <summary>
/// Tests base class functionaltiy by using child.
/// </summary>
public static BikeViewModelBase TestStateText_LoggedIn_Booked(Func<TINK.Model.Bikes.BikeInfoNS.BC.BikeInfoMutable, User, BikeViewModelBase> p_oFactory)
{
var l_oBike = new BikeInfoMutable("2", LockModel.ILockIt, false, new List<string> { "TINK" }, WheelType.Two, TypeOfBike.Cargo, "Test description", "3");
// Update from Copri.
l_oBike.State.Load(
InUseStateEnum.Booked,
new DateTime(2017, 10, 24, 21, 49, 3),
"ragu@gnu-systems.de",
"4asdfA");
var l_oCopriServer = new CopriCallsMemory("MyMerchId", SampleSets.Set1, 1);
var l_oStoreMock = new StoreMock(new Account("ragu@gnu-systems.de", "123456789" /* password */, false, "987654321" /* session cookie */, new List<string> { "TINK" }));
var l_oUser = new User(
l_oStoreMock,
l_oStoreMock.Load().Result,
"123456789"); // Device id
// Verify prerequisites
Assert.AreEqual(InUseStateEnum.Booked, l_oBike.State.Value);
Assert.IsTrue(l_oUser.IsLoggedIn);
Assert.AreEqual(l_oBike.State.MailAddress, l_oUser.Mail);
var l_oViewModel = p_oFactory(l_oBike, l_oUser);
return l_oViewModel;
}
}
}

View file

@ -1,7 +1,8 @@
using System;
using System;
using System.Linq;
using NUnit.Framework;
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
using TINK.Services.Geolocation;
namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
{
@ -62,5 +63,60 @@ namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
Assert.IsTrue((new byte[] { 1, 12 }).SequenceEqual(lockInfo.Seed));
Assert.AreEqual(LockingState.Closed, lockInfo.State);
}
[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();
// Veryfy 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;
// Veryfy that location is kept because bike might be returned later.
Assert.That(
lockInfo.Location,
Is.Null);
}
}
}

View file

@ -0,0 +1,192 @@
using System.Threading.Tasks;
using Newtonsoft.Json;
using NSubstitute;
using NUnit.Framework;
using TINK.Model.Connector;
using TINK.Model.Services.CopriApi;
using TINK.Repository;
using TINK.Repository.Response;
using TINK.Services.CopriApi;
namespace TestTINKLib.Fixtures.ObjectTests.Connector.Query
{
[TestFixture]
public class TestCachedQuery
{
private const string BIKESAVAILABLE = @"{
""copri_version"" : ""4.1.0.0"",
""bikes"" : {},
""response_state"" : ""OK"",
""apiserver"" : ""https://app.tink-konstanz.de"",
""authcookie"" : """",
""response"" : ""bikes_available"",
""bikes"" : {
""2352"" : {
""description"" : ""Cargo Long"",
""state"" : ""available"",
""bike"" : ""1"",
""gps"" : { ""latitude"": ""47.669888"", ""longitude"": ""9.167749"" },
""station"" : ""9""
}
}
}";
private const string STATIONSALL = @"{
""copri_version"" : ""4.1.0.0"",
""stations"" : {
""5"" : {
""station"" : ""5"",
""bike_soll"" : ""0"",
""bike_ist"" : ""7"",
""station_group"" : [ ""TINK"" ],
""gps"" : { ""latitude"": ""47.66756"", ""longitude"": ""9.16477"" },
""state"" : ""available"",
""description"" : """"
},
""13"" : {
""station"" : ""13"",
""bike_soll"" : ""4"",
""bike_ist"" : ""1"",
""station_group"" : [ ""TINK"" ],
""gps"" : { ""latitude"": ""47.657756"", ""longitude"": ""9.176084"" },
""state"" : ""available"",
""description"" : """"
},
""30"" : {
""station"" : ""30"",
""bike_soll"" : ""5"",
""bike_ist"" : ""0"",
""station_group"" : [ ""TINK"", ""Konrad"" ],
""gps"" : { ""latitude"": ""47.657766"", ""longitude"": ""9.176094"" },
""state"" : ""available"",
""description"" : ""Test für Stadtradstation""
}
},
""user_group"" : [ ""Konrad"", ""TINK"" ],
""response_state"" : ""OK"",
""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"",
""debuglevel"" : ""2"",
""response"" : ""stations_all"",
""user_id"" : ""javaminister@gmail.com"",
""apiserver"" : ""https://tinkwwp.copri-bike.de""
}";
private const string STATIONSALLEMPTY = @"{
""copri_version"" : ""4.1.0.0"",
""stations"" : {
},
""user_group"" : [ ""Konrad"", ""TINK"" ],
""response_state"" : ""OK"",
""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"",
""debuglevel"" : ""2"",
""response"" : ""stations_all"",
""user_id"" : ""javaminister@gmail.com"",
""apiserver"" : ""https://tinkwwp.copri-bike.de""
}";
[Test]
public async Task TestGetStations_StationsFromCache()
{
var server = Substitute.For<ICachedCopriServer>();
server.GetStations(false).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
typeof(CopriCallsMonkeyStore),
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL),
new GeneralData(),
new System.Exception("Bang when getting stations..."))));
server.GetBikesAvailable(true).Returns(Task.Run(() => new Result<BikesAvailableResponse>(
typeof(CopriCallsMonkeyStore),
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
new GeneralData())));
var result = await new CachedQuery(server).GetBikesAndStationsAsync();
Assert.AreEqual(3, result.Response.StationsAll.Count);
Assert.AreEqual(1, result.Response.Bikes.Count);
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
Assert.AreEqual("Bang when getting stations...", result.Exception.Message);
}
[Test]
public async Task TestGetStations_BikesAvailableFromCache()
{
var server = Substitute.For<ICachedCopriServer>();
server.GetStations(false).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
typeof(CopriCallsHttps),
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALLEMPTY),
new GeneralData())));
server.GetBikesAvailable(false).Returns(Task.Run(() => new Result<BikesAvailableResponse>(
typeof(CopriCallsMonkeyStore),
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
new GeneralData(),
new System.Exception("Bang when getting bikes..."))));
server.GetStations(true).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
typeof(CopriCallsMonkeyStore),
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL),
new GeneralData())));
var result = await new CachedQuery(server).GetBikesAndStationsAsync();
Assert.AreEqual(3, result.Response.StationsAll.Count);
Assert.AreEqual(1, result.Response.Bikes.Count);
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
Assert.AreEqual("Bang when getting bikes...", result.Exception.Message);
}
[Test]
public async Task TestGetStations()
{
var server = Substitute.For<ICachedCopriServer>();
server.GetStations(false).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
typeof(CopriCallsHttps),
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL),
new GeneralData())));
server.GetBikesAvailable(false).Returns(Task.Run(() => new Result<BikesAvailableResponse>(
typeof(CopriCallsHttps),
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
new GeneralData())));
var result = await new CachedQuery(server).GetBikesAndStationsAsync();
Assert.AreEqual(3, result.Response.StationsAll.Count);
Assert.AreEqual(1, result.Response.Bikes.Count);
Assert.AreEqual(typeof(CopriCallsHttps), result.Source);
Assert.IsNull(result.Exception);
}
[Test]
public async Task TestGetBikes()
{
var server = Substitute.For<ICachedCopriServer>();
server.GetBikesAvailable().Returns(Task.Run(() => new Result<BikesAvailableResponse>(
typeof(CopriCallsHttps),
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
new GeneralData())));
var result = await new CachedQuery(server).GetBikesAsync();
Assert.AreEqual(1, result.Response.Count);
Assert.AreEqual(typeof(CopriCallsHttps), result.Source);
Assert.IsNull(result.Exception);
}
[Test]
public async Task TestGetBikesOccupied()
{
var server = Substitute.For<ICachedCopriServer>();
var result = await new CachedQuery(server).GetBikesOccupiedAsync();
Assert.AreEqual(0, result.Response.Count);
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
Assert.AreEqual(result.Exception.Message, "Abfrage der reservierten/ gebuchten Räder nicht möglich. Kein Benutzer angemeldet.");
}
}
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Threading.Tasks;
using Newtonsoft.Json;
using NSubstitute;
@ -294,5 +294,346 @@ namespace TestShareeLib.Model.Connector
bikesResponse.Response.Count,
Is.EqualTo(1));
}
private const string BIKESAVAILABLE = @"{
""copri_version"" : ""4.1.0.0"",
""bikes"" : {},
""response_state"" : ""OK"",
""apiserver"" : ""https://app.tink-konstanz.de"",
""authcookie"" : """",
""response"" : ""bikes_available"",
""bikes"" : {
""2352"" : {
""description"" : ""Cargo Long"",
""state"" : ""available"",
""bike"" : ""1"",
""gps"" : { ""latitude"": ""47.669888"", ""longitude"": ""9.167749"" },
""station"" : ""9""
}
}
}";
private const string BIKESAVAILABLEEMPTY = @"{
""copri_version"" : ""4.1.0.0"",
""bikes"" : {},
""response_state"" : ""OK"",
""apiserver"" : ""https://app.tink-konstanz.de"",
""authcookie"" : """",
""response"" : ""bikes_available"",
""bikes"" : {
}
}";
private const string BIKESOCCUPIED = @"{
""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"",
""debuglevel"" : ""2"",
""user_group"" : [ ""TINK"" ],
""user_id"" : ""javaminister@gmail.com"",
""response"" : ""user_bikes_occupied"",
""response_state"" : ""OK"",
""response_text"" : ""Die Liste der reservierten und gebuchten Fahrräder wurde erfolgreich geladen"",
""apiserver"" : ""https://tinkwwp.copri-bike.de"",
""bikes_occupied"" : {
""89004"" : {
""start_time"" : ""2018-01-27 17:33:00.989464+01"",
""station"" : ""9"",
""unit_price"" : ""2.00"",
""tariff_description"": {
""free_hours"" : ""0.5"",
""name"" : ""TINK Tarif"",
""max_eur_per_day"" : ""9.00""
},
""timeCode"" : ""2061"",
""description"" : ""Cargo Long"",
""bike"" : ""4"",
""total_price"" : ""20.00"",
""state"" : ""requested"",
""real_hours"" : ""66.05"",
""bike_group"" : [ ""TINK"" ],
""now_time"" : ""2018-01-30 11:36:45"",
""request_time"" : ""2018-01-27 17:33:00.989464+01"",
""computed_hours"" : ""10.0""
}
}
}";
private const string STATIONSALL = @"{
""copri_version"" : ""4.1.0.0"",
""stations"" : {
""5"" : {
""station"" : ""5"",
""bike_soll"" : ""0"",
""bike_ist"" : ""7"",
""station_group"" : [ ""TINK"" ],
""gps"" : { ""latitude"": ""47.66756"", ""longitude"": ""9.16477"" },
""state"" : ""available"",
""description"" : """"
},
""13"" : {
""station"" : ""13"",
""bike_soll"" : ""4"",
""bike_ist"" : ""1"",
""station_group"" : [ ""TINK"" ],
""gps"" : { ""latitude"": ""47.657756"", ""longitude"": ""9.176084"" },
""state"" : ""available"",
""description"" : """"
},
""30"" : {
""station"" : ""30"",
""bike_soll"" : ""5"",
""bike_ist"" : ""0"",
""station_group"" : [ ""TINK"", ""Konrad"" ],
""gps"" : { ""latitude"": ""47.657766"", ""longitude"": ""9.176094"" },
""state"" : ""available"",
""description"" : ""Test für Stadtradstation""
}
},
""user_group"" : [ ""Konrad"", ""TINK"" ],
""response_state"" : ""OK"",
""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"",
""debuglevel"" : ""2"",
""response"" : ""stations_all"",
""user_id"" : ""javaminister@gmail.com"",
""apiserver"" : ""https://tinkwwp.copri-bike.de""
}";
private const string STATIONSALLEMPTY = @"{
""copri_version"" : ""4.1.0.0"",
""stations"" : {
},
""user_group"" : [ ""Konrad"", ""TINK"" ],
""response_state"" : ""OK"",
""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"",
""debuglevel"" : ""2"",
""response"" : ""stations_all"",
""user_id"" : ""javaminister@gmail.com"",
""apiserver"" : ""https://tinkwwp.copri-bike.de""
}";
[Test]
public async Task TestGetStations_StationsFromCache()
{
var server = Substitute.For<ICachedCopriServer>();
server.GetStations(false).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
typeof(CopriCallsMonkeyStore),
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL),
new GeneralData(),
new System.Exception("Bang when getting stations..."))));
server.GetBikesAvailable(true).Returns(Task.Run(() => new Result<BikesAvailableResponse>(
typeof(CopriCallsMonkeyStore),
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
new GeneralData())));
server.GetBikesOccupied(true).Returns(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
typeof(CopriCallsMonkeyStore),
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED),
new GeneralData())));
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync();
Assert.AreEqual(3, result.Response.StationsAll.Count);
Assert.AreEqual(2, result.Response.Bikes.Count);
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
Assert.AreEqual("Bang when getting stations...", result.Exception.Message);
}
[Test]
public async Task TestGetStations_BikesAvailableFromCache()
{
var server = Substitute.For<ICachedCopriServer>();
server.GetStations(false).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
typeof(CopriCallsHttps),
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALLEMPTY),
new GeneralData())));
server.GetBikesAvailable(false).Returns(Task.Run(() => new Result<BikesAvailableResponse>(
typeof(CopriCallsMonkeyStore),
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
new GeneralData(),
new System.Exception("Bang when getting bikes..."))));
server.GetBikesOccupied(true).Returns(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
typeof(CopriCallsMonkeyStore),
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED),
new GeneralData())));
server.GetStations(true).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
typeof(CopriCallsMonkeyStore),
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL),
new GeneralData())));
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync();
Assert.AreEqual(3, result.Response.StationsAll.Count);
Assert.AreEqual(2, result.Response.Bikes.Count);
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
Assert.AreEqual("Bang when getting bikes...", result.Exception.Message);
}
[Test]
public async Task TestGetStations_BikesOccupiedFromCache()
{
var server = Substitute.For<ICachedCopriServer>();
server.GetStations(false).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
typeof(CopriCallsHttps),
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALLEMPTY),
new GeneralData())));
server.GetBikesAvailable(false).Returns(Task.Run(() => new Result<BikesAvailableResponse>(
typeof(CopriCallsHttps),
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLEEMPTY),
new GeneralData())));
server.GetBikesOccupied(false).Returns(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
typeof(CopriCallsMonkeyStore),
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED),
new GeneralData(),
new System.Exception("Bang when getting bikes occupied..."))));
server.GetBikesAvailable(true).Returns(Task.Run(() => new Result<BikesAvailableResponse>(
typeof(CopriCallsMonkeyStore),
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
new GeneralData())));
server.GetStations(true).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
typeof(CopriCallsMonkeyStore),
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL),
new GeneralData())));
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync();
Assert.AreEqual(3, result.Response.StationsAll.Count);
Assert.AreEqual(2, result.Response.Bikes.Count);
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
Assert.AreEqual("Bang when getting bikes occupied...", result.Exception.Message);
}
[Test]
public async Task TestGetStations()
{
var server = Substitute.For<ICachedCopriServer>();
server.GetStations(false).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
typeof(CopriCallsHttps),
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL),
new GeneralData())));
server.GetBikesAvailable(false).Returns(Task.Run(() => new Result<BikesAvailableResponse>(
typeof(CopriCallsHttps),
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
new GeneralData())));
server.GetBikesOccupied(false).Returns(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
typeof(CopriCallsHttps),
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED),
new GeneralData())));
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync();
Assert.AreEqual(3, result.Response.StationsAll.Count);
Assert.AreEqual(2, result.Response.Bikes.Count);
Assert.AreEqual(typeof(CopriCallsHttps), result.Source);
Assert.IsNull(result.Exception);
}
[Test]
public async Task TestGetBikes_BikesAvailableFromCache()
{
var server = Substitute.For<ICachedCopriServer>();
server.GetBikesAvailable().Returns(Task.Run(() => new Result<BikesAvailableResponse>(
typeof(CopriCallsMonkeyStore),
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
new GeneralData(),
new System.Exception("Bang, bikes avail..."))));
server.GetBikesOccupied(true).Returns(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
typeof(CopriCallsHttps),
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED),
new GeneralData())));
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAsync();
Assert.AreEqual(2, result.Response.Count);
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
Assert.AreEqual("Bang, bikes avail...", result.Exception.Message);
}
[Test]
public async Task TestGetBikes_BikesOccupiedFromCache()
{
var server = Substitute.For<ICachedCopriServer>();
server.GetBikesAvailable(false).Returns(Task.Run(() => new Result<BikesAvailableResponse>(
typeof(CopriCallsHttps),
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLEEMPTY),
new GeneralData())));
server.GetBikesOccupied(false).Returns(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
typeof(CopriCallsMonkeyStore),
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED),
new GeneralData(),
new System.Exception("Bang, error bikes occupied"))));
server.GetBikesAvailable(true).Returns(Task.Run(() => new Result<BikesAvailableResponse>(
typeof(CopriCallsMonkeyStore),
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
new GeneralData())));
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAsync();
Assert.AreEqual(2, result.Response.Count);
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
Assert.AreEqual("Bang, error bikes occupied", result.Exception.Message);
}
[Test]
public async Task TestGetBikes()
{
var server = Substitute.For<ICachedCopriServer>();
server.GetBikesAvailable().Returns(Task.Run(() => new Result<BikesAvailableResponse>(
typeof(CopriCallsHttps),
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
new GeneralData())));
server.GetBikesOccupied().Returns(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
typeof(CopriCallsHttps),
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED),
new GeneralData())));
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAsync();
Assert.AreEqual(2, result.Response.Count);
Assert.AreEqual(typeof(CopriCallsHttps), result.Source);
Assert.IsNull(result.Exception);
}
[Test]
public async Task TestGetBikesOccupied()
{
var server = Substitute.For<ICachedCopriServer>();
server.GetBikesAvailable().Returns(Task.Run(() => new Result<BikesAvailableResponse>(
typeof(CopriCallsHttps),
JsonConvert.DeserializeObject<BikesAvailableResponse>("{}"),
new GeneralData())));
server.GetBikesOccupied().Returns(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
typeof(CopriCallsHttps),
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED),
new GeneralData())));
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesOccupiedAsync();
Assert.AreEqual(1, result.Response.Count);
Assert.AreEqual(typeof(CopriCallsHttps), result.Source);
Assert.IsNull(result.Exception);
}
}
}

View file

@ -0,0 +1,75 @@
using System;
using System.Threading.Tasks;
using Newtonsoft.Json;
using NSubstitute;
using NSubstitute.ReceivedExtensions;
using NUnit.Framework;
using TINK.Model.Connector;
using TINK.Repository;
using TINK.Repository.Exception;
using TINK.Repository.Response;
namespace TestTINKLib.Fixtures.ObjectTests.Connector
{
[TestFixture]
public class TestCommandLoggedIn
{
/// <summary> Verifies, that logout leads to expected call on copri server. </summary>
[Test]
public void TestDoLogout()
{
var l_oServer = Substitute.For<ICopriServer>();
l_oServer.DoAuthoutAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<AuthorizationoutResponse>("{ \"response_state\" : \"OK\", \"authcookie\" : \"1\"}")));
var l_oCmd = new CommandLoggedIn(l_oServer, "MeinKeks", "EMehl", () => DateTime.Now);
LoginStateChangedEventArgs l_oEventArgs = null;
l_oCmd.LoginStateChanged += (sender, eventargs) => l_oEventArgs = eventargs;
l_oCmd.DoLogout().Wait();
l_oServer.Received().DoAuthoutAsync();
Assert.IsNotNull(l_oEventArgs);
}
/// <summary> Verifies, that logout leads to expected call on copri server. </summary>
[Test]
public void TestDoLogout_AuthcookieNotDefined()
{
var l_oServer = Substitute.For<ICopriServer>();
l_oServer.When(x => x.DoAuthoutAsync()).Throw(new AuthcookieNotDefinedException("Testing action", JsonConvert.DeserializeObject<ResponseBase>(@"{ ""response_state"" : ""Some inner error description""}")));
var l_oCmd = new CommandLoggedIn(l_oServer, "MeinKeks", "EMehl", () => DateTime.Now);
LoginStateChangedEventArgs l_oEventArgs = null;
l_oCmd.LoginStateChanged += (sender, eventargs) => l_oEventArgs = eventargs;
l_oCmd.DoLogout().Wait();
l_oServer.Received().DoAuthoutAsync();
Assert.IsNotNull(l_oEventArgs);
}
/// <summary> Verifies, that logout leads to expected call on copri server. </summary>
[Test]
public void TestDoLogout_Exception()
{
var l_oServer = Substitute.For<ICopriServer>();
l_oServer.When(x => x.DoAuthoutAsync()).Throw(new System.Exception("Sometheing went wrong."));
var l_oCmd = new CommandLoggedIn(l_oServer, "MeinKeks", "EMehl", () => DateTime.Now);
LoginStateChangedEventArgs l_oEventArgs = null;
l_oCmd.LoginStateChanged += (sender, eventargs) => l_oEventArgs = eventargs;
Assert.Throws<AggregateException>(() => l_oCmd.DoLogout().Wait());
l_oServer.Received().DoAuthoutAsync();
Assert.IsNull(l_oEventArgs);
}
}
}

View file

@ -0,0 +1,90 @@
using System;
using NSubstitute;
using NUnit.Framework;
using TINK.Model.Connector;
using TINK.Model.Services.CopriApi;
using TINK.Repository;
namespace TestTINKLib.Fixtures.ObjectTests.Connector
{
[TestFixture]
public class TestConnector
{
/// <summary>
/// Verifies that factory method returns correcty type depending on session cookie.
/// </summary>
[Test]
public void TestCommandFactory()
{
var l_oCopri = Substitute.For<ICachedCopriServer>();
// Construct not logged in version of connector.
var l_oCommand = new TINK.Model.Connector.Connector(
new System.Uri("http://1.2.3.4"),
new AppContextInfo("oiF2kahH", "sharee.bike.test", new Version(3, 0, 267)),
null /*UI language */,
"", // Not logged in
"",
server: l_oCopri).Command;
Assert.AreEqual(typeof(Command), l_oCommand.GetType());
}
/// <summary>
/// Verifies that factory method returns correcty type depending on session cookie.
/// </summary>
[Test]
public void TestCommandFactory_LoggedIn()
{
var l_oCopri = Substitute.For<ICachedCopriServer>();
var l_oCommand = new TINK.Model.Connector.Connector(
new System.Uri("http://1.2.3.4"),
new AppContextInfo("oiF2kahH", "sharee.bike.test", new Version(3, 0, 267)),
null /*UI language */,
"123", // Logged in
"a@b",
server: l_oCopri).Command;
Assert.AreEqual(typeof(CommandLoggedIn), l_oCommand.GetType());
}
/// <summary>
/// Verifies that factory method returns correcty type depending on session cookie.
/// </summary>
[Test]
public void TestQueryFactory_CachedServer()
{
var l_oCopri = Substitute.For<ICachedCopriServer>();
var l_oQuery = new TINK.Model.Connector.Connector(
new Uri("http://1.2.3.4"),
new AppContextInfo("oiF2kahH", "sharee.bike.test", new Version(3, 0, 267)),
null /*UI language */,
"",
"",
server: l_oCopri).Query;
Assert.AreEqual(typeof(CachedQuery), l_oQuery.GetType());
}
/// <summary>
/// Verifies that factory method returns correcty type depending on session cookie.
/// </summary>
[Test]
public void TestQueryFactory_LoggedIn()
{
var l_oCopri = Substitute.For<ICachedCopriServer>();
var l_oQuery = new TINK.Model.Connector.Connector(
new System.Uri("http://1.2.3.4"),
new AppContextInfo("oiF2kahH", "sharee.bike.test", new Version(3, 0, 267)),
null /*UI language */,
"123",
"a@b",
server: l_oCopri).Query;
Assert.AreEqual(typeof(CachedQueryLoggedIn), l_oQuery.GetType());
}
}
}

View file

@ -0,0 +1,85 @@
using System;
using NSubstitute;
using NUnit.Framework;
using TINK.Model.Connector;
using TINK.Repository;
namespace TestTINKLib.Fixtures.ObjectTests.Connector
{
[TestFixture]
public class TestConnectorCache
{
/// <summary>
/// Verifies that factory method returns correcty type depending on session cookie.
/// </summary>
[Test]
public void TestCommandFactory()
{
var l_oCopri = Substitute.For<ICopriServer>();
// Construct not logged in version of connector.
var l_oCommand = new ConnectorCache(
new AppContextInfo("MyMerchId", "MyApp", new Version(1, 2)),
null /*UI language */,
"", // Not logged in
"",
server: l_oCopri).Command;
Assert.AreEqual(typeof(Command), l_oCommand.GetType());
}
/// <summary>
/// Verifies that factory method returns correcty type depending on session cookie.
/// </summary>
[Test]
public void TestCommandFactory_LoggedIn()
{
var l_oCopri = Substitute.For<ICopriServer>();
var l_oCommand = new ConnectorCache(
new AppContextInfo("MyMerchId", "MyApp", new Version(1, 2)),
null /*UI language */,
"123", // Logged in
"a@b",
server: l_oCopri).Command;
Assert.AreEqual(typeof(CommandLoggedIn), l_oCommand.GetType());
}
/// <summary>
/// Verifies that factory method returns correcty type depending on session cookie.
/// </summary>
[Test]
public void TestQueryFactory_CachedServer()
{
var l_oCopri = Substitute.For<ICopriServer>();
var l_oQuery = new ConnectorCache(
new AppContextInfo("MyMerchId", "MyApp", new Version(1, 2)),
null /*UI language */,
"",
"",
server: l_oCopri).Query;
Assert.AreEqual(typeof(TINK.Model.Connector.Query), l_oQuery.GetType());
}
/// <summary>
/// Verifies that factory method returns correcty type depending on session cookie.
/// </summary>
[Test]
public void TestQueryFactory_LoggedIn()
{
var l_oCopri = Substitute.For<ICopriServer>();
var l_oQuery = new ConnectorCache(
new AppContextInfo("MyMerchId", "MyApp", new Version(1, 2)),
null /*UI language */,
"123",
"a@b",
server: l_oCopri).Query;
Assert.AreEqual(typeof(QueryLoggedIn), l_oQuery.GetType());
}
}
}

View file

@ -0,0 +1,163 @@
using System.Linq;
using NUnit.Framework;
using TINK.Repository;
using TINK.Repository.Response;
namespace TestTINKLib.Fixtures.ObjectTests.Connector.Request
{
[TestFixture]
public class TestCopriCallsStatic
{
[Test]
public void TestDeserializeObjectBikesAvailableValidResponse()
{
const string VALID_RESPONSE = @"
{
""shareejson"": {
""authcookie"": 0,
""apiserver"": ""https://tinkwwp.copri-bike.de"",
""response"": ""bikes_available"",
""bikes"": {
""3399"": {
""description"": ""Cargo Trike"",
""bike"": ""26"",
""state"": ""available"",
""gps"" : { ""latitude"": ""47.6586936667"", ""longitude"": ""9.16863116667"" },
""station"" : ""4""
},
},
""response_state"": ""OK"",
""copri_version"" : ""4.1.0.0""
}
}
";
// Ensure that answer holds a valid bike.
var l_oBike = CopriCallsStatic.DeserializeResponse<BikesAvailableResponse>(VALID_RESPONSE).bikes.FirstOrDefault().Value;
Assert.NotNull(l_oBike, "Response must contain at leas one bike.");
Assert.Greater(l_oBike.description.Length, 0, "Bike despcription must never be empty.");
Assert.AreEqual(l_oBike.bike, "26");
Assert.That(
l_oBike.station,
Is.EqualTo("4"),
"Station index must never be negative");
Assert.AreEqual("available", l_oBike.state);
Assert.That(l_oBike.gps, Is.Not.Null, "Gps position must never be empty.");
}
[Test]
public void TestDeserializeObjectBikesAvailableValidResponse_NoDescription()
{
const string INVALID_RESPONSE = @"
{
""shareejson"": {
""authcookie"": 0,
""apiserver"": ""https://tinkwwp.copri-bike.de"",
""response"": ""bikes_available"",
""bikes"": {
""3399"": {
""bike"": 26,
""state"": ""available"",
""gps"" : { ""latitude"": ""47.6586936667"", ""longitude"": ""9.16863116667"" },
""station"" : 4
},
},
""response_state"": ""OK"",
""copri_version"" : ""4.1.0.0"",
}
}
";
// Ensure that answer holds a valid bike.
var l_oBike = CopriCallsStatic.DeserializeResponse<BikesAvailableResponse>(INVALID_RESPONSE).bikes.FirstOrDefault().Value;
Assert.NotNull(l_oBike, "Response must contain at leas one bike.");
Assert.IsNull(l_oBike.description);
Assert.That(l_oBike.bike, Is.Not.Null);
Assert.That(l_oBike.station, Is.Not.Null);
Assert.AreEqual("available", l_oBike.state);
Assert.That(l_oBike.gps, Is.Not.Null, "Gps position must never be empty.");
}
[Test]
public void TestDeserializeObjectBikesAvailableValidResponse_NoBikeId()
{
const string VALID_RESPONSE = @"
{
""shareejson"": {
""authcookie"": 0,
""apiserver"": ""https://tinkwwp.copri-bike.de"",
""response"": ""bikes_available"",
""bikes"": {
""3399"": {
""description"": ""Cargo Trike"",
""state"": ""available"",
""gps"" : { ""latitude"": ""47.6586936667"", ""longitude"": ""9.16863116667"" },
""station"" : ""4""
},
},
""response_state"": ""OK"",
""copri_version"" : ""4.1.0.0"",
}
}";
// Ensure that answer holds a valid bike.
var l_oBike = CopriCallsStatic.DeserializeResponse<BikesAvailableResponse>(VALID_RESPONSE).bikes.FirstOrDefault().Value;
Assert.NotNull(l_oBike, "Response must contain at leas one bike.");
Assert.Greater(l_oBike.description.Length, 0, "Bike despcription must never be empty.");
Assert.That(l_oBike.bike, Is.Null);
Assert.That(l_oBike.station, Is.Not.Null);
Assert.AreEqual("available", l_oBike.state);
Assert.That(l_oBike.gps, Is.Not.Null, "Gps position must never be empty.");
}
[Test]
public void TestDeserializeObjectBikesOccupiedValidResponse()
{
const string VALID_RESPONSE = @"
{
""shareejson"": {
""response_state"": ""OK"",
""bikes_occupied"": {
""87781"": {
""timeCode"": ""3630"",
""state"": ""occupied"",
""station"" : ""5"",
""description"": ""Cargo Long"",
""start_time"": ""2017-11-28 11:01:51.637747+01"",
""bike"": ""8""
},
""87782"": {
""timeCode"": ""2931"",
""state"": ""occupied"",
""station"" : ""4"",
""description"": ""Cargo Long"",
""start_time"": ""2017-11-28 13:06:55.147368+01"",
""bike"": ""7""
}
},
""authcookie"": ""b76b97e43a2d76b8499f32e6dd597af8"",
""response"": ""user_bikes_occupied"",
""apiserver"": ""https://tinkwwp.copri-bike.de"",
""copri_version"" : ""4.1.0.0"",
}
}";
// Ensure that answer holds a valid bike.
var l_oBike = CopriCallsStatic.DeserializeResponse<BikesReservedOccupiedResponse>(VALID_RESPONSE).bikes_occupied.FirstOrDefault().Value;
Assert.NotNull(l_oBike, "Response must contain at leas one bike.");
Assert.Greater(l_oBike.description.Length, 0, "Bike despcription must never be empty.");
Assert.That(l_oBike.bike, Is.Not.Null);
Assert.That(l_oBike.station, Is.Not.Null);
Assert.Greater(l_oBike.state.Length, 0, "State info must never be null or empty.");
// Todo: Requested bikes do not have a gps position. What is about booked bikes?
// Assert.Greater(l_oBike.gps.Length, 0, "Gps position must never be empty.");
Assert.Greater(l_oBike.start_time.Length, 0, "Time when request/ booking was performed must never be null or empty.");
Assert.Greater(l_oBike.timeCode.Length, 0, "Booking code must never be null or empty.");
}
}
}

View file

@ -0,0 +1,113 @@
using System.Threading.Tasks;
using Newtonsoft.Json;
using NSubstitute;
using NUnit.Framework;
using TINK.Repository;
using TINK.Repository.Response;
namespace TestTINKLib.Fixtures.ObjectTests.Query
{
[TestFixture]
public class TestQuery
{
private const string BIKESAVAILABLE = @"{
""copri_version"" : ""4.1.0.0"",
""bikes"" : {},
""response_state"" : ""OK"",
""apiserver"" : ""https://app.tink-konstanz.de"",
""authcookie"" : """",
""response"" : ""bikes_available"",
""bikes"" : {
""2352"" : {
""description"" : ""Cargo Long"",
""state"" : ""available"",
""bike"" : ""1"",
""gps"" : { ""latitude"": ""47.669888"", ""longitude"": ""9.167749"" },
""station"" : ""9""
}
}
}";
private const string STATIONSALL = @"{
""copri_version"" : ""4.1.0.0"",
""stations"" : {
""5"" : {
""station"" : ""5"",
""bike_soll"" : ""0"",
""bike_ist"" : ""7"",
""station_group"" : [ ""TINK"" ],
""gps"" : { ""latitude"": ""47.66756"", ""longitude"": ""9.16477"" },
""state"" : ""available"",
""description"" : """"
},
""13"" : {
""station"" : ""13"",
""bike_soll"" : ""4"",
""bike_ist"" : ""1"",
""station_group"" : [ ""TINK"" ],
""gps"" : { ""latitude"": ""47.657756"", ""longitude"": ""9.176084"" },
""state"" : ""available"",
""description"" : """"
},
""30"" : {
""station"" : ""30"",
""bike_soll"" : ""5"",
""bike_ist"" : ""0"",
""station_group"" : [ ""TINK"", ""Konrad"" ],
""gps"" : { ""latitude"": ""47.657766"", ""longitude"": ""9.176094"" },
""state"" : ""available"",
""description"" : ""Test für Stadtradstation""
}
},
""user_group"" : [ ""Konrad"", ""TINK"" ],
""response_state"" : ""OK"",
""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"",
""debuglevel"" : ""2"",
""response"" : ""stations_all"",
""user_id"" : ""javaminister@gmail.com"",
""apiserver"" : ""https://tinkwwp.copri-bike.de""
}";
[Test]
public async Task TestGetStations()
{
var server = Substitute.For<ICopriServer>();
server.GetStationsAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL)));
server.GetBikesAvailableAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE)));
var result = await new TINK.Model.Connector.Query(server).GetBikesAndStationsAsync();
Assert.AreEqual(3, result.Response.StationsAll.Count);
Assert.AreEqual(1, result.Response.Bikes.Count);
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
Assert.IsNull(result.Exception);
}
[Test]
public async Task TestGetBikes()
{
var server = Substitute.For<ICopriServer>();
server.GetBikesAvailableAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE)));
var result = await new TINK.Model.Connector.Query(server).GetBikesAsync();
Assert.AreEqual(1, result.Response.Count);
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
Assert.IsNull(result.Exception);
}
[Test]
public async Task TestGetBikesOccupied()
{
var server = Substitute.For<ICopriServer>();
var result = await new TINK.Model.Connector.Query(server).GetBikesOccupiedAsync();
Assert.AreEqual(0, result.Response.Count);
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
Assert.AreEqual(result.Exception.Message, "Abfrage der reservierten/ gebuchten Räder fehlgeschlagen. Kein Benutzer angemeldet.");
}
}
}

View file

@ -0,0 +1,155 @@
using System;
using System.Threading.Tasks;
using Newtonsoft.Json;
using NSubstitute;
using NUnit.Framework;
using TINK.Model.Connector;
using TINK.Repository;
using TINK.Repository.Response;
namespace TestTINKLib.Fixtures.ObjectTests.Connector
{
[TestFixture]
public class TestQueryLoggedIn
{
private const string BIKESAVAILABLE = @"{
""copri_version"" : ""4.1.0.0"",
""bikes"" : {},
""response_state"" : ""OK"",
""apiserver"" : ""https://app.tink-konstanz.de"",
""authcookie"" : """",
""response"" : ""bikes_available"",
""bikes"" : {
""2352"" : {
""description"" : ""Cargo Long"",
""state"" : ""available"",
""bike"" : ""1"",
""gps"" : { ""latitude"": ""47.669888"", ""longitude"": ""9.167749"" },
""station"" : ""9""
}
}
}";
private const string BIKESOCCUPIED = @"{
""copri_version"" : ""4.1.0.0"",
""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"",
""debuglevel"" : ""2"",
""user_group"" : [ ""TINK"" ],
""user_id"" : ""javaminister@gmail.com"",
""response"" : ""user_bikes_occupied"",
""response_state"" : ""OK"",
""response_text"" : ""Die Liste der reservierten und gebuchten Fahrräder wurde erfolgreich geladen"",
""apiserver"" : ""https://tinkwwp.copri-bike.de"",
""bikes_occupied"" : {
""89004"" : {
""start_time"" : ""2018-01-27 17:33:00.989464+01"",
""station"" : ""9"",
""unit_price"" : ""2.00"",
""tariff_description"": {
""free_hours"" : ""0.5"",
""name"" : ""TINK Tarif"",
""max_eur_per_day"" : ""9.00""
},
""timeCode"" : ""2061"",
""description"" : ""Cargo Long"",
""bike"" : ""4"",
""total_price"" : ""20.00"",
""state"" : ""requested"",
""real_hours"" : ""66.05"",
""bike_group"" : [ ""TINK"" ],
""now_time"" : ""2018-01-30 11:36:45"",
""request_time"" : ""2018-01-27 17:33:00.989464+01"",
""computed_hours"" : ""10.0""
}
}
}";
private const string STATIONSALL = @"{
""copri_version"" : ""4.1.0.0"",
""stations"" : {
""5"" : {
""station"" : ""5"",
""bike_soll"" : ""0"",
""bike_ist"" : ""7"",
""station_group"" : [ ""TINK"" ],
""gps"" : { ""latitude"": ""47.66756"", ""longitude"": ""9.16477"" },
""state"" : ""available"",
""description"" : """"
},
""13"" : {
""station"" : ""13"",
""bike_soll"" : ""4"",
""bike_ist"" : ""1"",
""station_group"" : [ ""TINK"" ],
""gps"" : { ""latitude"": ""47.657756"", ""longitude"": ""9.176084"" },
""state"" : ""available"",
""description"" : """"
},
""30"" : {
""station"" : ""30"",
""bike_soll"" : ""5"",
""bike_ist"" : ""0"",
""station_group"" : [ ""TINK"", ""Konrad"" ],
""gps"" : { ""latitude"": ""47.657766"", ""longitude"": ""9.176094"" },
""state"" : ""available"",
""description"" : ""Test für Stadtradstation""
}
},
""user_group"" : [ ""Konrad"", ""TINK"" ],
""response_state"" : ""OK"",
""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"",
""debuglevel"" : ""2"",
""response"" : ""stations_all"",
""user_id"" : ""javaminister@gmail.com"",
""apiserver"" : ""https://tinkwwp.copri-bike.de""
}";
[Test]
public async Task TestGetStations()
{
var server = Substitute.For<ICopriServer>();
server.GetStationsAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL)));
server.GetBikesAvailableAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE)));
server.GetBikesOccupiedAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED)));
var result = await new QueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync();
Assert.AreEqual(3, result.Response.StationsAll.Count);
Assert.AreEqual(2, result.Response.Bikes.Count);
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
Assert.IsNull(result.Exception);
}
[Test]
public async Task TestGetBikes()
{
var server = Substitute.For<ICopriServer>();
server.GetBikesAvailableAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE)));
server.GetBikesOccupiedAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED)));
var result = await new QueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAsync();
Assert.AreEqual(2, result.Response.Count);
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
Assert.IsNull(result.Exception);
}
[Test]
public async Task TestGetBikesOccupied()
{
var server = Substitute.For<ICopriServer>();
server.GetBikesAvailableAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<BikesAvailableResponse>("{}")));
server.GetBikesOccupiedAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED)));
var result = await new QueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesOccupiedAsync();
Assert.AreEqual(1, result.Response.Count);
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
Assert.IsNull(result.Exception);
}
}
}

View file

@ -0,0 +1,188 @@
using System;
using System.Collections.Generic;
using NSubstitute;
using NUnit.Framework;
using TINK.Model.State;
namespace TestTINKLib
{
[TestFixture]
public class TestStateInfo
{
[Test]
public void TestConstruct()
{
var l_oInUseState = new StateInfoMutable(() => new DateTime(2017, 09, 20, 23, 20, 0));
// Verify initial values of properties.
Assert.AreEqual(InUseStateEnum.Disposable, l_oInUseState.Value, "Default state is available");
Assert.AreEqual("Disposable", l_oInUseState.ToString());
Assert.IsNull(l_oInUseState.RemainingTime);
Assert.IsNull(l_oInUseState.From);
Assert.IsNull(l_oInUseState.Code);
}
[Test]
public void TestConstructCopy()
{
// State is available.
var l_oSource = Substitute.For<IStateInfo>();
l_oSource.Value.Returns(InUseStateEnum.Disposable);
var l_oState = new StateInfoMutable(state: l_oSource);
Assert.AreEqual(InUseStateEnum.Disposable, l_oState.Value);
Assert.IsNull(l_oState.RemainingTime);
Assert.IsNull(l_oState.From);
Assert.IsNull(l_oState.Code);
// State is requested.
l_oSource = Substitute.For<IStateInfo>();
l_oSource.Value.Returns(InUseStateEnum.Reserved);
l_oSource.From.Returns(new DateTime(2018, 1, 4, 17, 26, 0));
l_oSource.MailAddress.Returns("who@the");
l_oSource.Code.Returns("323");
l_oState = new StateInfoMutable(() => new DateTime(2018, 1, 4, 17, 30, 1), l_oSource);
Assert.AreEqual(InUseStateEnum.Reserved, l_oState.Value);
Assert.AreEqual(new TimeSpan(0, 10, 59), l_oState.RemainingTime);
Assert.AreEqual(new DateTime(2018, 1, 4, 17, 26, 0), l_oState.From);
Assert.AreEqual("who@the", l_oState.MailAddress);
Assert.AreEqual("323", l_oState.Code);
// State is booked.
l_oSource = Substitute.For<IStateInfo>();
l_oSource.Value.Returns(InUseStateEnum.Booked);
l_oSource.From.Returns(new DateTime(2018, 1, 4, 17, 00, 0));
l_oSource.MailAddress.Returns("who@the");
l_oSource.Code.Returns("323");
l_oState = new StateInfoMutable(() => new DateTime(2018, 1, 4, 17, 30, 1), l_oSource);
Assert.AreEqual(InUseStateEnum.Booked, l_oState.Value);
Assert.IsNull(l_oState.RemainingTime);
Assert.AreEqual(new DateTime(2018, 1, 4, 17, 00, 0), l_oState.From);
Assert.AreEqual("who@the", l_oState.MailAddress);
Assert.AreEqual("323", l_oState.Code);
}
[Test]
public void TestDoUpdate()
{
var l_oReservedAt = new DateTime(2017, 09, 20, 22, 01, 00);
var l_oDateTimeMock = new DateTimeMocker(new List<DateTime> {
l_oReservedAt, // Booking time
l_oReservedAt.Add(new TimeSpan(0, 4, 0)), // Reserved for 4 mns
l_oReservedAt.Add(new TimeSpan(0, 16, 0)) // Time elapsed since booking 16 mns
});
var l_oStateInfo = new StateInfoMutable(l_oDateTimeMock.GetDateTime);
// Update state from Copri.
l_oStateInfo.Load(
InUseStateEnum.Reserved, // Copri acknowledges state reserved.
l_oDateTimeMock.GetDateTime(),
"heiz@mustermann"); // Owner from Copri.
// Invoke first update (after simulated 4mns)
l_oStateInfo.UpdateOnTimeElapsed();
Assert.AreEqual(InUseStateEnum.Reserved, l_oStateInfo.Value);
Assert.AreEqual(11, l_oStateInfo.RemainingTime.Value.Minutes);
Assert.AreEqual(new DateTime(2017, 09, 20, 22, 01, 00), l_oStateInfo.From.Value);
Assert.AreEqual("heiz@mustermann", l_oStateInfo.MailAddress);
Assert.IsNull(l_oStateInfo.Code);
// Invoke second update (after simulated 16 mns)
l_oStateInfo.UpdateOnTimeElapsed();
Assert.AreEqual(InUseStateEnum.Disposable, l_oStateInfo.Value);
Assert.IsNull(l_oStateInfo.RemainingTime);
Assert.IsNull(l_oStateInfo.From);
Assert.IsNull(l_oStateInfo.MailAddress);
Assert.IsNull(l_oStateInfo.Code);
}
[Test]
public void TestUpdateFromWebserver()
{
Func<DateTime> l_oNowMock = () => new DateTime(2017, 09, 21, 23, 40, 0);
var l_oStateInfo = new StateInfoMutable(l_oNowMock);
l_oStateInfo.Load(InUseStateEnum.Booked, new DateTime(2017, 09, 21, 23, 30, 0), "heiz@mustermann", "21");
Assert.AreEqual(InUseStateEnum.Booked, l_oStateInfo.Value);
Assert.AreEqual("Booked", l_oStateInfo.ToString());
Assert.IsNull(l_oStateInfo.RemainingTime);
Assert.AreEqual(new DateTime(2017, 09, 21, 23, 30, 0), l_oStateInfo.From.Value);
Assert.AreEqual("heiz@mustermann", l_oStateInfo.MailAddress);
Assert.AreEqual("21", l_oStateInfo.Code);
DateTime FROM = new DateTime(2017, 09, 21, 23, 35, 0);
l_oStateInfo.Load(InUseStateEnum.Reserved, FROM, "heiz@mustermann", "22");
// Verify initial values of properties.
Assert.AreEqual(InUseStateEnum.Reserved, l_oStateInfo.Value);
Assert.AreEqual("Reserved", l_oStateInfo.ToString());
Assert.AreEqual(new TimeSpan(0, 15, 0).Subtract(l_oNowMock().Subtract(FROM)).Minutes, l_oStateInfo.RemainingTime.Value.Minutes);
Assert.AreEqual(FROM, l_oStateInfo.From);
Assert.AreEqual("heiz@mustermann", l_oStateInfo.MailAddress);
Assert.AreEqual("22", l_oStateInfo.Code);
l_oStateInfo.Load(InUseStateEnum.Disposable, new DateTime(1970, 1, 1, 0, 0, 0), "heiz@mustermann", "unused");
// Verify initial values of properties.
Assert.AreEqual(InUseStateEnum.Disposable, l_oStateInfo.Value);
Assert.AreEqual("Disposable", l_oStateInfo.ToString());
Assert.IsNull(l_oStateInfo.RemainingTime);
Assert.IsNull(l_oStateInfo.From);
Assert.IsNull(l_oStateInfo.MailAddress);
Assert.IsNull(l_oStateInfo.Code);
}
[Test]
public void TestLoad()
{
var l_oState = new StateInfoMutable(
() => new DateTime(2018, 01, 03, 21, 14, 0)); // Now
Assert.AreEqual(InUseStateEnum.Disposable, l_oState.Value);
Assert.IsNull(l_oState.From);
Assert.IsNull(l_oState.RemainingTime);
Assert.IsNull(l_oState.MailAddress);
Assert.IsNull(l_oState.Code);
// Construct requested state object.
var l_oSource = new StateInfo(
() => new DateTime(2018, 01, 03, 21, 53, 0),
new DateTime(2018, 01, 03, 21, 13, 0), // Requested from
"a@b",
"123");
l_oState.Load(l_oSource);
Assert.AreEqual(InUseStateEnum.Reserved, l_oState.Value);
Assert.AreEqual(new DateTime(2018, 01, 03, 21, 13, 0), l_oState.From);
Assert.AreEqual(14, l_oState.RemainingTime.Value.Minutes);
Assert.AreEqual("a@b", l_oState.MailAddress);
Assert.AreEqual("123", l_oState.Code);
// Construct booked state object.
l_oSource = new StateInfo(new DateTime(2018, 01, 03, 21, 37, 0), "a@b", "123");
l_oState.Load(l_oSource);
Assert.AreEqual(InUseStateEnum.Booked, l_oState.Value);
Assert.AreEqual(new DateTime(2018, 01, 03, 21, 37, 0), l_oState.From);
Assert.IsNull(l_oState.RemainingTime);
Assert.AreEqual("a@b", l_oState.MailAddress);
Assert.AreEqual("123", l_oState.Code);
// Construct disposable object
l_oSource = new StateInfo();
l_oState.Load(l_oSource);
Assert.AreEqual(InUseStateEnum.Disposable, l_oState.Value);
Assert.IsNull(l_oState.From);
Assert.IsNull(l_oState.RemainingTime);
Assert.IsNull(l_oState.MailAddress);
Assert.IsNull(l_oState.Code);
}
}
}

View file

@ -0,0 +1,90 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
using TINK.Model.State;
namespace TestTINKLib
{
[TestFixture]
public class TestStateRequestedInfo
{
[Test]
public void TestConstruct_FromApp()
{
Assert.AreEqual(
InUseStateEnum.Reserved,
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), "a@b", null).Value);
Assert.AreEqual(
"a@b",
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), "a@b", null).MailAddress);
Assert.IsNull(
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), "a@b", null).Code);
Assert.AreEqual(
new DateTime(2017, 09, 20, 12, 0, 0),
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), "a@b", null).From);
Assert.IsTrue(
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), "a@b", null).GetIsStillReserved(out TimeSpan? l_oRemainigTime));
Assert.AreEqual(
14,
l_oRemainigTime.Value.Minutes);
}
[Test]
public void TestConstruct_FromWebserver()
{
Assert.AreEqual(
InUseStateEnum.Reserved,
new StateRequestedInfo(() => new DateTime(2017, 09, 20), new DateTime(2017, 09, 19), "a@b", "372").Value);
Assert.AreEqual(
"a@b",
new StateRequestedInfo(() => new DateTime(2017, 09, 20), new DateTime(2017, 09, 19), "a@b", "372").MailAddress);
Assert.AreEqual(
"372",
new StateRequestedInfo(() => new DateTime(2017, 09, 20), new DateTime(2017, 09, 19), "a@b", "372").Code);
Assert.AreEqual(
new DateTime(2017, 09, 19),
new StateRequestedInfo(() => new DateTime(2017, 09, 20), new DateTime(2017, 09, 19), "a@b", "372").From);
Assert.IsTrue(
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 12, 0), new DateTime(2017, 09, 20, 12, 0, 0), "a@b", "372").GetIsStillReserved(out TimeSpan? l_oRemainigTime));
Assert.AreEqual(
3,
l_oRemainigTime.Value.Minutes);
}
[Test]
public void TestTryUpdateOnTimeElapsed()
{
var l_oReservedAt = new DateTime(2017, 09, 20, 22, 01, 00);
var l_oDateTimeMock = new DateTimeMocker(new List<DateTime> {
l_oReservedAt.Add(new TimeSpan(0, 4, 0)), // Reserved for 4 mns
l_oReservedAt.Add(new TimeSpan(0, 16, 0)) // Time elapsed since booking 16 mns
});
var l_oReservedInfo = new StateRequestedInfo(l_oDateTimeMock.GetDateTime, l_oReservedAt, "a@b", null);
Assert.AreEqual("a@b", l_oReservedInfo.MailAddress);
Assert.AreEqual(new DateTime(2017, 09, 20, 22, 01, 00), l_oReservedInfo.From, "a@b");
// Invoke first update (after simulated 4mns)
Assert.IsTrue(l_oReservedInfo.GetIsStillReserved(out TimeSpan? l_oRemainigTime));
Assert.AreEqual(11, l_oRemainigTime.Value.Minutes);
Assert.AreEqual(new DateTime(2017, 09, 20, 22, 01, 00), l_oReservedInfo.From, "a@b");
// Invoke second update (after simulated 16 mns)
Assert.IsFalse(l_oReservedInfo.GetIsStillReserved(out l_oRemainigTime));
Assert.IsNull(l_oRemainigTime);
Assert.AreEqual(new DateTime(2017, 09, 20, 22, 01, 00), l_oReservedInfo.From, "a@b");
}
}
}

View file

@ -43,7 +43,7 @@ namespace TestShareeLib.UseCases.Login
merchantId: "MyMerchId",
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: permissions,
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocation>>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: locksService, // Cipher
device: device,
specialFolder: specialFolder,

View file

@ -48,7 +48,7 @@ namespace TestTINKLib.Fixtures.UseCases.Logout
merchantId: "MyMerchId",
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: permissions,
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocation>>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: locksService, // Cipher
device: device,
specialFolder: specialFolder,

View file

@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using NSubstitute;
using NUnit.Framework;
using Plugin.BLE.Abstractions.Contracts;
using TestFramework.Model.Device;
using TestFramework.Model.Services.Geolocation;
using TestFramework.Model.User.Account;
using TestFramework.Services.BluetoothLock;
using TINK.Model;
using TINK.Model.Bikes;
using TINK.Model.Connector;
using TINK.Model.Settings;
using TINK.Model.Station;
using TINK.Model.User;
using TINK.Repository;
using TINK.Services;
using TINK.Services.Geolocation;
using TINK.Services.Permissions;
using TINK.ViewModel.Settings;
using static TINK.Repository.CopriCallsMemory;
namespace TestTINKLib.Fixtures.UseCases.SelectStation
{
[TestFixture]
public class TestTinkApp
{
/// <summary>
/// Get all bikes at a given station from copri.
/// </summary>
private static async Task<BikeCollectionMutable> GetBikesAtStation(
User user,
TINK.Model.Connector.IConnector connector,
IEnumerable<IStation> stations,
string selectedStationId)
{
var l_oBikesAtStation = new BikeCollectionMutable();
var l_oBikesAvailable = (await connector.Query.GetBikesAsync()).Response;
l_oBikesAtStation.Update(l_oBikesAvailable.GetAtStation(selectedStationId), stations);
return l_oBikesAtStation;
}
[Test]
public void TestBikesAtStation_AccountStoreMock_NoUser_CopriMock_Set2()
{
const string MERCH_ID = "MyMerchId";
var l_oConnector = new ConnectorCache(
new AppContextInfo(MERCH_ID, "MyApp", new Version(1, 2)),
null /*UI language */,
string.Empty,
string.Empty,
server: new CopriCallsMemory(MERCH_ID, SampleSets.Set2, 1));
var l_oTinkApp = new TinkApp(
new Settings(
new TINK.ViewModel.Map.GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
activeLockService: typeof(LocksServiceMock).FullName,
activeGeolocationService: typeof(GeolocationMock).FullName),
new StoreMock(),
isConnectedFunc: () => true,
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(new AppContextInfo(MERCH_ID, "MyApp", new Version(1, 2)), null /*UI language */, sessionCookie, mail, server: new CopriCallsMemory(MERCH_ID, SampleSets.Set2, 1)),
merchantId: MERCH_ID,
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: new LocksServiceMock(), // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
cipher: null,
theme: null,
currentVersion: new Version(3, 2, 0, 115),
lastVersion: new Version(3, 0, 173)); // Current app version. Must be larger or equal 3.0.173 to
Assert.AreEqual(0, GetBikesAtStation(l_oTinkApp.ActiveUser, l_oConnector, l_oTinkApp.Stations, l_oTinkApp.SelectedStation.Id).Result.Count);
l_oTinkApp.SelectedStation = new TINK.Model.Station.Station("5", new List<string>(), null);
Assert.AreEqual(3, GetBikesAtStation(l_oTinkApp.ActiveUser, l_oConnector, l_oTinkApp.Stations, l_oTinkApp.SelectedStation.Id).Result.Count);
Assert.AreEqual("25", GetBikesAtStation(l_oTinkApp.ActiveUser, l_oConnector, l_oTinkApp.Stations, l_oTinkApp.SelectedStation.Id).Result.GetById("25").Id);
Assert.AreEqual("11", GetBikesAtStation(l_oTinkApp.ActiveUser, l_oConnector, l_oTinkApp.Stations, l_oTinkApp.SelectedStation.Id).Result.GetById("11").Id);
Assert.AreEqual("2", GetBikesAtStation(l_oTinkApp.ActiveUser, l_oConnector, l_oTinkApp.Stations, l_oTinkApp.SelectedStation.Id).Result.GetById("2").Id);
l_oTinkApp.SelectedStation = new TINK.Model.Station.Station("10", new List<string>(), null);
Assert.AreEqual(
1,
GetBikesAtStation(l_oTinkApp.ActiveUser, l_oConnector, l_oTinkApp.Stations, l_oTinkApp.SelectedStation.Id).Result.Count);
Assert.AreEqual("18", GetBikesAtStation(l_oTinkApp.ActiveUser, l_oConnector, l_oTinkApp.Stations, l_oTinkApp.SelectedStation.Id).Result.GetById("18").Id);
l_oTinkApp.SelectedStation = new TINK.Model.Station.Station("91345", new List<string>(), null);
Assert.AreEqual(0, GetBikesAtStation(l_oTinkApp.ActiveUser, l_oConnector, l_oTinkApp.Stations, l_oTinkApp.SelectedStation.Id).Result.Count);
}
}
}

View file

@ -0,0 +1,51 @@
using System.Collections.Generic;
using System.Linq;
using NSubstitute;
using NUnit.Framework;
using TINK.Model.Connector;
using TINK.Model.User.Account;
namespace TestTINKLib.Fixtures.ObjectTests.User.Account
{
[TestFixture]
public class TestAccountExtensions
{
/// <summary> If no user is logged in filter is not applied. </summary>
[Test]
public void TestDoFilter_NoUserLoggedIn()
{
var l_oAccount = Substitute.For<IAccount>();
l_oAccount.Mail.Returns("a@b");
l_oAccount.SessionCookie.Returns(""); // User is not logged in
l_oAccount.Group.Returns(new List<string> { $"HOM_{FilterHelper.CARGOBIKE}", "HOM_117025" });
var l_oSource = new List<string> { $"HOM_{FilterHelper.CARGOBIKE}", $"HOM_{FilterHelper.CITYBIKE}", "HOM_117025" };
var l_oResult = l_oAccount.DoFilter(l_oSource);
Assert.AreEqual(3, l_oResult.ToList().Count);
Assert.AreEqual($"HOM_{FilterHelper.CARGOBIKE}", l_oResult.ToList()[0]);
Assert.AreEqual($"HOM_{FilterHelper.CITYBIKE}", l_oResult.ToList()[1]);
Assert.AreEqual("HOM_117025", l_oResult.ToList()[2]);
}
/// <summary> </summary>
[Test]
public void TestDoFilter()
{
var l_oAccount = Substitute.For<IAccount>();
l_oAccount.Mail.Returns("a@b");
l_oAccount.SessionCookie.Returns("123");
l_oAccount.Group.Returns(new List<string> { $"HOM_{FilterHelper.CARGOBIKE}", "HOM_117025" });
var l_oSource = new List<string> { $"HOM_{FilterHelper.CARGOBIKE}", $"HOM_{FilterHelper.CITYBIKE}", "HOM_117025" };
var l_oResult = l_oAccount.DoFilter(l_oSource);
Assert.AreEqual(2, l_oResult.ToList().Count);
Assert.AreEqual($"HOM_{FilterHelper.CARGOBIKE}", l_oResult.ToList()[0]);
Assert.AreEqual("HOM_117025", l_oResult.ToList()[1]);
}
}
}

View file

@ -26,11 +26,11 @@ namespace TestTINKLib.Fixtures.Connector.Request
Assert.IsNull(
l_oCopri.GetBikesAvailableAsync().Result.bikes.Values.FirstOrDefault(x => x.state != "available"),
"Bikes available must return bikes which are all of state available.");
"Bikes available must end rentals which are all of state available.");
Assert.IsNull(
l_oCopri.GetBikesOccupiedAsync().Result.bikes_occupied.Values.FirstOrDefault(x => x.state == "available"),
"Bikes occupied must return bikes which are either reserved or booked.");
"Bikes occupied must end rentals which are either reserved or booked.");
}
}
}

View file

@ -1,4 +1,5 @@
using Newtonsoft.Json;
using System.Linq;
using Newtonsoft.Json;
using NUnit.Framework;
using TINK.Repository;
using TINK.Repository.Response;
@ -82,5 +83,158 @@ namespace TestShareeLib.Repository
() => response.DeserializeResponse<ResponseBase>(version => new System.Exception("Ho")).copri_version,
Throws.InstanceOf<System.Exception>());
}
[Test]
public void TestDeserializeObjectBikesAvailableValidResponse()
{
const string VALID_RESPONSE = @"
{
""shareejson"": {
""authcookie"": 0,
""apiserver"": ""https://tinkwwp.copri-bike.de"",
""response"": ""bikes_available"",
""bikes"": {
""3399"": {
""description"": ""Cargo Trike"",
""bike"": ""26"",
""state"": ""available"",
""gps"" : { ""latitude"": ""47.6586936667"", ""longitude"": ""9.16863116667"" },
""station"" : ""4""
},
},
""response_state"": ""OK"",
""copri_version"" : ""4.1.0.0""
}
}
";
// Ensure that answer holds a valid bike.
var l_oBike = CopriCallsStatic.DeserializeResponse<BikesAvailableResponse>(VALID_RESPONSE).bikes.FirstOrDefault().Value;
Assert.NotNull(l_oBike, "Response must contain at leas one bike.");
Assert.Greater(l_oBike.description.Length, 0, "Bike despcription must never be empty.");
Assert.AreEqual(l_oBike.bike, "26");
Assert.That(
l_oBike.station,
Is.EqualTo("4"),
"Station index must never be negative");
Assert.AreEqual("available", l_oBike.state);
Assert.That(l_oBike.gps, Is.Not.Null, "Gps position must never be empty.");
}
[Test]
public void TestDeserializeObjectBikesAvailableValidResponse_NoDescription()
{
const string INVALID_RESPONSE = @"
{
""shareejson"": {
""authcookie"": 0,
""apiserver"": ""https://tinkwwp.copri-bike.de"",
""response"": ""bikes_available"",
""bikes"": {
""3399"": {
""bike"": 26,
""state"": ""available"",
""gps"" : { ""latitude"": ""47.6586936667"", ""longitude"": ""9.16863116667"" },
""station"" : 4
},
},
""response_state"": ""OK"",
""copri_version"" : ""4.1.0.0"",
}
}
";
// Ensure that answer holds a valid bike.
var l_oBike = CopriCallsStatic.DeserializeResponse<BikesAvailableResponse>(INVALID_RESPONSE).bikes.FirstOrDefault().Value;
Assert.NotNull(l_oBike, "Response must contain at leas one bike.");
Assert.IsNull(l_oBike.description);
Assert.That(l_oBike.bike, Is.Not.Null);
Assert.That(l_oBike.station, Is.Not.Null);
Assert.AreEqual("available", l_oBike.state);
Assert.That(l_oBike.gps, Is.Not.Null, "Gps position must never be empty.");
}
[Test]
public void TestDeserializeObjectBikesAvailableValidResponse_NoBikeId()
{
const string VALID_RESPONSE = @"
{
""shareejson"": {
""authcookie"": 0,
""apiserver"": ""https://tinkwwp.copri-bike.de"",
""response"": ""bikes_available"",
""bikes"": {
""3399"": {
""description"": ""Cargo Trike"",
""state"": ""available"",
""gps"" : { ""latitude"": ""47.6586936667"", ""longitude"": ""9.16863116667"" },
""station"" : ""4""
},
},
""response_state"": ""OK"",
""copri_version"" : ""4.1.0.0"",
}
}";
// Ensure that answer holds a valid bike.
var l_oBike = CopriCallsStatic.DeserializeResponse<BikesAvailableResponse>(VALID_RESPONSE).bikes.FirstOrDefault().Value;
Assert.NotNull(l_oBike, "Response must contain at leas one bike.");
Assert.Greater(l_oBike.description.Length, 0, "Bike despcription must never be empty.");
Assert.That(l_oBike.bike, Is.Null);
Assert.That(l_oBike.station, Is.Not.Null);
Assert.AreEqual("available", l_oBike.state);
Assert.That(l_oBike.gps, Is.Not.Null, "Gps position must never be empty.");
}
[Test]
public void TestDeserializeObjectBikesOccupiedValidResponse()
{
const string VALID_RESPONSE = @"
{
""shareejson"": {
""response_state"": ""OK"",
""bikes_occupied"": {
""87781"": {
""timeCode"": ""3630"",
""state"": ""occupied"",
""station"" : ""5"",
""description"": ""Cargo Long"",
""start_time"": ""2017-11-28 11:01:51.637747+01"",
""bike"": ""8""
},
""87782"": {
""timeCode"": ""2931"",
""state"": ""occupied"",
""station"" : ""4"",
""description"": ""Cargo Long"",
""start_time"": ""2017-11-28 13:06:55.147368+01"",
""bike"": ""7""
}
},
""authcookie"": ""b76b97e43a2d76b8499f32e6dd597af8"",
""response"": ""user_bikes_occupied"",
""apiserver"": ""https://tinkwwp.copri-bike.de"",
""copri_version"" : ""4.1.0.0"",
}
}";
// Ensure that answer holds a valid bike.
var l_oBike = CopriCallsStatic.DeserializeResponse<BikesReservedOccupiedResponse>(VALID_RESPONSE).bikes_occupied.FirstOrDefault().Value;
Assert.NotNull(l_oBike, "Response must contain at leas one bike.");
Assert.Greater(l_oBike.description.Length, 0, "Bike despcription must never be empty.");
Assert.That(l_oBike.bike, Is.Not.Null);
Assert.That(l_oBike.station, Is.Not.Null);
Assert.Greater(l_oBike.state.Length, 0, "State info must never be null or empty.");
// Todo: Requested bikes do not have a gps position. What is about booked bikes?
// Assert.Greater(l_oBike.gps.Length, 0, "Gps position must never be empty.");
Assert.Greater(l_oBike.start_time.Length, 0, "Time when request/ booking was performed must never be null or empty.");
Assert.Greater(l_oBike.timeCode.Length, 0, "Booking code must never be null or empty.");
}
}
}

View file

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using NUnit.Framework;
using TINK.Services;
@ -64,5 +64,35 @@ namespace TestShareeLib.Services
private class MyTypeB { }
private class MyTypeC { }
[Test]
public void TestCtor2()
{
var container = new ServicesContainerMutableT<object>(new List<object> { new MyTypeA(), new MyTypeB() }, typeof(MyTypeB).FullName);
Assert.That(container.Active.GetType().FullName, Is.EqualTo("TestShareeLib.Services.TestServicesContainerMutable+MyTypeB"));
}
[Test]
public void TestCtorExceptionDupes()
{
Assert.That(() => new ServicesContainerMutableT<object>(new List<object> { new MyTypeA(), new MyTypeB(), new MyTypeA() }, typeof(MyTypeB).FullName), Throws.InstanceOf<Exception>());
}
[Test]
public void TestCtorExceptionActiveNotFound()
{
Assert.That(() => new ServicesContainerMutableT<object>(new List<object> { new MyTypeA(), new MyTypeB() }, "MyTypeF"), Throws.InstanceOf<ArgumentException>());
}
[Test]
public void TestSetActive2()
{
var container = new ServicesContainerMutableT<object>(new List<object> { new MyTypeA(), new MyTypeB() }, typeof(MyTypeB).FullName);
container.SetActive(typeof(MyTypeA).FullName);
Assert.That(container.Active.GetType().FullName, Is.EqualTo("TestShareeLib.Services.TestServicesContainerMutable+MyTypeA"));
}
}
}

View file

@ -29,7 +29,7 @@
<ItemGroup>
<PackageReference Include="NSubstitute" Version="5.0.0" />
<PackageReference Include="NUnit" Version="3.13.3" />
<PackageReference Include="NUnit3TestAdapter" Version="4.3.1" />
<PackageReference Include="NUnit3TestAdapter" Version="4.4.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.5.0" />
<PackageReference Include="Xamarin.Essentials" Version="1.7.5" />
</ItemGroup>

View file

@ -0,0 +1,265 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using NSubstitute;
using NUnit.Framework;
using Plugin.BLE.Abstractions.Contracts;
using TestFramework.Model.Device;
using TestFramework.Model.Services.Geolocation;
using TestFramework.Model.User.Account;
using TestFramework.Repository;
using TestFramework.Services.BluetoothLock;
using TestFramework.Services.CopriApi.Connector;
using TINK.Model;
using TINK.Model.Connector;
using TINK.Model.Services.CopriApi;
using TINK.Model.Settings;
using TINK.Repository;
using TINK.Repository.Exception;
using TINK.Services;
using TINK.Services.Geolocation;
using TINK.Services.Permissions;
using TINK.View;
using TINK.ViewModel.Account;
using TINK.ViewModel.Map;
using TINK.ViewModel.Settings;
using static TINK.Repository.CopriCallsMemory;
namespace TestTINKLib.Fixtures.ObjectTests.Account
{
public class TestAccountPageViewModel
{
[Test]
public void TestConstruct_NotLoggedIn()
{
const string MERCH_ID = "MyMerchId";
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
activeLockService: typeof(LocksServiceMock).FullName,
activeGeolocationService: typeof(GeolocationMock).FullName),
new StoreMock(),
isConnectedFunc: () => true,
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(new AppContextInfo(MERCH_ID, "MyApp", new Version(1, 2)), null /*UI language */, sessionCookie, mail, server: new CopriCallsMemory(MERCH_ID, SampleSets.Set2, 1, sessionCookie)),
merchantId: MERCH_ID,
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: new LocksServiceMock(), // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
cipher: null,
theme: null,
postAction: (d, obj) => d(obj),
currentVersion: new Version(3, 2, 0, 115), // Current app version
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
whatsNewShownInVersion: null); // Whats new page was never shown.
var viewService = Substitute.For<IViewService>();
var settingsPageViewModel = new AccountPageViewModel(
tinkApp,
(uri) => { },
viewService);
Assert.AreEqual("No user logged in.", settingsPageViewModel.LoggedInInfo);
Assert.IsFalse(settingsPageViewModel.IsBookingStateInfoVisible, "No user logged in.");
Assert.AreEqual(string.Empty, settingsPageViewModel.BookingStateInfo);
}
[Test]
public async Task TestConstruct()
{
const string MERCH_ID = "MyMerchId";
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
activeLockService: typeof(LocksServiceMock).FullName,
activeGeolocationService: typeof(GeolocationMock).FullName),
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", false, "UnknownCookie", new List<string> { "TINK" })),
isConnectedFunc: () => true,
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(new AppContextInfo(MERCH_ID, "MyApp", new Version(1, 2)), null /*UI language */, sessionCookie, mail, server: new CopriCallsMemory(MERCH_ID, SampleSets.Set2, 1, sessionCookie)),
merchantId: MERCH_ID,
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: new LocksServiceMock(), // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
cipher: null,
theme: null,
postAction: (d, obj) => d(obj),
currentVersion: new Version(3, 2, 0, 115), // Current app version
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
whatsNewShownInVersion: null); // Whats new page was never shown.
var viewService = Substitute.For<IViewService>();
var settingsPageViewModel = new AccountPageViewModel(
tinkApp,
(uri) => { },
viewService);
await settingsPageViewModel.OnAppearing();
Assert.AreEqual("Logged in as a@b.", settingsPageViewModel.LoggedInInfo);
Assert.IsFalse(settingsPageViewModel.IsBookingStateInfoVisible, "A user is logged but no bikes requested/ booked.");
Assert.AreEqual(string.Empty, settingsPageViewModel.BookingStateInfo);
}
[Test]
public async Task TestConstruct_TwoBikes()
{
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
activeLockService: typeof(LocksServiceMock).FullName,
activeGeolocationService: typeof(GeolocationMock).FullName),
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", false, "6103_112e96b36ba33de245943c5ffaf369cd_", new List<string> { "TINK" })),
isConnectedFunc: () => true,
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(new AppContextInfo("MyMerchId", "MyApp", new Version(1, 2)), null /*UI language */, sessionCookie, mail, server: new CopriCallsMemory001(sessionCookie)),
merchantId: "MyMerchId",
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: new LocksServiceMock(), // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
cipher: null,
theme: null,
postAction: (d, obj) => d(obj),
currentVersion: new Version(3, 2, 0, 115), // Current app version
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
whatsNewShownInVersion: null); // Whats new page was never shown.
var viewService = Substitute.For<IViewService>();
var settingsPageViewModel = new AccountPageViewModel(
tinkApp,
(uri) => { },
viewService);
await settingsPageViewModel.OnAppearing();
Assert.AreEqual("Logged in as a@b.", settingsPageViewModel.LoggedInInfo);
Assert.IsTrue(settingsPageViewModel.IsBookingStateInfoVisible, "A user is logged but no bikes requested/ booked.");
Assert.AreEqual("Aktuell 2 Fahrräder reserviert/ gebucht.", settingsPageViewModel.BookingStateInfo);
}
[Test]
public async Task TestConstruct_TwoBikes_Offline()
{
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
activeLockService: typeof(LocksServiceMock).FullName,
activeGeolocationService: typeof(GeolocationMock).FullName),
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", false, "6103_112e96b36ba33de245943c5ffaf369cd_", new List<string> { "TINK" })),
isConnectedFunc: () => false,
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(new AppContextInfo("MyMerchId", "MyApp", new Version(1, 2)), null /*UI language */, sessionCookie, mail, server: new CopriCallsMemory001(sessionCookie)),
merchantId: "MyMerchId",
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: new LocksServiceMock(), // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
cipher: null, // Offline
theme: null,
postAction: (d, obj) => d(obj),
currentVersion: new Version(3, 2, 0, 115), // Current app version
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
whatsNewShownInVersion: null); // Whats new page was never shown.
var viewService = Substitute.For<IViewService>();
var settingsPageViewModel = new AccountPageViewModel(
tinkApp,
(uri) => { },
viewService);
await settingsPageViewModel.OnAppearing();
Assert.AreEqual("Logged in as a@b.", settingsPageViewModel.LoggedInInfo);
Assert.IsTrue(settingsPageViewModel.IsBookingStateInfoVisible, "A user is logged but no bikes requested/ booked.");
Assert.AreEqual("Aktuell 2 Fahrräder reserviert/ gebucht. Verbindungsstatus: Offline.", settingsPageViewModel.BookingStateInfo);
}
[Test]
public async Task TestConstruct_TwoBikes_WebConnectCommunicationError()
{
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
activeLockService: typeof(LocksServiceMock).FullName,
activeGeolocationService: typeof(GeolocationMock).FullName),
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", false, "6103_112e96b36ba33de245943c5ffaf369cd_", new List<string> { "TINK" })),
isConnectedFunc: () => false,
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new TINK.Model.Connector.Connector(
uri,
new AppContextInfo("oiF2kahH", "sharee.bike.test", new Version(3, 0, 267)),
null /*UI language */,
sessionCookie,
mail,
server: new CopriProviderHttps(
uri,
TinkApp.MerchantId,
new AppContextInfo("oiF2kahH", "sharee.bike.test", new Version(3, 0, 267)),
null /*UI language */,
sessionCookie: sessionCookie,
cacheServer: new CopriCallsCacheMemory001(sessionCookie: sessionCookie),
httpsServer: new ExceptionServer((msg) => new WebConnectFailureException(msg, new Exception("Source expection."))))),
merchantId: "MyMerchId",
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: new LocksServiceMock(), // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
cipher: null, // Offline
theme: null,
postAction: (d, obj) => d(obj),
currentVersion: new Version(3, 2, 0, 115), // Current app version
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
whatsNewShownInVersion: null); // Whats new page was never shown.
var viewService = Substitute.For<IViewService>();
var settingsPageViewModel = new AccountPageViewModel(
tinkApp,
(uri) => { },
viewService);
await settingsPageViewModel.OnAppearing();
Assert.AreEqual("Logged in as a@b.", settingsPageViewModel.LoggedInInfo); // CopriCallsCacheMemory(SampleSets.Set2,
Assert.IsTrue(settingsPageViewModel.IsBookingStateInfoVisible, "A user is logged but no bikes requested/ booked.");
Assert.AreEqual("Aktuell 2 Fahrräder reserviert/ gebucht. Verbindungsstatus: Offline.", settingsPageViewModel.BookingStateInfo);
}
}
}

View file

@ -0,0 +1,239 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
using TestFramework.Model.User.Account;
using TINK.Model.Bikes.BikeInfoNS.BikeNS;
using TINK.Model.Bikes.BikeInfoNS.DriveNS;
using TINK.Model.Device;
using TINK.Model.State;
using TINK.Model.User;
using TINK.Model.User.Account;
using TINK.ViewModel;
using TINK.ViewModel.Bikes;
using Xamarin.Forms;
namespace UITest.Fixtures.ViewModel
{
[TestFixture]
public class TestBikeAtStationViewModel
{
private class BikeInfoMutable : TINK.Model.Bikes.BikeInfoNS.BC.BikeInfoMutable
{
public BikeInfoMutable(
string id,
LockModel lockModel,
bool isDemo = false,
IEnumerable<string> group = null,
WheelType? wheelType = null,
TypeOfBike? typeOfBike = null,
string description = null,
string stationId = null,
string stationName = null,
Uri operatorUri = null,
Func<DateTime> dateTimeProvider = null,
IStateInfo stateInfo = null) : base(
new Bike(id, lockModel, wheelType, typeOfBike, description),
new Drive(),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
isDemo,
group,
stationId,
stationName,
operatorUri,
null,
dateTimeProvider,
stateInfo)
{
}
}
/// <summary>
/// Tests base class functionaltiy by using child.
/// </summary>
[Test]
public void TestStateText_NotLoggedIn()
{
var l_oBike = new BikeInfoMutable("2", LockModel.ILockIt, false, new List<string> { "TINK" }, WheelType.Two, TypeOfBike.Cargo);
var l_oStoreMock = new StoreMock(); // Account without user name, password and cookie
var l_oUser = new User(
l_oStoreMock,
l_oStoreMock.Load().Result,
"123456789"); // Device identifier
// Verify prerequisites
Assert.AreEqual(InUseStateEnum.Disposable, l_oBike.State.Value);
Assert.IsFalse(l_oUser.IsLoggedIn);
// Verify view model.
var l_oViewModel = new TINK.ViewModel.Bikes.Bike.BC.BikeViewModel(
null,
null,
null,
null,
NSubstitute.Substitute.For<ISmartDevice>(),
null,
l_oBike,
l_oUser,
new MyBikeInUseStateInfoProvider(),
NSubstitute.Substitute.For<IBikesViewModel>(),
url => { });
Assert.AreEqual("2", l_oViewModel.Name);
Assert.AreEqual("", l_oViewModel.DisplayId);
Assert.AreEqual("2", l_oViewModel.Id);
Assert.AreEqual("Available.", l_oViewModel.StateText);
Assert.AreEqual(Color.Default, l_oViewModel.StateColor);
}
/// <summary>
/// Tests base class functionaltiy by using child.
/// </summary>
[Test]
public void TestStateText_LoggedIn_Reserved()
{
var l_oViewModel = TestBikeViewModel.TestStateText_LoggedIn_Reserved(
(bike, user) => new TINK.ViewModel.Bikes.Bike.BC.BikeViewModel(
null,
null,
null,
null,
NSubstitute.Substitute.For<ISmartDevice>(),
null,
bike,
user,
new BikeAtStationInUseStateInfoProvider(),
NSubstitute.Substitute.For<IBikesViewModel>(),
url => { }));
Assert.AreEqual("Still 15 min. reserved.", l_oViewModel.StateText);
}
/// <summary>
/// Tests base class functionaltiy by using child.
/// </summary>
[Test]
public void TestStateText_LoggedIn_ReservedWithCopriConnect()
{
var l_oViewModel = TestBikeViewModel.TestStateText_LoggedIn_ReservedWithCopriConnect(
(bike, user) => new TINK.ViewModel.Bikes.Bike.BC.BikeViewModel(
null,
null,
null,
null,
NSubstitute.Substitute.For<ISmartDevice>(),
null,
bike,
user,
new BikeAtStationInUseStateInfoProvider(),
NSubstitute.Substitute.For<IBikesViewModel>(),
url => { }));
Assert.AreEqual("Code 4asdfA, still 7 min. reserved.", l_oViewModel.StateText);
}
/// <summary>
/// Tests base class functionaltiy by using child.
/// </summary>
[Test]
public void TestStateText_LoggedIn_Booked()
{
var l_oViewModel = TestBikeViewModel.TestStateText_LoggedIn_Booked(
(bike, user) => new TINK.ViewModel.Bikes.Bike.BC.BikeViewModel(
null,
null,
null,
null,
NSubstitute.Substitute.For<ISmartDevice>(),
null,
bike,
user,
new BikeAtStationInUseStateInfoProvider(),
NSubstitute.Substitute.For<IBikesViewModel>(),
url => { }));
Assert.AreEqual(
$"Code 4asdfA, rented since {new DateTime(2018, 10, 24, 21, 49, 00).ToString("dd. MMMM HH:mm")}.",
l_oViewModel.StateText);
}
/// <summary>
/// Tests base class functionaltiy by using child.
/// </summary>
[Test]
public void TestStateText_LoggedIn_ReservedBySomeoneElse()
{
var l_oBike = new BikeInfoMutable("2", LockModel.ILockIt, false, new List<string> { "TINK" }, WheelType.Two, TypeOfBike.Cargo, "Test description", "3");
l_oBike.State.Load(
InUseStateEnum.Reserved,
new DateTime(2017, 10, 24, 21, 49, 3),
"ragu@gnu-systems.de",
"4asdfA");
var l_oStoreMock = new StoreMock(new Account("john@long", "123456789" /* password */, false, "987654321" /* session cookie */, new List<string> { "TINK" }));
var l_oViewModel = new TINK.ViewModel.Bikes.Bike.BC.BikeViewModel(
null,
null,
null,
null,
NSubstitute.Substitute.For<ISmartDevice>(),
null,
l_oBike,
new User(
l_oStoreMock,
l_oStoreMock.Load().Result,
"123456789"), // Device id
new BikeAtStationInUseStateInfoProvider(),
NSubstitute.Substitute.For<IBikesViewModel>(),
url => { });
Assert.AreEqual("Test description", l_oViewModel.Name);
Assert.AreEqual("2", l_oViewModel.DisplayId);
Assert.AreEqual("2", l_oViewModel.Id);
Assert.AreEqual("Fahrrad bereits reserviert durch anderen Nutzer.", l_oViewModel.StateText);
Assert.AreEqual(Color.Red, l_oViewModel.StateColor);
}
/// <summary>
/// Tests base class functionaltiy by using child.
/// </summary>
[Test]
public void TestStateText_LoggedIn_BookedBySomeoneElse()
{
var l_oBike = new BikeInfoMutable("2", LockModel.ILockIt, false, new List<string> { "TINK" }, WheelType.Two, TypeOfBike.Cargo, "Test description", "3");
l_oBike.State.Load(
InUseStateEnum.Booked,
new DateTime(2017, 10, 24, 21, 49, 3),
"ragu@gnu-systems.de",
"4asdfA");
var l_oStoreMock = new StoreMock(new Account("john@long", "123456789" /* password */, false, "987654321" /* session cookie */, new List<string> { "TINK" }));
var l_oViewModel = new TINK.ViewModel.Bikes.Bike.BC.BikeViewModel(
null,
null,
null,
null,
NSubstitute.Substitute.For<ISmartDevice>(),
null,
l_oBike,
new User(
l_oStoreMock,
l_oStoreMock.Load().Result,
"123456789"),
new BikeAtStationInUseStateInfoProvider(),
NSubstitute.Substitute.For<IBikesViewModel>(),
url => { });
Assert.AreEqual("Test description", l_oViewModel.Name);
Assert.AreEqual("2", l_oViewModel.DisplayId);
Assert.AreEqual("2", l_oViewModel.Id);
Assert.AreEqual("Fahrrad bereits gebucht durch anderen Nutzer.", l_oViewModel.StateText);
Assert.AreEqual(Color.Red, l_oViewModel.StateColor);
}
}
}

View file

@ -0,0 +1,88 @@
using System;
using NSubstitute;
using NUnit.Framework;
using TINK.Model.Device;
using TINK.ViewModel;
using TINK.ViewModel.Bikes;
namespace UITest.Fixtures.ViewModel
{
[TestFixture]
public class TestMyBikesPageViewModel
{
/// <summary>
/// Tests base class functionaltiy by using child.
/// </summary>
[Test]
public void TestStateText_LoggedIn_Reserved()
{
var l_oViewModel = TestBikeViewModel.TestStateText_LoggedIn_Reserved(
(bike, user) => new TINK.ViewModel.Bikes.Bike.BC.BikeViewModel(
null,
null,
null,
null,
Substitute.For<ISmartDevice>(),
null,
bike,
user,
new MyBikeInUseStateInfoProvider(),
Substitute.For<IBikesViewModel>(),
url => { }));
Assert.AreEqual("Location Station 3, still 15 min. reserved.", l_oViewModel.StateText);
}
/// <summary>
/// Tests base class functionaltiy by using child.
/// </summary>
[Test]
public void TestStateText_LoggedIn_ReservedWithCopriConnect()
{
var l_oViewModel = TestBikeViewModel.TestStateText_LoggedIn_ReservedWithCopriConnect(
(bike, user) => new TINK.ViewModel.Bikes.Bike.BC.BikeViewModel(
null,
null,
null,
null,
Substitute.For<ISmartDevice>(),
null,
bike,
user,
new MyBikeInUseStateInfoProvider(),
Substitute.For<IBikesViewModel>(),
url => { }));
Assert.AreEqual("Code 4asdfA, location Station 3, still 7 min. reserved.", l_oViewModel.StateText);
}
/// <summary>
/// Tests base class functionaltiy by using child.
/// </summary>
///
[Test]
public void TestStateText_LoggedIn_Booked()
{
var l_oViewModel = TestBikeViewModel.TestStateText_LoggedIn_Booked(
(bike, user) => new TINK.ViewModel.Bikes.Bike.BC.BikeViewModel(
null,
null,
null,
null,
Substitute.For<ISmartDevice>(),
null,
bike,
user,
new MyBikeInUseStateInfoProvider(),
Substitute.For<IBikesViewModel>(),
url => { }));
Assert.AreEqual(
$"Code 4asdfA, location Station 3, rented since {new DateTime(2018, 10, 24, 21, 49, 00).ToString("dd. MMMM HH:mm")}.",
l_oViewModel.StateText);
}
}
}

View file

@ -1,8 +1,10 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using NSubstitute;
using NSubstitute.ExceptionExtensions;
using NUnit.Framework;
using TINK.Model;
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
@ -37,7 +39,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
Substitute.For<IBikeInfoMutable>(),
() => true, // isConnectedDelegate
(isConnexted) => Substitute.For<IConnector>(),
Substitute.For<IGeolocation>(),
Substitute.For<IGeolocationService>(),
Substitute.For<ILocksService>(),
() => Substitute.For<IPollingUpdateTaskManager>(),
Substitute.For<ISmartDevice>(),
@ -46,14 +48,140 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
Substitute.For<IUser>());
// Verify prerequisites.
//Assert.AreEqual("Return bike", handler.ButtonText);
//Assert.AreEqual("End rental", handler.ButtonText);
//Assert.IsTrue(handler.IsButtonVisible);
Assert.AreEqual("Open lock", handler.LockitButtonText);
Assert.IsTrue(handler.IsLockitButtonVisible);
}
/// <summary>
/// Use case: Return bike.
/// Use case: End rental.
/// Final state: Booked, lock state unknown.
/// </summary>
/// <remarks> Replaces test TestReturnOutOfReach which was removed for sharee.bike verion ~3.0.362. </remarks>
[Test]
public void TestReturnLastGeolocatonNullLockOfOfReach()
{
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 pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
var bikesViewModel = Substitute.For<IBikesViewModel>();
var activeUser = Substitute.For<IUser>();
var handler = new BookedClosed(
bike,
() => true, // isConnectedDelegate
(isConnexted) => connector,
geolocation,
locks,
() => pollingManager,
Substitute.For<ISmartDevice>(),
viewService,
bikesViewModel,
activeUser);
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);
var subsequent = handler.HandleRequestOption1().Result;
// Verify behaviour
Received.InOrder(() =>
{
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
locks[0].GetDeviceState();
viewService.DisplayAlert(
"Error at ending rental!",
"We could not assign the bike to any station. For this we need your location information while you are standing right next to the bike. Only then your rental can be terminated!\r\n\r\nApproach the bike, turn on Bluetooth and Location services and try again.",
"OK");
bikesViewModel.ActionText = "Disconnecting lock...";
locks.DisconnectAsync(0, Arg.Any<Guid>());
bikesViewModel.ActionText = string.Empty;
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state after action
Assert.AreEqual("BookedDisconnected", subsequent.ButtonText);
Assert.IsFalse(subsequent.IsButtonVisible);
Assert.AreEqual("Search lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
/// <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 connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
var bikesViewModel = Substitute.For<IBikesViewModel>();
var activeUser = Substitute.For<IUser>();
var handler = new BookedClosed(
bike,
() => true, // isConnectedDelegate
(isConnexted) => connector,
geolocation,
locks,
() => pollingManager,
Substitute.For<ISmartDevice>(),
viewService,
bikesViewModel,
activeUser);
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.
var subsequent = handler.HandleRequestOption1().Result;
// Verify behaviour
Received.InOrder(() =>
{
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
locks[0].GetDeviceState();
bikesViewModel.ActionText = "Start query location...";
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>());
viewService.DisplayAlert(
"Error at ending rental!",
"End rental at an unknown location is not possible.\r\nStart getting geolocation failed.",
"OK");
bikesViewModel.ActionText = string.Empty;
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state after action
Assert.AreEqual("End rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
/// <summary>
/// Use case: End rental.
/// Comment: User deceide to abort returning bike
/// Final state: Same as initial state.
/// </summary>
@ -63,7 +191,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -84,7 +212,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(false));
viewService.DisplayAlert(string.Empty, "End rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(false));
var subsequent = handler.HandleRequestOption1().Result;
@ -94,28 +222,28 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
Received.InOrder(() =>
{
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
viewService.DisplayAlert(string.Empty, "Return bike Nr. 0?", "Yes", "No");
viewService.DisplayAlert(string.Empty, "End rental of bike Nr. 0?", "Yes", "No");
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state after action
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("End rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
/// <summary>
/// Use case: Return bike.
/// Final state: Disposable closed
/// Use case: End rental.
/// Final state: Booked, lock state unknown.
/// </summary>
[Test]
public void TestReturnOutOfReach()
public void TestReturnGetGeolocationException()
{
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -136,11 +264,14 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
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[0].GetDeviceState().Returns(DeviceState.Connected); // Simulate bike in reach.
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
viewService.DisplayAlert(string.Empty, "End rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>())
.Returns(Task.FromException<IGeolocation>(new Exception("Ups..."))); // Simulate error starting query for geolocation.
var subsequent = handler.HandleRequestOption1().Result;
@ -148,27 +279,27 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
Received.InOrder(() =>
{
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Returning bike...";
connector.Command.DoReturn(bike, Arg.Is<LocationDto>(x => x == null));
bikesViewModel.ActionText = "Disconnecting lock...";
locks.DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>());
locks[0].GetDeviceState();
bikesViewModel.ActionText = "Start query location...";
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>());
viewService.DisplayAlert(
"Error at ending rental!",
"End rental at an unknown location is not possible.\r\nGetting geolocation failed.",
"OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state after action
Assert.AreEqual("Reserve bike", subsequent.ButtonText);
Assert.AreEqual("End rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("DisposableDisconnected", subsequent.LockitButtonText);
Assert.IsFalse(subsequent.IsLockitButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
/// <summary>
/// Use case: Return bike.
/// Use case: End rental.
/// Final state: Disposable closed
/// </summary>
[Test]
@ -177,7 +308,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -196,15 +327,21 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel,
activeUser);
bike.LockInfo.Location.Returns((IGeolocation)null);
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
viewService.DisplayAlert(string.Empty, "End rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
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);
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>()).Returns(Task.FromResult(
new Xamarin.Essentials.Location(7, 9)
));
location
)); ;
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
bike.LockInfo.State.Returns(LockingState.Closed); // Requsthandler factory queries lock state to create appropriate request handler object.
@ -219,7 +356,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Query location...";
bikesViewModel.ActionText = "Returning bike...";
bikesViewModel.ActionText = "Ending rental...";
connector.Command.DoReturn(bike, Arg.Is<LocationDto>(x => x != null));
bikesViewModel.ActionText = "Disconnecting lock...";
locks.DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>());
@ -237,74 +374,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
}
/// <summary>
/// Use case: Return bike.
/// Final state: Disposable closed
/// </summary>
[Test]
public void TestReturnLockInReachNoGeolocation()
{
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
var bikesViewModel = Substitute.For<IBikesViewModel>();
var activeUser = Substitute.For<IUser>();
var handler = new BookedClosed(
bike,
() => true, // isConnectedDelegate
(isConnexted) => connector,
geolocation,
locks,
() => pollingManager,
Substitute.For<ISmartDevice>(),
viewService,
bikesViewModel,
activeUser);
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
locks[0].GetDeviceState().Returns(DeviceState.Connected); // Simulate bike in reach. If bike is out of reach bluetooth state changes to unknown.
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>()).Returns<Xamarin.Essentials.Location>(x => throw new Exception());
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
bike.LockInfo.State.Returns(LockingState.Closed); // Requsthandler factory queries lock state to create appropriate request handler object.
var subsequent = handler.HandleRequestOption1().Result;
// Verify behaviour
Received.InOrder(() =>
{
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>());
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Query location...";
bikesViewModel.ActionText = "Returning bike...";
connector.Command.DoReturn(bike, Arg.Is<LocationDto>(x => x == null));
bikesViewModel.ActionText = "Disconnecting lock...";
locks.DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>());
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
bikesViewModel.Received(1).IsIdle = true; // GUI must be unlocked
});
// Verify state after action
Assert.AreEqual("Reserve bike", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("DisposableDisconnected", subsequent.LockitButtonText);
Assert.IsFalse(subsequent.IsLockitButtonVisible);
}
/// <summary>
/// Use case: Return bike.
/// Use case: End rental.
/// Final state: Same as initial state.
/// </summary>
[Test]
@ -313,7 +383,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -334,7 +404,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
viewService.DisplayAlert(string.Empty, "End rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
locks[0].GetDeviceState().Returns(DeviceState.Connected); // Simulate bike in reach. If bike is out of reach bluetooth state changes to unknown.
@ -355,12 +425,12 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Returning bike...";
bikesViewModel.ActionText = "Ending rental...";
connector.Command.DoReturn(bike, Arg.Any<LocationDto>());
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAdvancedAlert(
"Connection error when returning the bike!",
"Internet must be available when returning the bike.\r\nIs WIFI available/ mobile network available and mobile data activated / ... ?",
"Connection error when ending rental.",
"Internet must be available when ending rental. Please establish an Internet connection!\r\nIs WIFI/mobile network available and mobile data activated?",
"Context info",
"OK");
bikesViewModel.ActionText = "Updating...";
@ -370,14 +440,14 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state after action
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.AreEqual("End rental", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
/// <summary>
/// Use case: Return bike.
/// Use case: End rental.
/// Final state: Same as initial state.
/// </summary>
[Test]
@ -386,7 +456,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -407,7 +477,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
viewService.DisplayAlert(string.Empty, "End rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
locks[0].GetDeviceState().Returns(DeviceState.Connected); // Simulate bike in reach. If bike is out of reach bluetooth state changes to unknown.
@ -429,10 +499,10 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Returning bike...";
bikesViewModel.ActionText = "Ending rental...";
connector.Command.DoReturn(bike, Arg.Any<LocationDto>());
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert("Error returning bike!", "Returning bike outside of station is not possible. Distance to station 42 is 15986 m.", "OK");
viewService.DisplayAlert("Error at ending rental!", "End rental outside of station is not possible. Distance to station 42 is 15986 m.", "OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -440,14 +510,14 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state after action
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.AreEqual("End rental", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
/// <summary>
/// Use case: Return bike.
/// Use case: End rental.
/// Final state: Same as initial state.
/// </summary>
[Test]
@ -456,7 +526,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -477,7 +547,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
viewService.DisplayAlert(string.Empty, "End rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
locks[0].GetDeviceState().Returns(DeviceState.Connected); // Simulate bike in reach. If bike is out of reach bluetooth state changes to unknown.
@ -499,10 +569,10 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Returning bike...";
bikesViewModel.ActionText = "Ending rental...";
connector.Command.DoReturn(bike, Arg.Any<LocationDto>());
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert("Error returning bike!", "Returning bike at an unknown location is not possible.\r\nBike can be returned if\r\n- location information is available when closing lock\r\n- bike is in reach and location information is available when pressing button \"Return bike\"", "OK");
viewService.DisplayAlert("Error at ending rental!", "End rental at an unknown location is not possible.\r\nRental can be ended if\r\n- location information is available when closing lock\r\n- bike is in reach and location information is available when pressing button \"End rental\"", "OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -510,14 +580,14 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state after action
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.AreEqual("End rental", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
/// <summary>
/// Use case: Return bike.
/// Use case: End rental.
/// Final state: Same as initial state.
/// </summary>
[Test]
@ -526,7 +596,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -547,7 +617,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
viewService.DisplayAlert(string.Empty, "End rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
locks[0].GetDeviceState().Returns(DeviceState.Connected); // Simulate bike in reach. If bike is out of reach bluetooth state changes to unknown.
@ -567,7 +637,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Returning bike...";
bikesViewModel.ActionText = "Ending rental...";
connector.Command.DoReturn(bike, Arg.Any<LocationDto>());
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAdvancedAlert("Statusfehler beim Zurückgeben des Rads!", "Outer message.", "Some invalid data received!", "OK");
@ -578,14 +648,14 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state after action
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.AreEqual("End rental", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
}
/// <summary>
/// Use case: Return bike.
/// Use case: End rental.
/// Final state: Same as initial state.
/// </summary>
[Test]
@ -594,7 +664,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -615,7 +685,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
viewService.DisplayAlert(string.Empty, "End rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
locks[0].GetDeviceState().Returns(DeviceState.Connected); // Simulate bike in reach. If bike is out of reach bluetooth state changes to unknown.
@ -634,10 +704,10 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Returning bike...";
bikesViewModel.ActionText = "Ending rental...";
connector.Command.DoReturn(bike, Arg.Any<LocationDto>());
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert("Error returning bike!", "Exception message.", "OK");
viewService.DisplayAlert("Error at ending rental!", "Exception message.", "OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -645,7 +715,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state after action
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.AreEqual("End rental", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -661,7 +731,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -706,7 +776,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -722,7 +792,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -782,7 +852,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -843,7 +913,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -887,7 +957,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.AreEqual("End rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -903,7 +973,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -939,7 +1009,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.ActionText = "<h4><b>Lock is opening.<br/>Please wait until it is completely open.</b></h4>";
locks.Received()[0].OpenAsync(); // Lock must be closed
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert("Lock can not be opened!", "The lock could not be opened correctly. Please try again.\r\n\r\nAttention! Your rental has already started.\r\n\r\nIf the lock still won't open, make sure the lock is closed and return the bike. Please report it to the support!", "OK");
viewService.DisplayAlert("Lock can not be opened!", "The lock could not be opened correctly. Try again!\r\n\r\nAttention! Your rental has already started.\r\nIf the lock still won't open, make sure the lock is closed and end rental.\r\nImportant: Send an email to the operator (otherwise your paid rental will continue!) with: Problem description, bike number, drop-off station.", "OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -963,7 +1033,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -1023,7 +1093,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -1071,7 +1141,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -1087,7 +1157,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -1135,7 +1205,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -1151,7 +1221,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -1192,7 +1262,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
locks[0].GetBatteryPercentageAsync();
bikesViewModel.ActionText = "Updating lock state...";
connector.Command.UpdateLockingStateAsync(bike, null);
bikesViewModel.ActionText = "No web error on updating locking status.";
bikesViewModel.ActionText = "Internet must be available for updating lock status. Please establish an Internet connection!";
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -1200,7 +1270,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -1216,7 +1286,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -1265,7 +1335,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -1281,7 +1351,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -1331,7 +1401,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);

View file

@ -32,7 +32,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
Substitute.For<IBikeInfoMutable>(),
() => true, // isConnectedDelegate
(isConnexted) => Substitute.For<IConnector>(),
Substitute.For<IGeolocation>(),
Substitute.For<IGeolocationService>(),
Substitute.For<ILocksService>(),
() => Substitute.For<IPollingUpdateTaskManager>(),
Substitute.For<ISmartDevice>(),
@ -53,7 +53,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -91,7 +91,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -137,7 +137,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -153,7 +153,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -187,7 +187,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Request server...";
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert("Error when connecting with lock!", "Internet must be reachable to connect to lock of rented bike.\r\nContext info\r\nIs WIFI available/ mobile network available and mobile data activated / ... ?", "OK");
viewService.DisplayAlert("Error when connecting with lock!", "Internet must be reachable to connect to lock of rented bike. Please establish an Internet connection!\r\nContext info\r\nIs WIFI/mobile network available and mobile data activated?", "OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -211,7 +211,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -269,7 +269,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -336,7 +336,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -404,7 +404,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();

View file

@ -21,7 +21,7 @@ using TINK.View;
using TINK.ViewModel;
using TINK.ViewModel.Bikes;
using TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler;
using Xamarin.Essentials;
using Geolocation = TINK.Services.Geolocation.Geolocation;
namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
{
@ -38,7 +38,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
Substitute.For<IBikeInfoMutable>(),
() => true, // isConnectedDelegate
(isConnexted) => Substitute.For<IConnector>(),
Substitute.For<IGeolocation>(),
Substitute.For<IGeolocationService>(),
Substitute.For<ILocksService>(),
() => Substitute.For<IPollingUpdateTaskManager>(),
Substitute.For<ISmartDevice>(),
@ -47,7 +47,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
Substitute.For<IUser>());
// Verify prerequisites.
Assert.AreEqual("Close lock & return bike", handler.ButtonText);
Assert.AreEqual("Close lock & end rental", handler.ButtonText);
Assert.IsTrue(handler.IsButtonVisible);
Assert.AreEqual("Close lock", handler.LockitButtonText);
Assert.IsTrue(handler.IsLockitButtonVisible);
@ -65,7 +65,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -84,7 +84,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel,
activeUser);
viewService.DisplayAlert(string.Empty, "Close lock and return bike Nr. 0 Allround Mono?", "Yes", "No").Returns(Task.FromResult(false));
viewService.DisplayAlert(string.Empty, "Close lock and end rental of bike Nr. 0 Allround Mono?", "Yes", "No").Returns(Task.FromResult(false));
var subsequent = handler.HandleRequestOption1().Result;
@ -96,7 +96,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -113,7 +113,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -134,12 +134,16 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Close lock and return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
viewService.DisplayAlert(string.Empty, "Close lock and end rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
locks[0].CloseAsync()
.Returns(Task.FromResult((LockitLockingState?)LockitLockingState.Closed)); // Return lock state indicating success
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>()).Returns(Task.FromResult(new Location(1, 2)));
var location = Substitute.For<IGeolocation>();
location.Latitude.Returns(1);
location.Longitude.Returns(2);
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>()).Returns(Task.FromResult(location));
bike.State.Value.Returns(InUseStateEnum.Disposable); // Return call leads to setting of state to disposable.
@ -152,12 +156,12 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>()); // Geolocation must be retrieved
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Starting bike return...";
bikesViewModel.ActionText = "Starting end rental...";
connector.Command.StartReturningBike(bike); // Notify about start
bikesViewModel.ActionText = "<h4><b>Lock is closing.<br/>Please wait until it is completely closed.</b></h4>";
locks.Received()[0].CloseAsync(); // Lock must be closed
bikesViewModel.ActionText = "Query location...";
bikesViewModel.ActionText = "Returning bike...";
bikesViewModel.ActionText = "Ending rental...";
connector.Command.DoReturn(bike, Arg.Is<LocationDto>(x => x.Latitude == 1 && x.Longitude == 2), Arg.Any<ISmartDevice>()); // Booking must be performed
bikesViewModel.ActionText = "Disconnecting lock...";
locks.DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>());
@ -184,7 +188,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -205,7 +209,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Close lock and return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
viewService.DisplayAlert(string.Empty, "Close lock and end rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
locks[0].CloseAsync()
.Returns<LockitLockingState?>(x => throw new OutOfReachException());
@ -224,7 +228,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>());
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Starting bike return...";
bikesViewModel.ActionText = "Starting end rental...";
connector.Command.StartReturningBike(bike); // Notify about start
bikesViewModel.ActionText = "<h4><b>Lock is closing.<br/>Please wait until it is completely closed.</b></h4>";
locks.Received()[0].CloseAsync(); // Lock must be closed
@ -251,7 +255,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -272,7 +276,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Close lock and return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
viewService.DisplayAlert(string.Empty, "Close lock and end rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
connector.Command.StartReturningBike(bike).Returns(x => throw new WebConnectFailureException("Context info", new Exception("hoppla")));
@ -291,12 +295,12 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>());
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Starting bike return...";
bikesViewModel.ActionText = "Starting end rental...";
connector.Command.StartReturningBike(bike); // Notify about start
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAdvancedAlert(
"Connection error when returning the bike!",
"Internet must be available when returning the bike.\r\nIs WIFI available/ mobile network available and mobile data activated / ... ?",
"Connection error when ending rental.",
"Internet must be available when ending rental. Please establish an Internet connection!\r\nIs WIFI/mobile network available and mobile data activated?",
"Context info",
"OK");
bikesViewModel.ActionText = "Updating...";
@ -306,7 +310,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -318,7 +322,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -339,7 +343,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Close lock and return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
viewService.DisplayAlert(string.Empty, "Close lock and end rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
connector.Command.StartReturningBike(bike).Returns(x => throw new Exception("Context info", new Exception("hoppla")));
@ -358,11 +362,11 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>());
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Starting bike return...";
bikesViewModel.ActionText = "Starting end rental...";
connector.Command.StartReturningBike(bike); // Notify about start
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert(
"Error returning bike!",
"Error at ending rental!",
"Context info",
"OK");
bikesViewModel.ActionText = "Updating...";
@ -372,7 +376,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -388,7 +392,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -409,7 +413,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Close lock and return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
viewService.DisplayAlert(string.Empty, "Close lock and end rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
locks[0].CloseAsync()
.Returns<LockitLockingState?>(x => throw new Exception("Blu"));
@ -429,7 +433,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>());
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Starting bike return...";
bikesViewModel.ActionText = "Starting end rental...";
connector.Command.StartReturningBike(bike); // Notify about start
bikesViewModel.ActionText = "<h4><b>Lock is closing.<br/>Please wait until it is completely closed.</b></h4>";
locks.Received()[0].CloseAsync(); // Lock must be closed
@ -460,7 +464,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -481,7 +485,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Close lock and return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
viewService.DisplayAlert(string.Empty, "Close lock and end rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
locks[0].CloseAsync()
.Returns<LockitLockingState?>(x => throw new CouldntCloseMovingException());
@ -501,7 +505,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>());
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Starting bike return...";
bikesViewModel.ActionText = "Starting end rental...";
connector.Command.StartReturningBike(bike); // Notify about start
bikesViewModel.ActionText = "<h4><b>Lock is closing.<br/>Please wait until it is completely closed.</b></h4>";
locks.Received()[0].CloseAsync(); // Lock must be closed
@ -519,7 +523,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -535,7 +539,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -556,7 +560,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Close lock and return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
viewService.DisplayAlert(string.Empty, "Close lock and end rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
locks[0].CloseAsync()
.Returns(LockitLockingState.Open);
@ -575,7 +579,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>());
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Starting bike return...";
bikesViewModel.ActionText = "Starting end rental...";
connector.Command.StartReturningBike(bike); // Notify about start
bikesViewModel.ActionText = "<h4><b>Lock is closing.<br/>Please wait until it is completely closed.</b></h4>";
locks.Received()[0].CloseAsync(); // Lock must be closed
@ -590,7 +594,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -606,7 +610,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -627,12 +631,12 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Close lock and return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
viewService.DisplayAlert(string.Empty, "Close lock and end rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
locks[0].CloseAsync()
.Returns(LockitLockingState.Closed);
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>()).Returns(Task.FromException<Location>(new Exception("noloc")));
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>()).Returns(Task.FromException<IGeolocation>(new Exception("noloc")));
bike.State.Value.Returns(InUseStateEnum.Booked); // Booking state remains unchanged if closing fails.
@ -646,13 +650,13 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.Received(1).IsIdle = false; // GUI must be locked
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Starting bike return...";
bikesViewModel.ActionText = "Starting end rental...";
connector.Command.StartReturningBike(bike); // Notify about start
bikesViewModel.ActionText = "<h4><b>Lock is closing.<br/>Please wait until it is completely closed.</b></h4>";
locks.Received()[0].CloseAsync(); // Lock must be closed
bikesViewModel.ActionText = "Query location...";
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAdvancedAlert("Error Query Location!", "Closing the lock and ending the rental is not possible.", "noloc", "OK");
viewService.DisplayAdvancedAlert("Error query location!", "Closing the lock and ending the rental is not possible.", "noloc", "OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -660,7 +664,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked closed" after action
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.AreEqual("End rental", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -676,7 +680,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -697,7 +701,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Close lock and return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
viewService.DisplayAlert(string.Empty, "Close lock and end rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
locks[0].CloseAsync()
.Returns(LockitLockingState.Closed);
@ -718,16 +722,16 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>());
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Starting bike return...";
bikesViewModel.ActionText = "Starting end rental...";
connector.Command.StartReturningBike(bike); // Notify about start
bikesViewModel.ActionText = "<h4><b>Lock is closing.<br/>Please wait until it is completely closed.</b></h4>";
locks.Received()[0].CloseAsync(); // Lock must be closed
bikesViewModel.ActionText = "Query location...";
bikesViewModel.ActionText = "Returning bike...";
bikesViewModel.ActionText = "Ending rental...";
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAdvancedAlert(
"Connection error when returning the bike!",
"Internet must be available when returning the bike.\r\nIs WIFI available/ mobile network available and mobile data activated / ... ?",
"Connection error when ending rental.",
"Internet must be available when ending rental. Please establish an Internet connection!\r\nIs WIFI/mobile network available and mobile data activated?",
"Context info",
"OK");
bikesViewModel.ActionText = "Updating...";
@ -737,7 +741,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked closed" after action
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.AreEqual("End rental", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -753,7 +757,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -774,7 +778,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Close lock and return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
viewService.DisplayAlert(string.Empty, "Close lock and end rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
locks[0].CloseAsync()
.Returns(LockitLockingState.Closed);
@ -795,14 +799,14 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>());
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Starting bike return...";
bikesViewModel.ActionText = "Starting end rental...";
connector.Command.StartReturningBike(bike); // Notify about start
bikesViewModel.ActionText = "<h4><b>Lock is closing.<br/>Please wait until it is completely closed.</b></h4>";
locks.Received()[0].CloseAsync(); // Lock must be closed
bikesViewModel.ActionText = "Query location...";
bikesViewModel.ActionText = "Returning bike...";
bikesViewModel.ActionText = "Ending rental...";
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert("Error returning bike!", "Exception message.", "OK");
viewService.DisplayAlert("Error at ending rental!", "Exception message.", "OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -810,7 +814,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked closed" after action
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.AreEqual("End rental", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -826,7 +830,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -847,7 +851,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Close lock and return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
viewService.DisplayAlert(string.Empty, "Close lock and end rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
locks[0].CloseAsync()
.Returns(LockitLockingState.Closed);
@ -871,14 +875,14 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>());
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Starting bike return...";
bikesViewModel.ActionText = "Starting end rental...";
connector.Command.StartReturningBike(bike); // Notify about start
bikesViewModel.ActionText = "<h4><b>Lock is closing.<br/>Please wait until it is completely closed.</b></h4>";
locks.Received()[0].CloseAsync(); // Lock must be closed
bikesViewModel.ActionText = "Query location...";
bikesViewModel.ActionText = "Returning bike...";
bikesViewModel.ActionText = "Ending rental...";
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert("Error returning bike!", "Returning bike outside of station is not possible. Distance to station 77 is 15986 m.", "OK");
viewService.DisplayAlert("Error at ending rental!", "End rental outside of station is not possible. Distance to station 77 is 15986 m.", "OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -886,7 +890,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked closed" after action
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.AreEqual("End rental", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -902,7 +906,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -923,7 +927,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Close lock and return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
viewService.DisplayAlert(string.Empty, "Close lock and end rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
locks[0].CloseAsync()
.Returns(LockitLockingState.Closed);
@ -947,14 +951,14 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>());
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Starting bike return...";
bikesViewModel.ActionText = "Starting end rental...";
connector.Command.StartReturningBike(bike); // Notify about start
bikesViewModel.ActionText = "<h4><b>Lock is closing.<br/>Please wait until it is completely closed.</b></h4>";
locks.Received()[0].CloseAsync(); // Lock must be closed
bikesViewModel.ActionText = "Query location...";
bikesViewModel.ActionText = "Returning bike...";
bikesViewModel.ActionText = "Ending rental...";
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert("Error returning bike!", "Returning bike at an unknown location is not possible.\r\nBike can only be returned if bike is in reach and location information is available.", "OK");
viewService.DisplayAlert("Error at ending rental!", "End rental at an unknown location is not possible.\r\nRental can only be ended if bike is in reach and location information is available.", "OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -962,7 +966,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked closed" after action
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.AreEqual("End rental", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -978,7 +982,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -999,7 +1003,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bike.Id.Returns("0");
viewService.DisplayAlert(string.Empty, "Close lock and return bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
viewService.DisplayAlert(string.Empty, "Close lock and end rental of bike Nr. 0?", "Yes", "No").Returns(Task.FromResult(true));
locks[0].CloseAsync()
.Returns(LockitLockingState.Closed);
@ -1021,12 +1025,12 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime>());
bikesViewModel.ActionText = "One moment please...";
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Starting bike return...";
bikesViewModel.ActionText = "Starting end rental...";
connector.Command.StartReturningBike(bike); // Notify about start
bikesViewModel.ActionText = "<h4><b>Lock is closing.<br/>Please wait until it is completely closed.</b></h4>";
locks.Received()[0].CloseAsync(); // Lock must be closed
bikesViewModel.ActionText = "Query location...";
bikesViewModel.ActionText = "Returning bike...";
bikesViewModel.ActionText = "Ending rental...";
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAdvancedAlert("Statusfehler beim Zurückgeben des Rads!", "Outer message.", "Some invalid data received!", "OK");
bikesViewModel.ActionText = "Updating...";
@ -1036,7 +1040,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked closed" after action
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.AreEqual("End rental", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -1052,13 +1056,17 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
var bikesViewModel = Substitute.For<IBikesViewModel>();
var activeUser = Substitute.For<IUser>();
var startOfTest = DateTime.Now;
geolocation.GetAsync(Arg.Any<CancellationToken?>(), Arg.Any<DateTime?>()).Returns(new Geolocation.Builder { Latitude = 47.99, Longitude = 7.78}.Build());
var handler = new BookedOpen(
bike,
() => true, // isConnectedDelegate
@ -1078,6 +1086,14 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var subsequent = handler.HandleRequestOption2().Result;
// Veryfy 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));
// Verify behaviour
Received.InOrder(() =>
{
@ -1095,7 +1111,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.AreEqual("End rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -1111,7 +1127,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -1171,7 +1187,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -1231,7 +1247,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -1269,7 +1285,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
locks.Received()[0].CloseAsync(); // Lock must be closed
bikesViewModel.ActionText = "Updating lock state...";
connector.Command.UpdateLockingStateAsync(bike, Arg.Any<LocationDto>());
bikesViewModel.ActionText = "No web error on updating locking status.";
bikesViewModel.ActionText = "Internet must be available for updating lock status. Please establish an Internet connection!";
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -1277,7 +1293,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.AreEqual("End rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -1293,7 +1309,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -1339,7 +1355,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.AreEqual("End rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -1355,7 +1371,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -1402,7 +1418,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.AreEqual("End rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);

View file

@ -36,7 +36,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
Substitute.For<IBikeInfoMutable>(),
() => true, // isConnectedDelegate
(isConnexted) => Substitute.For<IConnector>(),
Substitute.For<IGeolocation>(),
Substitute.For<IGeolocationService>(),
Substitute.For<ILocksService>(),
() => Substitute.For<IPollingUpdateTaskManager>(),
Substitute.For<ISmartDevice>(),
@ -61,7 +61,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -106,7 +106,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -122,7 +122,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -182,7 +182,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -242,7 +242,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -286,7 +286,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.AreEqual("End rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -302,7 +302,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -338,7 +338,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
bikesViewModel.ActionText = "<h4><b>Lock is opening.<br/>Please wait until it is completely open.</b></h4>";
locks.Received()[0].OpenAsync(); // Lock must be closed
bikesViewModel.ActionText = "";
viewService.DisplayAlert("Lock can not be opened!", "The lock could not be opened correctly. Please try again.\r\n\r\nAttention! Your rental has already started.\r\n\r\nIf the lock still won't open, make sure the lock is closed and return the bike. Please report it to the support!", "OK");
viewService.DisplayAlert("Lock can not be opened!", "The lock could not be opened correctly. Try again!\r\n\r\nAttention! Your rental has already started.\r\nIf the lock still won't open, make sure the lock is closed and end rental.\r\nImportant: Send an email to the operator (otherwise your paid rental will continue!) with: Problem description, bike number, drop-off station.", "OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -362,7 +362,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -422,7 +422,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -470,7 +470,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -487,7 +487,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -535,7 +535,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -551,7 +551,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -592,7 +592,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
locks[0].GetBatteryPercentageAsync();
bikesViewModel.ActionText = "Updating lock state...";
connector.Command.UpdateLockingStateAsync(bike, null);
bikesViewModel.ActionText = "No web error on updating locking status.";
bikesViewModel.ActionText = "Internet must be available for updating lock status. Please establish an Internet connection!";
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -600,7 +600,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -616,7 +616,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -665,7 +665,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -681,7 +681,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -731,7 +731,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -747,7 +747,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -790,7 +790,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Open" after action
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.AreEqual("End rental", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -806,7 +806,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -866,7 +866,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -926,7 +926,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -964,7 +964,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
locks.Received()[0].CloseAsync(); // Lock must be closed
bikesViewModel.ActionText = "Updating lock state...";
connector.Command.UpdateLockingStateAsync(bike, Arg.Any<LocationDto>());
bikesViewModel.ActionText = "No web error on updating locking status.";
bikesViewModel.ActionText = "Internet must be available for updating lock status. Please establish an Internet connection!";
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -972,7 +972,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.AreEqual("End rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -988,7 +988,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -1034,7 +1034,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.AreEqual("End rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -1050,7 +1050,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -1097,7 +1097,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.AreEqual("End rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);

View file

@ -32,7 +32,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
Substitute.For<IBikeInfoMutable>(),
() => true, // isConnectedDelegate
(isConnexted) => Substitute.For<IConnector>(),
Substitute.For<IGeolocation>(),
Substitute.For<IGeolocationService>(),
Substitute.For<ILocksService>(),
() => Substitute.For<IPollingUpdateTaskManager>(),
Substitute.For<ISmartDevice>(),
@ -57,7 +57,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -107,7 +107,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -171,7 +171,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -187,7 +187,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -226,7 +226,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.ActionText = "Reserving bike...";
connector.Command.DoReserve(bike); // Booking must be performed
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert("Hint", string.Format("A reservation of bike {0} was rejected because the maximum allowed number of {1} reservations/ rentals had already been made.", 0, 7), "OK");
viewService.DisplayAlert("Hint", string.Format("A reservation of bike {0} was rejected because the maximum allowed number of {1} reservations/rentals had already been made.", 0, 7), "OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -250,7 +250,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -289,7 +289,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.ActionText = "Reserving bike...";
connector.Command.DoReserve(bike); // Booking must be performed
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert("Connection error when reserving the bike!", "Context info.\r\nIs WIFI available/ mobile network available and mobile data activated / ... ?", "OK");
viewService.DisplayAlert("Connection error when reserving the bike!", "Context info.\r\nIs WIFI/mobile network available and mobile data activated?", "OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -313,7 +313,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -376,7 +376,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -442,7 +442,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -508,7 +508,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -569,7 +569,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
Substitute.For<IBikeInfoMutable>(),
() => true, // isConnectedDelegate
(isConnexted) => Substitute.For<IConnector>(),
Substitute.For<IGeolocation>(),
Substitute.For<IGeolocationService>(),
Substitute.For<ILocksService>(),
() => Substitute.For<IPollingUpdateTaskManager>(),
Substitute.For<ISmartDevice>(),

View file

@ -33,7 +33,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
Substitute.For<IBikeInfoMutable>(),
() => true, // isConnectedDelegate
(isConnexted) => Substitute.For<IConnector>(),
Substitute.For<IGeolocation>(),
Substitute.For<IGeolocationService>(),
Substitute.For<ILocksService>(),
() => Substitute.For<IPollingUpdateTaskManager>(),
Substitute.For<ISmartDevice>(),
@ -58,7 +58,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -118,7 +118,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -181,7 +181,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -244,7 +244,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -289,7 +289,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -305,7 +305,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -349,7 +349,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert(
"Connection error when renting the bike!",
string.Format("Attention: Lock is closed!\r\n{0}\r\n{1}", "Context info.", "Is WIFI available/ mobile network available and mobile data activated / ... ?"),
string.Format("Attention: Lock is closed!\r\n{0}\r\n{1}", "Context info.", "Is WIFI/mobile network available and mobile data activated?"),
"OK");
bikesViewModel.ActionText = "Verschließe Schloss...";
locks[0].CloseAsync();
@ -378,7 +378,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();

View file

@ -35,7 +35,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
Substitute.For<IBikeInfoMutable>(),
() => true, // isConnectedDelegate
(isConnexted) => Substitute.For<IConnector>(),
Substitute.For<IGeolocation>(),
Substitute.For<IGeolocationService>(),
Substitute.For<ILocksService>(),
() => Substitute.For<IPollingUpdateTaskManager>(),
Substitute.For<ISmartDevice>(),
@ -61,7 +61,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -113,7 +113,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -174,7 +174,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -251,7 +251,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -293,7 +293,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert(
"Connection error when canceling the reservation!",
"Context info.\r\nIs WIFI available/ mobile network available and mobile data activated / ... ?",
"Context info.\r\nIs WIFI/mobile network available and mobile data activated?",
"OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
@ -319,7 +319,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -387,7 +387,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -435,7 +435,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -486,7 +486,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -503,7 +503,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -545,7 +545,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAdvancedAlert(
"Connection error when renting the bike!",
"Is WIFI available/ mobile network available and mobile data activated / ... ?",
"Is WIFI/mobile network available and mobile data activated?",
"Context info",
"OK");
bikesViewModel.ActionText = "Updating...";
@ -572,7 +572,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -641,7 +641,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -708,7 +708,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -775,7 +775,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -839,7 +839,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -893,7 +893,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -910,7 +910,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -964,7 +964,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -981,7 +981,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -1027,7 +1027,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
locks[0].GetBatteryPercentageAsync();
bikesViewModel.ActionText = "Updating lock state...";
connector.Command.UpdateLockingStateAsync(bike, null);
bikesViewModel.ActionText = "No web error on updating locking status.";
bikesViewModel.ActionText = "Internet must be available for updating lock status. Please establish an Internet connection!";
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -1035,7 +1035,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -1052,7 +1052,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -1106,7 +1106,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -1123,7 +1123,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -1178,7 +1178,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);

View file

@ -33,7 +33,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
Substitute.For<IBikeInfoMutable>(),
() => true, // isConnectedDelegate
(isConnexted) => Substitute.For<IConnector>(),
Substitute.For<IGeolocation>(),
Substitute.For<IGeolocationService>(),
Substitute.For<ILocksService>(),
() => Substitute.For<IPollingUpdateTaskManager>(),
Substitute.For<ISmartDevice>(),
@ -59,7 +59,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -109,7 +109,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -168,7 +168,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -243,7 +243,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -283,7 +283,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert(
"Connection error when canceling the reservation!",
"Context info\r\nIs WIFI available/ mobile network available and mobile data activated / ... ?",
"Context info\r\nIs WIFI/mobile network available and mobile data activated?",
"OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
@ -309,7 +309,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -374,7 +374,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -436,7 +436,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -452,7 +452,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -486,7 +486,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
pollingManager.StopUpdatePeridically(); // Polling must be stopped before any COPR and lock service action
bikesViewModel.ActionText = "Request server...";
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert("Error when connecting to lock!", "Internet must be reachable to connect to lock of reserved bike.\r\nContext info.\r\nIs WIFI available/ mobile network available and mobile data activated / ... ?", "OK");
viewService.DisplayAlert("Error when connecting to lock!", "Internet must be reachable to connect to lock of reserved bike. Please establish an Internet connection!\r\nContext info.\r\nIs WIFI/mobile network available and mobile data activated?", "OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -510,7 +510,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -568,7 +568,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -635,7 +635,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -704,7 +704,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();

View file

@ -34,7 +34,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
Substitute.For<IBikeInfoMutable>(),
() => true, // isConnectedDelegate
(isConnexted) => Substitute.For<IConnector>(),
Substitute.For<IGeolocation>(),
Substitute.For<IGeolocationService>(),
Substitute.For<ILocksService>(),
() => Substitute.For<IPollingUpdateTaskManager>(),
Substitute.For<ISmartDevice>(),
@ -59,7 +59,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -102,7 +102,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
});
// Verify state after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -118,7 +118,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -160,7 +160,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert(
"Connection error when renting the bike!",
string.Format("Attention: Lock is closed!\r\n{0}\r\n{1}", "Context info.", "Is WIFI available/ mobile network available and mobile data activated / ... ?"),
string.Format("Attention: Lock is closed!\r\n{0}\r\n{1}", "Context info.", "Is WIFI/mobile network available and mobile data activated?"),
"OK");
bikesViewModel.ActionText = "Wiederverschließe Schloss...";
locks[0].CloseAsync();
@ -187,7 +187,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -253,7 +253,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -317,7 +317,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -365,7 +365,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert(
"Lock can not be closed!",
"Lock cannot be closed until bike is near.\r\nPlease try again to close bike or report bike to support!",
"Lock cannot be closed until bike is near.\r\nPlease try again to close bike or report bike to operator!",
"OK");
bikesViewModel.ActionText = "Updating...";
@ -391,7 +391,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -439,7 +439,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert(
"Lock can not be closed!",
"Please try to lock again or report bike to support!\r\nException message.",
"Please try to lock again or report bike to operator!\r\nException message.",
"OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
@ -464,7 +464,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -544,7 +544,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -590,7 +590,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert(
"Connection error when canceling the reservation!",
"Context info\r\nIs WIFI available/ mobile network available and mobile data activated / ... ?",
"Context info\r\nIs WIFI/mobile network available and mobile data activated?",
"OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
@ -615,7 +615,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();

View file

@ -38,7 +38,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
Substitute.For<IBikeInfoMutable>(),
() => true, // isConnectedDelegate
(isConnexted) => Substitute.For<IConnector>(),
Substitute.For<IGeolocation>(),
Substitute.For<IGeolocationService>(),
Substitute.For<ILocksService>(),
() => Substitute.For<IPollingUpdateTaskManager>(),
Substitute.For<ISmartDevice>(),
@ -63,7 +63,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -108,7 +108,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -124,7 +124,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -184,7 +184,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -244,7 +244,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -288,7 +288,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Closed" after action
//Assert.AreEqual("Return bike", subsequent.ButtonText);
//Assert.AreEqual("End rental", subsequent.ButtonText);
//Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -304,7 +304,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -340,7 +340,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
bikesViewModel.ActionText = "<h4><b>Lock is opening.<br/>Please wait until it is completely open.</b></h4>";
locks.Received()[0].OpenAsync(); // Lock must be closed
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert("Lock can not be opened!", "The lock could not be opened correctly. Please try again.\r\n\r\nAttention! Your rental has already started.\r\n\r\nIf the lock still won't open, make sure the lock is closed and return the bike. Please report it to the support!", "OK");
viewService.DisplayAlert("Lock can not be opened!", "The lock could not be opened correctly. Try again!\r\n\r\nAttention! Your rental has already started.\r\nIf the lock still won't open, make sure the lock is closed and end rental.\r\nImportant: Send an email to the operator (otherwise your paid rental will continue!) with: Problem description, bike number, drop-off station.", "OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -364,7 +364,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -424,7 +424,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -465,7 +465,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
locks[0].GetBatteryPercentageAsync();
bikesViewModel.ActionText = "Updating lock state...";
connector.Command.UpdateLockingStateAsync(bike, null);
bikesViewModel.ActionText = "No web error on updating locking status.";
bikesViewModel.ActionText = "Internet must be available for updating lock status. Please establish an Internet connection!";
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -473,7 +473,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -489,7 +489,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -538,7 +538,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -554,7 +554,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -604,7 +604,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Open" after action
Assert.AreEqual("Close lock & return bike", subsequent.ButtonText);
Assert.AreEqual("Close lock & end rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Close lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -620,7 +620,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -663,7 +663,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.AreEqual("End rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -675,7 +675,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -735,7 +735,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -796,7 +796,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -834,7 +834,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
locks.Received()[0].CloseAsync(); // Lock must be closed
bikesViewModel.ActionText = "Updating lock state...";
connector.Command.UpdateLockingStateAsync(bike, Arg.Any<LocationDto>());
bikesViewModel.ActionText = "No web error on updating locking status.";
bikesViewModel.ActionText = "Internet must be available for updating lock status. Please establish an Internet connection!";
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
bikesViewModel.ActionText = string.Empty;
@ -842,7 +842,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.AreEqual("End rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -858,7 +858,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -904,7 +904,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.AreEqual("End rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);
@ -920,7 +920,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
var bike = Substitute.For<IBikeInfoMutable>();
var connector = Substitute.For<IConnector>();
var command = Substitute.For<ICommand>();
var geolocation = Substitute.For<IGeolocation>();
var geolocation = Substitute.For<IGeolocationService>();
var locks = Substitute.For<ILocksService>();
var pollingManager = Substitute.For<IPollingUpdateTaskManager>();
var viewService = Substitute.For<IViewService>();
@ -967,7 +967,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
});
// Verify state "Booked Closed" after action
Assert.AreEqual("Return bike", subsequent.ButtonText);
Assert.AreEqual("End rental", subsequent.ButtonText);
Assert.IsTrue(subsequent.IsButtonVisible);
Assert.AreEqual("Open lock", subsequent.LockitButtonText);
Assert.IsTrue(subsequent.IsLockitButtonVisible);

View file

@ -62,7 +62,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.CopriLock.RequestHandler
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAdvancedAlert(
"Connection error when opening the lock!",
"Is WIFI available/ mobile network available and mobile data activated / ... ?",
"Is WIFI/mobile network available and mobile data activated?",
"Context info",
"OK");
bikesViewModel.ActionText = "Updating...";

View file

@ -62,7 +62,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.CopriLock.RequestHandler
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAdvancedAlert(
"Connection error when opening the lock!",
"Is WIFI available/ mobile network available and mobile data activated / ... ?",
"Is WIFI/mobile network available and mobile data activated?",
"Context info",
"OK");
bikesViewModel.ActionText = "Updating...";

View file

@ -130,7 +130,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.CopriLock.RequestHandler
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAdvancedAlert(
"Connection error when renting the bike!",
"Is WIFI available/ mobile network available and mobile data activated / ... ?",
"Is WIFI/mobile network available and mobile data activated?",
"Context info",
"OK");
bikesViewModel.ActionText = "Updating...";
@ -411,7 +411,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.CopriLock.RequestHandler
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAlert(
"Hint",
"A reservation of bike Nr. 0 was rejected because the maximum allowed number of 4 reservations/ rentals had already been made.",
"A reservation of bike Nr. 0 was rejected because the maximum allowed number of 4 reservations/rentals had already been made.",
"OK");
bikesViewModel.ActionText = "Updating...";
pollingManager.StartUpdateAyncPeridically(); // polling must be restarted again
@ -486,7 +486,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.CopriLock.RequestHandler
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAdvancedAlert(
"Connection error when reserving the bike!",
"Is WIFI available/ mobile network available and mobile data activated / ... ?",
"Is WIFI/mobile network available and mobile data activated?",
"Context info",
"OK");
bikesViewModel.ActionText = "Updating...";

View file

@ -78,7 +78,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.CopriLock.RequestHandler
Is.False);
Assert.That(
subsequent.LockitButtonText,
Is.EqualTo("Give Feedback"));
Is.EqualTo("Give feedback"));
Assert.That(
subsequent.IsLockitButtonVisible,
Is.True);
@ -135,7 +135,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.CopriLock.RequestHandler
Is.False);
Assert.That(
subsequent.LockitButtonText,
Is.EqualTo("Give Feedback"));
Is.EqualTo("Give feedback"));
Assert.That(
subsequent.IsLockitButtonVisible,
Is.True);
@ -195,7 +195,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.CopriLock.RequestHandler
Is.False);
Assert.That(
subsequent.LockitButtonText,
Is.EqualTo("Give Feedback"));
Is.EqualTo("Give feedback"));
Assert.That(
subsequent.IsLockitButtonVisible,
Is.True);

View file

@ -197,7 +197,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.CopriLock.RequestHandler
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAdvancedAlert(
"Connection error when canceling the reservation!",
"Is WIFI available/ mobile network available and mobile data activated / ... ?",
"Is WIFI/mobile network available and mobile data activated?",
"Context info",
"OK");
bikesViewModel.ActionText = "Updating...";
@ -472,7 +472,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.CopriLock.RequestHandler
bikesViewModel.ActionText = string.Empty;
viewService.DisplayAdvancedAlert(
"Connection error when renting the bike!",
"Is WIFI available/ mobile network available and mobile data activated / ... ?",
"Is WIFI/mobile network available and mobile data activated?",
"Context info",
"OK");
bikesViewModel.ActionText = "Updating...";

View file

@ -38,7 +38,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
[Test]
public async Task TestConstruct_Droid_NotLoggedIn()
{
var geolocation = Substitute.For<IServicesContainer<IGeolocation>>();
var geolocation = Substitute.For<IServicesContainer<IGeolocationService>>();
var locksService = Substitute.For<ILocksService>();
var timeOut = Substitute.For<ITimeOutProvider>();
var viewService = Substitute.For<IViewService>();
@ -122,7 +122,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
[Test]
public async Task TestConstruct_Droid_NoBikes()
{
var geolocation = Substitute.For<IServicesContainer<IGeolocation>>();
var geolocation = Substitute.For<IServicesContainer<IGeolocationService>>();
var locksService = Substitute.For<ILocksService>();
var timeOut = Substitute.For<ITimeOutProvider>();
var viewService = Substitute.For<IViewService>();
@ -192,7 +192,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
[Test]
public async Task TestConstruct_Droid()
{
var geolocation = Substitute.For<IServicesContainer<IGeolocation>>();
var geolocation = Substitute.For<IServicesContainer<IGeolocationService>>();
var locksService = Substitute.For<ILocksService>();
var timeOut = Substitute.For<ITimeOutProvider>();
var viewService = Substitute.For<IViewService>();
@ -314,7 +314,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
[Test]
public async Task TestConstruct_Droid_NoPermissions_OpenSettings()
{
var geolocation = Substitute.For<IServicesContainer<IGeolocation>>();
var geolocation = Substitute.For<IServicesContainer<IGeolocationService>>();
var locksService = Substitute.For<ILocksService>();
var timeOut = Substitute.For<ITimeOutProvider>();
var viewService = Substitute.For<IViewService>();
@ -444,7 +444,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
[Test]
public async Task TestConstruct_Droid_NoPermissions()
{
var geolocation = Substitute.For<IServicesContainer<IGeolocation>>();
var geolocation = Substitute.For<IServicesContainer<IGeolocationService>>();
var locksService = Substitute.For<ILocksService>();
var timeOut = Substitute.For<ITimeOutProvider>();
var viewService = Substitute.For<IViewService>();
@ -571,7 +571,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
[Test]
public async Task TestConstruct_Droid_GeolocationOff()
{
var geolocation = Substitute.For<IServicesContainer<IGeolocation>>();
var geolocation = Substitute.For<IServicesContainer<IGeolocationService>>();
var locksService = Substitute.For<ILocksService>();
var timeOut = Substitute.For<ITimeOutProvider>();
var viewService = Substitute.For<IViewService>();
@ -694,7 +694,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
[Test]
public async Task TestConstruct_Droid_BluetoothOff()
{
var geolocation = Substitute.For<IServicesContainer<IGeolocation>>();
var geolocation = Substitute.For<IServicesContainer<IGeolocationService>>();
var locksService = Substitute.For<ILocksService>();
var timeOut = Substitute.For<ITimeOutProvider>();
var viewService = Substitute.For<IViewService>();
@ -847,7 +847,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
merchantId: MERCH_ID,
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocation>>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: locksService, // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
@ -926,7 +926,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
merchantId: "MyMerchId",
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocation>>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: locksService, // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
@ -1003,7 +1003,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
merchantId: "MyMerchId",
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocation>>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: locksService, // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
@ -1080,7 +1080,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
merchantId: "MyMerchId",
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocation>>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: locksService, // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
@ -1168,7 +1168,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
merchantId: "MyMerchId",
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocation>>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: locksService, // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
@ -1260,7 +1260,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
merchantId: "MyMerchId",
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocation>>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: locksService, // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),

View file

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using NUnit.Framework;
using TINK.Model;
using TINK.Model.Connector;
@ -39,5 +39,156 @@ namespace UITest.Fixtures.ObjectTests.Map
Assert.IsTrue(l_oFilter.IsToggleVisible);
}
/// <summary>
/// Verifies that if Konrad is turned off in settings map page filter does no more contain Konrad option.
/// </summary>
[Test]
public void TestGetFilterDictinaryMapPage_NoKonrad_TinkOnKonradOff()
{
var l_oDict = GroupFilterMapPageHelper.CreateUpdated(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }), // Last map page filter (Konrad was still available but off)
new List<string> { "TINK" }); // Filters from settings page.
Assert.AreEqual(1, l_oDict.Count);
Assert.IsTrue(l_oDict.ContainsKey("TINK"));
Assert.AreEqual(FilterState.On, l_oDict["TINK"]);
}
/// <summary>
/// Verifies that if Konrad is turned off in settings map page filter does no more contain Konrad option.
/// </summary>
[Test]
public void TestGetFilterDictinaryMapPage_NoKonrad_TinkOffKonradOn()
{
var l_oDict = GroupFilterMapPageHelper.CreateUpdated(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.Off }, { "Konrad", FilterState.On } }), // Last map page filter (Konrad was still available but off)
new List<string> { "TINK" }); // Filters from settings page.
Assert.AreEqual(1, l_oDict.Count);
Assert.IsTrue(l_oDict.ContainsKey("TINK"));
Assert.AreEqual(FilterState.On, l_oDict["TINK"]);
}
/// <summary>
/// Verifies that if TINK.* is turned off in settings map page filter does no more contain TINK option.
/// </summary>
[Test]
public void TestGetFilterDictinaryMapPage_NoTink_TinkOnKonradOff()
{
var l_oDict = GroupFilterMapPageHelper.CreateUpdated(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }), // Last map page filter (Konrad was still available but off)
new List<string> { "Konrad" }); // Filters from settings page.
Assert.AreEqual(1, l_oDict.Count);
Assert.IsTrue(l_oDict.ContainsKey("Konrad"));
Assert.AreEqual(FilterState.On, l_oDict["Konrad"]);
}
/// <summary>
/// Verifies that if Konrad is turned on in settings map page filter is updated with entry Konrad.
/// </summary>
[Test]
public void TestGetFilterDictinaryMapPage_TinkOn()
{
var l_oDict = GroupFilterMapPageHelper.CreateUpdated(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On } }), // Last map page filter (Konrad was still available but off)
new List<string> { "TINK", "Konrad" }); // Filters from settings page.
Assert.AreEqual(2, l_oDict.Count);
Assert.IsTrue(l_oDict.ContainsKey("TINK"));
Assert.AreEqual(FilterState.Off, l_oDict["TINK"]);
Assert.IsTrue(l_oDict.ContainsKey("Konrad"));
Assert.AreEqual(FilterState.On, l_oDict["Konrad"]);
}
/// <summary>
/// Verifies that if Konrad is turned on in settings map page filter is updated with entry Konrad.
/// </summary>
[Test]
public void TestGetFilterDictinaryMapPage_TinkOff()
{
var l_oDict = GroupFilterMapPageHelper.CreateUpdated(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.Off } }), // Last map page filter (Konrad was still available but off)
new List<string> { "TINK", "Konrad" }); // Filters from settings page.
Assert.AreEqual(2, l_oDict.Count);
Assert.IsTrue(l_oDict.ContainsKey("TINK"));
Assert.AreEqual(FilterState.Off, l_oDict["TINK"]);
Assert.IsTrue(l_oDict.ContainsKey("Konrad"));
Assert.AreEqual(FilterState.On, l_oDict["Konrad"]);
}
/// <summary>
/// Verifies that map page filters are not touched if state is consitend.
/// </summary>
[Test]
public void TestGetFilterDictinaryMapPage_AllOn_KonradActivated()
{
var l_oDict = GroupFilterMapPageHelper.CreateUpdated(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.Off }, { "Konrad", FilterState.On } }), // Last map page filter (Konrad was still available but off)
new List<string> { "TINK", "Konrad" }); // Filters from settings page.
Assert.AreEqual(2, l_oDict.Count);
Assert.IsTrue(l_oDict.ContainsKey("TINK"));
Assert.AreEqual(FilterState.Off, l_oDict["TINK"]);
Assert.IsTrue(l_oDict.ContainsKey("Konrad"));
Assert.AreEqual(FilterState.On, l_oDict["Konrad"]);
}
/// <summary>
/// Verifies that map page filters are not touched if state is consitend..
/// </summary>
[Test]
public void TestGetFilterDictinaryMapPage_AllOn_TinkActivated()
{
var l_oDict = GroupFilterMapPageHelper.CreateUpdated(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }), // Last map page filter (Konrad was still available but off)
new List<string> { "TINK", "Konrad" }); // Filters from settings page.
Assert.AreEqual(2, l_oDict.Count);
Assert.IsTrue(l_oDict.ContainsKey("TINK"));
Assert.AreEqual(FilterState.On, l_oDict["TINK"]);
Assert.IsTrue(l_oDict.ContainsKey("Konrad"));
Assert.AreEqual(FilterState.Off, l_oDict["Konrad"]);
}
/// <summary>
/// Verifies that map page filters are not touched if state is consitend.
/// </summary>
[Test]
public void TestGetFilterDictinaryMapPage_NullFilter()
{
var l_oDict = GroupFilterMapPageHelper.CreateUpdated(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }), // Last map page filter (Konrad was still available but off)
null);
Assert.AreEqual(2, l_oDict.Count, "Do not apply any filter if filter value null is detected.");
Assert.IsTrue(l_oDict.ContainsKey("TINK"));
Assert.AreEqual(FilterState.On, l_oDict["TINK"]);
Assert.IsTrue(l_oDict.ContainsKey("Konrad"));
Assert.AreEqual(FilterState.Off, l_oDict["Konrad"]);
l_oDict = GroupFilterMapPageHelper.CreateUpdated(
null,
null);
Assert.IsNull(l_oDict, "Do not apply any filter if filter value null is detected.");
}
[Test]
public void TestDoToggle()
{
var l_oFilter = new TinkKonradToggleViewModel(new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }));
l_oFilter = new TinkKonradToggleViewModel(l_oFilter.FilterDictionary).DoToggle();
Assert.AreEqual("Konrad", l_oFilter.CurrentFilter);
l_oFilter = new TinkKonradToggleViewModel(l_oFilter.FilterDictionary).DoToggle();
Assert.AreEqual("TINK", l_oFilter.CurrentFilter);
}
}
}

View file

@ -50,7 +50,7 @@ namespace TestShareeLib.UseCases.Startup
merchantId: "MyMerchId",
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocation>>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: new LocksServiceMock(), // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
@ -71,7 +71,7 @@ namespace TestShareeLib.UseCases.Startup
tinkApp,
locationPermission,
Substitute.For<IBluetoothLE>(),
Substitute.For<IGeolocation>(),
Substitute.For<IGeolocationService>(),
(mapspan) => { },
viewService,
navigationService);
@ -131,7 +131,7 @@ namespace TestShareeLib.UseCases.Startup
merchantId: "MyMerchId",
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocation>>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: new LocksServiceMock(), // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
@ -152,7 +152,7 @@ namespace TestShareeLib.UseCases.Startup
tinkApp,
locationPermission,
NSubstitute.Substitute.For<Plugin.BLE.Abstractions.Contracts.IBluetoothLE>(),
NSubstitute.Substitute.For<IGeolocation>(),
NSubstitute.Substitute.For<IGeolocationService>(),
(mapspan) => { },
viewService,
navigationService);
@ -209,7 +209,7 @@ namespace TestShareeLib.UseCases.Startup
merchantId: "MyMerchId",
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocation>>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: new LocksServiceMock(), // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
@ -228,7 +228,7 @@ namespace TestShareeLib.UseCases.Startup
tinkApp,
locationPermission,
Substitute.For<Plugin.BLE.Abstractions.Contracts.IBluetoothLE>(),
Substitute.For<IGeolocation>(),
Substitute.For<IGeolocationService>(),
(mapspan) => { },
viewService,
navigationService);
@ -282,7 +282,7 @@ namespace TestShareeLib.UseCases.Startup
merchantId: "MyMerchId",
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocation>>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: new LocksServiceMock(), // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
@ -301,7 +301,7 @@ namespace TestShareeLib.UseCases.Startup
tinkApp,
locationPermission,
Substitute.For<Plugin.BLE.Abstractions.Contracts.IBluetoothLE>(),
Substitute.For<IGeolocation>(),
Substitute.For<IGeolocationService>(),
(mapspan) => { },
viewService,
navigationService);
@ -355,7 +355,7 @@ namespace TestShareeLib.UseCases.Startup
merchantId: "MyMerchId",
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocation>>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: new LocksServiceMock(), // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
@ -374,7 +374,7 @@ namespace TestShareeLib.UseCases.Startup
tinkApp,
locationPermission,
Substitute.For<Plugin.BLE.Abstractions.Contracts.IBluetoothLE>(),
Substitute.For<IGeolocation>(),
Substitute.For<IGeolocationService>(),
(mapspan) => { },
viewService,
navigationService);
@ -444,7 +444,7 @@ namespace TestShareeLib.UseCases.Startup
merchantId: "MyMerchId",
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocation>>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: new LocksServiceMock(), // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
@ -463,7 +463,7 @@ namespace TestShareeLib.UseCases.Startup
tinkApp,
locationPermission,
Substitute.For<Plugin.BLE.Abstractions.Contracts.IBluetoothLE>(),
Substitute.For<IGeolocation>(),
Substitute.For<IGeolocationService>(),
(mapspan) => { },
viewService,
navigationService);
@ -534,7 +534,7 @@ namespace TestShareeLib.UseCases.Startup
merchantId: "MyMerchId",
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocation>>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: new LocksServiceMock(), // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
@ -554,7 +554,7 @@ namespace TestShareeLib.UseCases.Startup
tinkApp,
locationPermission,
Substitute.For<Plugin.BLE.Abstractions.Contracts.IBluetoothLE>(),
Substitute.For<IGeolocation>(),
Substitute.For<IGeolocationService>(),
(mapspan) => { },
viewService,
navigationService);

View file

@ -0,0 +1,853 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using NSubstitute;
using NSubstitute.ExceptionExtensions;
using NUnit.Framework;
using Plugin.BLE.Abstractions.Contracts;
using TestFramework.Model.Device;
using TestFramework.Model.Services.Geolocation;
using TestFramework.Model.User.Account;
using TestFramework.Repository;
using TestTINKLib.Mocks.Connector;
using TINK.Model;
using TINK.Model.Connector;
using TINK.Model.Device;
using TINK.Model.Services.CopriApi;
using TINK.Model.Settings;
using TINK.Repository;
using TINK.Repository.Exception;
using TINK.Services;
using TINK.Services.BluetoothLock;
using TINK.Services.BluetoothLock.Tdo;
using TINK.Services.Geolocation;
using TINK.Services.Permissions;
using TINK.View;
using TINK.ViewModel.Map;
using TINK.ViewModel.MyBikes;
using TINK.ViewModel.Settings;
using Xamarin.Forms;
using static TINK.Repository.CopriCallsMemory;
namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
{
[TestFixture]
public class TestMyBikesPageViewModel
{
[Test]
public async Task TestConstruct_Droid()
{
var geolocation = Substitute.For<IServicesContainer<IGeolocationService>>();
var locksService = Substitute.For<ILocksService>();
var timeOut = Substitute.For<ITimeOutProvider>();
var viewService = Substitute.For<IViewService>();
var permissions = Substitute.For<ILocationPermission>();
var bluetooth = Substitute.For<IBluetoothLE>();
locksService.TimeOut.Returns(timeOut);
timeOut.MultiConnect.Returns(new TimeSpan(0));
// Fake location permissions to be set
permissions.CheckStatusAsync().Returns(Task.FromResult(Status.Granted));
geolocation.Active.IsGeolcationEnabled.Returns(true); // Fake gps to be on
bluetooth.State.Returns(BluetoothState.On); // Fake bluetooth to be on
// Fake bluetooth answer for locks with id 2200545 and 2200537.
locksService.GetLocksStateAsync(Arg.Any<IEnumerable<LockInfoAuthTdo>>(), Arg.Any<TimeSpan>()).Returns(
new List<LockInfoTdo> {
{ new LockInfoTdo.Builder { Id = 2200545, State = LockitLockingState.Open }.Build() },
{ new LockInfoTdo.Builder { Id = 2200537, State = LockitLockingState.Closed }.Build() }
}
);
const string MERCH_ID = "MyMerchId";
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
activeLockService: locksService.GetType().FullName,
activeGeolocationService: typeof(GeolocationMock).FullName),
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", false, "5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH", new List<string> { "300001", "300029" })),
isConnectedFunc: () => true,
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(new AppContextInfo(MERCH_ID, "MyApp", new Version(1, 2)), null /*UI language */, sessionCookie, mail, server: new CopriCallsMemory(MERCH_ID, SampleSets.ShareeFr01_Set1, 1, sessionCookie)),
merchantId: MERCH_ID,
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: null,
locationServicesContainer: geolocation,
locksService: locksService, // Cipher
device: new DeviceMock(), // Permissions,
specialFolder: new SpecialFolderMock(),
cipher: null,
theme: null,
postAction: (d, obj) => d(obj),
currentVersion: new Version(3, 2, 0, 115), // Current app version
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
whatsNewShownInVersion: null); // Whats new page was never shown.
var myBikes = new MyBikesPageViewModel(
tinkApp.ActiveUser,
permissions, /* permissions */
bluetooth, /* bluetooth */
Device.Android,
() => tinkApp.GetIsConnected(),
(isConnected) => tinkApp.GetConnector(isConnected),
geolocation.Active, // geolocation
locksService,
tinkApp.Stations,
tinkApp.Polling,
(d, obj) => d(obj),
Substitute.For<ISmartDevice>(),
viewService,
url => { });
await myBikes.OnAppearingOrRefresh();
// Verify behaviour
Received.InOrder(() =>
{
permissions.CheckStatusAsync();
var glDummy = geolocation.Active.Received().IsGeolcationEnabled;
var btDummy = bluetooth.Received().State;
locksService.GetLocksStateAsync(Arg.Any<IEnumerable<LockInfoAuthTdo>>(), Arg.Any<TimeSpan>());
});
Assert.IsEmpty(myBikes.StatusInfoText);
Assert.AreEqual(2, myBikes.Count);
Assert.IsTrue(myBikes.IsIdle);
Assert.IsTrue(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible.");
var bike1545 = myBikes.FirstOrDefault(x => x.Id == "1545") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
var bike1537 = myBikes.FirstOrDefault(x => x.Id == "1537") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
Assert.AreEqual($"Rented since {DateTime.Parse("2020-11-06 17:53:22.784681+01"):dd. MMMM HH:mm}.", bike1545.StateText);
Assert.AreEqual($"Rented since {DateTime.Parse("2020-10-12 08:38:12.374231+02"):dd. MMMM HH:mm}.", bike1537.StateText);
Assert.AreEqual("Close lock", bike1545.LockitButtonText);
Assert.AreEqual("Open lock", bike1537.LockitButtonText);
Assert.IsFalse(myBikes.IsNoBikesOccupiedVisible);
Assert.IsEmpty(myBikes.NoBikesOccupiedText);
}
[Test]
public async Task TestConstruct_Droid_NoPermissions_OpenSettings()
{
var geolocation = Substitute.For<IServicesContainer<IGeolocationService>>();
var locksService = Substitute.For<ILocksService>();
var timeOut = Substitute.For<ITimeOutProvider>();
var viewService = Substitute.For<IViewService>();
var permissions = Substitute.For<ILocationPermission>();
var bluetooth = Substitute.For<IBluetoothLE>();
locksService.TimeOut.Returns(timeOut);
timeOut.MultiConnect.Returns(new TimeSpan(0));
// Fake location permissions not to be set
permissions.CheckStatusAsync().Returns(Task.FromResult(Status.Denied));
// Fake anwser on question whether to open permissions dialog
viewService.DisplayAlert(Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>()).Returns(true);
locksService.GetLocksStateAsync(Arg.Any<IEnumerable<LockInfoAuthTdo>>(), Arg.Any<TimeSpan>()).Returns(
new List<LockInfoTdo> {
{ new LockInfoTdo.Builder { Id = 2200545, State = LockitLockingState.Open }.Build() },
{ new LockInfoTdo.Builder { Id = 2200537, State = LockitLockingState.Closed }.Build() }
}
);
const string MERCH_ID = "MyMerchId";
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
activeLockService: locksService.GetType().FullName,
activeGeolocationService: typeof(GeolocationMock).FullName),
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", false, "5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH", new List<string> { "300001", "300029" })),
isConnectedFunc: () => true,
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(new AppContextInfo(MERCH_ID, "MyApp", new Version(1, 2)), null /*UI language */, sessionCookie, mail, server: new CopriCallsMemory(MERCH_ID, SampleSets.ShareeFr01_Set1, 1, sessionCookie)),
merchantId: MERCH_ID,
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: null,
locationServicesContainer: geolocation,
locksService: locksService, // Cipher
device: new DeviceMock(), // Permissions,
specialFolder: new SpecialFolderMock(),
cipher: null,
theme: null,
postAction: (d, obj) => d(obj),
currentVersion: new Version(3, 2, 0, 115), // Current app version
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
whatsNewShownInVersion: null); // Whats new page was never shown.
var myBikes = new MyBikesPageViewModel(
tinkApp.ActiveUser,
permissions, /* permissions */
bluetooth, /* bluetooth */
Device.Android,
() => tinkApp.GetIsConnected(),
(isConnected) => tinkApp.GetConnector(isConnected),
geolocation.Active, // geolocation
locksService,
tinkApp.Stations,
tinkApp.Polling,
(d, obj) => d(obj),
Substitute.For<ISmartDevice>(),
viewService,
url => { });
await myBikes.OnAppearingOrRefresh();
// Verify behaviour
Received.InOrder(() =>
{
permissions.CheckStatusAsync();
var glDummy = geolocation.Active.Received().IsGeolcationEnabled;
permissions.RequestAsync(); // Ask user from permissions.
viewService.DisplayAlert(
"Hint",
"Please allow location sharing so that bike lock/locks can be managed.\r\nOpen sharing dialog?",
"Yes",
"No");
permissions.OpenAppSettings();
});
Assert.IsEmpty(myBikes.StatusInfoText, "Unexpected status info text detected.");
Assert.AreEqual(2, myBikes.Count);
Assert.IsTrue(myBikes.IsIdle);
Assert.IsTrue(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible.");
var bike1545 = myBikes.FirstOrDefault(x => x.Id == "1545") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
var bike1537 = myBikes.FirstOrDefault(x => x.Id == "1537") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
Assert.AreEqual($"Rented since {DateTime.Parse("2020-11-06 17:53:22.784681+01"):dd. MMMM HH:mm}.", bike1545.StateText);
Assert.AreEqual($"Rented since {DateTime.Parse("2020-10-12 08:38:12.374231+02"):dd. MMMM HH:mm}.", bike1537.StateText);
Assert.AreEqual("Search lock", bike1545.LockitButtonText);
Assert.AreEqual("Search lock", bike1537.LockitButtonText);
Assert.IsFalse(myBikes.IsNoBikesOccupiedVisible);
Assert.IsEmpty(myBikes.NoBikesOccupiedText, "There must not be any bikes occupied.");
}
[Test]
public async Task TestConstruct_Droid_NoPermissions()
{
var geolocation = Substitute.For<IServicesContainer<IGeolocationService>>();
var locksService = Substitute.For<ILocksService>();
var timeOut = Substitute.For<ITimeOutProvider>();
var viewService = Substitute.For<IViewService>();
var permissions = Substitute.For<ILocationPermission>();
var bluetooth = Substitute.For<IBluetoothLE>();
locksService.TimeOut.Returns(timeOut);
timeOut.MultiConnect.Returns(new TimeSpan(0));
// Fake location permissions not to be set
permissions.CheckStatusAsync().Returns(Task.FromResult(Status.Denied));
permissions.OpenAppSettings().Throws<Exception>(); // Ensures that method is not called and fixture succeeds.
// Fake anwser on question whether to open permissions dialog
viewService.DisplayAlert(Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>(), Arg.Any<string>()).Returns(false);
// Fake bluetooth answer for locks with id 2200545 and 2200537.
var lockInfoTdo = new List<LockInfoTdo> {
{ new LockInfoTdo.Builder { Id = 2200545, State = LockitLockingState.Open }.Build() },
{ new LockInfoTdo.Builder { Id = 2200537, State = LockitLockingState.Closed }.Build() }
};
locksService.GetLocksStateAsync(Arg.Any<IEnumerable<LockInfoAuthTdo>>(), Arg.Any<TimeSpan>()).Returns(lockInfoTdo);
const string MERCH_ID = "MyMerchId";
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
activeLockService: locksService.GetType().FullName,
activeGeolocationService: typeof(GeolocationMock).FullName),
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", false, "5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH", new List<string> { "300001", "300029" })),
isConnectedFunc: () => true,
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(new AppContextInfo(MERCH_ID, "MyApp", new Version(1, 2)), null /*UI language */, sessionCookie, mail, server: new CopriCallsMemory(MERCH_ID, SampleSets.ShareeFr01_Set1, 1, sessionCookie)),
merchantId: MERCH_ID,
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: null,
locationServicesContainer: geolocation,
locksService: locksService, // Cipher
device: new DeviceMock(), // Permissions,
specialFolder: new SpecialFolderMock(),
cipher: null,
theme: null,
postAction: (d, obj) => d(obj),
currentVersion: new Version(3, 2, 0, 115), // Current app version
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
whatsNewShownInVersion: null); // Whats new page was never shown.
var myBikes = new MyBikesPageViewModel(
tinkApp.ActiveUser,
permissions, /* permissions */
bluetooth, /* bluetooth */
Device.Android,
() => tinkApp.GetIsConnected(),
(isConnected) => tinkApp.GetConnector(isConnected),
geolocation.Active, // geolocation
locksService,
tinkApp.Stations,
tinkApp.Polling,
(d, obj) => d(obj),
Substitute.For<ISmartDevice>(),
viewService,
url => { });
await myBikes.OnAppearingOrRefresh();
// Verify behaviour
Received.InOrder(() =>
{
permissions.CheckStatusAsync();
var glDummy = geolocation.Active.Received().IsGeolcationEnabled;
permissions.RequestAsync(); // Ask user from permissions.
viewService.DisplayAlert(
"Hint",
"Please allow location sharing so that bike lock/locks can be managed.\r\nOpen sharing dialog?",
"Yes",
"No");
});
Assert.IsEmpty(myBikes.StatusInfoText, "Unexpected status info text detected.");
Assert.AreEqual(2, myBikes.Count);
Assert.IsTrue(myBikes.IsIdle);
Assert.IsTrue(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible.");
var bike1545 = myBikes.FirstOrDefault(x => x.Id == "1545") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
var bike1537 = myBikes.FirstOrDefault(x => x.Id == "1537") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
Assert.AreEqual($"Rented since {DateTime.Parse("2020-11-06 17:53:22.784681+01"):dd. MMMM HH:mm}.", bike1545.StateText);
Assert.AreEqual($"Rented since {DateTime.Parse("2020-10-12 08:38:12.374231+02"):dd. MMMM HH:mm}.", bike1537.StateText);
Assert.AreEqual("Search lock", bike1545.LockitButtonText);
Assert.AreEqual("Search lock", bike1537.LockitButtonText);
Assert.IsFalse(myBikes.IsNoBikesOccupiedVisible);
Assert.IsEmpty(myBikes.NoBikesOccupiedText, "There must not be any bikes occupied.");
}
[Test]
public async Task TestConstruct_Droid_GeolocationOff()
{
var geolocation = Substitute.For<IServicesContainer<IGeolocationService>>();
var locksService = Substitute.For<ILocksService>();
var timeOut = Substitute.For<ITimeOutProvider>();
var viewService = Substitute.For<IViewService>();
var permissions = Substitute.For<ILocationPermission>();
var bluetooth = Substitute.For<IBluetoothLE>();
locksService.TimeOut.Returns(timeOut);
timeOut.MultiConnect.Returns(new TimeSpan(0));
// Fake location permissions to be set
permissions.CheckStatusAsync().Returns(Task.FromResult(Status.Granted));
geolocation.Active.IsGeolcationEnabled.Returns(false); // Fake gps to be off
// Fake bluetooth answer for locks with id 2200545 and 2200537.
locksService.GetLocksStateAsync(Arg.Any<IEnumerable<LockInfoAuthTdo>>(), Arg.Any<TimeSpan>()).Returns(
new List<LockInfoTdo> {
{ new LockInfoTdo.Builder { Id = 2200545, State = LockitLockingState.Open }.Build() },
{ new LockInfoTdo.Builder { Id = 2200537, State = LockitLockingState.Closed }.Build() }
}
);
const string MERCH_ID = "MyMerchId";
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
activeLockService: locksService.GetType().FullName,
activeGeolocationService: typeof(GeolocationMock).FullName),
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", false, "5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH", new List<string> { "300001", "300029" })),
isConnectedFunc: () => true,
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(new AppContextInfo(MERCH_ID, "MyApp", new Version(1, 2)), null /*UI language */, sessionCookie, mail, server: new CopriCallsMemory(MERCH_ID, SampleSets.ShareeFr01_Set1, 1, sessionCookie)),
merchantId: MERCH_ID,
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: null,
locationServicesContainer: geolocation,
locksService: locksService, // Cipher
device: new DeviceMock(), // Permissions,
specialFolder: new SpecialFolderMock(),
cipher: null,
theme: null,
postAction: (d, obj) => d(obj),
currentVersion: new Version(3, 2, 0, 115), // Current app version
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
whatsNewShownInVersion: null); // Whats new page was never shown.
var myBikes = new MyBikesPageViewModel(
tinkApp.ActiveUser,
permissions, /* permissions */
bluetooth, /* bluetooth */
Device.Android,
() => tinkApp.GetIsConnected(),
(isConnected) => tinkApp.GetConnector(isConnected),
geolocation.Active, // geolocation
locksService,
tinkApp.Stations,
tinkApp.Polling,
(d, obj) => d(obj),
Substitute.For<ISmartDevice>(),
viewService,
url => { });
await myBikes.OnAppearingOrRefresh();
// Verify behaviour
Received.InOrder(() =>
{
permissions.CheckStatusAsync();
var glDummy = geolocation.Active.Received().IsGeolcationEnabled;
viewService.DisplayAlert(
"Hint",
"Please activate location so that bike lock can be found!",
"OK");
});
Assert.IsEmpty(myBikes.StatusInfoText);
Assert.AreEqual(2, myBikes.Count);
Assert.IsTrue(myBikes.IsIdle);
Assert.IsTrue(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible.");
var bike1545 = myBikes.FirstOrDefault(x => x.Id == "1545") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
var bike1537 = myBikes.FirstOrDefault(x => x.Id == "1537") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
Assert.AreEqual($"Rented since {DateTime.Parse("2020-11-06 17:53:22.784681+01"):dd. MMMM HH:mm}.", bike1545.StateText);
Assert.AreEqual($"Rented since {DateTime.Parse("2020-10-12 08:38:12.374231+02"):dd. MMMM HH:mm}.", bike1537.StateText);
Assert.AreEqual("Search lock", bike1545.LockitButtonText);
Assert.AreEqual("Search lock", bike1537.LockitButtonText);
Assert.IsFalse(myBikes.IsNoBikesOccupiedVisible);
Assert.IsEmpty(myBikes.NoBikesOccupiedText);
}
[Test]
public async Task TestConstruct_Droid_BluetoothOff()
{
var geolocation = Substitute.For<IServicesContainer<IGeolocationService>>();
var locksService = Substitute.For<ILocksService>();
var timeOut = Substitute.For<ITimeOutProvider>();
var viewService = Substitute.For<IViewService>();
var permissions = Substitute.For<ILocationPermission>();
var bluetooth = Substitute.For<IBluetoothLE>();
locksService.TimeOut.Returns(timeOut);
timeOut.MultiConnect.Returns(new TimeSpan(0));
// Fake location permissions to be set
permissions.CheckStatusAsync().Returns(Task.FromResult(Status.Granted));
geolocation.Active.IsGeolcationEnabled.Returns(true); // Fake gps to be on
bluetooth.State.Returns(BluetoothState.Off); // Fake bluetooth to be off
var lockInfoTdo = new List<LockInfoTdo> {
{ new LockInfoTdo.Builder { Id = 2200545, State = LockitLockingState.Open }.Build() },
{ new LockInfoTdo.Builder { Id = 2200537, State = LockitLockingState.Closed }.Build() }
};
locksService.GetLocksStateAsync(Arg.Any<IEnumerable<LockInfoAuthTdo>>(), Arg.Any<TimeSpan>()).Returns(lockInfoTdo);
const string MERCH_ID = "MyMerchId";
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
activeLockService: locksService.GetType().FullName,
activeGeolocationService: typeof(GeolocationMock).FullName),
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", false, "5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH", new List<string> { "300001", "300029" })),
isConnectedFunc: () => true,
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(new AppContextInfo(MERCH_ID, "MyApp", new Version(1, 2)), null /*UI language */, sessionCookie, mail, server: new CopriCallsMemory(MERCH_ID, SampleSets.ShareeFr01_Set1, 1, sessionCookie)),
merchantId: MERCH_ID,
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: null,
locationServicesContainer: geolocation,
locksService: locksService, // Cipher
device: new DeviceMock(), // Permissions,
specialFolder: new SpecialFolderMock(),
cipher: null,
theme: null,
postAction: (d, obj) => d(obj),
currentVersion: new Version(3, 2, 0, 115), // Current app version
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
whatsNewShownInVersion: null); // Whats new page was never shown.
var myBikes = new MyBikesPageViewModel(
tinkApp.ActiveUser,
permissions, /* permissions */
bluetooth, /* bluetooth */
Device.Android,
() => tinkApp.GetIsConnected(),
(isConnected) => tinkApp.GetConnector(isConnected),
geolocation.Active, // geolocation
locksService,
tinkApp.Stations,
tinkApp.Polling,
(d, obj) => d(obj),
Substitute.For<ISmartDevice>(),
viewService,
url => { });
await myBikes.OnAppearingOrRefresh();
// Verify behaviour
Received.InOrder(() =>
{
permissions.CheckStatusAsync();
var glDummy = geolocation.Active.Received().IsGeolcationEnabled;
var btDummy = bluetooth.Received().State;
viewService.DisplayAlert(
"Hint",
"Please enable Bluetooth to manage bike lock/locks.",
"OK");
});
Assert.That(
myBikes.StatusInfoText,
Is.Empty,
"Status info text must be empty.");
Assert.AreEqual(2, myBikes.Count);
Assert.IsTrue(myBikes.IsIdle);
Assert.IsTrue(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible.");
var bike1545 = myBikes.FirstOrDefault(x => x.Id == "1545") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
var bike1537 = myBikes.FirstOrDefault(x => x.Id == "1537") as TINK.ViewModel.Bikes.Bike.BluetoothLock.BikeViewModel;
Assert.AreEqual($"Rented since {DateTime.Parse("2020-11-06 17:53:22.784681+01"):dd. MMMM HH:mm}.", bike1545.StateText);
Assert.AreEqual($"Rented since {DateTime.Parse("2020-10-12 08:38:12.374231+02"):dd. MMMM HH:mm}.", bike1537.StateText);
Assert.AreEqual("Search lock", bike1545.LockitButtonText);
Assert.AreEqual("Search lock", bike1537.LockitButtonText);
Assert.IsFalse(myBikes.IsNoBikesOccupiedVisible);
Assert.That(
myBikes.NoBikesOccupiedText,
Is.Empty,
"Label which informs that no bikes are reserved/ rented must be empty.");
}
[Test]
public async Task TestConstruct_NoBikesOccupied()
{
var locksService = Substitute.For<ILocksService>();
var timeOut = Substitute.For<ITimeOutProvider>();
var viewService = Substitute.For<IViewService>();
var permissions = Substitute.For<ILocationPermission>();
var bluetooth = Substitute.For<IBluetoothLE>();
locksService.TimeOut.Returns(timeOut);
timeOut.MultiConnect.Returns(new TimeSpan(0));
const string MERCH_ID = "MyMerchId";
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
activeLockService: locksService.GetType().FullName,
activeGeolocationService: typeof(GeolocationMock).FullName),
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", false, "Invalid_SessionCookie", new List<string> { "TINK" })),
isConnectedFunc: () => true,
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(new AppContextInfo(MERCH_ID, "MyApp", new Version(1, 2)), null /*UI language */, sessionCookie, mail, server: new CopriCallsMemory(MERCH_ID, SampleSets.Set2, 1, sessionCookie)),
merchantId: MERCH_ID,
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: locksService, // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
cipher: null,
theme: null,
postAction: (d, obj) => d(obj),
currentVersion: new Version(3, 2, 0, 115), // Current app version
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
whatsNewShownInVersion: null); // Whats new page was never shown.
var myBikes = new MyBikesPageViewModel(
tinkApp.ActiveUser,
permissions, // Permissions,
bluetooth,
Device.iOS,
() => tinkApp.GetIsConnected(),
(isConnected) => tinkApp.GetConnector(isConnected),
new GeolocationMock(),
locksService,
tinkApp.Stations,
tinkApp.Polling,
(d, obj) => d(obj),
Substitute.For<ISmartDevice>(),
viewService,
url => { });
await myBikes.OnAppearingOrRefresh();
Assert.IsTrue(new List<string> { "Updating...", string.Empty }.Contains(myBikes.StatusInfoText));
Assert.AreEqual(0, myBikes.Count);
Assert.IsTrue(myBikes.IsIdle);
Assert.IsFalse(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible.");
Assert.IsTrue(myBikes.IsNoBikesOccupiedVisible);
Assert.AreEqual("There are currently no bikes reserved/rented by user a@b.", myBikes.NoBikesOccupiedText);
}
[Test]
public async Task TestConstruct_Offline()
{
var locksService = Substitute.For<ILocksService>();
var timeOut = Substitute.For<ITimeOutProvider>();
var viewService = Substitute.For<IViewService>();
var permissions = Substitute.For<ILocationPermission>();
var bluetooth = Substitute.For<IBluetoothLE>();
locksService.TimeOut.Returns(timeOut);
timeOut.MultiConnect.Returns(new TimeSpan(0));
const string MERCH_ID = "MyMerchId";
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
activeLockService: locksService.GetType().FullName,
activeGeolocationService: typeof(GeolocationMock).FullName),
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", false, "4da3044c8657a04ba60e2eaa753bc51a", new List<string> { "TINK" })),
isConnectedFunc: () => false,
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(new AppContextInfo(MERCH_ID, "MyApp", new Version(1, 2)), null /*UI language */, sessionCookie, mail, server: new CopriCallsMemory(MERCH_ID, SampleSets.Set2, 1, sessionCookie)),
merchantId: MERCH_ID,
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: null,
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: locksService, // Cipher
device: new DeviceMock(), // Permissions
specialFolder: new SpecialFolderMock(),
cipher: null, // Offline
theme: null,
postAction: (d, obj) => d(obj),
currentVersion: new Version(3, 2, 0, 115), // Current app version
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
whatsNewShownInVersion: null); // Whats new page was never shown.
var myBikes = new MyBikesPageViewModel(
tinkApp.ActiveUser,
permissions, // Permissions,
bluetooth,
Device.iOS,
() => tinkApp.GetIsConnected(),
(isConnected) => tinkApp.GetConnector(isConnected),
new GeolocationMock(),
locksService,
tinkApp.Stations,
tinkApp.Polling,
(d, obj) => d(obj),
Substitute.For<ISmartDevice>(),
viewService,
url => { });
await myBikes.OnAppearingOrRefresh();
Assert.AreEqual("Offline.", myBikes.StatusInfoText);
Assert.AreEqual(2, myBikes.Count);
Assert.IsTrue(myBikes.IsIdle);
Assert.IsTrue(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible.");
Assert.AreEqual($"Rented since {DateTime.Parse("2017-11-28 13:06:55.147368+01"):dd. MMMM HH:mm}.", myBikes.FirstOrDefault(x => x.Id == "7").StateText);
Assert.AreEqual($"Rented since {DateTime.Parse("2017-11-28 11:01:51.637747+01"):dd. MMMM HH:mm}.", myBikes.FirstOrDefault(x => x.Id == "8").StateText);
Assert.IsFalse(myBikes.IsNoBikesOccupiedVisible);
Assert.AreEqual(string.Empty, myBikes.NoBikesOccupiedText);
}
[Test]
public async Task TestTinkApp_WebConnectCommunicationError()
{
var locksService = Substitute.For<ILocksService>();
var timeOut = Substitute.For<ITimeOutProvider>();
var viewService = Substitute.For<IViewService>();
var permissions = Substitute.For<ILocationPermission>();
var bluetooth = Substitute.For<IBluetoothLE>();
locksService.TimeOut.Returns(timeOut);
timeOut.MultiConnect.Returns(new TimeSpan(0));
const string MERCH_ID = "MyMerchId";
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
activeLockService: locksService.GetType().FullName,
activeGeolocationService: typeof(GeolocationMock).FullName),
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", false, "4da3044c8657a04ba60e2eaa753bc51a", new List<string> { "TINK" })),
isConnectedFunc: () => false,
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new TINK.Model.Connector.Connector(
uri,
new AppContextInfo("oiF2kahH", "sharee.bike.test", new Version(3, 0, 267)),
null /*UI language */,
sessionCookie,
mail,
server: new CopriProviderHttps(
uri,
TinkApp.MerchantId,
new AppContextInfo("oiF2kahH", "sharee.bike.test", new Version(3, 0, 267)),
null /*UI language */,
sessionCookie: sessionCookie,
cacheServer: new CopriCallsCacheMemory(MERCH_ID, sessionCookie: sessionCookie),
httpsServer: new ExceptionServer((msg) => new WebConnectFailureException(msg, new Exception("Source expection."))))),
merchantId: MERCH_ID,
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: Substitute.For<ILocationPermission>(),
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: locksService, // Cipher
device: new DeviceMock(),
specialFolder: new SpecialFolderMock(),
cipher: null, // Offline
theme: null,
postAction: (d, obj) => d(obj),
currentVersion: new Version(3, 2, 0, 115), // Current app version
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
whatsNewShownInVersion: null); // Whats new page was never shown.
var myBikes = new MyBikesPageViewModel(
tinkApp.ActiveUser,
permissions, // Permissions,
bluetooth,
Device.iOS,
() => tinkApp.GetIsConnected(),
(isConnected) => tinkApp.GetConnector(isConnected),
new GeolocationMock(),
locksService,
tinkApp.Stations,
tinkApp.Polling,
(d, obj) => d(obj),
Substitute.For<ISmartDevice>(),
viewService,
url => { })
{
IsReportLevelVerbose = true
};
await myBikes.OnAppearingOrRefresh();
Assert.AreEqual("Connection interrupted, server unreachable.", myBikes.StatusInfoText);
Assert.AreEqual(2, myBikes.Count);
Assert.IsTrue(myBikes.IsIdle);
Assert.IsTrue(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible.");
Assert.AreEqual($"Rented since {DateTime.Parse("2017-11-28 13:06:55.147368+01"):dd. MMMM HH:mm}.", myBikes.FirstOrDefault(x => x.Id == "7").StateText);
Assert.AreEqual($"Rented since {DateTime.Parse("2017-11-28 11:01:51.637747+01"):dd. MMMM HH:mm}.", myBikes.FirstOrDefault(x => x.Id == "8").StateText);
Assert.IsFalse(myBikes.IsNoBikesOccupiedVisible);
Assert.AreEqual(string.Empty, myBikes.NoBikesOccupiedText);
}
[Test]
public async Task TestTinkApp_GeneralPurposeError()
{
var locksService = Substitute.For<ILocksService>();
var timeOut = Substitute.For<ITimeOutProvider>();
var viewService = Substitute.For<IViewService>();
var permissions = Substitute.For<ILocationPermission>();
var bluetooth = Substitute.For<IBluetoothLE>();
locksService.TimeOut.Returns(timeOut);
timeOut.MultiConnect.Returns(new TimeSpan(0));
const string MERCH_ID = "MyMerchId";
var tinkApp = new TinkApp(
new TINK.Model.Settings.Settings(
new GroupFilterMapPage(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.Off } }),
new GroupFilterSettings(new Dictionary<string, FilterState> { { "TINK", FilterState.On }, { "Konrad", FilterState.On } }),
new StartupSettings(),
new Uri("https://shareeapp-primary.copri-bike.de/APIjsonserver"),
new TINK.Settings.PollingParameters(new TimeSpan(10000), true),
Serilog.Events.LogEventLevel.Error,
activeLockService: locksService.GetType().FullName,
activeGeolocationService: typeof(GeolocationMock).FullName),
new StoreMock(new TINK.Model.User.Account.Account("a@b", "123456789", false, "4da3044c8657a04ba60e2eaa753bc51a", new List<string> { "TINK" })),
isConnectedFunc: () => false,
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new TINK.Model.Connector.Connector(
uri,
new AppContextInfo("oiF2kahH", "sharee.bike.test", new Version(3, 0, 267)),
null /*UI language */,
sessionCookie,
mail,
server: new CopriProviderHttps(
uri,
TinkApp.MerchantId,
new AppContextInfo("oiF2kahH", "sharee.bike.test", new Version(3, 0, 267)),
null /*UI language */,
sessionCookie: sessionCookie,
cacheServer: new CopriCallsCacheMemory(MERCH_ID, sessionCookie: sessionCookie),
httpsServer: new ExceptionServer((msg) => new Exception(msg)))),
merchantId: MERCH_ID,
bluetoothService: Substitute.For<IBluetoothLE>(),
locationPermissionsService: null,
locationServicesContainer: Substitute.For<IServicesContainer<IGeolocationService>>(),
locksService: locksService, // Cipher
device: new DeviceMock(), // Permissions.
specialFolder: new SpecialFolderMock(),
cipher: null, // Offline
theme: null,
postAction: (d, obj) => d(obj),
currentVersion: new Version(3, 2, 0, 115), // Current app version
lastVersion: new Version(3, 0, 173), // Current app version. Must be larger or equal 3.0.173 to
whatsNewShownInVersion: null); // Whats new page was never shown.
var myBikes = new MyBikesPageViewModel(
tinkApp.ActiveUser,
permissions, // Permissions,
bluetooth,
Device.iOS,
() => tinkApp.GetIsConnected(),
(isConnected) => tinkApp.GetConnector(isConnected),
new GeolocationMock(),
locksService,
tinkApp.Stations,
tinkApp.Polling,
(d, obj) => d(obj),
Substitute.For<ISmartDevice>(),
viewService,
url => { })
{
IsReportLevelVerbose = true
};
await myBikes.OnAppearingOrRefresh();
Assert.AreEqual("Connection interrupted.", myBikes.StatusInfoText);
Assert.AreEqual(2, myBikes.Count);
Assert.IsTrue(myBikes.IsIdle);
Assert.IsTrue(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible.");
Assert.AreEqual($"Rented since {DateTime.Parse("2017-11-28 13:06:55.147368+01"):dd. MMMM HH:mm}.", myBikes.FirstOrDefault(x => x.Id == "7").StateText);
Assert.AreEqual($"Rented since {DateTime.Parse("2017-11-28 11:01:51.637747+01"):dd. MMMM HH:mm}.", myBikes.FirstOrDefault(x => x.Id == "8").StateText);
Assert.IsFalse(myBikes.IsNoBikesOccupiedVisible);
Assert.AreEqual(string.Empty, myBikes.NoBikesOccupiedText);
}
}
}