2022-09-06 16:08:19 +02:00
using System ;
2021-07-12 21:31:46 +02:00
using System.Collections.Generic ;
using System.Linq ;
using System.Threading.Tasks ;
using NSubstitute ;
2022-08-30 15:42:25 +02:00
using NUnit.Framework ;
using Plugin.BLE.Abstractions.Contracts ;
2024-04-09 12:53:23 +02:00
using SharedBusinessLogic.Tests.Framework.Model.Device ;
using SharedBusinessLogic.Tests.Framework.Model.Services.Geolocation ;
using SharedBusinessLogic.Tests.Framework.Model.User.Account ;
using SharedBusinessLogic.Tests.Framework.Repository ;
using SharedBusinessLogic.Tests.Framework.Services.BluetoothLock ;
using ShareeBike.Model ;
using ShareeBike.Model.Bikes.BikeInfoNS.BluetoothLock ;
using ShareeBike.Model.Bikes.BikeInfoNS.BikeNS ;
using ShareeBike.Model.Bikes.BikeInfoNS.DriveNS ;
using ShareeBike.Model.Connector ;
using ShareeBike.Model.Services.CopriApi ;
using ShareeBike.Model.Settings ;
using ShareeBike.Model.Stations.StationNS ;
using ShareeBike.Repository ;
using ShareeBike.Repository.Exception ;
using ShareeBike.Services ;
using ShareeBike.Services.Geolocation ;
using ShareeBike.Services.Permissions ;
using ShareeBike.View ;
using ShareeBike.ViewModel.Map ;
using ShareeBike.ViewModel.Settings ;
2022-08-30 15:42:25 +02:00
using Xamarin.Forms ;
2024-04-09 12:53:23 +02:00
using ShareeBike.Model.Bikes.BikeInfoNS ;
using ShareeBike.Model.Stations.StationNS.Operator ;
2021-11-14 23:27:29 +01:00
2024-04-09 12:53:23 +02:00
namespace SharedBusinessLogic.Tests.UseCases.Startup
2021-07-12 21:31:46 +02:00
{
2022-09-06 16:08:19 +02:00
[TestFixture]
public class TestMapPageViewModel
{
[Test]
public async Task TestConstruct ( )
{
2024-04-09 12:53:23 +02:00
var shareeBikeApp = new ShareeBikeApp (
2022-10-17 18:45:38 +02:00
new Settings (
2022-09-06 16:08:19 +02:00
new GroupFilterMapPage ( new Dictionary < string , FilterState > { { FilterHelper . CARGOBIKE , FilterState . On } , { FilterHelper . CITYBIKE , FilterState . Off } } ) ,
new GroupFilterSettings ( new Dictionary < string , FilterState > { { FilterHelper . CARGOBIKE , FilterState . On } , { FilterHelper . CITYBIKE , FilterState . On } } ) ,
2022-10-17 18:45:38 +02:00
new StartupSettings ( ) ,
2022-09-06 16:08:19 +02:00
new Uri ( "https://tinkwwp.copri-bike.de/APIjsonserver" ) ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Settings . PollingParameters ( new TimeSpan ( 10000 ) , true ) ,
2022-09-06 16:08:19 +02:00
Serilog . Events . LogEventLevel . Error ,
activeLockService : typeof ( LocksServiceMock ) . FullName ,
activeGeolocationService : typeof ( GeolocationMock ) . FullName ) ,
new StoreMock ( ) ,
isConnectedFunc : ( ) = > true ,
2023-05-09 08:47:52 +02:00
connectorFactory : ( isConnected , uri , sessionCookie , mail , expiresAfter ) = > new ConnectorCache ( new AppContextInfo ( "MyMerchId" , "MyApp" , new Version ( 1 , 2 ) ) , null /*UI language */ , sessionCookie , mail , server : new CopriCallsMemory001v2NotLoggedIn ( sessionCookie ) ) ,
2022-09-06 16:08:19 +02:00
merchantId : "MyMerchId" ,
bluetoothService : Substitute . For < IBluetoothLE > ( ) ,
locationPermissionsService : Substitute . For < ILocationPermission > ( ) ,
2023-04-05 15:02:10 +02:00
locationServicesContainer : Substitute . For < IServicesContainer < IGeolocationService > > ( ) ,
2022-09-06 16:08:19 +02:00
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 navigationService = Substitute . For < INavigation > ( ) ;
var locationPermission = Substitute . For < ILocationPermission > ( ) ;
locationPermission . CheckStatusAsync ( ) . Returns ( Status . Granted ) ;
var viewModel = new MapPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp ,
2022-09-06 16:08:19 +02:00
locationPermission ,
Substitute . For < IBluetoothLE > ( ) ,
2023-04-05 15:02:10 +02:00
Substitute . For < IGeolocationService > ( ) ,
2022-09-06 16:08:19 +02:00
( mapspan ) = > { } ,
viewService ,
navigationService ) ;
try
{
await viewModel . OnAppearing ( ) ; // Is called when page shows.
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . Exception , Is . Null ) ;
2022-09-06 16:08:19 +02:00
// Verify pins on map
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . Pins . Count , Is . EqualTo ( 27 ) ) ; // Were 8 pins when loading from CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)
2022-09-06 16:08:19 +02:00
Assert . That (
2023-05-09 08:47:52 +02:00
viewModel . Pins . FirstOrDefault ( pin = > pin . Icon . Id . Contains ( "Open_Green" ) ) ? . Tag ,
2022-09-06 16:08:19 +02:00
Is . EqualTo ( "FR101" ) ,
2023-05-09 08:47:52 +02:00
"Station FR105 must be marked green because there are bikes." ) ;
2022-09-06 16:08:19 +02:00
Assert . That (
2023-05-09 08:47:52 +02:00
viewModel . Pins . FirstOrDefault ( pin = > pin . Icon . Id . Contains ( "Open_Red" ) ) ? . Tag ,
2022-09-06 16:08:19 +02:00
Is . EqualTo ( "KN12" ) ,
"Station KN12 must be marked red because there is no bike." ) ; // Was station id 31
// Verify buttons
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . IsToggleVisible , Is . True , "ShareeBike and Citybike are activated in settings." ) ;
Assert . That ( viewModel . CargoColor , Is . EqualTo ( Color . White ) , "ShareeBike bikes are shown." ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . CitybikeColor , Is . EqualTo ( Color . FromRgba ( 0 , 0 , 0 , 0 ) ) , "Citybike bikes are hidden." ) ;
2022-09-06 16:08:19 +02:00
var statusInfoText = viewModel . StatusInfoText ;
Assert . That (
statusInfoText ,
Does . Contain ( "Updating..." ) . Or . Contain ( "" ) ,
2024-04-09 12:53:23 +02:00
"Unexpected text detected. Text might be \"Updating...\" or empty depending on activity of update thread." ) ;
2022-09-06 16:08:19 +02:00
}
finally
{
await viewModel . OnDisappearing ( ) ;
}
}
[Test]
2024-04-09 12:53:23 +02:00
public async Task TestConstruct_CitybikeActive ( )
2022-09-06 16:08:19 +02:00
{
2024-04-09 12:53:23 +02:00
var shareeBikeApp = new ShareeBikeApp (
2022-10-17 18:45:38 +02:00
new Settings (
2022-09-06 16:08:19 +02:00
new GroupFilterMapPage ( new Dictionary < string , FilterState > { { FilterHelper . CARGOBIKE , FilterState . Off } , { FilterHelper . CITYBIKE , FilterState . On } } ) ,
new GroupFilterSettings ( new Dictionary < string , FilterState > { { FilterHelper . CARGOBIKE , FilterState . On } , { FilterHelper . CITYBIKE , FilterState . On } } ) ,
2022-10-17 18:45:38 +02:00
new StartupSettings ( ) ,
2022-09-06 16:08:19 +02:00
new Uri ( "https://tinkwwp.copri-bike.de/APIjsonserver" ) ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Settings . PollingParameters ( new TimeSpan ( 10000 ) , true ) ,
2022-09-06 16:08:19 +02:00
Serilog . Events . LogEventLevel . Error ,
activeLockService : typeof ( LocksServiceMock ) . FullName ,
activeGeolocationService : typeof ( GeolocationMock ) . FullName ) ,
new StoreMock ( ) ,
isConnectedFunc : ( ) = > true ,
2023-05-09 08:47:52 +02:00
connectorFactory : ( isConnected , uri , sessionCookie , mail , expiresAfter ) = > new ConnectorCache ( new AppContextInfo ( "MyMerchId" , "MyApp" , new Version ( 1 , 2 ) ) , null /*UI language */ , sessionCookie , mail , server : new CopriCallsMemory001v2NotLoggedIn ( sessionCookie ) ) ,
2022-09-06 16:08:19 +02:00
merchantId : "MyMerchId" ,
bluetoothService : Substitute . For < IBluetoothLE > ( ) ,
locationPermissionsService : Substitute . For < ILocationPermission > ( ) ,
2023-04-05 15:02:10 +02:00
locationServicesContainer : Substitute . For < IServicesContainer < IGeolocationService > > ( ) ,
2022-09-06 16:08:19 +02:00
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 navigationService = Substitute . For < INavigation > ( ) ;
var locationPermission = Substitute . For < ILocationPermission > ( ) ;
locationPermission . CheckStatusAsync ( ) . Returns ( Status . Granted ) ;
var viewModel = new MapPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp ,
2022-09-06 16:08:19 +02:00
locationPermission ,
2023-05-09 08:47:52 +02:00
Substitute . For < IBluetoothLE > ( ) ,
Substitute . For < IGeolocationService > ( ) ,
2022-09-06 16:08:19 +02:00
( mapspan ) = > { } ,
viewService ,
navigationService ) ;
try
{
await viewModel . OnAppearing ( ) ; // Is called when page shows.
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . Exception , Is . Null ) ;
2022-09-06 16:08:19 +02:00
// Verify pins on map
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . Pins . Count , Is . EqualTo ( 21 ) ) ; // Were 2 pins when loading from CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)
2022-09-06 16:08:19 +02:00
Assert . That (
2023-05-09 08:47:52 +02:00
viewModel . Pins . FirstOrDefault ( pin = > pin . Icon . Id . Contains ( "Open_Green" ) ) ? . Tag , // Was station 5
2022-09-06 16:08:19 +02:00
Is . EqualTo ( "FR103" ) ,
"Station FR101 must be marked green because there is are bike." ) ;
Assert . That (
2023-05-09 08:47:52 +02:00
viewModel . Pins . FirstOrDefault ( pin = > pin . Icon . Id . Contains ( "Open_Red" ) ) ? . Tag , // Was station 14
2022-09-06 16:08:19 +02:00
Is . EqualTo ( "KN12" ) ,
"Station KN12 must be marked red because there is no bike." ) ;
// Verify buttons
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . IsToggleVisible , Is . True , "ShareeBike and Citybike are activated in settings." ) ;
Assert . That ( viewModel . CargoColor , Is . EqualTo ( Color . FromRgba ( 0 , 0 , 0 , 0 ) ) , "ShareeBike bikes are hidden." ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . CitybikeColor , Is . EqualTo ( Color . White ) , "Citybike bikes are shown." ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
Assert . That (
new [ ] { "Updating..." , "" } . Contains ( viewModel . StatusInfoText ) , Is . True ,
2022-09-06 16:08:19 +02:00
"Text might be \"Updating...\" or empty depending on acivity of update thread." ) ;
}
finally
{
await viewModel . OnDisappearing ( ) ;
}
}
[Test]
2024-04-09 12:53:23 +02:00
public async Task TestConstruct_CitybikeOnly ( )
2022-09-06 16:08:19 +02:00
{
2024-04-09 12:53:23 +02:00
var shareeBikeApp = new ShareeBikeApp (
2022-10-17 18:45:38 +02:00
new Settings (
2022-09-06 16:08:19 +02:00
new GroupFilterMapPage ( new Dictionary < string , FilterState > { { FilterHelper . CITYBIKE , FilterState . On } } ) ,
new GroupFilterSettings ( new Dictionary < string , FilterState > { { FilterHelper . CARGOBIKE , FilterState . Off } , { FilterHelper . CITYBIKE , FilterState . On } } ) ,
2022-10-17 18:45:38 +02:00
new StartupSettings ( ) ,
2022-09-06 16:08:19 +02:00
new Uri ( "https://tinkwwp.copri-bike.de/APIjsonserver" ) ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Settings . PollingParameters ( new TimeSpan ( 10000 ) , true ) ,
2022-09-06 16:08:19 +02:00
Serilog . Events . LogEventLevel . Error ,
activeLockService : typeof ( LocksServiceMock ) . FullName ,
activeGeolocationService : typeof ( GeolocationMock ) . FullName ) ,
new StoreMock ( ) ,
isConnectedFunc : ( ) = > true ,
2023-05-09 08:47:52 +02:00
connectorFactory : ( isConnected , uri , sessionCookie , mail , expiresAfter ) = > new ConnectorCache ( new AppContextInfo ( "MyMerchId" , "MyApp" , new Version ( 1 , 2 ) ) , null /*UI language */ , sessionCookie , mail , server : new CopriCallsMemory001v2NotLoggedIn ( sessionCookie ) ) ,
2022-09-06 16:08:19 +02:00
merchantId : "MyMerchId" ,
bluetoothService : Substitute . For < IBluetoothLE > ( ) ,
locationPermissionsService : Substitute . For < ILocationPermission > ( ) ,
2023-04-05 15:02:10 +02:00
locationServicesContainer : Substitute . For < IServicesContainer < IGeolocationService > > ( ) ,
2022-09-06 16:08:19 +02:00
locksService : new LocksServiceMock ( ) , // Cipher
device : new DeviceMock ( ) ,
specialFolder : new SpecialFolderMock ( ) ,
cipher : null ,
theme : null ,
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
var viewService = Substitute . For < IViewService > ( ) ;
var navigationService = Substitute . For < INavigation > ( ) ;
var locationPermission = Substitute . For < ILocationPermission > ( ) ;
locationPermission . CheckStatusAsync ( ) . Returns ( Status . Granted ) ;
var viewModel = new MapPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp ,
2022-09-06 16:08:19 +02:00
locationPermission ,
Substitute . For < Plugin . BLE . Abstractions . Contracts . IBluetoothLE > ( ) ,
2023-04-05 15:02:10 +02:00
Substitute . For < IGeolocationService > ( ) ,
2022-09-06 16:08:19 +02:00
( mapspan ) = > { } ,
viewService ,
navigationService ) ;
try
{
await viewModel . OnAppearing ( ) ; // Is called when page shows.
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . Exception , Is . Null ) ;
2022-09-06 16:08:19 +02:00
// Verify pins on map
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . Pins . Count , Is . EqualTo ( 21 ) ) ; // Were 2 when loading from CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)
2022-09-06 16:08:19 +02:00
Assert . That (
2023-05-09 08:47:52 +02:00
viewModel . Pins . FirstOrDefault ( pin = > pin . Icon . Id . Contains ( "Open_Green" ) ) ? . Tag , // Was station id 31
2022-09-06 16:08:19 +02:00
Is . EqualTo ( "FR103" ) ,
"Station FR101 must be marked green because there is are bike." ) ;
Assert . That (
2023-05-09 08:47:52 +02:00
viewModel . Pins . FirstOrDefault ( pin = > pin . Icon . Id . Contains ( "Open_Red" ) ) ? . Tag , // Was 14
2022-09-06 16:08:19 +02:00
Is . EqualTo ( "KN12" ) ,
"Station KN12 must be marked red because there is no bike." ) ;
// Verify buttons
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . IsToggleVisible , Is . False , "ShareeBike and Citybike is deactivated from settings." ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
Assert . That (
new [ ] { "Updating..." , "" } . Contains ( viewModel . StatusInfoText ) , Is . True ,
2022-09-06 16:08:19 +02:00
"Text might be \"Updating...\" or empty depending on acivity of update thread." ) ;
}
finally
{
await viewModel . OnDisappearing ( ) ;
}
}
[Test]
2024-04-09 12:53:23 +02:00
public async Task TestConstruct_CargoOnly ( )
2022-09-06 16:08:19 +02:00
{
2024-04-09 12:53:23 +02:00
var shareeBikeApp = new ShareeBikeApp (
2022-10-17 18:45:38 +02:00
new Settings (
2022-09-06 16:08:19 +02:00
new GroupFilterMapPage ( new Dictionary < string , FilterState > { { FilterHelper . CARGOBIKE , FilterState . On } } ) ,
new GroupFilterSettings ( new Dictionary < string , FilterState > { { FilterHelper . CARGOBIKE , FilterState . On } , { FilterHelper . CITYBIKE , FilterState . On } } ) ,
2022-10-17 18:45:38 +02:00
new StartupSettings ( ) ,
2022-09-06 16:08:19 +02:00
new Uri ( "https://tinkwwp.copri-bike.de/APIjsonserver" ) ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Settings . PollingParameters ( new TimeSpan ( 10000 ) , true ) ,
2022-09-06 16:08:19 +02:00
Serilog . Events . LogEventLevel . Error ,
activeLockService : typeof ( LocksServiceMock ) . FullName ,
activeGeolocationService : typeof ( GeolocationMock ) . FullName ) ,
new StoreMock ( ) ,
isConnectedFunc : ( ) = > true ,
2023-05-09 08:47:52 +02:00
connectorFactory : ( isConnected , uri , sessionCookie , mail , expiresAfter ) = > new ConnectorCache ( new AppContextInfo ( "MyMerchId" , "MyApp" , new Version ( 1 , 2 ) ) , null /*UI language */ , sessionCookie , mail , server : new CopriCallsMemory001v2NotLoggedIn ( sessionCookie ) ) ,
2022-09-06 16:08:19 +02:00
merchantId : "MyMerchId" ,
bluetoothService : Substitute . For < IBluetoothLE > ( ) ,
locationPermissionsService : Substitute . For < ILocationPermission > ( ) ,
2023-04-05 15:02:10 +02:00
locationServicesContainer : Substitute . For < IServicesContainer < IGeolocationService > > ( ) ,
2022-09-06 16:08:19 +02:00
locksService : new LocksServiceMock ( ) , // Cipher
device : new DeviceMock ( ) ,
specialFolder : new SpecialFolderMock ( ) ,
cipher : null ,
theme : null ,
currentVersion : new Version ( 3 , 2 , 0 , 115 ) , // Current app version
lastVersion : new Version ( 3 , 0 , 173 ) ) ;
var viewService = Substitute . For < IViewService > ( ) ;
var navigationService = Substitute . For < INavigation > ( ) ;
var locationPermission = Substitute . For < ILocationPermission > ( ) ;
locationPermission . CheckStatusAsync ( ) . Returns ( Status . Granted ) ;
var viewModel = new MapPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp ,
2022-09-06 16:08:19 +02:00
locationPermission ,
Substitute . For < Plugin . BLE . Abstractions . Contracts . IBluetoothLE > ( ) ,
2023-04-05 15:02:10 +02:00
Substitute . For < IGeolocationService > ( ) ,
2022-09-06 16:08:19 +02:00
( mapspan ) = > { } ,
viewService ,
navigationService ) ;
try
{
await viewModel . OnAppearing ( ) ; // Is called when page shows.
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . Exception , Is . Null ) ;
2022-09-06 16:08:19 +02:00
// Verify pins on map
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . Pins . Count , Is . EqualTo ( 27 ) ) ; // Were 8 pin when loading from CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)
2022-09-06 16:08:19 +02:00
Assert . That (
2023-05-09 08:47:52 +02:00
viewModel . Pins . FirstOrDefault ( pin = > pin . Icon . Id . Contains ( "Open_Green" ) ) ? . Tag ,
2022-09-06 16:08:19 +02:00
Is . EqualTo ( "FR101" ) , // Was station id 4
"Station FR101 must be marked green because there is are bike." ) ;
Assert . That (
2023-05-09 08:47:52 +02:00
viewModel . Pins . FirstOrDefault ( pin = > pin . Icon . Id . Contains ( "Open_Red" ) ) ? . Tag , // Was 31
2022-09-06 16:08:19 +02:00
Is . EqualTo ( "KN12" ) , // Was station id 31
"Station KN12 must be marked red because there is no bike." ) ;
// Verify buttons
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . IsToggleVisible , Is . False , "ShareeBike and Citybike is deactivated from settings." ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
Assert . That (
new [ ] { "Updating..." , "" } . Contains ( viewModel . StatusInfoText ) , Is . True ,
2022-09-06 16:08:19 +02:00
"Text might be \"Updating...\" or empty depending on acivity of update thread." ) ;
}
finally
{
await viewModel . OnDisappearing ( ) ;
}
}
[Test]
public async Task TestConstruct_Offline ( )
{
2024-04-09 12:53:23 +02:00
var shareeBikeApp = new ShareeBikeApp (
2022-10-17 18:45:38 +02:00
new Settings (
2022-09-06 16:08:19 +02:00
new GroupFilterMapPage ( new Dictionary < string , FilterState > { { FilterHelper . CARGOBIKE , FilterState . On } , { FilterHelper . CITYBIKE , FilterState . Off } } ) ,
new GroupFilterSettings ( new Dictionary < string , FilterState > { { FilterHelper . CARGOBIKE , FilterState . On } , { FilterHelper . CITYBIKE , FilterState . On } } ) ,
2022-10-17 18:45:38 +02:00
new StartupSettings ( ) ,
2022-09-06 16:08:19 +02:00
new Uri ( "https://tinkwwp.copri-bike.de/APIjsonserver" ) ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Settings . PollingParameters ( new TimeSpan ( 10000 ) , true ) ,
2022-09-06 16:08:19 +02:00
Serilog . Events . LogEventLevel . Error ,
activeLockService : typeof ( LocksServiceMock ) . FullName ,
activeGeolocationService : typeof ( GeolocationMock ) . FullName ) ,
new StoreMock ( ) ,
isConnectedFunc : ( ) = > false ,
2023-05-09 08:47:52 +02:00
connectorFactory : ( isConnected , uri , sessionCookie , mail , expiresAfter ) = > new ConnectorCache ( new AppContextInfo ( "MyMerchId" , "MyApp" , new Version ( 1 , 2 ) ) , null /*UI language */ , sessionCookie , mail , server : new CopriCallsMemory001v2NotLoggedIn ( sessionCookie ) ) ,
2022-09-06 16:08:19 +02:00
merchantId : "MyMerchId" ,
bluetoothService : Substitute . For < IBluetoothLE > ( ) ,
locationPermissionsService : Substitute . For < ILocationPermission > ( ) ,
2023-04-05 15:02:10 +02:00
locationServicesContainer : Substitute . For < IServicesContainer < IGeolocationService > > ( ) ,
2022-09-06 16:08:19 +02:00
locksService : new LocksServiceMock ( ) , // Cipher
device : new DeviceMock ( ) ,
specialFolder : new SpecialFolderMock ( ) ,
cipher : null ,
theme : null ,
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
var viewService = Substitute . For < IViewService > ( ) ;
var navigationService = Substitute . For < INavigation > ( ) ;
var locationPermission = Substitute . For < ILocationPermission > ( ) ;
locationPermission . CheckStatusAsync ( ) . Returns ( Status . Granted ) ;
var viewModel = new MapPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp ,
2022-09-06 16:08:19 +02:00
locationPermission ,
2023-05-09 08:47:52 +02:00
Substitute . For < IBluetoothLE > ( ) ,
2023-04-05 15:02:10 +02:00
Substitute . For < IGeolocationService > ( ) ,
2022-09-06 16:08:19 +02:00
( mapspan ) = > { } ,
viewService ,
navigationService ) ;
try
{
await viewModel . OnAppearing ( ) ; // Is called when page shows.
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . Exception , Is . Null ) ;
2022-09-06 16:08:19 +02:00
// Verify pins on map
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . Pins . Count , Is . EqualTo ( 27 ) ) ; // Were 8 pins when loading from CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)
2022-09-06 16:08:19 +02:00
Assert . That (
2023-05-09 08:47:52 +02:00
viewModel . Pins . FirstOrDefault ( pin = > pin . Icon . Id . Contains ( "Open_Green" ) ) ? . Tag , // Was station id 4
2022-09-06 16:08:19 +02:00
Is . EqualTo ( "FR101" ) ,
"Station FR101 must be marked green because there is are bike." ) ;
Assert . That (
2023-05-09 08:47:52 +02:00
viewModel . Pins . FirstOrDefault ( pin = > pin . Icon . Id . Contains ( "Open_Red" ) ) ? . Tag , // Was 31
2022-09-06 16:08:19 +02:00
Is . EqualTo ( "KN12" ) ,
"Station KN12 must be marked red because there is no bike." ) ;
// Verify buttons
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . IsToggleVisible , Is . True , "ShareeBike and Citybike are activated in settings." ) ;
Assert . That ( viewModel . CargoColor , Is . EqualTo ( Color . White ) , "ShareeBike bikes are hidden." ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . CitybikeColor , Is . EqualTo ( Color . FromRgba ( 0 , 0 , 0 , 0 ) ) , "Citybike bikes are shown." ) ;
2022-09-06 16:08:19 +02:00
}
finally
{
await viewModel . OnDisappearing ( ) ;
}
}
[Test]
public async Task TestConstruct_WebConnectCommunicationError ( )
{
2024-04-09 12:53:23 +02:00
var shareeBikeApp = new ShareeBikeApp (
2022-10-17 18:45:38 +02:00
new Settings (
2022-09-06 16:08:19 +02:00
new GroupFilterMapPage ( new Dictionary < string , FilterState > { { FilterHelper . CARGOBIKE , FilterState . On } , { FilterHelper . CITYBIKE , FilterState . Off } } ) ,
new GroupFilterSettings ( new Dictionary < string , FilterState > { { FilterHelper . CARGOBIKE , FilterState . On } , { FilterHelper . CITYBIKE , FilterState . On } } ) ,
2022-10-17 18:45:38 +02:00
new StartupSettings ( ) ,
2022-09-06 16:08:19 +02:00
new Uri ( "https://tinkwwp.copri-bike.de/APIjsonserver" ) ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Settings . PollingParameters ( new TimeSpan ( 10000 ) , true ) ,
2022-09-06 16:08:19 +02:00
Serilog . Events . LogEventLevel . Error ,
true /* IsReportLevelVerbose */ ,
activeLockService : typeof ( LocksServiceMock ) . FullName ,
activeGeolocationService : typeof ( GeolocationMock ) . FullName ) ,
new StoreMock ( ) ,
isConnectedFunc : ( ) = > false ,
connectorFactory : ( isConnected , uri , sessionCookie , mail , expiresAfter ) = > new Connector (
uri ,
new AppContextInfo ( "oiF2kahH" , "sharee.bike.test" , new Version ( 3 , 0 , 267 ) ) ,
null /*UI language */ ,
sessionCookie ,
mail ,
server : new CopriProviderHttps (
uri ,
2024-04-09 12:53:23 +02:00
ShareeBikeApp . MerchantId ,
2022-09-06 16:08:19 +02:00
new AppContextInfo ( "oiF2kahH" , "sharee.bike.test" , new Version ( 3 , 0 , 267 ) ) ,
null /*UI language */ ,
sessionCookie : sessionCookie ,
2023-05-09 08:47:52 +02:00
cacheServer : new CopriCallsCacheMemory001v2NotLoggedIn ( sessionCookie : sessionCookie ) ,
2022-09-06 16:08:19 +02:00
httpsServer : new ExceptionServer ( ( msg ) = > new WebConnectFailureException ( msg , new Exception ( "Source expection." ) ) ) ) ) ,
merchantId : "MyMerchId" ,
bluetoothService : Substitute . For < IBluetoothLE > ( ) ,
locationPermissionsService : Substitute . For < ILocationPermission > ( ) ,
2023-04-05 15:02:10 +02:00
locationServicesContainer : Substitute . For < IServicesContainer < IGeolocationService > > ( ) ,
2022-09-06 16:08:19 +02:00
locksService : new LocksServiceMock ( ) , // Cipher
device : new DeviceMock ( ) ,
specialFolder : new SpecialFolderMock ( ) ,
cipher : null ,
theme : null ,
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
var viewService = Substitute . For < IViewService > ( ) ;
var navigationService = Substitute . For < INavigation > ( ) ;
var locationPermission = Substitute . For < ILocationPermission > ( ) ;
locationPermission . CheckStatusAsync ( ) . Returns ( Status . Granted ) ;
var viewModel = new MapPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp ,
2022-09-06 16:08:19 +02:00
locationPermission ,
Substitute . For < Plugin . BLE . Abstractions . Contracts . IBluetoothLE > ( ) ,
2023-04-05 15:02:10 +02:00
Substitute . For < IGeolocationService > ( ) ,
2022-09-06 16:08:19 +02:00
( mapspan ) = > { } ,
viewService ,
navigationService ) ;
try
{
await viewModel . OnAppearing ( ) ; // Is called when page shows.
2024-04-09 12:53:23 +02:00
Assert . That (
viewModel . Exception . Message , Is . EqualTo ( "Simulated error thrown at GetStationsAsync." ) ) ;
2022-09-06 16:08:19 +02:00
// Verify pins on map
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . Pins . Count , Is . EqualTo ( 27 ) ) ;
2022-09-06 16:08:19 +02:00
Assert . That (
2023-05-09 08:47:52 +02:00
viewModel . Pins . FirstOrDefault ( pin = > pin . Icon . Id . Contains ( "Open_Green" ) ) ? . Tag , // Was station id 4
2022-09-06 16:08:19 +02:00
Is . EqualTo ( "FR101" ) ,
"Station FR101 must be marked green because there is are bike." ) ;
Assert . That (
2023-05-09 08:47:52 +02:00
viewModel . Pins . FirstOrDefault ( pin = > pin . Icon . Id . Contains ( "Open_Red" ) ) ? . Tag , // Was 31
2022-09-06 16:08:19 +02:00
Is . EqualTo ( "KN12" ) ,
"Station KN12 must be marked red because there is no bike." ) ;
// Verify buttons
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . IsToggleVisible , Is . True , "ShareeBike and Citybike are activated in settings." ) ;
Assert . That ( viewModel . CargoColor , Is . EqualTo ( Color . White ) , "ShareeBike bikes are hidden." ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . CitybikeColor , Is . EqualTo ( Color . FromRgba ( 0 , 0 , 0 , 0 ) ) , "Citybike bikes are shown." ) ;
2022-09-06 16:08:19 +02:00
}
finally
{
await viewModel . OnDisappearing ( ) ;
}
}
[Test]
public async Task TestConstruct_GeneralPurposeCommunicationError ( )
{
2024-04-09 12:53:23 +02:00
var shareeBikeApp = new ShareeBikeApp (
2022-10-17 18:45:38 +02:00
new Settings (
2022-09-06 16:08:19 +02:00
new GroupFilterMapPage ( new Dictionary < string , FilterState > { { FilterHelper . CARGOBIKE , FilterState . On } , { FilterHelper . CITYBIKE , FilterState . Off } } ) ,
new GroupFilterSettings ( new Dictionary < string , FilterState > { { FilterHelper . CARGOBIKE , FilterState . On } , { FilterHelper . CITYBIKE , FilterState . On } } ) ,
2022-10-17 18:45:38 +02:00
new StartupSettings ( ) ,
2022-09-06 16:08:19 +02:00
new Uri ( "https://tinkwwp.copri-bike.de/APIjsonserver" ) ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Settings . PollingParameters ( new TimeSpan ( 10000 ) , true ) ,
2022-09-06 16:08:19 +02:00
Serilog . Events . LogEventLevel . Error ,
true /* IsReportLevelVerbose */ ,
activeLockService : typeof ( LocksServiceMock ) . FullName ,
activeGeolocationService : typeof ( GeolocationMock ) . FullName ) ,
new StoreMock ( ) ,
isConnectedFunc : ( ) = > false ,
connectorFactory : ( isConnected , uri , sessionCookie , mail , expiresAfter ) = > new Connector (
uri ,
new AppContextInfo ( "oiF2kahH" , "sharee.bike.test" , new Version ( 3 , 0 , 267 ) ) ,
null /*UI language */ ,
sessionCookie ,
mail ,
server : new CopriProviderHttps (
uri ,
2024-04-09 12:53:23 +02:00
ShareeBikeApp . MerchantId ,
2022-09-06 16:08:19 +02:00
new AppContextInfo ( "oiF2kahH" , "sharee.bike.test" , new Version ( 3 , 0 , 267 ) ) ,
null /*UI language */ ,
sessionCookie : sessionCookie ,
2023-05-09 08:47:52 +02:00
cacheServer : new CopriCallsCacheMemory001v2NotLoggedIn ( sessionCookie : sessionCookie ) ,
2022-09-06 16:08:19 +02:00
httpsServer : new ExceptionServer ( ( msg ) = > new Exception ( msg ) ) ) ) ,
merchantId : "MyMerchId" ,
bluetoothService : Substitute . For < IBluetoothLE > ( ) ,
locationPermissionsService : Substitute . For < ILocationPermission > ( ) ,
2023-04-05 15:02:10 +02:00
locationServicesContainer : Substitute . For < IServicesContainer < IGeolocationService > > ( ) ,
2022-09-06 16:08:19 +02:00
locksService : new LocksServiceMock ( ) , // Cipher
device : new DeviceMock ( ) ,
specialFolder : new SpecialFolderMock ( ) ,
cipher : null ,
theme : null ,
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
var viewService = Substitute . For < IViewService > ( ) ;
var navigationService = Substitute . For < INavigation > ( ) ;
var locationPermission = Substitute . For < ILocationPermission > ( ) ;
locationPermission . CheckStatusAsync ( ) . Returns ( Status . Granted ) ;
var viewModel = new MapPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp ,
2022-09-06 16:08:19 +02:00
locationPermission ,
Substitute . For < Plugin . BLE . Abstractions . Contracts . IBluetoothLE > ( ) ,
2023-04-05 15:02:10 +02:00
Substitute . For < IGeolocationService > ( ) ,
2022-09-06 16:08:19 +02:00
( mapspan ) = > { } ,
viewService ,
navigationService ) ;
try
{
await viewModel . OnAppearing ( ) ; // Is called when page shows.
2024-04-09 12:53:23 +02:00
Assert . That (
viewModel . Exception . Message , Is . EqualTo ( "Simulated error thrown at GetStationsAsync." ) ) ;
2022-09-06 16:08:19 +02:00
// Verify pins on map
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . Pins . Count , Is . EqualTo ( 27 ) ) ;
2022-09-06 16:08:19 +02:00
Assert . That (
viewModel . Pins . Where ( pin = > pin . Icon . Id . Contains ( "Open_Green" ) ) . Select ( pin = > pin . Tag . ToString ( ) ) ,
Does . Contain ( "FR101" ) , // Was station id 4
"Station FR103 must be marked green because there is are bike." ) ;
Assert . That (
viewModel . Pins . Where ( pin = > pin . Icon . Id . Contains ( "Open_Red" ) ) . Select ( pin = > pin . Tag . ToString ( ) ) ,
Does . Contain ( "KN12" ) , // Was station id 31
"Station 31 must be marked red because there is no bike." ) ;
// Verify buttons
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . IsToggleVisible , Is . True , "ShareeBike and Citybike are activated in settings." ) ;
Assert . That ( viewModel . CargoColor , Is . EqualTo ( Color . White ) , "ShareeBike bikes are hidden." ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
Assert . That ( viewModel . CitybikeColor , Is . EqualTo ( Color . FromRgba ( 0 , 0 , 0 , 0 ) ) , "Citybike bikes are shown." ) ;
2022-09-06 16:08:19 +02:00
}
finally
{
await viewModel . OnDisappearing ( ) ;
}
}
2023-05-09 08:47:52 +02:00
[Test]
public void TestGetStationColors ( )
{
var stationIds = new List < string > ( ) { "FR101" , "BVB9003" , "BVB9001" } ;
var bikeGroupFr101 = Substitute . For < IBikeGroupCol > ( ) ;
var bikeGroupBVB9003 = Substitute . For < IBikeGroupCol > ( ) ;
var bikeGroupBVB9001 = Substitute . For < IBikeGroupCol > ( ) ;
bikeGroupFr101 . AvailableCount . Returns ( 1 ) ;
bikeGroupBVB9003 . AvailableCount . Returns ( 7 ) ;
bikeGroupBVB9001 . AvailableCount . Returns ( 0 ) ;
var stations = new List < Station >
{
new Station ( "FR101" , new List < string > ( ) /* group */ , Substitute . For < IPosition > ( ) , bikeGropCol : bikeGroupFr101 ) ,
new Station ( "BVB9003" , new List < string > ( ) /* group */ , Substitute . For < IPosition > ( ) , bikeGropCol : bikeGroupBVB9003 ) ,
new Station ( "BVB9001" , new List < string > ( ) /* group */ , Substitute . For < IPosition > ( ) , bikeGropCol : bikeGroupBVB9001 )
} ;
2024-04-09 12:53:23 +02:00
var bikes = new List < ShareeBike . Model . Bikes . BikeInfoNS . BC . BikeInfo > {
2023-05-09 08:47:52 +02:00
// Add a reserved bike to station "FR101"
new BikeInfo (
new Bike ( "Id1" , LockModel . ILockIt ) ,
2023-08-31 12:31:38 +02:00
new DriveMutable ( ) ,
2024-04-09 12:53:23 +02:00
ShareeBike . Model . Bikes . BikeInfoNS . BC . DataSource . Copri ,
2023-05-09 08:47:52 +02:00
123 , // Lock id
new Guid ( ) ,
new byte [ 0 ] ,
new byte [ 0 ] ,
new byte [ 0 ] ,
DateTime . Parse ( "2023-03-26 15:19" ) ,
"a@b" ,
"FR101" ,
new Uri ( "https://1.2.3.4" ) ,
new RentalDescription ( ) ,
( ) = > DateTime . Now )
} ;
var colorList = MapPageViewModel . GetStationColors ( stationIds , stations , bikes ) ;
Assert . That ( colorList [ 0 ] , Is . EqualTo ( Color . LightBlue ) , "1 bike reserved/ rented." ) ;
Assert . That ( colorList [ 1 ] , Is . EqualTo ( Color . Green ) , "7 available bikes." ) ;
Assert . That ( colorList [ 2 ] , Is . EqualTo ( Color . Red ) , "No bike" ) ;
}
[Test]
public void TestGetStationColorsNullIds ( )
{
var colorList = MapPageViewModel . GetStationColors ( null , null , null ) ;
Assert . That ( colorList . Count , Is . EqualTo ( 0 ) ) ;
}
[Test]
public void TestGetStationColorsNoStations ( )
{
var stationIds = new List < string > ( ) { "FR101" , "BVB9003" , "BVB9001" } ;
2024-04-09 12:53:23 +02:00
var bikes = new List < ShareeBike . Model . Bikes . BikeInfoNS . BC . BikeInfo > {
2023-05-09 08:47:52 +02:00
// Add a reserved bike to station "FR101"
new BikeInfo (
new Bike ( "Id1" , LockModel . ILockIt ) ,
2023-08-31 12:31:38 +02:00
new DriveMutable ( ) ,
2024-04-09 12:53:23 +02:00
ShareeBike . Model . Bikes . BikeInfoNS . BC . DataSource . Copri ,
2023-05-09 08:47:52 +02:00
123 , // Lock id
new Guid ( ) ,
new byte [ 0 ] ,
new byte [ 0 ] ,
new byte [ 0 ] ,
DateTime . Parse ( "2023-03-26 15:19" ) ,
"a@b" ,
"FR101" ,
new Uri ( "https://1.2.3.4" ) ,
new RentalDescription ( ) ,
( ) = > DateTime . Now )
} ;
var colorList = MapPageViewModel . GetStationColors ( stationIds , null , bikes ) ;
Assert . That ( colorList [ 0 ] , Is . EqualTo ( Color . LightBlue ) , "1 bike reserved/ rented." ) ;
Assert . That ( colorList [ 1 ] , Is . EqualTo ( Color . Red ) , "No bike." ) ;
Assert . That ( colorList [ 2 ] , Is . EqualTo ( Color . Red ) , "No bike" ) ;
}
[Test]
public void TestGetStationColorsNoBikes ( )
{
var stationIds = new List < string > ( ) { "FR101" , "BVB9003" , "BVB9001" } ;
var bikeGroupFr101 = Substitute . For < IBikeGroupCol > ( ) ;
var bikeGroupBVB9003 = Substitute . For < IBikeGroupCol > ( ) ;
var bikeGroupBVB9001 = Substitute . For < IBikeGroupCol > ( ) ;
bikeGroupFr101 . AvailableCount . Returns ( 1 ) ;
bikeGroupBVB9003 . AvailableCount . Returns ( 7 ) ;
bikeGroupBVB9001 . AvailableCount . Returns ( 0 ) ;
var stations = new List < Station >
{
new Station ( "FR101" , new List < string > ( ) /* group */ , Substitute . For < IPosition > ( ) , bikeGropCol : bikeGroupFr101 ) ,
new Station ( "BVB9003" , new List < string > ( ) /* group */ , Substitute . For < IPosition > ( ) , bikeGropCol : bikeGroupBVB9003 ) ,
new Station ( "BVB9001" , new List < string > ( ) /* group */ , Substitute . For < IPosition > ( ) , bikeGropCol : bikeGroupBVB9001 )
} ;
var colorList = MapPageViewModel . GetStationColors ( stationIds , stations , null ) ;
Assert . That ( colorList [ 0 ] , Is . EqualTo ( Color . Green ) , "No bike reserved/ rented." ) ;
Assert . That ( colorList [ 1 ] , Is . EqualTo ( Color . Green ) , "7 available bikes." ) ;
Assert . That ( colorList [ 2 ] , Is . EqualTo ( Color . Red ) , "No bike" ) ;
}
2022-09-06 16:08:19 +02:00
}
2021-07-12 21:31:46 +02:00
}