2022-10-17 18:45:38 +02:00
using System ;
2021-07-12 21:31:46 +02:00
using System.Collections.Generic ;
using System.Linq ;
using System.Threading.Tasks ;
2022-08-30 15:42:25 +02:00
using NSubstitute ;
using NSubstitute.ExceptionExtensions ;
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 ShareeBike.Model ;
using ShareeBike.Model.Connector ;
using ShareeBike.Model.Device ;
using ShareeBike.Model.Services.CopriApi ;
using ShareeBike.Model.Settings ;
using ShareeBike.Repository ;
using ShareeBike.Repository.Exception ;
using ShareeBike.Services ;
using ShareeBike.Services.BluetoothLock ;
using ShareeBike.Services.BluetoothLock.Tdo ;
using ShareeBike.Services.Geolocation ;
using ShareeBike.Services.Permissions ;
using ShareeBike.View ;
using ShareeBike.ViewModel.BikesAtStation ;
using ShareeBike.ViewModel.Map ;
using ShareeBike.ViewModel.Settings ;
2022-01-04 18:59:16 +01:00
using Xamarin.Forms ;
2024-04-09 12:53:23 +02:00
using static ShareeBike . Repository . CopriCallsMemory ;
2021-07-12 21:31:46 +02:00
2024-04-09 12:53:23 +02:00
namespace SharedBusinessLogic.Tests.Fixtures.ObjectTests.ViewModel
2021-07-12 21:31:46 +02:00
{
2022-09-06 16:08:19 +02:00
[TestFixture]
public class TestBikesAtStationPageViewModel
{
[Test]
public async Task TestConstruct_Droid_NotLoggedIn ( )
{
2023-04-05 15:02:10 +02:00
var geolocation = Substitute . For < IServicesContainer < IGeolocationService > > ( ) ;
2022-09-06 16:08:19 +02:00
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 > ( ) ;
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://shareeapp-primary.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 : locksService . GetType ( ) . FullName ,
activeGeolocationService : typeof ( GeolocationMock ) . FullName ) ,
2024-04-09 12:53:23 +02:00
new StoreMock ( new ShareeBike . Model . User . Account . Account ( "" , null , false , null , new List < string > ( ) ) ) ,
2022-09-06 16:08:19 +02:00
isConnectedFunc : ( ) = > true ,
2023-02-22 14:03:35 +01:00
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 ) ) ,
2022-09-06 16:08:19 +02:00
merchantId : "MyMerchId" ,
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 bikesAtStation = new BikesAtStationPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp . ActiveUser ,
2022-09-06 16:08:19 +02:00
permissions ,
bluetooth ,
Device . Android ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Model . Stations . StationNS . Station ( "FR103" , new List < string > ( ) , null ) , // Was station id 103 before switching from data provider CopriCallsMemory(SampleSets.ShareeFr01_Set1, 1, ...)
( ) = > shareeBikeApp . GetIsConnected ( ) ,
( isConnected ) = > shareeBikeApp . GetConnector ( isConnected ) ,
2022-09-06 16:08:19 +02:00
geolocation . Active , // geolocation
locksService ,
2024-04-09 12:53:23 +02:00
shareeBikeApp . Polling ,
2022-09-06 16:08:19 +02:00
( url ) = > { } ,
( d , obj ) = > d ( obj ) ,
Substitute . For < ISmartDevice > ( ) ,
viewService ) ;
2023-02-22 14:03:35 +01:00
await bikesAtStation . OnAppearingOrRefresh ( ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . StatusInfoText , Is . Empty ) ;
2022-09-06 16:08:19 +02:00
// Verify list of bikes
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . Count , Is . EqualTo ( 2 ) ) ;
Assert . That ( bikesAtStation . IsIdle , Is . True ) ;
Assert . That ( bikesAtStation . IsBikesListVisible , Is . True , "If there are any bikes, list must be visible." ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
var bikeFR9999 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "FR9999" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ; // Was id 1315
var bikeFR9998 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "FR9998" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ; // Was id 1543
2022-09-06 16:08:19 +02:00
Assert . That (
bikeFR9999 ,
Is . Not . Null ) ;
Assert . That (
bikeFR9998 ,
Is . Not . Null ) ;
2024-04-09 12:53:23 +02:00
Assert . That ( bikeFR9999 . StateText , Is . EqualTo ( "Available." ) ) ;
Assert . That ( bikeFR9998 . StateText , Is . EqualTo ( "Available." ) ) ;
Assert . That ( bikeFR9999 . LockitButtonText , Is . EqualTo ( "NotLoggedIn" ) ) ;
Assert . That ( bikeFR9998 . LockitButtonText , Is . EqualTo ( "NotLoggedIn" ) ) ;
2022-09-06 16:08:19 +02:00
// Login hint/ no bikes frame
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . IsLoginRequiredHintVisible , Is . True ) ;
Assert . That ( bikesAtStation . IsNoBikesAtStationVisible , Is . False ) ;
Assert . That ( bikesAtStation . NoBikesAtStationText , Is . EqualTo ( string . Empty ) ) ;
2022-09-06 16:08:19 +02:00
}
[Test]
public async Task TestConstruct_Droid_NoBikes ( )
{
2023-04-05 15:02:10 +02:00
var geolocation = Substitute . For < IServicesContainer < IGeolocationService > > ( ) ;
2022-09-06 16:08:19 +02:00
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 > ( ) ;
const string MERCH_ID = "MyMerchId" ;
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://shareeapp-primary.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 : locksService . GetType ( ) . FullName ,
activeGeolocationService : typeof ( GeolocationMock ) . FullName ) ,
2024-04-09 12:53:23 +02:00
new StoreMock ( new ShareeBike . Model . User . Account . Account ( "a@b" , "123456789" , false , "5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH" , new List < string > { "300001" , "300029" } ) ) ,
2022-09-06 16:08:19 +02:00
isConnectedFunc : ( ) = > true ,
2023-02-22 14:03:35 +01:00
connectorFactory : ( isConnected , uri , sessionCookie , mail , expiresAfter ) = > new ConnectorCache ( new AppContextInfo ( "MyMerchId" , "MyApp" , new Version ( 1 , 2 ) ) , null /*UI language */ , sessionCookie , mail , server : new CopriCallsMemory ( MERCH_ID , SampleSets . ShareeFr01_Set1 , 1 , sessionCookie ) ) ,
2022-09-06 16:08:19 +02:00
merchantId : "MyMerchId" ,
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 bikesAtStation = new BikesAtStationPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp . ActiveUser ,
2022-09-06 16:08:19 +02:00
permissions ,
bluetooth ,
Device . Android ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Model . Stations . StationNS . Station ( "102" , new List < string > ( ) , null /* position*/ , operatorUri : new Uri ( "https://shareeapp-fr01.copri.eu//APIjsonserver" ) ) , // Station 102
( ) = > shareeBikeApp . GetIsConnected ( ) ,
( isConnected ) = > shareeBikeApp . GetConnector ( isConnected ) ,
2022-09-06 16:08:19 +02:00
geolocation . Active , // geolocation
locksService ,
2024-04-09 12:53:23 +02:00
shareeBikeApp . Polling ,
2022-09-06 16:08:19 +02:00
( url ) = > { } ,
( d , obj ) = > d ( obj ) ,
Substitute . For < ISmartDevice > ( ) ,
viewService ) ;
2023-02-22 14:03:35 +01:00
await bikesAtStation . OnAppearingOrRefresh ( ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . StatusInfoText , Is . Empty ) ;
2022-09-06 16:08:19 +02:00
// Verify list of bikes
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . Count , Is . EqualTo ( 0 ) ) ;
Assert . That ( bikesAtStation . IsIdle , Is . True ) ;
Assert . That ( bikesAtStation . IsBikesListVisible , Is . False , "If there are any bikes, list must be visible." ) ;
2022-09-06 16:08:19 +02:00
// Login hint/ no bikes frame
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . IsLoginRequiredHintVisible , Is . False ) ;
Assert . That ( bikesAtStation . IsNoBikesAtStationVisible , Is . True ) ;
Assert . That ( bikesAtStation . NoBikesAtStationText , Is . EqualTo ( "There are currently no bicycles available at this station." ) ) ;
2022-09-06 16:08:19 +02:00
}
[Test]
public async Task TestConstruct_Droid ( )
{
2023-04-05 15:02:10 +02:00
var geolocation = Substitute . For < IServicesContainer < IGeolocationService > > ( ) ;
2022-09-06 16:08:19 +02:00
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 > ( ) ;
// 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" ;
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://shareeapp-primary.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 : locksService . GetType ( ) . FullName ,
activeGeolocationService : typeof ( GeolocationMock ) . FullName ) ,
2024-04-09 12:53:23 +02:00
new StoreMock ( new ShareeBike . Model . User . Account . Account ( "a@b" , "123456789" , false , "5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH" , new List < string > { "300001" , "300029" } ) ) ,
2022-09-06 16:08:19 +02:00
isConnectedFunc : ( ) = > true ,
2023-02-22 14:03:35 +01:00
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 ) ) ,
2022-09-06 16:08:19 +02:00
merchantId : MERCH_ID , // Instance geolocation mocks both parts
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 bikesAtStation = new BikesAtStationPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp . ActiveUser ,
2022-09-06 16:08:19 +02:00
permissions ,
bluetooth ,
Device . Android ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Model . Stations . StationNS . Station ( "103" , new List < string > ( ) , null ) , // Station 103
( ) = > shareeBikeApp . GetIsConnected ( ) ,
( isConnected ) = > shareeBikeApp . GetConnector ( isConnected ) ,
2022-09-06 16:08:19 +02:00
geolocation . Active , // geolocation
locksService ,
2024-04-09 12:53:23 +02:00
shareeBikeApp . Polling ,
2022-09-06 16:08:19 +02:00
( url ) = > { } ,
( d , obj ) = > d ( obj ) ,
Substitute . For < ISmartDevice > ( ) ,
viewService ) ;
2023-02-22 14:03:35 +01:00
await bikesAtStation . OnAppearingOrRefresh ( ) ;
2022-09-06 16:08:19 +02:00
2023-04-19 12:14:14 +02:00
// Verify behavior
2022-09-06 16:08:19 +02:00
Received . InOrder ( ( ) = >
{
permissions . CheckStatusAsync ( ) ;
var glDummy = geolocation . Active . Received ( ) . IsGeolcationEnabled ;
var btDummy = bluetooth . Received ( ) . State ;
locksService . GetLocksStateAsync ( Arg . Any < IEnumerable < LockInfoAuthTdo > > ( ) , Arg . Any < TimeSpan > ( ) ) ;
} ) ;
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . StatusInfoText , Is . Empty ) ;
2022-09-06 16:08:19 +02:00
// Verify list of bikes
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . Count , Is . EqualTo ( 4 ) ) ;
Assert . That ( bikesAtStation . IsIdle , Is . True ) ;
Assert . That ( bikesAtStation . IsBikesListVisible , Is . True , "If there are any bikes, list must be visible." ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
var bike1545 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1545" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
var bike1537 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1537" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
var bike1315 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1315" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
var bike1543 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1543" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
2022-09-06 16:08:19 +02:00
Assert . That (
bike1545 ,
Is . Not . Null ) ;
Assert . That (
bike1537 ,
Is . Not . Null ) ;
Assert . That (
bike1315 ,
Is . Not . Null ) ;
Assert . That (
bike1543 ,
Is . Not . Null ) ;
2024-04-09 12:53:23 +02:00
Assert . That ( bike1545 . StateText , Is . EqualTo ( $"Rented since {DateTime.Parse(" 2020 - 11 - 06 17 : 53 : 22.784681 + 01 "):dd. MMMM HH:mm}." ) ) ;
Assert . That ( bike1537 . StateText , Is . EqualTo ( $"Rented since {DateTime.Parse(" 2020 - 10 - 12 08 : 38 : 12.374231 + 02 "):dd. MMMM HH:mm}." ) ) ;
Assert . That ( bike1315 . StateText , Is . EqualTo ( "Available." ) ) ;
Assert . That ( bike1543 . StateText , Is . EqualTo ( "Available." ) ) ;
Assert . That ( bike1545 . ButtonText , Is . EqualTo ( "Close lock" ) ) ;
Assert . That ( bike1545 . LockitButtonText , Is . EqualTo ( "BookedOpen" ) ) ;
Assert . That ( bike1537 . LockitButtonText , Is . EqualTo ( "Open lock" ) ) ;
Assert . That ( bike1315 . LockitButtonText , Is . EqualTo ( "DisposableDisconnected" ) ) ;
Assert . That ( bike1543 . LockitButtonText , Is . EqualTo ( "DisposableDisconnected" ) ) ;
2022-09-06 16:08:19 +02:00
// Login hint/ no bikes frame
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . IsLoginRequiredHintVisible , Is . False ) ;
Assert . That ( bikesAtStation . IsNoBikesAtStationVisible , Is . False ) ;
Assert . That ( bikesAtStation . NoBikesAtStationText , Is . EqualTo ( string . Empty ) ) ;
2022-09-06 16:08:19 +02:00
}
[Test]
public async Task TestConstruct_Droid_NoPermissions_OpenSettings ( )
{
2023-04-05 15:02:10 +02:00
var geolocation = Substitute . For < IServicesContainer < IGeolocationService > > ( ) ;
2022-09-06 16:08:19 +02:00
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 > ( ) ;
// 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 ) ;
// 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 ( ) }
}
) ;
bluetooth . State . Returns ( BluetoothState . On ) ;
const string MERCH_ID = "MyMerchId" ;
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://shareeapp-primary.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 : locksService . GetType ( ) . FullName ,
activeGeolocationService : typeof ( GeolocationMock ) . FullName ) ,
2024-04-09 12:53:23 +02:00
new StoreMock ( new ShareeBike . Model . User . Account . Account ( "a@b" , "123456789" , false , "5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH" , new List < string > { "300001" , "300029" } ) ) ,
2022-09-06 16:08:19 +02:00
isConnectedFunc : ( ) = > true ,
2023-02-22 14:03:35 +01:00
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 ) ) ,
2022-09-06 16:08:19 +02:00
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 bikesAtStation = new BikesAtStationPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp . ActiveUser ,
2022-09-06 16:08:19 +02:00
permissions ,
bluetooth ,
Device . Android ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Model . Stations . StationNS . Station ( "103" , new List < string > ( ) , null ) , // Station 103
( ) = > shareeBikeApp . GetIsConnected ( ) ,
( isConnected ) = > shareeBikeApp . GetConnector ( isConnected ) ,
2022-09-06 16:08:19 +02:00
geolocation . Active , // geolocation
locksService ,
2024-04-09 12:53:23 +02:00
shareeBikeApp . Polling ,
2022-09-06 16:08:19 +02:00
( url ) = > { } ,
( d , obj ) = > d ( obj ) ,
Substitute . For < ISmartDevice > ( ) ,
viewService ) ;
2023-02-22 14:03:35 +01:00
await bikesAtStation . OnAppearingOrRefresh ( ) ;
2022-09-06 16:08:19 +02:00
2023-04-19 12:14:14 +02:00
// Verify behavior
2022-09-06 16:08:19 +02:00
Received . InOrder ( ( ) = >
{
permissions . CheckStatusAsync ( ) ;
var glDummy = geolocation . Active . Received ( ) . IsGeolcationEnabled ;
2022-12-07 16:54:52 +01:00
// permissions.RequestAsync(); // Ask user from permissions (disabled, since no secondary request allowed).
2022-09-06 16:08:19 +02:00
viewService . DisplayAlert (
"Hint" ,
"Please allow location sharing so that bike lock/locks can be managed.\r\nOpen sharing dialog?" ,
"Yes" ,
"No" ) ;
permissions . OpenAppSettings ( ) ;
} ) ;
2024-04-09 12:53:23 +02:00
Assert . That ( new List < string > { "Updating..." , string . Empty } . Contains ( bikesAtStation . StatusInfoText ) , Is . True ) ;
2022-09-06 16:08:19 +02:00
// Verify list of bikes
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . Count , Is . EqualTo ( 4 ) ) ;
Assert . That ( bikesAtStation . IsIdle , Is . True ) ;
Assert . That ( bikesAtStation . IsBikesListVisible , Is . True , "If there are any bikes, list must be visible." ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
var bike1545 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1545" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
var bike1537 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1537" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
var bike1315 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1315" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
var bike1543 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1543" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
2022-09-06 16:08:19 +02:00
Assert . That (
bike1545 ,
Is . Not . Null ) ;
Assert . That (
bike1537 ,
Is . Not . Null ) ;
Assert . That (
bike1315 ,
Is . Not . Null ) ;
Assert . That (
bike1543 ,
Is . Not . Null ) ;
2024-04-09 12:53:23 +02:00
Assert . That ( bike1545 . StateText , Is . EqualTo ( $"Rented since {DateTime.Parse(" 2020 - 11 - 06 17 : 53 : 22.784681 + 01 "):dd. MMMM HH:mm}." ) ) ;
Assert . That ( bike1537 . StateText , Is . EqualTo ( $"Rented since {DateTime.Parse(" 2020 - 10 - 12 08 : 38 : 12.374231 + 02 "):dd. MMMM HH:mm}." ) ) ;
Assert . That ( bike1315 . StateText , Is . EqualTo ( "Available." ) ) ;
Assert . That ( bike1543 . StateText , Is . EqualTo ( "Available." ) ) ;
Assert . That ( bike1545 . ButtonText , Is . EqualTo ( "Connect lock" ) ) ;
Assert . That ( bike1537 . ButtonText , Is . EqualTo ( "Connect lock" ) ) ;
Assert . That ( bike1315 . LockitButtonText , Is . EqualTo ( "DisposableDisconnected" ) ) ;
Assert . That ( bike1543 . LockitButtonText , Is . EqualTo ( "DisposableDisconnected" ) ) ;
2022-09-06 16:08:19 +02:00
// Login hint/ no bikes frame
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . IsLoginRequiredHintVisible , Is . False ) ;
Assert . That ( bikesAtStation . IsNoBikesAtStationVisible , Is . False ) ;
Assert . That ( bikesAtStation . NoBikesAtStationText , Is . EqualTo ( string . Empty ) ) ;
2022-09-06 16:08:19 +02:00
}
[Test]
public async Task TestConstruct_Droid_NoPermissions ( )
{
2023-04-05 15:02:10 +02:00
var geolocation = Substitute . For < IServicesContainer < IGeolocationService > > ( ) ;
2022-09-06 16:08:19 +02:00
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 > ( ) ;
// 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.
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" ;
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://shareeapp-primary.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 : locksService . GetType ( ) . FullName ,
activeGeolocationService : typeof ( GeolocationMock ) . FullName ) ,
2024-04-09 12:53:23 +02:00
new StoreMock ( new ShareeBike . Model . User . Account . Account ( "a@b" , "123456789" , false , "5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH" , new List < string > { "300001" , "300029" } ) ) ,
2022-09-06 16:08:19 +02:00
isConnectedFunc : ( ) = > true ,
2023-02-22 14:03:35 +01:00
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 ) ) ,
2022-09-06 16:08:19 +02:00
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 bikesAtStation = new BikesAtStationPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp . ActiveUser ,
2022-09-06 16:08:19 +02:00
permissions ,
bluetooth ,
Device . Android ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Model . Stations . StationNS . Station ( "103" , new List < string > ( ) , null ) , // Station 103
( ) = > shareeBikeApp . GetIsConnected ( ) ,
( isConnected ) = > shareeBikeApp . GetConnector ( isConnected ) ,
2022-09-06 16:08:19 +02:00
geolocation . Active , // geolocation
locksService ,
2024-04-09 12:53:23 +02:00
shareeBikeApp . Polling ,
2022-09-06 16:08:19 +02:00
( url ) = > { } ,
( d , obj ) = > d ( obj ) ,
Substitute . For < ISmartDevice > ( ) ,
viewService ) ;
2023-02-22 14:03:35 +01:00
await bikesAtStation . OnAppearingOrRefresh ( ) ;
2022-09-06 16:08:19 +02:00
2023-04-19 12:14:14 +02:00
// Verify behavior
2022-09-06 16:08:19 +02:00
Received . InOrder ( ( ) = >
{
permissions . CheckStatusAsync ( ) ;
var glDummy = geolocation . Active . Received ( ) . IsGeolcationEnabled ;
2022-12-07 16:54:52 +01:00
//permissions.RequestAsync(); // Ask user from permissions (disabled, since no secondary request allowed).
2022-09-06 16:08:19 +02:00
viewService . DisplayAlert (
"Hint" ,
"Please allow location sharing so that bike lock/locks can be managed.\r\nOpen sharing dialog?" ,
"Yes" ,
"No" ) ;
} ) ;
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . StatusInfoText , Is . Empty ) ;
2022-09-06 16:08:19 +02:00
// Verify list of bikes
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . Count , Is . EqualTo ( 4 ) ) ;
Assert . That ( bikesAtStation . IsIdle , Is . True ) ;
Assert . That ( bikesAtStation . IsBikesListVisible , Is . True , "If there are any bikes, list must be visible." ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
var bike1545 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1545" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
var bike1537 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1537" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
var bike1315 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1315" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
var bike1543 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1543" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
2022-09-06 16:08:19 +02:00
Assert . That (
bike1545 ,
Is . Not . Null ) ;
Assert . That (
bike1537 ,
Is . Not . Null ) ;
Assert . That (
bike1315 ,
Is . Not . Null ) ;
Assert . That (
bike1543 ,
Is . Not . Null ) ;
2024-04-09 12:53:23 +02:00
Assert . That ( bike1545 . StateText , Is . EqualTo ( $"Rented since {DateTime.Parse(" 2020 - 11 - 06 17 : 53 : 22.784681 + 01 "):dd. MMMM HH:mm}." ) ) ;
Assert . That ( bike1537 . StateText , Is . EqualTo ( $"Rented since {DateTime.Parse(" 2020 - 10 - 12 08 : 38 : 12.374231 + 02 "):dd. MMMM HH:mm}." ) ) ;
Assert . That ( bike1315 . StateText , Is . EqualTo ( "Available." ) ) ;
Assert . That ( bike1543 . StateText , Is . EqualTo ( "Available." ) ) ;
Assert . That ( bike1545 . ButtonText , Is . EqualTo ( "Connect lock" ) ) ;
Assert . That ( bike1537 . ButtonText , Is . EqualTo ( "Connect lock" ) ) ;
Assert . That ( bike1315 . LockitButtonText , Is . EqualTo ( "DisposableDisconnected" ) ) ;
Assert . That ( bike1543 . LockitButtonText , Is . EqualTo ( "DisposableDisconnected" ) ) ;
2022-09-06 16:08:19 +02:00
// Login hint/ no bikes frame
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . IsLoginRequiredHintVisible , Is . False ) ;
Assert . That ( bikesAtStation . IsNoBikesAtStationVisible , Is . False ) ;
Assert . That ( bikesAtStation . NoBikesAtStationText , Is . EqualTo ( string . Empty ) ) ;
2022-09-06 16:08:19 +02:00
}
[Test]
public async Task TestConstruct_Droid_GeolocationOff ( )
{
2023-04-05 15:02:10 +02:00
var geolocation = Substitute . For < IServicesContainer < IGeolocationService > > ( ) ;
2022-09-06 16:08:19 +02:00
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 > ( ) ;
// Fake location permissions to be set
permissions . CheckStatusAsync ( ) . Returns ( Task . FromResult ( Status . Granted ) ) ;
geolocation . Active . IsGeolcationEnabled . Returns ( false ) ; // Fake gps to be off
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" ;
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://shareeapp-primary.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 : locksService . GetType ( ) . FullName ,
activeGeolocationService : typeof ( GeolocationMock ) . FullName ) ,
2024-04-09 12:53:23 +02:00
new StoreMock ( new ShareeBike . Model . User . Account . Account ( "a@b" , "123456789" , false , "5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH" , new List < string > { "300001" , "300029" } ) ) ,
2022-09-06 16:08:19 +02:00
isConnectedFunc : ( ) = > true ,
2023-02-22 14:03:35 +01:00
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 ) ) ,
2022-09-06 16:08:19 +02:00
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 bikesAtStation = new BikesAtStationPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp . ActiveUser ,
2022-09-06 16:08:19 +02:00
permissions ,
bluetooth ,
Device . Android ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Model . Stations . StationNS . Station ( "103" , new List < string > ( ) , null ) , // Station 103
( ) = > shareeBikeApp . GetIsConnected ( ) ,
( isConnected ) = > shareeBikeApp . GetConnector ( isConnected ) ,
2022-09-06 16:08:19 +02:00
geolocation . Active , // geolocation
locksService ,
2024-04-09 12:53:23 +02:00
shareeBikeApp . Polling ,
2022-09-06 16:08:19 +02:00
( url ) = > { } ,
( d , obj ) = > d ( obj ) ,
Substitute . For < ISmartDevice > ( ) ,
viewService ) ;
2023-02-22 14:03:35 +01:00
await bikesAtStation . OnAppearingOrRefresh ( ) ;
2022-09-06 16:08:19 +02:00
2023-04-19 12:14:14 +02:00
// Verify behavior
2022-09-06 16:08:19 +02:00
Received . InOrder ( ( ) = >
{
permissions . CheckStatusAsync ( ) ;
var glDummy = geolocation . Active . Received ( ) . IsGeolcationEnabled ;
viewService . DisplayAlert (
"Hint" ,
"Please activate location so that bike lock can be found!" ,
"OK" ) ;
} ) ;
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . StatusInfoText , Is . Empty ) ;
2022-09-06 16:08:19 +02:00
// Verify list of bikes
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . Count , Is . EqualTo ( 4 ) ) ;
Assert . That ( bikesAtStation . IsIdle , Is . True ) ;
Assert . That ( bikesAtStation . IsBikesListVisible , Is . True , "If there are any bikes, list must be visible." ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
var bike1545 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1545" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
var bike1537 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1537" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
var bike1315 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1315" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
var bike1543 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1543" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
2022-09-06 16:08:19 +02:00
Assert . That (
bike1545 ,
Is . Not . Null ) ;
Assert . That (
bike1537 ,
Is . Not . Null ) ;
Assert . That (
bike1315 ,
Is . Not . Null ) ;
Assert . That (
bike1543 ,
Is . Not . Null ) ;
2024-04-09 12:53:23 +02:00
Assert . That ( bike1545 . StateText , Is . EqualTo ( $"Rented since {DateTime.Parse(" 2020 - 11 - 06 17 : 53 : 22.784681 + 01 "):dd. MMMM HH:mm}." ) ) ;
Assert . That ( bike1537 . StateText , Is . EqualTo ( $"Rented since {DateTime.Parse(" 2020 - 10 - 12 08 : 38 : 12.374231 + 02 "):dd. MMMM HH:mm}." ) ) ;
Assert . That ( bike1315 . StateText , Is . EqualTo ( "Available." ) ) ;
Assert . That ( bike1543 . StateText , Is . EqualTo ( "Available." ) ) ;
Assert . That ( bike1545 . ButtonText , Is . EqualTo ( "Connect lock" ) ) ;
Assert . That ( bike1537 . ButtonText , Is . EqualTo ( "Connect lock" ) ) ;
Assert . That ( bike1315 . LockitButtonText , Is . EqualTo ( "DisposableDisconnected" ) ) ;
Assert . That ( bike1543 . LockitButtonText , Is . EqualTo ( "DisposableDisconnected" ) ) ;
2022-09-06 16:08:19 +02:00
// Login hint/ no bikes frame
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . IsLoginRequiredHintVisible , Is . False ) ;
Assert . That ( bikesAtStation . IsNoBikesAtStationVisible , Is . False ) ;
Assert . That ( bikesAtStation . NoBikesAtStationText , Is . EqualTo ( string . Empty ) ) ;
2022-09-06 16:08:19 +02:00
}
[Test]
public async Task TestConstruct_Droid_BluetoothOff ( )
{
2023-04-05 15:02:10 +02:00
var geolocation = Substitute . For < IServicesContainer < IGeolocationService > > ( ) ;
2022-09-06 16:08:19 +02:00
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 > ( ) ;
// 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
// 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" ;
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://shareeapp-primary.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 : locksService . GetType ( ) . FullName ,
activeGeolocationService : typeof ( GeolocationMock ) . FullName ) ,
2024-04-09 12:53:23 +02:00
new StoreMock ( new ShareeBike . Model . User . Account . Account ( "a@b" , "123456789" , false , "5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH" , new List < string > { "300001" , "300029" } ) ) ,
2022-09-06 16:08:19 +02:00
isConnectedFunc : ( ) = > true ,
2023-02-22 14:03:35 +01:00
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 ) ) ,
2022-09-06 16:08:19 +02:00
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 bikesAtStation = new BikesAtStationPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp . ActiveUser ,
2022-09-06 16:08:19 +02:00
permissions ,
bluetooth ,
Device . Android ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Model . Stations . StationNS . Station ( "103" , new List < string > ( ) , null ) , // Station 103
( ) = > shareeBikeApp . GetIsConnected ( ) ,
( isConnected ) = > shareeBikeApp . GetConnector ( isConnected ) ,
2022-09-06 16:08:19 +02:00
geolocation . Active , // geolocation
locksService ,
2024-04-09 12:53:23 +02:00
shareeBikeApp . Polling ,
2022-09-06 16:08:19 +02:00
( url ) = > { } ,
( d , obj ) = > d ( obj ) ,
Substitute . For < ISmartDevice > ( ) ,
viewService ) ;
2023-02-22 14:03:35 +01:00
await bikesAtStation . OnAppearingOrRefresh ( ) ;
2022-09-06 16:08:19 +02:00
2023-04-19 12:14:14 +02:00
// Verify behavior
2022-09-06 16:08:19 +02:00
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" ) ;
} ) ;
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . StatusInfoText , Is . Empty ) ;
2022-09-06 16:08:19 +02:00
// Verify list of bikes
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . Count , Is . EqualTo ( 4 ) ) ;
Assert . That ( bikesAtStation . IsIdle , Is . True ) ;
Assert . That ( bikesAtStation . IsBikesListVisible , Is . True , "If there are any bikes, list must be visible." ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
var bike1545 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1545" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
var bike1537 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1537" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
var bike1315 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1315" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
var bike1543 = bikesAtStation . FirstOrDefault ( x = > x . Id = = "1543" ) as ShareeBike . ViewModel . Bikes . Bike . BluetoothLock . BikeViewModel ;
2022-09-06 16:08:19 +02:00
Assert . That (
bike1545 ,
Is . Not . Null ) ;
Assert . That (
bike1537 ,
Is . Not . Null ) ;
Assert . That (
bike1315 ,
Is . Not . Null ) ;
Assert . That (
bike1543 ,
Is . Not . Null ) ;
2024-04-09 12:53:23 +02:00
Assert . That ( bike1545 . StateText , Is . EqualTo ( $"Rented since {DateTime.Parse(" 2020 - 11 - 06 17 : 53 : 22.784681 + 01 "):dd. MMMM HH:mm}." ) ) ;
Assert . That ( bike1537 . StateText , Is . EqualTo ( $"Rented since {DateTime.Parse(" 2020 - 10 - 12 08 : 38 : 12.374231 + 02 "):dd. MMMM HH:mm}." ) ) ;
Assert . That ( bike1315 . StateText , Is . EqualTo ( "Available." ) ) ;
Assert . That ( bike1543 . StateText , Is . EqualTo ( "Available." ) ) ;
Assert . That ( bike1545 . ButtonText , Is . EqualTo ( "Connect lock" ) ) ;
Assert . That ( bike1537 . ButtonText , Is . EqualTo ( "Connect lock" ) ) ;
Assert . That ( bike1315 . LockitButtonText , Is . EqualTo ( "DisposableDisconnected" ) ) ;
Assert . That ( bike1543 . LockitButtonText , Is . EqualTo ( "DisposableDisconnected" ) ) ;
2022-09-06 16:08:19 +02:00
// Login hint/ no bikes frame
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . IsLoginRequiredHintVisible , Is . False ) ;
Assert . That ( bikesAtStation . IsNoBikesAtStationVisible , Is . False ) ;
Assert . That ( bikesAtStation . NoBikesAtStationText , Is . EqualTo ( string . Empty ) ) ;
2022-09-06 16:08:19 +02:00
}
[Test]
2024-04-09 12:53:23 +02:00
public async Task TestConstructCitybike ( )
2022-09-06 16:08:19 +02:00
{
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 > ( ) ;
bluetooth . State . Returns ( BluetoothState . On ) ;
locksService . TimeOut . Returns ( timeOut ) ;
timeOut . MultiConnect . Returns ( new TimeSpan ( 0 ) ) ;
const string MERCH_ID = "MyMerchId" ;
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://shareeapp-primary.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 : locksService . GetType ( ) . FullName ,
activeGeolocationService : typeof ( GeolocationMock ) . FullName ) ,
new StoreMock ( ) ,
isConnectedFunc : ( ) = > true ,
2023-02-22 14:03:35 +01:00
connectorFactory : ( isConnected , uri , sessionCookie , mail , expiresAfter ) = > new ConnectorCache ( new AppContextInfo ( MERCH_ID , "MyApp" , new Version ( 1 , 2 ) ) , null /*UI language */ , sessionCookie , mail , server : new CopriCallsMemory001 ( sessionCookie ) ) ,
2022-09-06 16:08:19 +02:00
merchantId : MERCH_ID ,
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 : 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 bikesAtStation = new BikesAtStationPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp . ActiveUser ,
2022-09-06 16:08:19 +02:00
permissions ,
bluetooth ,
Device . iOS ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Model . Stations . StationNS . Station ( "FR101" , new List < string > ( ) , null ) , // Was 31 before switching CopriCallsMemory(SampleSets.Set2, 1, ...)
( ) = > shareeBikeApp . GetIsConnected ( ) ,
( isConnected ) = > shareeBikeApp . GetConnector ( isConnected ) ,
2022-09-06 16:08:19 +02:00
new GeolocationMock ( ) ,
locksService ,
2024-04-09 12:53:23 +02:00
shareeBikeApp . Polling ,
2022-09-06 16:08:19 +02:00
( url ) = > { } ,
( d , obj ) = > d ( obj ) ,
Substitute . For < ISmartDevice > ( ) ,
viewService ) ;
2023-02-22 14:03:35 +01:00
await bikesAtStation . OnAppearingOrRefresh ( ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
Assert . That ( new List < string > { "Updating..." , string . Empty } . Contains ( bikesAtStation . StatusInfoText ) , Is . True ) ;
2022-09-06 16:08:19 +02:00
// Verify list of bikes
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . Count , Is . EqualTo ( 3 ) ) ; // Was 1 before switch.
Assert . That ( bikesAtStation . IsIdle , Is . True ) ;
Assert . That ( bikesAtStation . IsBikesListVisible , Is . True , "If there are any bikes, list must be visible." ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . FirstOrDefault ( x = > x . Id = = "FR1003" ) . StateText , Is . EqualTo ( "Available." ) ) ; // Was 52 before switch.
Assert . That ( bikesAtStation . FirstOrDefault ( x = > x . Id = = "FR1002" ) . StateText , Is . EqualTo ( "Available." ) ) ;
Assert . That ( bikesAtStation . FirstOrDefault ( x = > x . Id = = "FR1001" ) . StateText , Is . EqualTo ( "Available." ) ) ;
2022-09-06 16:08:19 +02:00
// Login hint/ no bikes frame
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . IsLoginRequiredHintVisible , Is . True ) ;
Assert . That ( bikesAtStation . IsNoBikesAtStationVisible , Is . False ) ;
Assert . That ( bikesAtStation . NoBikesAtStationText , Is . EqualTo ( string . Empty ) ) ;
2022-09-06 16:08:19 +02:00
}
[Test]
2024-04-09 12:53:23 +02:00
public async Task TestConstructCitybike_NoBikes ( )
2022-09-06 16:08:19 +02:00
{
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 > ( ) ;
bluetooth . State . Returns ( BluetoothState . On ) ;
locksService . TimeOut . Returns ( timeOut ) ;
timeOut . MultiConnect . Returns ( new TimeSpan ( 0 ) ) ;
const string MERCH_ID = "MyMerchId" ;
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 : locksService . GetType ( ) . FullName ,
activeGeolocationService : typeof ( GeolocationMock ) . FullName ) ,
new StoreMock ( ) ,
isConnectedFunc : ( ) = > true ,
2023-02-22 14:03:35 +01:00
connectorFactory : ( isConnected , uri , sessionCookie , mail , expiresAfter ) = > new ConnectorCache ( new AppContextInfo ( "MyMerchId" , "MyApp" , new Version ( 1 , 2 ) ) , null /*UI language */ , sessionCookie , mail , server : new CopriCallsMemory ( MERCH_ID , SampleSets . Set2 , 1 , 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 : 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 bikesAtStation = new BikesAtStationPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp . ActiveUser ,
2022-09-06 16:08:19 +02:00
permissions ,
bluetooth ,
Device . iOS ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Model . Stations . StationNS . Station ( "4" , new List < string > ( ) , null ) ,
( ) = > shareeBikeApp . GetIsConnected ( ) ,
( isConnected ) = > shareeBikeApp . GetConnector ( isConnected ) ,
2022-09-06 16:08:19 +02:00
new GeolocationMock ( ) ,
locksService ,
2024-04-09 12:53:23 +02:00
shareeBikeApp . Polling ,
2022-09-06 16:08:19 +02:00
( url ) = > { } ,
( d , obj ) = > d ( obj ) ,
Substitute . For < ISmartDevice > ( ) ,
viewService ) ;
2023-02-22 14:03:35 +01:00
await bikesAtStation . OnAppearingOrRefresh ( ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
Assert . That ( new List < string > { "Updating..." , string . Empty } . Contains ( bikesAtStation . StatusInfoText ) , Is . True ) ;
2022-09-06 16:08:19 +02:00
// Verify list of bikes
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . Count , Is . EqualTo ( 0 ) ) ;
Assert . That ( bikesAtStation . IsIdle , Is . True ) ;
Assert . That ( bikesAtStation . IsBikesListVisible , Is . False , "If there are any bikes, list must be visible." ) ;
2022-09-06 16:08:19 +02:00
// Login hint/ no bikes frame
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . IsLoginRequiredHintVisible , Is . False ) ;
Assert . That ( bikesAtStation . IsNoBikesAtStationVisible , Is . True ) ;
Assert . That ( bikesAtStation . NoBikesAtStationText , Is . EqualTo ( "There are currently no bicycles available at this station." ) ) ;
2022-09-06 16:08:19 +02:00
}
[Test]
public async Task TestConstruct_LoggedIn ( )
{
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 > ( ) ;
bluetooth . State . Returns ( BluetoothState . On ) ;
locksService . TimeOut . Returns ( timeOut ) ;
timeOut . MultiConnect . Returns ( new TimeSpan ( 0 ) ) ;
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://shareeapp-primary.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 : locksService . GetType ( ) . FullName ,
activeGeolocationService : locksService . GetType ( ) . FullName ) ,
2024-04-09 12:53:23 +02:00
new StoreMock ( new ShareeBike . Model . User . Account . Account (
2022-09-06 16:08:19 +02:00
LoginSessionCopriInfo . JavaministerHardwareNr1 . Mail ,
LoginSessionCopriInfo . JavaministerHardwareNr1 . Pwd ,
false ,
"6103_112e96b36ba33de245943c5ffaf369cd_" , // Was 4da3044c8657a04ba60e2eaa753bc51a before switching from data provider CopriCallsMemory(SampleSets.Set2, 1, ...)
new List < string > { FilterHelper . CARGOBIKE } ) ) ,
isConnectedFunc : ( ) = > true ,
2023-02-22 14:03:35 +01:00
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 ) ) ,
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 : 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 bikesAtStation = new BikesAtStationPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp . ActiveUser ,
2022-09-06 16:08:19 +02:00
permissions ,
bluetooth ,
Device . iOS ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Model . Stations . StationNS . Station ( "FR103" , new List < string > ( ) , null ) , // Was station id 4 before switching from data provider CopriCallsMemory(SampleSets.Set2, 1, ...)
( ) = > shareeBikeApp . GetIsConnected ( ) ,
( isConnected ) = > shareeBikeApp . GetConnector ( isConnected ) ,
2022-09-06 16:08:19 +02:00
new GeolocationMock ( ) ,
locksService ,
2024-04-09 12:53:23 +02:00
shareeBikeApp . Polling ,
2022-09-06 16:08:19 +02:00
( url ) = > { } ,
( d , obj ) = > d ( obj ) ,
Substitute . For < ISmartDevice > ( ) ,
viewService ) ;
2023-02-22 14:03:35 +01:00
await bikesAtStation . OnAppearingOrRefresh ( ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
Assert . That ( new List < string > { "Updating..." , string . Empty } . Contains ( bikesAtStation . StatusInfoText ) , Is . True ) ;
2022-09-06 16:08:19 +02:00
// Verify list of bikes
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . Count , Is . EqualTo ( 4 ) ) ; // Count of bikes was 4 before switching from data provider CopriCallsMemory(SampleSets.Set2, 1, ...)
Assert . That ( bikesAtStation . IsIdle , Is . True ) ;
Assert . That ( bikesAtStation . IsBikesListVisible , Is . True , "If there are any bikes, list must be visible." ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . FirstOrDefault ( x = > x . Id = = "FR9999" ) . StateText , Is . EqualTo ( "Available." ) ) ;
Assert . That ( bikesAtStation . FirstOrDefault ( x = > x . Id = = "FR9999" ) . StateText , Is . EqualTo ( "Available." ) ) ;
Assert . That ( bikesAtStation . FirstOrDefault ( x = > x . Id = = "FR1004" ) . StateText , Is . EqualTo ( "Max. reservation time expired." ) ) ;
Assert . That ( bikesAtStation . FirstOrDefault ( x = > x . Id = = "FR1544" ) . StateText , Is . EqualTo ( $"Rented since {DateTime.Parse(" 2021 - 11 - 06 18 : 57 : 25.445447 + 01 "):dd. MMMM HH:mm}." ) ) ; // Was 7
2022-09-06 16:08:19 +02:00
// Login hint/ no bikes frame
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . IsLoginRequiredHintVisible , Is . False ) ;
Assert . That ( bikesAtStation . IsNoBikesAtStationVisible , Is . False ) ;
Assert . That ( bikesAtStation . NoBikesAtStationText , Is . EqualTo ( string . Empty ) ) ;
2022-09-06 16:08:19 +02:00
}
[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 > ( ) ;
bluetooth . State . Returns ( BluetoothState . On ) ;
locksService . TimeOut . Returns ( timeOut ) ;
timeOut . MultiConnect . Returns ( new TimeSpan ( 0 ) ) ;
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://shareeapp-primary.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 : locksService . GetType ( ) . FullName ,
activeGeolocationService : typeof ( GeolocationMock ) . FullName ) ,
new StoreMock ( ) ,
isConnectedFunc : ( ) = > false ,
2023-02-22 14:03:35 +01:00
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 ) ) ,
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 : locksService , // Cipher
device : new DeviceMock ( ) ,
specialFolder : new SpecialFolderMock ( ) ,
cipher : null , // Not connected.
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 bikesAtStation = new BikesAtStationPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp . ActiveUser ,
2022-09-06 16:08:19 +02:00
permissions ,
bluetooth ,
Device . iOS ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Model . Stations . StationNS . Station ( "FR103" , new List < string > ( ) , null ) , // Was station id 4 before switching from data provider CopriCallsMemory(SampleSets.Set2, 1
( ) = > shareeBikeApp . GetIsConnected ( ) ,
( isConnected ) = > shareeBikeApp . GetConnector ( isConnected ) ,
2022-09-06 16:08:19 +02:00
new GeolocationMock ( ) ,
locksService ,
2024-04-09 12:53:23 +02:00
shareeBikeApp . Polling ,
2022-09-06 16:08:19 +02:00
( url ) = > { } ,
( d , obj ) = > d ( obj ) ,
Substitute . For < ISmartDevice > ( ) ,
viewService ) ;
2023-02-22 14:03:35 +01:00
await bikesAtStation . OnAppearingOrRefresh ( ) ;
2022-09-06 16:08:19 +02:00
// Verify list of bikes
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . Count , Is . EqualTo ( 2 ) ) ; // Count of bikes was 3. There is no more bike with id 26.
Assert . That ( bikesAtStation . IsIdle , Is . True ) ;
Assert . That ( bikesAtStation . IsBikesListVisible , Is . True , "If there are any bikes, list must be visible." ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . FirstOrDefault ( x = > x . Id = = "FR9999" ) . StateText , Is . EqualTo ( "Available." ) ) ; // Was id 5
Assert . That ( bikesAtStation . FirstOrDefault ( x = > x . Id = = "FR9998" ) . StateText , Is . EqualTo ( "Available." ) ) ; // Was is 14
2022-09-06 16:08:19 +02:00
// Login hint/ no bikes frame
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . IsLoginRequiredHintVisible , Is . True ) ;
Assert . That ( bikesAtStation . IsNoBikesAtStationVisible , Is . False ) ;
Assert . That ( bikesAtStation . NoBikesAtStationText , Is . EqualTo ( string . Empty ) ) ;
2022-09-06 16:08:19 +02:00
}
[Test]
public async Task TestConstruct_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 > ( ) ;
bluetooth . State . Returns ( BluetoothState . On ) ;
locksService . TimeOut . Returns ( timeOut ) ;
timeOut . MultiConnect . Returns ( new TimeSpan ( 0 ) ) ;
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://shareeapp-primary.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 : locksService . GetType ( ) . FullName ,
activeGeolocationService : typeof ( GeolocationMock ) . FullName ) ,
new StoreMock ( ) ,
isConnectedFunc : ( ) = > false ,
2024-04-09 12:53:23 +02:00
connectorFactory : ( isConnected , uri , sessionCookie , mail , expiresAfter ) = > new ShareeBike . Model . Connector . Connector (
2022-09-06 16:08:19 +02:00
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 ,
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 > ( ) ,
2023-04-05 15:02:10 +02:00
locationServicesContainer : Substitute . For < IServicesContainer < IGeolocationService > > ( ) ,
2022-09-06 16:08:19 +02:00
locksService : locksService , // Cipher
device : new DeviceMock ( ) ,
specialFolder : new SpecialFolderMock ( ) ,
cipher : null , // Not connected.
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 bikesAtStation = new BikesAtStationPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp . ActiveUser ,
2022-09-06 16:08:19 +02:00
permissions ,
bluetooth ,
Device . iOS ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Model . Stations . StationNS . Station ( "FR103" , new List < string > ( ) , null ) , // Was station id 4 before switching from data provider CopriCallsCacheMemory()
( ) = > shareeBikeApp . GetIsConnected ( ) ,
( isConnected ) = > shareeBikeApp . GetConnector ( isConnected ) ,
2022-09-06 16:08:19 +02:00
new GeolocationMock ( ) ,
locksService ,
2024-04-09 12:53:23 +02:00
shareeBikeApp . Polling ,
2022-09-06 16:08:19 +02:00
( url ) = > { } ,
( d , obj ) = > d ( obj ) ,
Substitute . For < ISmartDevice > ( ) ,
viewService )
{
IsReportLevelVerbose = true
} ;
2023-02-22 14:03:35 +01:00
await bikesAtStation . OnAppearingOrRefresh ( ) ;
2022-09-06 16:08:19 +02:00
// Verify list of bikes
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . Count , Is . EqualTo ( 2 ) ) ; // Count of bikes was 3. There is no more bike with id 26.
Assert . That ( bikesAtStation . IsIdle , Is . True ) ;
Assert . That ( bikesAtStation . IsBikesListVisible , Is . True , "If there are any bikes, list must be visible." ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . FirstOrDefault ( x = > x . Id = = "FR9999" ) . StateText , Is . EqualTo ( "Available." ) ) ; // Was id 5
Assert . That ( bikesAtStation . FirstOrDefault ( x = > x . Id = = "FR9998" ) . StateText , Is . EqualTo ( "Available." ) ) ; // Was is 14
2022-09-06 16:08:19 +02:00
// Login hint/ no bikes frame
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . IsLoginRequiredHintVisible , Is . True ) ;
Assert . That ( bikesAtStation . IsNoBikesAtStationVisible , Is . False ) ;
Assert . That ( bikesAtStation . NoBikesAtStationText , Is . EqualTo ( string . Empty ) ) ;
2022-09-06 16:08:19 +02:00
}
[Test]
2024-04-09 12:53:23 +02:00
public async Task TestShareeBikeApp_GeneralPurposeError ( )
2022-09-06 16:08:19 +02:00
{
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 > ( ) ;
bluetooth . State . Returns ( BluetoothState . On ) ;
locksService . TimeOut . Returns ( timeOut ) ;
timeOut . MultiConnect . Returns ( new TimeSpan ( 0 ) ) ;
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://shareeapp-primary.copri-bike.de/APIjsonserver" ) ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Settings . PollingParameters ( new TimeSpan ( 10000 ) ,
2022-09-06 16:08:19 +02:00
true ) ,
Serilog . Events . LogEventLevel . Error ,
activeLockService : locksService . GetType ( ) . FullName ,
activeGeolocationService : typeof ( GeolocationMock ) . FullName ) ,
new StoreMock ( ) ,
isConnectedFunc : ( ) = > false ,
2024-04-09 12:53:23 +02:00
connectorFactory : ( isConnected , uri , sessionCookie , mail , expiresAfter ) = > new ShareeBike . Model . Connector . Connector (
2022-09-06 16:08:19 +02:00
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 ,
cacheServer : new CopriCallsCacheMemory001 ( sessionCookie : sessionCookie ) ,
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 : locksService , // Cipher
device : new DeviceMock ( ) ,
specialFolder : new SpecialFolderMock ( ) ,
cipher : null , // Not connected.
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 bikesAtStation = new BikesAtStationPageViewModel (
2024-04-09 12:53:23 +02:00
shareeBikeApp . ActiveUser ,
2022-09-06 16:08:19 +02:00
permissions ,
bluetooth ,
Device . iOS ,
2024-04-09 12:53:23 +02:00
new ShareeBike . Model . Stations . StationNS . Station ( "FR103" , new List < string > ( ) , null ) , // Was station id 4 before switching from data provider CopriCallsCacheMemory()
( ) = > shareeBikeApp . GetIsConnected ( ) ,
( isConnected ) = > shareeBikeApp . GetConnector ( isConnected ) ,
2022-09-06 16:08:19 +02:00
new GeolocationMock ( ) ,
locksService ,
2024-04-09 12:53:23 +02:00
shareeBikeApp . Polling ,
2022-09-06 16:08:19 +02:00
( url ) = > { } ,
( d , obj ) = > d ( obj ) ,
Substitute . For < ISmartDevice > ( ) ,
viewService )
{
IsReportLevelVerbose = true
} ;
2023-02-22 14:03:35 +01:00
await bikesAtStation . OnAppearingOrRefresh ( ) ;
2022-09-06 16:08:19 +02:00
// Verify list of bikes
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . Count , Is . EqualTo ( 2 ) ) ; // Count of bikes was 3. There is no more bike with id 26.
Assert . That ( bikesAtStation . IsIdle , Is . True ) ;
Assert . That ( bikesAtStation . IsBikesListVisible , Is . True , "If there are any bikes, list must be visible." ) ;
2022-09-06 16:08:19 +02:00
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . FirstOrDefault ( x = > x . Id = = "FR9999" ) . StateText , Is . EqualTo ( "Available." ) ) ; // Was id 5
Assert . That ( bikesAtStation . FirstOrDefault ( x = > x . Id = = "FR9998" ) . StateText , Is . EqualTo ( "Available." ) ) ; // Was id 14.
2022-09-06 16:08:19 +02:00
// Login hint/ no bikes frame
2024-04-09 12:53:23 +02:00
Assert . That ( bikesAtStation . IsLoginRequiredHintVisible , Is . True ) ;
Assert . That ( bikesAtStation . IsNoBikesAtStationVisible , Is . False ) ;
Assert . That ( bikesAtStation . NoBikesAtStationText , Is . EqualTo ( string . Empty ) ) ;
2022-09-06 16:08:19 +02:00
}
}
2021-07-12 21:31:46 +02:00
}