mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2025-06-22 22:07:28 +02:00
Version 3.0.362
This commit is contained in:
parent
cba4da9357
commit
4ff3307997
128 changed files with 3954 additions and 3193 deletions
853
TestShareeLib/ViewModel/MyBikes/TestMyBikesPageViewModel.cs
Normal file
853
TestShareeLib/ViewModel/MyBikes/TestMyBikesPageViewModel.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue