mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2024-12-22 06:56:25 +01:00
Version 3.0.364
This commit is contained in:
parent
91d42552c7
commit
0b9196a78d
91 changed files with 3452 additions and 555 deletions
|
@ -3,9 +3,12 @@ Darmstadt
|
|||
enum
|
||||
Freiburg
|
||||
haveltec
|
||||
html
|
||||
javaminister
|
||||
konrad
|
||||
Mein
|
||||
serilog
|
||||
sharee
|
||||
tink
|
||||
ui
|
||||
xdoc
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.LastenradBayern" android:versionName="3.0.363" android:versionCode="363">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.LastenradBayern" android:versionName="3.0.364" android:versionCode="364">
|
||||
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="31" />
|
||||
<!-- Google Maps related permissions -->
|
||||
<!-- Permission to receive remote notifications from Google Play Services -->
|
||||
|
|
|
@ -56,8 +56,8 @@
|
|||
<key>CFBundleDisplayName</key>
|
||||
<string>LastenradBayern</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>363</string>
|
||||
<string>364</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>3.0.363</string>
|
||||
<string>3.0.364</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -56,7 +56,7 @@ namespace TINK
|
|||
var specialFolders = DependencyService.Get<ISpecialFolder>();
|
||||
var internalPersonalDir = specialFolders.GetInternalPersonalDir();
|
||||
|
||||
// Delete attachtment from previous session.
|
||||
// Delete attachment from previous session.
|
||||
DeleteAttachment(internalPersonalDir);
|
||||
|
||||
// Setup logger using default settings.
|
||||
|
@ -109,11 +109,11 @@ namespace TINK
|
|||
if (settings.MinimumLogEventLevel != Model.Settings.Settings.DEFAULTLOGGINLEVEL
|
||||
|| settings.LogToExternalFolder)
|
||||
{
|
||||
// Eigher
|
||||
// Either
|
||||
// - logging is not set to default value or
|
||||
// - logging is performed to external folder.
|
||||
// Need to reconfigure.
|
||||
Log.CloseAndFlush(); // Close before modifying logger configuration. Otherwise a sharing vialation occurs.
|
||||
Log.CloseAndFlush(); // Close before modifying logger configuration. Otherwise a sharing violation occurs.
|
||||
|
||||
TinkApp.SetupLogging(
|
||||
new LoggingLevelSwitch(settings.MinimumLogEventLevel),
|
||||
|
@ -133,7 +133,7 @@ namespace TINK
|
|||
{
|
||||
// App versions newer than 3.0.173 stored geolocation service in configuration.
|
||||
// Version 3.0.290: Geolocation service "GeolocationService" is no more supported.
|
||||
// For this reasons a swich of geolocation service is forced when loading configurations from ealier versions.
|
||||
// For this reasons a switch of geolocation service is forced when loading configurations from ealier versions.
|
||||
LocationServicesContainer.SetActive(settings.ActiveGeolocationService);
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ namespace TINK
|
|||
|
||||
const string MERCHANTID = "0000000000";
|
||||
|
||||
// Create new app instnace.
|
||||
// Create new app instance.
|
||||
Log.Debug("Constructing main model...");
|
||||
m_oModelRoot = new TinkApp(
|
||||
settings,
|
||||
|
|
|
@ -71,8 +71,9 @@
|
|||
Text="{x:Static resources:AppResources.ActionContactMailAppReleated}"
|
||||
IsEnabled="{Binding IsSendMailAvailable}"
|
||||
Command="{Binding OnMailAppRelatedRequest}"/>
|
||||
<!--- Link to App Store -->
|
||||
<Label
|
||||
<!--- Link to App Store
|
||||
inactivated since most feedback in App Store is not app-related-->
|
||||
<!--<Label
|
||||
Margin="0,10,0,0"
|
||||
TextType="Html"
|
||||
HorizontalOptions="Center"
|
||||
|
@ -81,7 +82,7 @@
|
|||
<Label.GestureRecognizers>
|
||||
<TapGestureRecognizer Command="{Binding OnRateRequest}"/>
|
||||
</Label.GestureRecognizers>
|
||||
</Label>
|
||||
</Label>-->
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</StackLayout>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
|
||||
#if USEFLYOUT
|
||||
|
@ -23,7 +23,7 @@ namespace TINK.View.Info.BikeInfo
|
|||
InitializeComponent();
|
||||
|
||||
ItemsSource = new BikeInfoViewModel(
|
||||
resourceName => ImageSource.FromResource($"{ViewModelResourceHelper.RessourcePrefix}Images.{resourceName}"),
|
||||
resourceName => ImageSource.FromResource($"{ViewModelResourceHelper.ResourcePrefix}Images.{resourceName}"),
|
||||
this).CarouselItems;
|
||||
}
|
||||
|
||||
|
@ -126,4 +126,4 @@ namespace TINK.View.Info.BikeInfo
|
|||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => throw new NotSupportedException();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
<StackLayout>
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickCopriServer_Converter}}"
|
||||
Text="{Binding CopriServerUriList.CorpiServerUriDescription}"/>
|
||||
Text="{Binding CopriServerUriList.CopriServerUriDescription}"/>
|
||||
<Picker
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickCopriServer_Converter}}"
|
||||
ItemsSource="{Binding CopriServerUriList.ServerTextList}"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System.IO;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Serilog;
|
||||
|
@ -7,8 +7,8 @@ namespace TINK.ViewModel
|
|||
{
|
||||
public static class ViewModelResourceHelper
|
||||
{
|
||||
/// <summary> Get ressource prefix depending on platform.</summary>
|
||||
public static string RessourcePrefix
|
||||
/// <summary> Get resource prefix depending on platform.</summary>
|
||||
public static string ResourcePrefix
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -24,19 +24,19 @@ namespace TINK.ViewModel
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary> Gets an an embedded html ressource.</summary>
|
||||
/// <summary> Gets an embedded html resource.</summary>
|
||||
/// <param name="resrouceName">Name of resource to get.</param>
|
||||
/// <returns></returns>
|
||||
public static string GetSource(string resrouceName)
|
||||
{
|
||||
var l_oRessourceName = RessourcePrefix + resrouceName;
|
||||
Log.Verbose($"Using this resource prefix {RessourcePrefix}.");
|
||||
var resourceName = ResourcePrefix + resrouceName;
|
||||
Log.Verbose($"Using this resource prefix {ResourcePrefix}.");
|
||||
// note that the prefix includes the trailing period '.' that is required
|
||||
var assembly = typeof(ViewModelResourceHelper).GetTypeInfo().Assembly;
|
||||
var stream = assembly.GetManifestResourceStream(l_oRessourceName);
|
||||
var stream = assembly.GetManifestResourceStream(resourceName);
|
||||
return stream != null
|
||||
? (new StreamReader(stream, Encoding.UTF8)).ReadToEnd()
|
||||
: string.Format("<!DOCTYPE html><html lang=\"de\"><body>An error occurred loading html- ressource {0}.</body>", l_oRessourceName);
|
||||
: string.Format("<!DOCTYPE html><html lang=\"de\"><body>An error occurred loading html- resource {0}.</body>", resourceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.Meinkonrad" android:versionName="3.0.363" android:versionCode="363">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.Meinkonrad" android:versionName="3.0.364" android:versionCode="364">
|
||||
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="31" />
|
||||
<!-- Google Maps related permissions -->
|
||||
<!-- Permission to receive remote notifications from Google Play Services -->
|
||||
|
|
|
@ -56,8 +56,8 @@
|
|||
<key>CFBundleDisplayName</key>
|
||||
<string>Mein konrad</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>363</string>
|
||||
<string>364</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>3.0.363</string>
|
||||
<string>3.0.364</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace TINK
|
|||
var specialFolders = DependencyService.Get<ISpecialFolder>();
|
||||
var internalPersonalDir = specialFolders.GetInternalPersonalDir();
|
||||
|
||||
// Delete attachtment from previous session.
|
||||
// Delete attachment from previous session.
|
||||
DeleteAttachment(internalPersonalDir);
|
||||
|
||||
// Setup logger using default settings.
|
||||
|
@ -108,11 +108,11 @@ namespace TINK
|
|||
if (settings.MinimumLogEventLevel != Model.Settings.Settings.DEFAULTLOGGINLEVEL
|
||||
|| settings.LogToExternalFolder)
|
||||
{
|
||||
// Eigher
|
||||
// Either
|
||||
// - logging is not set to default value or
|
||||
// - logging is performed to external folder.
|
||||
// Need to reconfigure.
|
||||
Log.CloseAndFlush(); // Close before modifying logger configuration. Otherwise a sharing vialation occurs.
|
||||
Log.CloseAndFlush(); // Close before modifying logger configuration. Otherwise a sharing violation occurs.
|
||||
|
||||
TinkApp.SetupLogging(
|
||||
new LoggingLevelSwitch(settings.MinimumLogEventLevel),
|
||||
|
@ -132,7 +132,7 @@ namespace TINK
|
|||
{
|
||||
// App versions newer than 3.0.173 stored geolocation service in configuration.
|
||||
// Version 3.0.290: Geolocation service "GeolocationService" is no more supported.
|
||||
// For this a swich of geolocation service is fored when loading configurations of older app versions.
|
||||
// For this a switch of geolocation service is forced when loading configurations of older app versions.
|
||||
LocationServicesContainer.SetActive(settings.ActiveGeolocationService);
|
||||
}
|
||||
|
||||
|
@ -148,7 +148,7 @@ namespace TINK
|
|||
|
||||
const string MERCHANTID = "0000000000";
|
||||
|
||||
// Create new app instnace.
|
||||
// Create new app instance.
|
||||
Log.Debug("Constructing main model...");
|
||||
m_oModelRoot = new TinkApp(
|
||||
settings,
|
||||
|
|
|
@ -70,11 +70,13 @@
|
|||
<Label FormattedText="{Binding LikeTinkApp}"/>
|
||||
<!--- Mail to app- related support -->
|
||||
<Button
|
||||
Style="{StaticResource SecondaryButton}"
|
||||
Text="{x:Static resources:AppResources.ActionContactMailAppReleated}"
|
||||
IsEnabled="{Binding IsSendMailAvailable}"
|
||||
Command="{Binding OnMailAppRelatedRequest}"/>
|
||||
<!--- Link to App Store -->
|
||||
<Label
|
||||
<!--- Link to App Store
|
||||
inactivated since most feedback in App Store is not app-related-->
|
||||
<!--<Label
|
||||
Margin="0,10,0,0"
|
||||
TextType="Html"
|
||||
HorizontalOptions="Center"
|
||||
|
@ -83,7 +85,7 @@
|
|||
<Label.GestureRecognizers>
|
||||
<TapGestureRecognizer Command="{Binding OnRateRequest}"/>
|
||||
</Label.GestureRecognizers>
|
||||
</Label>
|
||||
</Label>-->
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</StackLayout>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
|
||||
#if USEFLYOUT
|
||||
|
@ -23,7 +23,7 @@ namespace TINK.View.Info.BikeInfo
|
|||
InitializeComponent();
|
||||
|
||||
ItemsSource = new BikeInfoViewModel(
|
||||
resourceName => ImageSource.FromResource($"{ViewModelResourceHelper.RessourcePrefix}Images.{resourceName}"),
|
||||
resourceName => ImageSource.FromResource($"{ViewModelResourceHelper.ResourcePrefix}Images.{resourceName}"),
|
||||
this).CarouselItems;
|
||||
}
|
||||
|
||||
|
@ -126,4 +126,4 @@ namespace TINK.View.Info.BikeInfo
|
|||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => throw new NotSupportedException();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,7 +89,7 @@
|
|||
<StackLayout>
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickCopriServer_Converter}}"
|
||||
Text="{Binding CopriServerUriList.CorpiServerUriDescription}"/>
|
||||
Text="{Binding CopriServerUriList.CopriServerUriDescription}"/>
|
||||
<Picker
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickCopriServer_Converter}}"
|
||||
ItemsSource="{Binding CopriServerUriList.ServerTextList}"
|
||||
|
|
|
@ -7,8 +7,8 @@ namespace TINK.ViewModel
|
|||
{
|
||||
public static class ViewModelResourceHelper
|
||||
{
|
||||
/// <summary> Get ressource prefix depending on platform.</summary>
|
||||
public static string RessourcePrefix
|
||||
/// <summary> Get resource prefix depending on platform.</summary>
|
||||
public static string ResourcePrefix
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -24,19 +24,19 @@ namespace TINK.ViewModel
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary> Gets an an embedded html ressource.</summary>
|
||||
/// <summary> Gets an embedded html resource.</summary>
|
||||
/// <param name="resrouceName">Name of resource to get.</param>
|
||||
/// <returns></returns>
|
||||
public static string GetEmbeddedResource(string resrouceName)
|
||||
{
|
||||
var ressourceName = RessourcePrefix + resrouceName;
|
||||
Log.Verbose($"Using this resource prefix {RessourcePrefix}.");
|
||||
var resourceName = ResourcePrefix + resrouceName;
|
||||
Log.Verbose($"Using this resource prefix {ResourcePrefix}.");
|
||||
// note that the prefix includes the trailing period '.' that is required
|
||||
var assembly = typeof(ViewModelResourceHelper).GetTypeInfo().Assembly;
|
||||
var stream = assembly.GetManifestResourceStream(ressourceName);
|
||||
var stream = assembly.GetManifestResourceStream(resourceName);
|
||||
return stream != null
|
||||
? (new StreamReader(stream, Encoding.UTF8)).ReadToEnd()
|
||||
: string.Format("<!DOCTYPE html><html lang=\"de\"><body>An error occurred loading html- ressource {0}.</body>", ressourceName);
|
||||
: string.Format("<!DOCTYPE html><html lang=\"de\"><body>An error occurred loading html- resource {0}.</body>", resourceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System.ComponentModel;
|
||||
using System.ComponentModel;
|
||||
using TINK.MultilingualResources;
|
||||
|
||||
namespace ShareeSharedGuiLib.ViewModel
|
||||
|
@ -74,7 +74,7 @@ namespace ShareeSharedGuiLib.ViewModel
|
|||
public bool IsBatteryChargeLevelLabelVisible => Maximum.HasValue && Maximum.Value != 5;
|
||||
|
||||
/// <summary>
|
||||
/// Gets name of battery image ressource.
|
||||
/// Gets name of battery image resource.
|
||||
/// </summary>
|
||||
public string BatteryChargeLevelImageSourceString => Current.HasValue && Maximum.HasValue && Maximum.Value == 5
|
||||
? $"battery_{Current.Value}_{Maximum.Value}.png"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.hauffware.sharee" android:versionName="3.0.363" android:versionCode="363">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.hauffware.sharee" android:versionName="3.0.364" android:versionCode="364">
|
||||
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="31" />
|
||||
<!-- Google Maps related permissions -->
|
||||
<!-- Permission to receive remote notifications from Google Play Services -->
|
||||
|
|
|
@ -56,8 +56,8 @@
|
|||
<key>CFBundleDisplayName</key>
|
||||
<string>sharee.bike</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>363</string>
|
||||
<string>364</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>3.0.363</string>
|
||||
<string>3.0.364</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace TINK
|
|||
var specialFolders = DependencyService.Get<ISpecialFolder>();
|
||||
var internalPersonalDir = specialFolders.GetInternalPersonalDir();
|
||||
|
||||
// Delete attachtment from previous session.
|
||||
// Delete attachment from previous session.
|
||||
DeleteAttachment(internalPersonalDir);
|
||||
|
||||
// Setup logger using default settings.
|
||||
|
@ -108,11 +108,11 @@ namespace TINK
|
|||
if (settings.MinimumLogEventLevel != Model.Settings.Settings.DEFAULTLOGGINLEVEL
|
||||
|| settings.LogToExternalFolder)
|
||||
{
|
||||
// Eigher
|
||||
// Either
|
||||
// - logging is not set to default value or
|
||||
// - logging is performed to external folder.
|
||||
// Need to reconfigure.
|
||||
Log.CloseAndFlush(); // Close before modifying logger configuration. Otherwise a sharing vialation occurs.
|
||||
Log.CloseAndFlush(); // Close before modifying logger configuration. Otherwise a sharing violation occurs.
|
||||
|
||||
TinkApp.SetupLogging(
|
||||
new LoggingLevelSwitch(settings.MinimumLogEventLevel),
|
||||
|
@ -132,7 +132,7 @@ namespace TINK
|
|||
{
|
||||
// App versions newer than 3.0.173 stored geolocation service in configuration.
|
||||
// Version 3.0.290: Geolocation service "GeolocationService" is no more supported.
|
||||
// For this reasons a swich of geolocation service is forced when loading configurations from ealier versions.
|
||||
// For this reasons a switch of geolocation service is forced when loading configurations from ealier versions.
|
||||
LocationServicesContainer.SetActive(settings.ActiveGeolocationService);
|
||||
}
|
||||
|
||||
|
@ -148,7 +148,7 @@ namespace TINK
|
|||
|
||||
const string MERCHANTID = "0000000000";
|
||||
|
||||
// Create new app instnace.
|
||||
// Create new app instance.
|
||||
Log.Debug("Constructing main model...");
|
||||
m_oModelRoot = new TinkApp(
|
||||
settings,
|
||||
|
|
|
@ -69,11 +69,13 @@
|
|||
<Label FormattedText="{Binding LikeTinkApp}"/>
|
||||
<!--- Mail to app- related support -->
|
||||
<Button
|
||||
Style="{StaticResource SecondaryButton}"
|
||||
Text="{x:Static resources:AppResources.ActionContactMailAppReleated}"
|
||||
IsEnabled="{Binding IsSendMailAvailable}"
|
||||
Command="{Binding OnMailAppRelatedRequest}"/>
|
||||
<!--- Link to App Store -->
|
||||
<Label
|
||||
<!--- Link to App Store
|
||||
inactivated since most feedback in App Store is not app-related-->
|
||||
<!--<Label
|
||||
Margin="0,10,0,0"
|
||||
TextType="Html"
|
||||
HorizontalOptions="Center"
|
||||
|
@ -82,7 +84,7 @@
|
|||
<Label.GestureRecognizers>
|
||||
<TapGestureRecognizer Command="{Binding OnRateRequest}"/>
|
||||
</Label.GestureRecognizers>
|
||||
</Label>
|
||||
</Label>-->
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
</StackLayout>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Bikes.BikeInfoNS.DriveNS.BatteryNS;
|
||||
#if USEFLYOUT
|
||||
|
@ -23,7 +23,7 @@ namespace TINK.View.Info.BikeInfo
|
|||
InitializeComponent();
|
||||
|
||||
ItemsSource = new BikeInfoViewModel(
|
||||
resourceName => ImageSource.FromResource($"{ViewModelResourceHelper.RessourcePrefix}Images.{resourceName}"),
|
||||
resourceName => ImageSource.FromResource($"{ViewModelResourceHelper.ResourcePrefix}Images.{resourceName}"),
|
||||
this).CarouselItems;
|
||||
}
|
||||
|
||||
|
@ -126,4 +126,4 @@ namespace TINK.View.Info.BikeInfo
|
|||
public async Task<IUserFeedback> DisplayUserFeedbackPopup(IBattery battery = null, string co2Saving = null) => throw new NotSupportedException();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
<StackLayout>
|
||||
<Label
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickCopriServer_Converter}}"
|
||||
Text="{Binding CopriServerUriList.CorpiServerUriDescription}"/>
|
||||
Text="{Binding CopriServerUriList.CopriServerUriDescription}"/>
|
||||
<Picker
|
||||
IsVisible="{Binding DebugLevel, Converter={StaticResource PickCopriServer_Converter}}"
|
||||
ItemsSource="{Binding CopriServerUriList.ServerTextList}"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System.IO;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Serilog;
|
||||
|
@ -7,8 +7,8 @@ namespace TINK.ViewModel
|
|||
{
|
||||
public static class ViewModelResourceHelper
|
||||
{
|
||||
/// <summary> Get ressource prefix depending on platform.</summary>
|
||||
public static string RessourcePrefix
|
||||
/// <summary> Get resource prefix depending on platform.</summary>
|
||||
public static string ResourcePrefix
|
||||
{
|
||||
get
|
||||
{
|
||||
|
@ -24,19 +24,19 @@ namespace TINK.ViewModel
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary> Gets an an embedded html ressource.</summary>
|
||||
/// <summary> Gets embedded html resource.</summary>
|
||||
/// <param name="resrouceName">Name of resource to get.</param>
|
||||
/// <returns></returns>
|
||||
public static string GetSource(string resrouceName)
|
||||
{
|
||||
var l_oRessourceName = RessourcePrefix + resrouceName;
|
||||
Log.Verbose($"Using this resource prefix {RessourcePrefix}.");
|
||||
var resourceName = ResourcePrefix + resrouceName;
|
||||
Log.Verbose($"Using this resource prefix {ResourcePrefix}.");
|
||||
// note that the prefix includes the trailing period '.' that is required
|
||||
var assembly = typeof(ViewModelResourceHelper).GetTypeInfo().Assembly;
|
||||
var stream = assembly.GetManifestResourceStream(l_oRessourceName);
|
||||
var stream = assembly.GetManifestResourceStream(resourceName);
|
||||
return stream != null
|
||||
? (new StreamReader(stream, Encoding.UTF8)).ReadToEnd()
|
||||
: string.Format("<!DOCTYPE html><html lang=\"de\"><body>An error occurred loading html- ressource {0}.</body>", l_oRessourceName);
|
||||
: string.Format("<!DOCTYPE html><html lang=\"de\"><body>An error occurred loading html- resource {0}.</body>", resourceName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
|
|||
public enum DataSource
|
||||
{
|
||||
/// <summary>
|
||||
/// Data source corpi.
|
||||
/// Data source copri.
|
||||
/// </summary>
|
||||
Copri,
|
||||
/// <summary>
|
||||
|
|
|
@ -7,6 +7,7 @@ using TINK.Model.Connector.Filter;
|
|||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Model.Stations;
|
||||
using TINK.Model.Stations.StationNS;
|
||||
using TINK.Model.Stations.StationNS.Operator;
|
||||
using BikeInfo = TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
|
@ -92,11 +93,18 @@ namespace TINK.Model.Connector
|
|||
var providerBikesAndStations = await m_oInnerQuery.GetBikesAndStationsAsync();
|
||||
|
||||
// Do filtering.
|
||||
var filteredStationsDictionary = new StationDictionary(providerBikesAndStations.Response.StationsAll.CopriVersion, DoFilter(providerBikesAndStations.Response.StationsAll, Filter));
|
||||
var filteredBikesDictionary = new BikeCollection(DoFilter(providerBikesAndStations.Response.Bikes, Filter));
|
||||
var filteredStationsDictionary = new StationDictionary(
|
||||
providerBikesAndStations.Response.StationsAll.CopriVersion,
|
||||
DoFilter(providerBikesAndStations.Response.StationsAll, Filter));
|
||||
|
||||
var filteredBikesOccupiedDictionary = new BikeCollection(
|
||||
DoFilter(providerBikesAndStations.Response.BikesOccupied, Filter));
|
||||
|
||||
var filteredBikesAndStations = new Result<StationsAndBikesContainer>(
|
||||
providerBikesAndStations.Source,
|
||||
new StationsAndBikesContainer(filteredStationsDictionary, filteredBikesDictionary),
|
||||
new StationsAndBikesContainer(
|
||||
filteredStationsDictionary,
|
||||
filteredBikesOccupiedDictionary),
|
||||
providerBikesAndStations.GeneralData,
|
||||
providerBikesAndStations.Exception);
|
||||
|
||||
|
@ -106,17 +114,25 @@ namespace TINK.Model.Connector
|
|||
/// <summary> Filter bikes by group. </summary>
|
||||
/// <param name="bikes">Bikes to filter.</param>
|
||||
/// <returns>Filtered bikes.</returns>
|
||||
private static Dictionary<string, BikeInfo> DoFilter(BikeCollection bikes, IGroupFilter filter)
|
||||
{
|
||||
return bikes.Where(x => filter.DoFilter(x.Group).Count() > 0).ToDictionary(x => x.Id);
|
||||
}
|
||||
private static Dictionary<string, BikeInfo> DoFilter(BikeCollection bikes, IGroupFilter filter) =>
|
||||
bikes
|
||||
.Where(x => filter.DoFilter(x.Group).Count() > 0)
|
||||
.ToDictionary(x => x.Id);
|
||||
|
||||
/// <summary> Filter stations by group. </summary>
|
||||
/// <returns></returns>
|
||||
private static Dictionary<string, IStation> DoFilter(StationDictionary stations, IGroupFilter filter)
|
||||
{
|
||||
return stations.Where(x => filter.DoFilter(x.Group).Count() > 0).ToDictionary(x => x.Id);
|
||||
}
|
||||
/// <summary> Filter stations by group and removes bike group collection entries which do not match group filter. </summary>
|
||||
/// <returns>Matching stations.</returns>
|
||||
private static Dictionary<string, IStation> DoFilter(StationDictionary stations, IGroupFilter filter) =>
|
||||
stations
|
||||
.Where(station => filter.DoFilter(station.Group).Count() > 0)
|
||||
.Select(station => new Station(
|
||||
station.Id,
|
||||
station.Group,
|
||||
station.Position,
|
||||
station.StationName,
|
||||
station.OperatorData,
|
||||
new BikeGroupCol(station.BikeGroups
|
||||
.Where(group => filter.DoFilter(new List<string> { group.Group }).Count() > 0))) as IStation)
|
||||
.ToDictionary(x => x.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,8 +86,11 @@ namespace TINK.Model.Connector
|
|||
return new Result<StationsAndBikesContainer>(
|
||||
result.Source,
|
||||
new StationsAndBikesContainer(
|
||||
new StationDictionary(result.Response.StationsAll.CopriVersion, result.Response.StationsAll.ToDictionary(x => x.Id)),
|
||||
new BikeCollection(result.Response.Bikes.ToDictionary(x => x.Id))),
|
||||
new StationDictionary(
|
||||
result.Response.StationsAll.CopriVersion,
|
||||
result.Response.StationsAll.ToDictionary(x => x.Id)),
|
||||
new BikeCollection(
|
||||
result.Response.BikesOccupied?.ToDictionary(x => x.Id) ?? new Dictionary<string, BikeInfo>())),
|
||||
result.GeneralData,
|
||||
result.Exception);
|
||||
}
|
||||
|
|
|
@ -41,31 +41,19 @@ namespace TINK.Model.Connector
|
|||
resultStations.Source,
|
||||
new StationsAndBikesContainer(
|
||||
resultStations.Response.GetStationsAllMutable(),
|
||||
(await server.GetBikesAvailable(true)).Response.GetBikesAvailable(Bikes.BikeInfoNS.BC.DataSource.Cache)),
|
||||
new BikeCollection() /* There are no bikes occupied because user is not logged in. */),
|
||||
resultStations.GeneralData,
|
||||
resultStations.Exception);
|
||||
}
|
||||
|
||||
var resultBikes = await server.GetBikesAvailable();
|
||||
if (resultBikes.Source == typeof(CopriCallsMonkeyStore))
|
||||
{
|
||||
// Communication with copri in order to get bikes failed.
|
||||
return new Result<StationsAndBikesContainer>(
|
||||
resultBikes.Source,
|
||||
new StationsAndBikesContainer(
|
||||
(await server.GetStations(true)).Response.GetStationsAllMutable(),
|
||||
resultBikes.Response.GetBikesAvailable(Bikes.BikeInfoNS.BC.DataSource.Cache)),
|
||||
resultBikes.GeneralData,
|
||||
resultBikes.Exception);
|
||||
}
|
||||
|
||||
// Communicatin with copri succeeded.
|
||||
// Communication with copri succeeded.
|
||||
server.AddToCache(resultStations);
|
||||
server.AddToCache(resultBikes);
|
||||
|
||||
return new Result<StationsAndBikesContainer>(
|
||||
resultStations.Source,
|
||||
new StationsAndBikesContainer(resultStations.Response.GetStationsAllMutable(), resultBikes.Response.GetBikesAvailable(Bikes.BikeInfoNS.BC.DataSource.Copri)),
|
||||
new StationsAndBikesContainer(
|
||||
resultStations.Response.GetStationsAllMutable(),
|
||||
new BikeCollection()),
|
||||
resultStations.GeneralData);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog;
|
||||
|
@ -6,6 +7,7 @@ using TINK.Model.Bikes;
|
|||
using TINK.Model.Connector.Updater;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Repository;
|
||||
using TINK.Repository.Response;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
{
|
||||
|
@ -25,90 +27,47 @@ namespace TINK.Model.Connector
|
|||
Server = copriServer as ICachedCopriServer;
|
||||
if (Server == null)
|
||||
{
|
||||
throw new ArgumentException($"Copri server is not of expected typ. Type detected is {copriServer.GetType()}.");
|
||||
throw new ArgumentException($"Copri server is not of expected type. Type detected is {copriServer.GetType()}.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Gets all stations including positions.</summary>
|
||||
public async Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync()
|
||||
{
|
||||
BikeCollection GetBikeCollection(IEnumerable<BikeInfoReservedOrBooked> bikeInfoEnumerable, Bikes.BikeInfoNS.BC.DataSource dataSource) =>
|
||||
BikeCollectionFactory.GetBikesAll(
|
||||
null, // Bikes available are no more of interest because count of available bikes at each given station is was added to station object.
|
||||
bikeInfoEnumerable ?? new Dictionary<string, BikeInfoReservedOrBooked>().Values,
|
||||
Mail,
|
||||
DateTimeProvider,
|
||||
dataSource);
|
||||
|
||||
var stationsResponse = await Server.GetStations();
|
||||
|
||||
if (stationsResponse.Source == typeof(CopriCallsMonkeyStore)
|
||||
|| stationsResponse.Exception != null)
|
||||
{
|
||||
// Stations were read from cache ==> get bikes availbalbe and occupied from cache as well to avoid inconsistencies
|
||||
// Stations were read from cache ==> get bikes available and occupied from cache as well to avoid inconsistencies
|
||||
return new Result<StationsAndBikesContainer>(
|
||||
stationsResponse.Source,
|
||||
new StationsAndBikesContainer(
|
||||
stationsResponse.Response.GetStationsAllMutable(),
|
||||
BikeCollectionFactory.GetBikesAll(
|
||||
(await Server.GetBikesAvailable(true)).Response?.bikes?.Values,
|
||||
(await Server.GetBikesOccupied(true)).Response?.bikes_occupied?.Values,
|
||||
Mail,
|
||||
DateTimeProvider,
|
||||
Bikes.BikeInfoNS.BC.DataSource.Cache)),
|
||||
GetBikeCollection(stationsResponse.Response.bikes_occupied?.Values, Bikes.BikeInfoNS.BC.DataSource.Cache)),
|
||||
stationsResponse.GeneralData,
|
||||
stationsResponse.Exception);
|
||||
}
|
||||
|
||||
var bikesAvailableResponse = await Server.GetBikesAvailable();
|
||||
if (bikesAvailableResponse.Source == typeof(CopriCallsMonkeyStore)
|
||||
|| bikesAvailableResponse.Exception != null)
|
||||
{
|
||||
// Bikes avilable were read from cache ==> get bikes occupied from cache as well to avoid inconsistencies
|
||||
return new Result<StationsAndBikesContainer>(
|
||||
bikesAvailableResponse.Source,
|
||||
new StationsAndBikesContainer(
|
||||
(await Server.GetStations(true)).Response.GetStationsAllMutable(),
|
||||
BikeCollectionFactory.GetBikesAll(bikesAvailableResponse.Response?.bikes?.Values,
|
||||
(await Server.GetBikesOccupied(true)).Response?.bikes_occupied?.Values,
|
||||
Mail,
|
||||
DateTimeProvider,
|
||||
Bikes.BikeInfoNS.BC.DataSource.Cache)),
|
||||
bikesAvailableResponse.GeneralData,
|
||||
bikesAvailableResponse.Exception);
|
||||
}
|
||||
|
||||
var bikesOccupiedResponse = await Server.GetBikesOccupied();
|
||||
if (bikesOccupiedResponse.Source == typeof(CopriCallsMonkeyStore)
|
||||
|| bikesOccupiedResponse.Exception != null)
|
||||
{
|
||||
// Bikes occupied were read from cache ==> get bikes available from cache as well to avoid inconsistencies
|
||||
return new Result<StationsAndBikesContainer>(
|
||||
bikesOccupiedResponse.Source,
|
||||
new StationsAndBikesContainer(
|
||||
(await Server.GetStations(true)).Response.GetStationsAllMutable(),
|
||||
BikeCollectionFactory.GetBikesAll(
|
||||
(await Server.GetBikesAvailable(true)).Response?.bikes?.Values,
|
||||
bikesOccupiedResponse.Response?.bikes_occupied?.Values,
|
||||
Mail,
|
||||
DateTimeProvider,
|
||||
Bikes.BikeInfoNS.BC.DataSource.Cache)),
|
||||
bikesOccupiedResponse.GeneralData,
|
||||
bikesOccupiedResponse.Exception);
|
||||
}
|
||||
|
||||
// Both types bikes could read from copri => update cache
|
||||
Server.AddToCache(stationsResponse);
|
||||
Server.AddToCache(bikesAvailableResponse);
|
||||
Server.AddToCache(bikesOccupiedResponse);
|
||||
|
||||
var exceptions = new[] { stationsResponse?.Exception, bikesAvailableResponse?.Exception, bikesOccupiedResponse?.Exception }.Where(x => x != null).ToArray();
|
||||
|
||||
var stationsMutable = stationsResponse.Response.GetStationsAllMutable();
|
||||
var bikesMutable = BikeCollectionFactory.GetBikesAll(
|
||||
bikesAvailableResponse.Response?.bikes?.Values,
|
||||
bikesOccupiedResponse.Response?.bikes_occupied?.Values,
|
||||
Mail,
|
||||
DateTimeProvider,
|
||||
Bikes.BikeInfoNS.BC.DataSource.Copri);
|
||||
|
||||
return new Result<StationsAndBikesContainer>(
|
||||
stationsResponse.Source,
|
||||
new StationsAndBikesContainer(stationsMutable, bikesMutable),
|
||||
new StationsAndBikesContainer(
|
||||
stationsResponse.Response.GetStationsAllMutable(),
|
||||
GetBikeCollection(stationsResponse.Response.bikes_occupied?.Values, Bikes.BikeInfoNS.BC.DataSource.Copri)),
|
||||
stationsResponse.GeneralData,
|
||||
exceptions.Length > 0 ? new AggregateException(exceptions) : null);
|
||||
stationsResponse?.Exception);
|
||||
}
|
||||
|
||||
/// <summary> Gets bikes occupied. </summary>
|
||||
|
|
|
@ -32,11 +32,12 @@ namespace TINK.Model.Connector
|
|||
public async Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync()
|
||||
{
|
||||
var stationsAllResponse = await server.GetStationsAsync();
|
||||
var bikesAvailableResponse = await server.GetBikesAvailableAsync();
|
||||
|
||||
return new Result<StationsAndBikesContainer>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
new StationsAndBikesContainer(stationsAllResponse.GetStationsAllMutable(), bikesAvailableResponse.GetBikesAvailable(Bikes.BikeInfoNS.BC.DataSource.Cache)),
|
||||
new StationsAndBikesContainer(
|
||||
stationsAllResponse.GetStationsAllMutable(),
|
||||
new BikeCollection() /* There are no bikes occupied because user is not logged in. */),
|
||||
stationsAllResponse.GetGeneralData());
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Bikes;
|
||||
using TINK.Model.Connector.Updater;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Repository;
|
||||
using TINK.Repository.Response;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
{
|
||||
|
@ -34,16 +36,14 @@ namespace TINK.Model.Connector
|
|||
public async Task<Result<StationsAndBikesContainer>> GetBikesAndStationsAsync()
|
||||
{
|
||||
var stationResponse = await server.GetStationsAsync();
|
||||
var bikesAvailableResponse = await server.GetBikesAvailableAsync();
|
||||
var bikesOccupiedResponse = await server.GetBikesOccupiedAsync();
|
||||
|
||||
return new Result<StationsAndBikesContainer>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
new StationsAndBikesContainer(
|
||||
stationResponse.GetStationsAllMutable(),
|
||||
BikeCollectionFactory.GetBikesAll(
|
||||
bikesAvailableResponse?.bikes?.Values,
|
||||
bikesOccupiedResponse?.bikes_occupied?.Values,
|
||||
null, // Bikes available are no more of interest because count of available bikes at each given station is was added to station object.
|
||||
stationResponse.bikes_occupied?.Values ?? new Dictionary<string, BikeInfoReservedOrBooked>().Values,
|
||||
Mail,
|
||||
DateTimeProvider,
|
||||
Bikes.BikeInfoNS.BC.DataSource.Cache)),
|
||||
|
|
|
@ -7,9 +7,12 @@ using Serilog;
|
|||
using TINK.Model.Bikes.BikeInfoNS.BikeNS;
|
||||
using TINK.Model.Services.CopriApi.ServerUris;
|
||||
using TINK.Model.State;
|
||||
using TINK.Model.Stations.StationNS;
|
||||
using TINK.Model.Stations.StationNS.Operator;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Repository.Response;
|
||||
using TINK.Repository.Response.Stations.Station;
|
||||
using Xamarin.Forms;
|
||||
|
||||
namespace TINK.Model.Connector
|
||||
{
|
||||
|
@ -388,5 +391,52 @@ namespace TINK.Model.Connector
|
|||
/// <param name="bike">Bike get to state from.</param>
|
||||
public static bool GetIsFeedbackPending(this BikeInfoAvailable bike)
|
||||
=> bike.co2saving != null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the count of bikes available at station.
|
||||
/// </summary>
|
||||
/// <param name="stationInfo">Object to get information from.</param>
|
||||
/// <returns>Count of bikes available or null if information is unknown.</returns>
|
||||
public static int? GetBikesAvailableCount(this StationInfo stationInfo)
|
||||
=> !string.IsNullOrWhiteSpace(stationInfo?.bike_count)
|
||||
&& int.TryParse(stationInfo?.bike_count, out int bikeCount)
|
||||
? bikeCount
|
||||
: (int?)null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets station object from response object.
|
||||
/// </summary>
|
||||
/// <param name="station">Response object to get station object from.</param>
|
||||
/// <returns>Station object.</returns>
|
||||
public static Station GetStation(this StationInfo station) =>
|
||||
new Station(
|
||||
station.station,
|
||||
station.GetGroup(),
|
||||
station.GetPosition(),
|
||||
station.description,
|
||||
new Data(station.operator_data?.operator_name,
|
||||
station.operator_data?.operator_phone,
|
||||
station.operator_data?.operator_hours,
|
||||
station.operator_data?.operator_email,
|
||||
!string.IsNullOrEmpty(station.operator_data?.operator_color)
|
||||
? Color.FromHex(station.operator_data?.operator_color)
|
||||
: (Color?)null),
|
||||
new BikeGroupCol(station.station_type?.Select(x => new BikeGroupCol.Entry(
|
||||
x.Key,
|
||||
int.TryParse(x.Value.bike_count, out int count) ? count : 0,
|
||||
x.Value.bike_group)) ?? new List<BikeGroupCol.Entry>()
|
||||
));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the bike group object from response object.
|
||||
/// </summary>
|
||||
/// <param name="bikeGroup">Response object to get station from.</param>
|
||||
/// <param name="name">Name of the bike group.</param>
|
||||
/// <returns></returns>
|
||||
public static BikeGroupCol.Entry GetBikeGroup(this BikeGroup bikeGroup, string name) =>
|
||||
new BikeGroupCol.Entry(
|
||||
name,
|
||||
int.TryParse(bikeGroup?.bike_count ?? "0", out var countCity) ? countCity : 0,
|
||||
bikeGroup?.bike_group ?? string.Empty);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace TINK.Model.Connector.Updater
|
|||
/// <summary>
|
||||
/// Gets all station for station provider and add them into station list.
|
||||
/// </summary>
|
||||
/// <param name="p_oStationList">List of stations to update.</param>
|
||||
/// <param name="stationsAllResponse">List of stations to update.</param>
|
||||
public static StationDictionary GetStationsAllMutable(this StationsAvailableResponse stationsAllResponse)
|
||||
{
|
||||
// Get stations from Copri/ file/ memory, ....
|
||||
|
@ -43,7 +43,7 @@ namespace TINK.Model.Connector.Updater
|
|||
|
||||
Version.TryParse(stationsAllResponse.copri_version, out Version copriVersion);
|
||||
|
||||
var stations = new StationDictionary(p_oVersion: copriVersion);
|
||||
var stations = new StationDictionary(version: copriVersion);
|
||||
|
||||
foreach (var station in stationsAllResponse.stations)
|
||||
{
|
||||
|
@ -54,18 +54,7 @@ namespace TINK.Model.Connector.Updater
|
|||
string.Format("Station id {0} is not unique.", station.Value.station), stationsAllResponse);
|
||||
}
|
||||
|
||||
stations.Add(new Stations.StationNS.Station(
|
||||
station.Value.station,
|
||||
station.Value.GetGroup(),
|
||||
station.Value.GetPosition(),
|
||||
station.Value.description,
|
||||
new Data(station.Value.operator_data?.operator_name,
|
||||
station.Value.operator_data?.operator_phone,
|
||||
station.Value.operator_data?.operator_hours,
|
||||
station.Value.operator_data?.operator_email,
|
||||
!string.IsNullOrEmpty(station.Value.operator_data?.operator_color)
|
||||
? Color.FromHex(station.Value.operator_data?.operator_color)
|
||||
: (Color?)null)));
|
||||
stations.Add(station.Value.GetStation());
|
||||
}
|
||||
|
||||
return stations;
|
||||
|
|
|
@ -148,7 +148,7 @@ namespace TINK.Model.Settings
|
|||
/// <returns>Logging level</returns>
|
||||
public static Uri GetCopriHostUri(this IDictionary<string, string> settingsJSON)
|
||||
{
|
||||
// Get uri of corpi server.
|
||||
// Get uri of copri server.
|
||||
if (!settingsJSON.TryGetValue(typeof(CopriServerUriList).ToString(), out string uriText)
|
||||
|| string.IsNullOrEmpty(uriText))
|
||||
{
|
||||
|
@ -381,7 +381,7 @@ namespace TINK.Model.Settings
|
|||
/// <returns>Active lock service name.</returns>
|
||||
public static string GetActiveLockService(this IDictionary<string, string> settingsJSON)
|
||||
{
|
||||
// Get uri of corpi server.
|
||||
// Get uri of copri server.
|
||||
if (!settingsJSON.TryGetValue(typeof(ILocksService).Name, out string activeLockService)
|
||||
|| string.IsNullOrEmpty(activeLockService))
|
||||
{
|
||||
|
@ -418,7 +418,7 @@ namespace TINK.Model.Settings
|
|||
/// <returns>Active lock service name.</returns>
|
||||
public static string GetActiveGeolocationService(this IDictionary<string, string> settingsJSON)
|
||||
{
|
||||
// Get uri of corpi server.
|
||||
// Get uri of copri server.
|
||||
if (!settingsJSON.TryGetValue(typeof(IGeolocationService).Name, out string activeGeolocationService)
|
||||
|| string.IsNullOrEmpty(activeGeolocationService))
|
||||
{
|
||||
|
|
|
@ -10,19 +10,27 @@ namespace TINK.Model.Stations
|
|||
/// <summary> Holds the list of stations. </summary>
|
||||
private readonly IDictionary<string, IStation> m_oStationDictionary;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a station by key.
|
||||
/// </summary>
|
||||
/// <param name="key">Key to get station.</param>
|
||||
/// <returns>Station for given key.</returns>
|
||||
public IStation this[string key] =>
|
||||
ContainsKey(key) ? m_oStationDictionary[key] : new NullStation();
|
||||
|
||||
/// <summary> Count of stations. </summary>
|
||||
public int Count { get { return m_oStationDictionary.Count; } }
|
||||
|
||||
public Version CopriVersion { get; }
|
||||
|
||||
/// <summary> Constructs a station dictionary object. </summary>
|
||||
/// <param name="p_oVersion">Version of copri- service.</param>
|
||||
public StationDictionary(Version p_oVersion = null, IDictionary<string, IStation> p_oStations = null)
|
||||
/// <param name="version">Version of copri- service.</param>
|
||||
public StationDictionary(Version version = null, IDictionary<string, IStation> stations = null)
|
||||
{
|
||||
m_oStationDictionary = p_oStations ?? new Dictionary<string, IStation>();
|
||||
m_oStationDictionary = stations ?? new Dictionary<string, IStation>();
|
||||
|
||||
CopriVersion = p_oVersion != null
|
||||
? new Version(p_oVersion.Major, p_oVersion.Minor, p_oVersion.Revision, p_oVersion.Build)
|
||||
CopriVersion = version != null
|
||||
? new Version(version.Major, version.Minor, version.Revision, version.Build)
|
||||
: new Version(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,9 @@ using TINK.Model.Stations.StationNS.Operator;
|
|||
|
||||
namespace TINK.Model.Stations.StationNS
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds station information, i.e. static information like station name, station position and dynamic information like bikes available.
|
||||
/// </summary>
|
||||
public interface IStation
|
||||
{
|
||||
/// <summary> Holds the unique id of the station.c</summary>
|
||||
|
@ -19,5 +22,12 @@ namespace TINK.Model.Stations.StationNS
|
|||
|
||||
/// <summary> Holds operator related data.</summary>
|
||||
IData OperatorData { get; }
|
||||
|
||||
/// <summary> Gets the count of bikes available at station. </summary>
|
||||
int? AvailableBikesCount { get; }
|
||||
|
||||
/// <summary> Gets bike <see cref="BikeGroupCol.Entry"/> objects. </summary>
|
||||
/// <remarks> Each entry has a name, holds the count of available bikes at station and the group value. /// </remarks>
|
||||
IBikeGroupCol BikeGroups { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,5 +20,12 @@ namespace TINK.Model.Stations.StationNS
|
|||
|
||||
/// <summary> Holds operator related data.</summary>
|
||||
public IData OperatorData => new Data();
|
||||
|
||||
/// <summary> Gets the count of bikes available at station. </summary>
|
||||
public int? AvailableBikesCount => null;
|
||||
|
||||
/// <summary> Gets bike <see cref="BikeGroupCol.Entry"/> objects. </summary>
|
||||
/// <remarks> Each entry has a name, holds the count of available bikes at station and the group value. /// </remarks>
|
||||
public IBikeGroupCol BikeGroups => null;
|
||||
}
|
||||
}
|
||||
|
|
49
TINKLib/Model/Stations/StationNS/Operator/BikeGroupCol.cs
Normal file
49
TINKLib/Model/Stations/StationNS/Operator/BikeGroupCol.cs
Normal file
|
@ -0,0 +1,49 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace TINK.Model.Stations.StationNS.Operator
|
||||
{
|
||||
public class BikeGroupCol : List<BikeGroupCol.Entry> , IBikeGroupCol
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds a group of bikes at a station.
|
||||
/// </summary>
|
||||
public class Entry
|
||||
{
|
||||
/// <summary>
|
||||
/// Bike group entry.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the group, either "Citybikes" or "Cargobikes".</param>
|
||||
/// <param name="availableCount"></param>
|
||||
/// <param name="group"></param>
|
||||
public Entry(string name, int? availableCount = null, string group = null)
|
||||
{
|
||||
Name = name;
|
||||
AvailableCount = availableCount ?? 0;
|
||||
Group = group ?? string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Name of the group, either "Citybikes" or "Cargobikes".
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary> Holds the count of bikes available of given type at station. </summary>
|
||||
public int AvailableCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds the group of the bikes. Konrad separates cargo and city bikes by group.
|
||||
/// </summary>
|
||||
public string Group { get; }
|
||||
}
|
||||
|
||||
public BikeGroupCol() : base() { }
|
||||
|
||||
public BikeGroupCol(IEnumerable<Entry> source) : base(source) { }
|
||||
|
||||
/// <summary> Holds the count of bikes available of any type at station. </summary>
|
||||
public int AvailableCount => this.Select(x => x.AvailableCount).Sum();
|
||||
|
||||
}
|
||||
}
|
10
TINKLib/Model/Stations/StationNS/Operator/IBikeGroupCol.cs
Normal file
10
TINKLib/Model/Stations/StationNS/Operator/IBikeGroupCol.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace TINK.Model.Stations.StationNS.Operator
|
||||
{
|
||||
public interface IBikeGroupCol : IEnumerable<BikeGroupCol.Entry>
|
||||
{
|
||||
/// <summary> Holds the count of bikes available of given type at station. </summary>
|
||||
int AvailableCount { get; }
|
||||
}
|
||||
}
|
|
@ -14,16 +14,18 @@ namespace TINK.Model.Stations.StationNS
|
|||
/// <param name="stationName">Name of the station.</param>
|
||||
public Station(
|
||||
string id,
|
||||
IEnumerable<string> group,
|
||||
IPosition position,
|
||||
IEnumerable<string> group = null,
|
||||
IPosition position = null,
|
||||
string stationName = "",
|
||||
Data operatorData = null)
|
||||
IData operatorData = null,
|
||||
IBikeGroupCol bikeGropCol = null)
|
||||
{
|
||||
Id = id;
|
||||
Group = group ?? throw new ArgumentException("Can not construct station object. Group of stations must not be null.");
|
||||
Position = position;
|
||||
StationName = stationName ?? string.Empty;
|
||||
OperatorData = operatorData ?? new Data();
|
||||
BikeGroups = bikeGropCol ?? new BikeGroupCol();
|
||||
}
|
||||
|
||||
/// <summary> Holds the unique id of the station.c</summary>
|
||||
|
@ -40,5 +42,12 @@ namespace TINK.Model.Stations.StationNS
|
|||
|
||||
/// <summary> Holds operator related info.</summary>
|
||||
public IData OperatorData { get; }
|
||||
|
||||
/// <summary> Gets the count of bikes available at station. </summary>
|
||||
public int? AvailableBikesCount => BikeGroups.AvailableCount;
|
||||
|
||||
/// <summary> Gets bike <see cref="BikeGroupCol.Entry"/> objects. </summary>
|
||||
/// <remarks> Each entry has a name, holds the count of available bikes at station and the group value. /// </remarks>
|
||||
public IBikeGroupCol BikeGroups { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -408,7 +408,7 @@ namespace TINK.Model
|
|||
/// <summary> Holds available app themes.</summary>
|
||||
public IServicesContainer<IGeolocationService> GeolocationServices { get; }
|
||||
|
||||
/// <summary> Holds the flavor of the app, i.e. specifies if app is sharee.bike, Mein konrad or Lastenrad Bayern.</summary>
|
||||
/// <summary> Holds the flavor of the app, i.e. specifies if app is sharee.bike, Mein konrad or LastenRad Bayern.</summary>
|
||||
public AppFlavor Flavor { get; private set; }
|
||||
|
||||
/// <summary> Manages the different types of LocksService objects.</summary>
|
||||
|
@ -418,7 +418,7 @@ namespace TINK.Model
|
|||
private LoggingLevelSwitch m_oLoggingLevelSwitch;
|
||||
|
||||
/// <summary>
|
||||
/// Object to allow swithing logging level
|
||||
/// Object to allow switching logging level
|
||||
/// </summary>
|
||||
public LoggingLevelSwitch Level
|
||||
{
|
||||
|
@ -448,7 +448,7 @@ namespace TINK.Model
|
|||
return;
|
||||
}
|
||||
|
||||
Log.CloseAndFlush(); // Close before modifying logger configuration. Otherwise a sharing vialation occurs.
|
||||
Log.CloseAndFlush(); // Close before modifying logger configuration. Otherwise a sharing violation occurs.
|
||||
|
||||
Level.MinimumLevel = minimumLevel;
|
||||
|
||||
|
@ -480,7 +480,7 @@ namespace TINK.Model
|
|||
var sourceContex = e.Properties[Constants.SourceContextPropertyName].ToString();
|
||||
|
||||
if ((e.Level == LogEventLevel.Information) &&
|
||||
(sourceContex.Contains(typeof(AppAndEnvironmentInfo).Namespace) /* Log App and enviroment info. */
|
||||
(sourceContex.Contains(typeof(AppAndEnvironmentInfo).Namespace) /* Log App and environment info. */
|
||||
|| sourceContex.Contains(typeof(ViewModel.Bikes.Bike.BluetoothLock.RequestHandler.Base).Namespace /* Log info-level messages to provide context for bluetooth log. */ )))
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -687,6 +687,11 @@ namespace TINK.Model
|
|||
AppResources.ChangeLog_3_0_363_MK_SB,
|
||||
new List<AppFlavor> { AppFlavor.MeinKonrad, AppFlavor.ShareeBike }
|
||||
},
|
||||
{
|
||||
new Version(3, 0, 364),
|
||||
AppResources.ChangeLog_MinorImprovements,
|
||||
new List<AppFlavor> { AppFlavor.MeinKonrad, AppFlavor.ShareeBike }
|
||||
},
|
||||
};
|
||||
|
||||
/// <summary> Manges the whats new information.</summary>
|
||||
|
|
|
@ -1459,7 +1459,7 @@ namespace TINK.MultilingualResources {
|
|||
///1. close app,
|
||||
///2. press the button at the top of the lock briefly and release it as soon as it starts flashing,
|
||||
///3. make sure that the lock is completely closed and remains closed.
|
||||
///4. send e-mail to operator (otherwise your chargeable rental will continue!): Problem description, Drop-off station..
|
||||
///4. send e-mail to operator (otherwise your chargeable rental will continue!): Please include problem description, bike-id and drop-off station..
|
||||
/// </summary>
|
||||
public static string ErrorBookedSearchMessageEscalationLevel2 {
|
||||
get {
|
||||
|
|
|
@ -761,7 +761,7 @@ Alternativ:
|
|||
1. App schließen,
|
||||
2. auf den Knopf oben am Schloss kurz drücken und sofort loslassen, sobald Knopf zu blinken beginnt,
|
||||
3. sicherstellen, dass das Schloss vollständig geschlossen ist und geschlossen bleibt.
|
||||
4. E-Mail an Betreiber schicken (ansonsten läuft Ihre kostenpflichtige Miete weiter!): Problembeschreibung, Rad-ID, Abgabestation.</value>
|
||||
4. E-Mail an Betreiber schicken (ansonsten läuft Ihre kostenpflichtige Miete weiter!): Bitte Problembeschreibung, Rad-ID und Abgabestation angeben.</value>
|
||||
</data>
|
||||
<data name="ChangeLog3_0_278" xml:space="preserve">
|
||||
<value>Hinweise hinzugefügt, um das Schließen des Schlosses zu erleichtern, falls dies nicht beim ersten Versuch gelingt.</value>
|
||||
|
@ -840,7 +840,7 @@ Activity Indicator zu Konto-Verwaltungsseiten hinzugefügt und Logging erweitert
|
|||
<value>Starte Miete beenden...</value>
|
||||
</data>
|
||||
<data name="ExceptionTextWebConnectFailureException" xml:space="preserve">
|
||||
<value>Ist WLAN/Mobilfunknetz vefügbar und mobile Daten aktiviert?</value>
|
||||
<value>Ist WLAN/Mobilfunknetz verfügbar und mobile Daten aktiviert?</value>
|
||||
</data>
|
||||
<data name="ChangeLog3_0_289" xml:space="preserve">
|
||||
<value>Flyout-Menü Überschift verschönert.</value>
|
||||
|
|
|
@ -869,7 +869,7 @@ Alternative:
|
|||
1. close app,
|
||||
2. press the button at the top of the lock briefly and release it as soon as it starts flashing,
|
||||
3. make sure that the lock is completely closed and remains closed.
|
||||
4. send e-mail to operator (otherwise your chargeable rental will continue!): Problem description, Drop-off station.</value>
|
||||
4. send e-mail to operator (otherwise your chargeable rental will continue!): Please include problem description, bike-id and drop-off station.</value>
|
||||
</data>
|
||||
<data name="ChangeLog3_0_278" xml:space="preserve">
|
||||
<value>Hints added to ease closing of lock in case closing does not succeed on first try.</value>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:tc:xliff:document:1.2 xliff-core-1.2-transitional.xsd">
|
||||
<file datatype="xml" source-language="en-GB" target-language="de" original="TINKLIB/MULTILINGUALRESOURCES/APPRESOURCES.RESX" tool-id="MultilingualAppToolkit" product-name="n/a" product-version="n/a" build-num="n/a">
|
||||
<header>
|
||||
|
@ -1026,14 +1026,14 @@ Alternative:
|
|||
1. close app,
|
||||
2. press the button at the top of the lock briefly and release it as soon as it starts flashing,
|
||||
3. make sure that the lock is completely closed and remains closed.
|
||||
4. send e-mail to operator (otherwise your chargeable rental will continue!): Problem description, Drop-off station.</source>
|
||||
4. send e-mail to operator (otherwise your chargeable rental will continue!): Please include problem description, bike-id and drop-off station.</source>
|
||||
<target state="translated">Es kann weiterhin keine Verbindung zwischen Ihrem mobilen Gerät und dem Schloss aufgebaut werden. Rufen Sie den Betreiber an!
|
||||
|
||||
Alternativ:
|
||||
1. App schließen,
|
||||
2. auf den Knopf oben am Schloss kurz drücken und sofort loslassen, sobald Knopf zu blinken beginnt,
|
||||
3. sicherstellen, dass das Schloss vollständig geschlossen ist und geschlossen bleibt.
|
||||
4. E-Mail an Betreiber schicken (ansonsten läuft Ihre kostenpflichtige Miete weiter!): Problembeschreibung, Rad-ID, Abgabestation.</target>
|
||||
4. E-Mail an Betreiber schicken (ansonsten läuft Ihre kostenpflichtige Miete weiter!): Bitte Problembeschreibung, Rad-ID und Abgabestation angeben.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="ChangeLog3_0_278" translate="yes" xml:space="preserve">
|
||||
<source>Hints added to ease closing of lock in case closing does not succeed on first try.</source>
|
||||
|
@ -1141,7 +1141,7 @@ Activity Indicator zu Konto-Verwaltungsseiten hinzugefügt und Logging erweitert
|
|||
</trans-unit>
|
||||
<trans-unit id="ExceptionTextWebConnectFailureException" translate="yes" xml:space="preserve">
|
||||
<source>Is WIFI/mobile network available and mobile data activated?</source>
|
||||
<target state="translated">Ist WLAN/Mobilfunknetz vefügbar und mobile Daten aktiviert?</target>
|
||||
<target state="translated">Ist WLAN/Mobilfunknetz verfügbar und mobile Daten aktiviert?</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="ChangeLog3_0_289" translate="yes" xml:space="preserve">
|
||||
<source>Flyout menu header improved.</source>
|
||||
|
@ -1631,4 +1631,4 @@ Außerdem:<br/>
|
|||
</group>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
</xliff>
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using Serilog;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Repository.Response;
|
||||
|
@ -22,7 +22,7 @@ namespace TINK.Repository
|
|||
|
||||
public static Version UnsupportedVersionUpper => UNSUPPORTEDFUTURECOPRIVERSIONUPPER;
|
||||
|
||||
/// <summary> Deserializes reponse JSON if response is of supported version or provides default response otherwise. </summary>
|
||||
/// <summary> Deserializes response JSON if response is of supported version or provides default response otherwise. </summary>
|
||||
/// <typeparam name="T">Type of response object.</typeparam>
|
||||
/// <param name="response">Response JSON.</param>
|
||||
/// <param name="emptyResponseFactory">Factory providing default delegate.</param>
|
||||
|
|
|
@ -43,12 +43,12 @@ namespace TINK.Repository.Request
|
|||
|
||||
/// <summary> Gets reservation request (synonym: reservation == request == reservieren). </summary>
|
||||
/// <param name="bikeId">Id of the bike to reserve.</param>
|
||||
/// <returns>Requst to reserve bike.</returns>
|
||||
/// <returns>Request to reserve bike.</returns>
|
||||
string DoReserve(string bikeId);
|
||||
|
||||
/// <summary> Gets request to cancel reservation. </summary>
|
||||
/// <param name="bikeId">Id of the bike to cancel reservation for.</param>
|
||||
/// <returns>Requst on cancel booking request.</returns>
|
||||
/// <returns>Request on cancel booking request.</returns>
|
||||
string DoCancelReservation(string bikeId);
|
||||
|
||||
/// <summary> Request to get keys. </summary>
|
||||
|
@ -96,17 +96,17 @@ namespace TINK.Repository.Request
|
|||
/// <summary> Gets request for returning the bike. </summary>
|
||||
/// <param name="bikeId">Id of the bike to return.</param>
|
||||
/// <param name="location">Geolocation of lock when returning bike.</param>
|
||||
/// <returns>Requst on returning request.</returns>
|
||||
/// <returns>Request on returning request.</returns>
|
||||
string DoReturn(string bikeId, LocationDto location);
|
||||
|
||||
/// <summary> Returns a bike and starts closing. </summary>
|
||||
/// <param name="bikeId">Id of the bike to return.</param>
|
||||
/// <param name="smartDevice">Provides info about hard and software.</param>
|
||||
/// <returns>Response to send to corpi.</returns>
|
||||
/// <returns>Response to send to copri.</returns>
|
||||
string ReturnAndStartClosing(string bikeId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets request for submiting feedback to copri server.
|
||||
/// Gets request for submitting feedback to copri server.
|
||||
/// </summary>
|
||||
/// <param name="bikeId">Id of the bike to which the feedback is related to.</param>
|
||||
/// <param name="currentChargeBars">Null if bike has no engine or charge is unknown. Otherwise the charge filling level of the drive battery.</param>
|
||||
|
@ -119,7 +119,7 @@ namespace TINK.Repository.Request
|
|||
bool isBikeBroken = false);
|
||||
|
||||
/// <summary>
|
||||
/// Gets request for submiting mini survey to copri server.
|
||||
/// Gets request for submitting mini survey to copri server.
|
||||
/// </summary>
|
||||
/// <param name="answers">Collection of answers.</param>
|
||||
string DoSubmitMiniSurvey(IDictionary<string, string> answers);
|
||||
|
|
|
@ -139,7 +139,7 @@ namespace TINK.Repository.Request
|
|||
/// <summary> Returns a bike and starts closing. </summary>
|
||||
/// <param name="bikeId">Id of the bike to return.</param>
|
||||
/// <param name="smartDevice">Provides info about hard and software.</param>
|
||||
/// <returns>Response to send to corpi.</returns>
|
||||
/// <returns>Response to send to copri.</returns>
|
||||
public string ReturnAndStartClosing(string bikeId)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
|
@ -152,7 +152,7 @@ namespace TINK.Repository.Request
|
|||
=> throw new NotSupportedException();
|
||||
|
||||
/// <summary>
|
||||
/// Gets request for submiting mini survey to copri server.
|
||||
/// Gets request for submitting mini survey to copri server.
|
||||
/// </summary>
|
||||
/// <param name="answers">Collection of answers.</param>
|
||||
public string DoSubmitMiniSurvey(IDictionary<string, string> answers) =>
|
||||
|
|
|
@ -55,7 +55,7 @@ namespace TINK.Repository.Request
|
|||
private ISmartDevice SmartDevice { get; }
|
||||
|
||||
/// <summary> Gets request to log user in. </summary>
|
||||
/// <param name="mailAddress">Mailaddress of user to log in.</param>
|
||||
/// <param name="mailAddress">Mail address of user to log in.</param>
|
||||
/// <param name="password">Password to log in.</param>
|
||||
/// <param name="deviceId">Id specifying user and hardware.</param>
|
||||
/// <remarks>Response which holds auth cookie <see cref="ResponseBase.authcookie"/></remarks>
|
||||
|
@ -96,7 +96,7 @@ namespace TINK.Repository.Request
|
|||
/// <summary> Gets reservation request (synonym: reservation == request == reservieren). </summary>
|
||||
/// <remarks> Operator specific call.</remarks>
|
||||
/// <param name="bikeId">Id of the bike to reserve.</param>
|
||||
/// <returns>Requst to reserve bike.</returns>
|
||||
/// <returns>Request to reserve bike.</returns>
|
||||
public string DoReserve(string bikeId)
|
||||
=> "request=booking_request" +
|
||||
GetBikeIdParameter(bikeId) +
|
||||
|
@ -107,7 +107,7 @@ namespace TINK.Repository.Request
|
|||
/// <summary> Gets request to cancel reservation. </summary>
|
||||
/// <remarks> Operator specific call.</remarks>
|
||||
/// <param name="bikeId">Id of the bike to cancel reservation for.</param>
|
||||
/// <returns>Requst on cancel booking request.</returns>
|
||||
/// <returns>Request on cancel booking request.</returns>
|
||||
public string DoCancelReservation(string bikeId)
|
||||
=> "request=booking_cancel" +
|
||||
GetBikeIdParameter(bikeId) +
|
||||
|
@ -158,7 +158,7 @@ namespace TINK.Repository.Request
|
|||
UiIsoLanguageNameParameter;
|
||||
|
||||
|
||||
/// <summary> Gets booking request request (synonym: booking == renting == mieten). </summary>
|
||||
/// <summary> Gets booking request (synonym: booking == renting == mieten). </summary>
|
||||
/// <remarks> Operator specific call.</remarks>
|
||||
/// <param name="bikeId">Id of the bike to book.</param>
|
||||
/// <param name="guid">Used to publish GUID from app to copri. Used for initial setup of bike in copri.</param>
|
||||
|
@ -202,7 +202,7 @@ namespace TINK.Repository.Request
|
|||
/// <remarks> Operator specific call.</remarks>
|
||||
/// <param name="bikeId">Id of bike to return.</param>
|
||||
/// <param name="geolocation">Geolocation of lock when returning bike.</param>
|
||||
/// <returns>Requst on returning request.</returns>
|
||||
/// <returns>Request on returning request.</returns>
|
||||
public string DoReturn(string bikeId, LocationDto geolocation)
|
||||
=> "request=booking_update" +
|
||||
GetBikeIdParameter(bikeId) +
|
||||
|
@ -218,7 +218,7 @@ namespace TINK.Repository.Request
|
|||
/// <summary> Returns a bike and starts closing. </summary>
|
||||
/// <param name="bikeId">Id of the bike to return.</param>
|
||||
/// <param name="smartDevice">Provides info about hard and software.</param>
|
||||
/// <returns>Response to send to corpi.</returns>
|
||||
/// <returns>Response to send to copri.</returns>
|
||||
public string ReturnAndStartClosing(string bikeId)
|
||||
=> "request=booking_update" +
|
||||
GetBikeIdParameter(bikeId) +
|
||||
|
@ -258,7 +258,7 @@ namespace TINK.Repository.Request
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets request for submiting mini survey to copri server.
|
||||
/// Gets request for submitting mini survey to copri server.
|
||||
/// </summary>
|
||||
/// <param name="answers">Collection of answers.</param>
|
||||
public string DoSubmitMiniSurvey(IDictionary<string, string> answers)
|
||||
|
@ -313,7 +313,7 @@ namespace TINK.Repository.Request
|
|||
|
||||
/// <summary> Gets the geolocation parameter. </summary>
|
||||
/// <param name="geolocation">Geolocation or null.</param>
|
||||
/// <returns>Empty string if geoloction is null otherwise parmeter including latitude, longitude and age in a format which is urlencode invariant.</returns>
|
||||
/// <returns>Empty string if geolocation is null otherwise parameter including latitude, longitude and age in a format which is urlencode invariant.</returns>
|
||||
private static string GetLocationParameters(LocationDto geolocation)
|
||||
{
|
||||
if (geolocation == null)
|
||||
|
|
21
TINKLib/Repository/Response/Stations/Station/BikeGroup.cs
Normal file
21
TINKLib/Repository/Response/Stations/Station/BikeGroup.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using System.Runtime.Serialization;
|
||||
|
||||
namespace TINK.Repository.Response.Stations.Station
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds a single bike group.
|
||||
/// </summary>
|
||||
[DataContract]
|
||||
public class BikeGroup
|
||||
{
|
||||
/// <summary> Holds the count of bikes for the group. </summary>
|
||||
[DataMember]
|
||||
public string bike_count { get; private set;}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the group identifying the bike group type.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string bike_group { get; private set; }
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace TINK.Repository.Response.Stations.Station
|
||||
|
@ -28,5 +29,17 @@ namespace TINK.Repository.Response.Stations.Station
|
|||
|
||||
[DataMember]
|
||||
public OperatorData operator_data { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds the count of available bikes at the station.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string bike_count { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds the count type of station, i.e. which bikes are located at station.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public Dictionary<string, BikeGroup> station_type { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,5 +15,11 @@ namespace TINK.Repository.Response.Stations
|
|||
/// </summary>
|
||||
[DataMember]
|
||||
public Dictionary<string, StationInfo> stations { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Dictionary of bikes reserved (requested) and rented (occupied) by current user if user is logged in and has reserved or rented bikes.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public Dictionary<string, BikeInfoReservedOrBooked> bikes_occupied { get; private set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace TINK.Services.CopriApi
|
|||
}
|
||||
|
||||
/// <summary> Opens lock.</summary>
|
||||
/// <param name="corpiServer"> Instance to communicate with backend.</param>
|
||||
/// <param name="cachedServer"> Instance to communicate with backend.</param>
|
||||
/// <param name="bike">Bike object holding id of bike to open. Lock state of object is updated after open request.</param>
|
||||
public static async Task OpenAync(
|
||||
this ICachedCopriServer cachedServer,
|
||||
|
@ -70,11 +70,11 @@ namespace TINK.Services.CopriApi
|
|||
/// <summary>
|
||||
/// Books a bike and opens the lock.
|
||||
/// </summary>
|
||||
/// <param name="corpiServer"> Instance to communicate with backend.</param>
|
||||
/// <param name="copriServer"> Instance to communicate with backend.</param>
|
||||
/// <param name="bike">Bike to book and open.</param>
|
||||
/// <param name="mailAddress">Mail address of user which books bike.</param>
|
||||
public static async Task BookAndOpenAync(
|
||||
this ICopriServerBase corpiServer,
|
||||
this ICopriServerBase copriServer,
|
||||
IBikeInfoMutable bike,
|
||||
string mailAddress)
|
||||
{
|
||||
|
@ -83,13 +83,13 @@ namespace TINK.Services.CopriApi
|
|||
throw new ArgumentNullException(nameof(bike), "Can not book bike and open lock. No bike object available.");
|
||||
}
|
||||
|
||||
if (!(corpiServer is ICachedCopriServer cachedServer))
|
||||
throw new ArgumentNullException(nameof(corpiServer));
|
||||
if (!(copriServer is ICachedCopriServer cachedServer))
|
||||
throw new ArgumentNullException(nameof(copriServer));
|
||||
|
||||
// Send command to open lock
|
||||
var response = bike.State.Value == Model.State.InUseStateEnum.Disposable
|
||||
? (await corpiServer.BookAvailableAndStartOpeningAsync(bike.Id, bike.OperatorUri)).GetIsBookingResponseOk(bike.Id)
|
||||
: (await corpiServer.BookReservedAndStartOpeningAsync(bike.Id, bike.OperatorUri)).GetIsBookingResponseOk(bike.Id);
|
||||
? (await copriServer.BookAvailableAndStartOpeningAsync(bike.Id, bike.OperatorUri)).GetIsBookingResponseOk(bike.Id)
|
||||
: (await copriServer.BookReservedAndStartOpeningAsync(bike.Id, bike.OperatorUri)).GetIsBookingResponseOk(bike.Id);
|
||||
|
||||
// Upated locking state.
|
||||
var lockingState = await cachedServer.GetOccupiedBikeLockStateAsync(bike.Id);
|
||||
|
@ -128,17 +128,17 @@ namespace TINK.Services.CopriApi
|
|||
/// <summary>
|
||||
/// Returns a bike and closes the lock.
|
||||
/// </summary>
|
||||
/// <param name="corpiServer"> Instance to communicate with backend.</param>
|
||||
/// <param name="copriServer"> Instance to communicate with backend.</param>
|
||||
/// <param name="bike">Bike to close.</param>
|
||||
public static async Task CloseAync(
|
||||
this ICopriServerBase corpiServer,
|
||||
this ICopriServerBase copriServer,
|
||||
IBikeInfoMutable bike)
|
||||
{
|
||||
if (!(corpiServer is ICachedCopriServer cachedServer))
|
||||
throw new ArgumentNullException(nameof(corpiServer));
|
||||
if (!(copriServer is ICachedCopriServer cachedServer))
|
||||
throw new ArgumentNullException(nameof(copriServer));
|
||||
|
||||
// Send command to close lock
|
||||
await corpiServer.UpdateLockingStateAsync(
|
||||
await copriServer.UpdateLockingStateAsync(
|
||||
bike.Id,
|
||||
Repository.Request.lock_state.locking,
|
||||
bike.OperatorUri);
|
||||
|
@ -166,20 +166,20 @@ namespace TINK.Services.CopriApi
|
|||
/// <summary>
|
||||
/// Returns a bike and closes the lock.
|
||||
/// </summary>
|
||||
/// <param name="corpiServer"> Instance to communicate with backend.</param>
|
||||
/// <param name="copriServer"> Instance to communicate with backend.</param>
|
||||
/// <param name="smartDevice">Smart device on which app runs on.</param>
|
||||
/// <param name="mailAddress">Mail address of user which books bike.</param>
|
||||
public static async Task<BookingFinishedModel> ReturnAndCloseAync(
|
||||
this ICopriServerBase corpiServer,
|
||||
this ICopriServerBase copriServer,
|
||||
ISmartDevice smartDevice,
|
||||
IBikeInfoMutable bike)
|
||||
{
|
||||
if (!(corpiServer is ICachedCopriServer cachedServer))
|
||||
throw new ArgumentNullException(nameof(corpiServer));
|
||||
if (!(copriServer is ICachedCopriServer cachedServer))
|
||||
throw new ArgumentNullException(nameof(copriServer));
|
||||
|
||||
// Send command to open lock
|
||||
DoReturnResponse response =
|
||||
await corpiServer.ReturnAndStartClosingAsync(bike.Id, bike.OperatorUri);
|
||||
await copriServer.ReturnAndStartClosingAsync(bike.Id, bike.OperatorUri);
|
||||
|
||||
// Upate booking state
|
||||
bike.Load(Model.Bikes.BikeInfoNS.BC.NotifyPropertyChangedLevel.None);
|
||||
|
@ -209,21 +209,21 @@ namespace TINK.Services.CopriApi
|
|||
/// <summary>
|
||||
/// Queries the locking state from copri.
|
||||
/// </summary>
|
||||
/// <param name="corpiServer">Service to use.</param>
|
||||
/// <param name="copriServer">Service to use.</param>
|
||||
/// <param name="bikeId">Bike id to query lock state for.</param>
|
||||
/// <returns>Locking state</returns>
|
||||
private static async Task<LockingState> GetLockStateAsync(
|
||||
this ICachedCopriServer corpiServer,
|
||||
this ICachedCopriServer copriServer,
|
||||
string bikeId)
|
||||
{
|
||||
// Querry reserved or booked bikes first for performance reasons.
|
||||
var bikeReservedOrBooked = (await corpiServer.GetBikesOccupied(false))?.Response.bikes_occupied?.Values?.FirstOrDefault(x => x.bike == bikeId);
|
||||
var bikeReservedOrBooked = (await copriServer.GetBikesOccupied(false))?.Response.bikes_occupied?.Values?.FirstOrDefault(x => x.bike == bikeId);
|
||||
if (bikeReservedOrBooked != null)
|
||||
{
|
||||
return bikeReservedOrBooked.GetCopriLockingState();
|
||||
}
|
||||
|
||||
var bikeAvailable = (await corpiServer.GetBikesAvailable(false))?.Response.bikes?.Values?.FirstOrDefault(x => x.bike == bikeId);
|
||||
var bikeAvailable = (await copriServer.GetBikesAvailable(false))?.Response.bikes?.Values?.FirstOrDefault(x => x.bike == bikeId);
|
||||
if (bikeAvailable != null)
|
||||
{
|
||||
return bikeAvailable.GetCopriLockingState();
|
||||
|
@ -235,14 +235,14 @@ namespace TINK.Services.CopriApi
|
|||
/// <summary>
|
||||
/// Queries the locking state of a occupied bike from copri.
|
||||
/// </summary>
|
||||
/// <param name="corpiServer">Service to use.</param>
|
||||
/// <param name="copriServer">Service to use.</param>
|
||||
/// <param name="bikeId">Bike id to query lock state for.</param>
|
||||
/// <returns>Locking state if bike is still occupied, null otherwise.</returns>
|
||||
private static async Task<LockingState?> GetOccupiedBikeLockStateAsync(
|
||||
this ICachedCopriServer corpiServer,
|
||||
this ICachedCopriServer copriServer,
|
||||
string bikeId)
|
||||
{
|
||||
var bikeReservedOrBooked = (await corpiServer.GetBikesOccupied(false))?.Response.bikes_occupied?.Values?.FirstOrDefault(x => x.bike == bikeId);
|
||||
var bikeReservedOrBooked = (await copriServer.GetBikesOccupied(false))?.Response.bikes_occupied?.Values?.FirstOrDefault(x => x.bike == bikeId);
|
||||
if (bikeReservedOrBooked != null)
|
||||
{
|
||||
return bikeReservedOrBooked.GetCopriLockingState();
|
||||
|
|
|
@ -3,15 +3,37 @@ using TINK.Model.Stations;
|
|||
|
||||
namespace TINK.Model.Services.CopriApi
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds stations and bikes.
|
||||
/// </summary>
|
||||
public class StationsAndBikesContainer
|
||||
{
|
||||
public StationsAndBikesContainer(StationDictionary stations, BikeCollection bikes)
|
||||
/// <summary>
|
||||
/// Holds station and bikes.
|
||||
/// </summary>
|
||||
/// <param name="stations">Stations information which contains some information about bikes available at each station (bike count, ...).</param>
|
||||
/// <param name="bikesOccupied"></param>
|
||||
public StationsAndBikesContainer(StationDictionary stations, BikeCollection bikesOccupied)
|
||||
{
|
||||
StationsAll = stations;
|
||||
Bikes = bikes;
|
||||
BikesOccupied = bikesOccupied;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds all stations.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Since copri version writing <see cref="StationType"/> (>= 4.1.23.03) stations contain bikes available information.
|
||||
/// Prior to this copri version bikes available were part of <see cref="BikesOccupied"/>
|
||||
/// </remarks>
|
||||
public StationDictionary StationsAll { get; }
|
||||
|
||||
public BikeCollection Bikes { get; }
|
||||
/// <summary>
|
||||
/// Holds bikes occupied (i.e. bike reserved or booked).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Up to copri version writing <see cref="StationType"/> (>= 4.1.23.03) bike available were contained beside bikes occupied.
|
||||
/// </remarks>
|
||||
public BikeCollection BikesOccupied { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,4 +84,7 @@
|
|||
<LastGenOutput>AppResources.Designer.cs</LastGenOutput>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<InternalsVisibleTo Include="TestShareeLib" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -101,7 +101,7 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
|||
}
|
||||
}
|
||||
|
||||
// Notify corpi about unlock action in order to start booking.
|
||||
// Notify copri about unlock action in order to start booking.
|
||||
BikesViewModel.ActionText = AppResources.ActivityTextRentingBike;
|
||||
IsConnected = IsConnectedDelegate();
|
||||
try
|
||||
|
|
|
@ -204,7 +204,7 @@ namespace TINK.ViewModel.Contact
|
|||
? $"{stationId}" // there is a station marker with index letter for given station id
|
||||
: "Open"; // there is no station marker. Use open marker.
|
||||
|
||||
var colorPartPrefix = GetRessourceNameColorPart(stationsColorList[pinIndex]);
|
||||
var colorPartPrefix = GetResourceNameColorPart(stationsColorList[pinIndex]);
|
||||
|
||||
var l_iName = $"{indexPartPrefix.ToString().PadLeft(2, '0')}_{colorPartPrefix}{(DeviceInfo.Platform == DevicePlatform.Android ? ".png" : string.Empty)}";
|
||||
try
|
||||
|
@ -234,7 +234,7 @@ namespace TINK.ViewModel.Contact
|
|||
/// <summary> Gets the color related part of the ressrouce name.</summary>
|
||||
/// <param name="color">Color to get name for.</param>
|
||||
/// <returns>Resource name.</returns>
|
||||
private static string GetRessourceNameColorPart(Color color)
|
||||
private static string GetResourceNameColorPart(Color color)
|
||||
{
|
||||
if (color == Color.Blue)
|
||||
{
|
||||
|
@ -395,7 +395,7 @@ namespace TINK.ViewModel.Contact
|
|||
|
||||
var colors = GetStationColors(
|
||||
Pins.Select(x => x.Tag.ToString()).ToList(),
|
||||
resultStationsAndBikes.Response.Bikes);
|
||||
resultStationsAndBikes.Response.BikesOccupied);
|
||||
|
||||
// Update pins color form count of bikes located at station.
|
||||
UpdatePinsColor(colors);
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace TINK.ViewModel.Contact
|
|||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
|
||||
/// <summary> Holds value wether site caching is on or off.</summary>
|
||||
/// <summary> Holds value whether site caching is on or off.</summary>
|
||||
bool IsSiteCachingOn { get; }
|
||||
|
||||
/// <summary>
|
||||
|
@ -64,7 +64,7 @@ namespace TINK.ViewModel.Contact
|
|||
|
||||
/// <summary> Constructs view model.</summary>
|
||||
/// <param name="isSiteCachingOn">Set of user permissions</param>
|
||||
/// <param name="resourceProvider">Delegate to get an an embedded html ressource. Used as fallback if download from web page does not work and cache is empty.</param>
|
||||
/// <param name="resourceProvider">Delegate to get embedded html resource. Used as fallback if download from web page does not work and cache is empty.</param>
|
||||
/// <param name="query">Object to query resources path values if required.</param>
|
||||
public FeesAndBikesPageViewModel(
|
||||
string hostName,
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace TINK.ViewModel.Info
|
|||
/// <summary> Holds the name of the host.</summary>
|
||||
private string HostName { get; }
|
||||
|
||||
/// <summary> Holds value wether site caching is on or off.</summary>
|
||||
/// <summary> Holds value whether site caching is on or off.</summary>
|
||||
bool IsSiteCachingOn { get; }
|
||||
|
||||
/// <summary>
|
||||
|
@ -74,11 +74,11 @@ namespace TINK.ViewModel.Info
|
|||
|
||||
/// <summary> Constructs Info view model</summary>
|
||||
/// <param name="hostName">Name of the host to get html resources from.</param>
|
||||
/// <param name="isSiteCachingOn">Holds value wether site caching is on or off.</param>
|
||||
/// <param name="agbResourcePath"> Agb resouce path received from backend.</param>
|
||||
/// <param name="privacyResourcePath"> Privacy resouce path received from backend.</param>
|
||||
/// <param name="impressResourcePath"> Impress resouce path received from backend.</param>
|
||||
/// <param name="resourceProvider">Delegate to get an an embedded html ressource. Used as fallback if download from web page does not work and cache is empty.</param>
|
||||
/// <param name="isSiteCachingOn">Holds value whether site caching is on or off.</param>
|
||||
/// <param name="agbResourcePath"> Agb resource path received from backend.</param>
|
||||
/// <param name="privacyResourcePath"> Privacy resource path received from backend.</param>
|
||||
/// <param name="impressResourcePath"> Impress resource path received from backend.</param>
|
||||
/// <param name="resourceProvider">Delegate to get embedded html resource. Used as fallback if download from web page does not work and cache is empty.</param>
|
||||
/// <param name="queryProvider">Object to query resources urls object from backend if required.</param>
|
||||
/// <param name="updateUrlsAction">Action to update shared resources urls object</param>
|
||||
public InfoPageViewModel(
|
||||
|
@ -102,7 +102,7 @@ namespace TINK.ViewModel.Info
|
|||
InfoAgb = new HtmlWebViewSource { Html = "<html>Loading...</html>" };
|
||||
|
||||
ResourceProvider = resourceProvider
|
||||
?? throw new ArgumentException($"Can not instantiate {typeof(InfoPageViewModel)}-object. No ressource provider centered.");
|
||||
?? throw new ArgumentException($"Can not instantiate {typeof(InfoPageViewModel)}-object. No resource provider centered.");
|
||||
}
|
||||
|
||||
/// <summary> Called when page is shown. </summary>
|
||||
|
@ -147,7 +147,7 @@ namespace TINK.ViewModel.Info
|
|||
|
||||
if (string.IsNullOrEmpty(PrivacyResourcePath))
|
||||
{
|
||||
// Information to access ressource is missing
|
||||
// Information to access resource is missing
|
||||
return new HtmlWebViewSource
|
||||
{
|
||||
Html = await Task.FromResult(ViewModelHelper.FromBody("No privacy resource available. Resource path is null or empty."))
|
||||
|
@ -172,7 +172,7 @@ namespace TINK.ViewModel.Info
|
|||
|
||||
if (string.IsNullOrEmpty(ImpressResourcePath))
|
||||
{
|
||||
// Information to access ressource is missing
|
||||
// Information to access resource is missing
|
||||
return new HtmlWebViewSource
|
||||
{
|
||||
Html = await Task.FromResult(ViewModelHelper.FromBody("No impress resource available. Resource path is null or empty."))
|
||||
|
|
|
@ -329,7 +329,7 @@ namespace TINK.ViewModel
|
|||
return;
|
||||
}
|
||||
|
||||
// Swich to map page
|
||||
// Switch to map page
|
||||
#if USEFLYOUT
|
||||
m_oViewService.ShowPage(ViewTypes.BikeInfoCarouselPage, AppResources.MarkingLoginInstructions);
|
||||
#else
|
||||
|
|
|
@ -22,11 +22,11 @@ using TINK.Services.Permissions;
|
|||
using Xamarin.Essentials;
|
||||
using System.Threading;
|
||||
using TINK.MultilingualResources;
|
||||
using TINK.Services.BluetoothLock;
|
||||
using TINK.Repository;
|
||||
using TINK.Services.Geolocation;
|
||||
using TINK.Model.State;
|
||||
using TINK.ViewModel.Bikes;
|
||||
using TINK.Model.Bikes.BikeInfoNS.BC;
|
||||
using TINK.Model.Stations.StationNS;
|
||||
|
||||
#if !TRYNOTBACKSTYLE
|
||||
#endif
|
||||
|
@ -263,7 +263,7 @@ namespace TINK.ViewModel.Map
|
|||
? $"{stationId}" // there is a station marker with index letter for given station id
|
||||
: "Open"; // there is no station marker. Use open marker.
|
||||
|
||||
var colorPartPrefix = GetRessourceNameColorPart(stationsColorList[pinIndex]);
|
||||
var colorPartPrefix = GetResourceNameColorPart(stationsColorList[pinIndex]);
|
||||
var name = $"{indexPartPrefix.ToString().PadLeft(2, '0')}_{colorPartPrefix}{(DeviceInfo.Platform == DevicePlatform.Android ? ".png" : string.Empty)}";
|
||||
try
|
||||
{
|
||||
|
@ -306,7 +306,7 @@ namespace TINK.ViewModel.Map
|
|||
/// <summary> Gets the color related part of the ressrouce name.</summary>
|
||||
/// <param name="color">Color to get name for.</param>
|
||||
/// <returns>Resource name.</returns>
|
||||
private static string GetRessourceNameColorPart(Color color)
|
||||
private static string GetResourceNameColorPart(Color color)
|
||||
{
|
||||
if (color == Color.Blue)
|
||||
{
|
||||
|
@ -394,7 +394,8 @@ namespace TINK.ViewModel.Map
|
|||
|
||||
var colors = GetStationColors(
|
||||
Pins.Select(x => x.Tag.ToString()).ToList(),
|
||||
resultStationsAndBikes.Response.Bikes);
|
||||
resultStationsAndBikes.Response.StationsAll,
|
||||
resultStationsAndBikes.Response.BikesOccupied);
|
||||
|
||||
// Update pins color form count of bikes located at station.
|
||||
UpdatePinsColor(colors);
|
||||
|
@ -402,7 +403,7 @@ namespace TINK.ViewModel.Map
|
|||
Log.ForContext<MapPageViewModel>().Verbose("Update pins color done.");
|
||||
|
||||
// Load MyBikes Count -> MyBikes Icon/Button
|
||||
GetMyBikesCount(resultStationsAndBikes.Response.Bikes);
|
||||
GetMyBikesCount(resultStationsAndBikes.Response.BikesOccupied);
|
||||
|
||||
// Move and scale before getting stations and bikes which takes some time.
|
||||
ActionText = AppResources.ActivityTextCenterMap;
|
||||
|
@ -655,7 +656,7 @@ namespace TINK.ViewModel.Map
|
|||
}
|
||||
|
||||
// Load MyBikes Count -> MyBikes Icon/Button
|
||||
GetMyBikesCount(resultStationsAndBikes.Response.Bikes);
|
||||
GetMyBikesCount(resultStationsAndBikes.Response.BikesOccupied);
|
||||
|
||||
// Check if there are already any pins to the map.
|
||||
// If no initialize pins.
|
||||
|
@ -670,7 +671,8 @@ namespace TINK.ViewModel.Map
|
|||
// Set/ update pins colors.
|
||||
var l_oColors = GetStationColors(
|
||||
Pins.Select(x => x.Tag.ToString()).ToList(),
|
||||
resultStationsAndBikes.Response.Bikes);
|
||||
resultStationsAndBikes.Response.StationsAll,
|
||||
resultStationsAndBikes.Response.BikesOccupied);
|
||||
|
||||
// Update pins color form count of bikes located at station.
|
||||
TinkApp.PostAction(
|
||||
|
@ -758,10 +760,13 @@ namespace TINK.ViewModel.Map
|
|||
/// Gets the list of station color for all stations.
|
||||
/// </summary>
|
||||
/// <param name="stationsId">Station id list to get color for.</param>
|
||||
/// <param name="stations">Station object dictionary to get count of available bike from for each station.</param>
|
||||
/// <param name="bikesReserved">Bike collection to get count of reserved/ rented bikes from for each station.</param>
|
||||
/// <returns></returns>
|
||||
private static IList<Color> GetStationColors(
|
||||
internal static IList<Color> GetStationColors(
|
||||
IEnumerable<string> stationsId,
|
||||
BikeCollection bikesAll)
|
||||
IEnumerable<IStation> stations,
|
||||
IEnumerable<BikeInfo> bikesReserved)
|
||||
{
|
||||
if (stationsId == null)
|
||||
{
|
||||
|
@ -769,11 +774,14 @@ namespace TINK.ViewModel.Map
|
|||
return new List<Color>();
|
||||
}
|
||||
|
||||
if (bikesAll == null)
|
||||
if (stations == null)
|
||||
{
|
||||
// If object is null an error occurred querying bikes centered or bikes occupied which results in an unknown state.
|
||||
Log.ForContext<MapPageViewModel>().Error("No bikes available to determine pins color.");
|
||||
return new List<Color>(stationsId.Select(x => Color.Blue));
|
||||
Log.ForContext<MapPageViewModel>().Error("No stations info available to get count of bikes available to determine whether a pin is green or not.");
|
||||
}
|
||||
|
||||
if (bikesReserved == null)
|
||||
{
|
||||
Log.ForContext<MapPageViewModel>().Error("No bikes info available to determine whether a pins is light blue or not.");
|
||||
}
|
||||
|
||||
// Get state for each station.
|
||||
|
@ -781,15 +789,14 @@ namespace TINK.ViewModel.Map
|
|||
foreach (var stationId in stationsId)
|
||||
{
|
||||
// Get color of given station.
|
||||
var bikesAtStation = bikesAll.Where(x => x.StationId == stationId).ToList();
|
||||
if (bikesAtStation.FirstOrDefault(x => x.State.Value.IsOccupied()) != null)
|
||||
if (bikesReserved?.Where(x => x.StationId == stationId).Count() > 0)
|
||||
{
|
||||
// There is at least one requested or booked bike
|
||||
colors.Add(Color.LightBlue);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bikesAtStation.ToList().Count > 0)
|
||||
if (stations?.FirstOrDefault(x => x.Id == stationId)?.AvailableBikesCount > 0)
|
||||
{
|
||||
// There is at least one bike available
|
||||
colors.Add(Color.Green);
|
||||
|
@ -1030,7 +1037,8 @@ namespace TINK.ViewModel.Map
|
|||
Log.ForContext<MapPageViewModel>().Verbose("Starting update pins color on toggle...");
|
||||
var l_oColors = GetStationColors(
|
||||
Pins.Select(x => x.Tag.ToString()).ToList(),
|
||||
resultStationsAndBikes.Response.Bikes);
|
||||
resultStationsAndBikes.Response.StationsAll,
|
||||
resultStationsAndBikes.Response.BikesOccupied);
|
||||
|
||||
// Update pins color form count of bikes located at station.
|
||||
UpdatePinsColor(l_oColors);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
|
@ -66,12 +66,12 @@ namespace TINK.Model.Connector
|
|||
{
|
||||
NextActiveUri = new Uri(serverTextToUri.ContainsKey(value) ? serverTextToUri[value] : value);
|
||||
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CorpiServerUriDescription)));
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(CopriServerUriDescription)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Holds the description of the picker, i.e. binds to label Text.</summary>
|
||||
public string CorpiServerUriDescription
|
||||
public string CopriServerUriDescription
|
||||
{
|
||||
get
|
||||
{
|
||||
|
|
|
@ -65,21 +65,21 @@ namespace TINK.ViewModel
|
|||
/// <summary> Reference on the tink app instance. </summary>
|
||||
private ITinkApp TinkApp { get; }
|
||||
|
||||
IServicesContainer<IGeolocationService> GeoloctionServicesContainer { get; }
|
||||
IServicesContainer<IGeolocationService> GeolocationServicesContainer { get; }
|
||||
|
||||
/// <summary> Constructs a settings page view model object.</summary>
|
||||
/// <param name="tinkApp"> Reference to tink app model.</param>
|
||||
/// <param name="geoloctionServicesContainer"></param>
|
||||
/// <param name="geolocationServicesContainer"></param>
|
||||
/// <param name="viewService">Interface to view</param>
|
||||
public SettingsPageViewModel(
|
||||
ITinkApp tinkApp,
|
||||
IServicesContainer<IGeolocationService> geoloctionServicesContainer,
|
||||
IServicesContainer<IGeolocationService> geolocationServicesContainer,
|
||||
IViewService viewService)
|
||||
{
|
||||
TinkApp = tinkApp
|
||||
?? throw new ArgumentException("Can not instantiate settings page view model- object. No tink app object available.");
|
||||
|
||||
GeoloctionServicesContainer = geoloctionServicesContainer
|
||||
GeolocationServicesContainer = geolocationServicesContainer
|
||||
?? throw new ArgumentException($"Can not instantiate {nameof(SettingsPageViewModel)}- object. Geolocation services container object must not be null.");
|
||||
|
||||
m_oViewService = viewService
|
||||
|
@ -175,14 +175,14 @@ namespace TINK.ViewModel
|
|||
TinkApp.LocksServices.Active.GetType().FullName));
|
||||
|
||||
GeolocationServices = new ServicesViewModel(
|
||||
GeoloctionServicesContainer.Select(x => x.GetType().FullName),
|
||||
GeolocationServicesContainer.Select(x => x.GetType().FullName),
|
||||
new Dictionary<string, string> {
|
||||
{ typeof(LastKnownGeolocationService).FullName, "LastKnowGeolocation" },
|
||||
{ typeof(GeolocationAccuracyMediumService).FullName, "Medium Accuracy" },
|
||||
{ typeof(GeolocationAccuracyHighService).FullName, "High Accuracy" },
|
||||
{ typeof(GeolocationAccuracyBestService).FullName, "Best Accuracy" },
|
||||
{ typeof(SimulatedGeolocationService).FullName, "Simulation-AlwaysSamePosition" } },
|
||||
GeoloctionServicesContainer.Active.GetType().FullName);
|
||||
GeolocationServicesContainer.Active.GetType().FullName);
|
||||
|
||||
StartupSettings = new PickerViewModel(
|
||||
new Dictionary<string, string> {
|
||||
|
@ -310,7 +310,7 @@ namespace TINK.ViewModel
|
|||
|
||||
TinkApp.LocksServices.SetActive(LocksServices.Services.Active);
|
||||
|
||||
GeoloctionServicesContainer.SetActive(GeolocationServices.Active);
|
||||
GeolocationServicesContainer.SetActive(GeolocationServices.Active);
|
||||
|
||||
TinkApp.LocksServices.SetTimeOut(TimeSpan.FromSeconds(LocksServices.ConnectTimeoutSec));
|
||||
|
||||
|
|
|
@ -174,7 +174,7 @@ namespace TINK.ViewModel
|
|||
|
||||
}
|
||||
|
||||
/// <summary> Gets error message and handles aggegate exceptions. </summary>
|
||||
/// <summary> Gets error message and handles aggregate exceptions. </summary>
|
||||
public static string GetErrorMessage(this Exception exception)
|
||||
{
|
||||
if (exception == null)
|
||||
|
@ -239,8 +239,8 @@ namespace TINK.ViewModel
|
|||
|
||||
/// <summary> Called when page is shown. </summary>
|
||||
/// <param name="resourceUrl">Url to load data from.</param>
|
||||
/// <param name="isSiteCachingOn">Holds value wether site caching is on or off.</param>
|
||||
/// <param name="resourceProvider"> Provides resource from embedded ressources.</param>
|
||||
/// <param name="isSiteCachingOn">Holds value whether site caching is on or off.</param>
|
||||
/// <param name="resourceProvider"> Provides resource from embedded resources.</param>
|
||||
public static async Task<string> GetSource(
|
||||
string resourceUrl,
|
||||
bool isSiteCachingOn,
|
||||
|
@ -271,7 +271,7 @@ namespace TINK.ViewModel
|
|||
// An error occurred getting resource from web
|
||||
htmlContent = Barrel.Current.Exists(resourceUrl)
|
||||
? Barrel.Current.Get<string>(key: resourceUrl) // Get from MonkeyCache
|
||||
: resourceProvider != null ? resourceProvider() : $"<DOCTYPE html>Error loading {resourceUrl}."; // Get build in ressource.
|
||||
: resourceProvider != null ? resourceProvider() : $"<DOCTYPE html>Error loading {resourceUrl}."; // Get build in resource.
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -280,7 +280,7 @@ namespace TINK.ViewModel
|
|||
break;
|
||||
}
|
||||
|
||||
return htmlContent ?? FromBody("An error occurred loading html- ressource.");
|
||||
return htmlContent ?? FromBody("An error occurred loading html- resource.");
|
||||
}
|
||||
|
||||
public static string FromBody(string message) => $"<!DOCTYPE html><html lang=\"de\"><head><title>Error Information</title></head><body>{message}</body></html>";
|
||||
|
|
|
@ -16,13 +16,13 @@ namespace TINK.ViewModel.WhatsNew.Agb
|
|||
/// <summary> Holds the name of the host.</summary>
|
||||
private string HostName { get; }
|
||||
|
||||
/// <summary> Holds value wether site caching is on or off.</summary>
|
||||
/// <summary> Holds value whether site caching is on or off.</summary>
|
||||
bool IsSiteCachingOn { get; }
|
||||
|
||||
/// <summary> Constructs AGB view model</summary>
|
||||
/// <param name="isSiteCachingOn">Holds value wether site caching is on or off.</param>
|
||||
/// <param name="isSiteCachingOn">Holds value whether site caching is on or off.</param>
|
||||
/// <param name="uiIsoLangugageName">Two letter ISO language name.</param>
|
||||
/// <param name="resourceProvider">Delegate to get an an embedded html ressource. Used as fallback if download from web page does not work and cache is empty.</param>
|
||||
/// <param name="resourceProvider">Delegate to get embedded html resource. Used as fallback if download from web page does not work and cache is empty.</param>
|
||||
/// <param name="viewService">View service to close page.</param>
|
||||
public AgbViewModel(
|
||||
string hostName,
|
||||
|
@ -37,7 +37,7 @@ namespace TINK.ViewModel.WhatsNew.Agb
|
|||
?? throw new ArgumentException($"Can not instantiate {typeof(WhatsNewViewModel)}-object. No view available.");
|
||||
|
||||
ResourceProvider = resourceProvider
|
||||
?? throw new ArgumentException($"Can not instantiate {typeof(WhatsNewViewModel)}-object. No ressource provider centered.");
|
||||
?? throw new ArgumentException($"Can not instantiate {typeof(WhatsNewViewModel)}-object. No resource provider centered.");
|
||||
}
|
||||
|
||||
/// <summary> Gets the platfrom specific prefix. </summary>
|
||||
|
|
|
@ -11,7 +11,7 @@ using TINK.Repository.Response;
|
|||
using TINK.Repository.Response.Stations;
|
||||
using static TINK.Repository.CopriCallsMemory;
|
||||
|
||||
namespace TestTINKLib.Mocks.Connector
|
||||
namespace TestFramework.Repository
|
||||
{
|
||||
/// <summary> Allows use of memory for retrieving defined responses.</summary>
|
||||
public class CopriCallsCacheMemory : ICopriCache
|
||||
|
@ -111,7 +111,7 @@ namespace TestTINKLib.Mocks.Connector
|
|||
public Task<DoReturnResponse> ReturnAndStartClosingAsync(
|
||||
string bikeId,
|
||||
Uri operatorUri)
|
||||
=> throw new System.Exception("Rückgabe mit mit Schloss schließen Befehl Offlinemodus nicht möglich!");
|
||||
=> throw new Exception("Rückgabe mit mit Schloss schließen Befehl Offlinemodus nicht möglich!");
|
||||
|
||||
public Task<SubmitFeedbackResponse> DoSubmitFeedback(string bikeId, int? currentChargeBars, string message, bool isBikeBroken, Uri operatorUri)
|
||||
=> throw new NotImplementedException();
|
|
@ -1,7 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using TestFramework.Repository;
|
||||
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
|
@ -9,7 +8,7 @@ using TINK.Repository.Request;
|
|||
using TINK.Repository.Response;
|
||||
using TINK.Repository.Response.Stations;
|
||||
|
||||
namespace TestFramework.Services.CopriApi.Connector
|
||||
namespace TestFramework.Repository
|
||||
{
|
||||
/// <summary> Allows use of memory for retrieving defined responses.</summary>
|
||||
public class CopriCallsCacheMemory001 : ICopriCache
|
|
@ -0,0 +1,126 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Repository.Request;
|
||||
using TINK.Repository.Response.Stations;
|
||||
using TINK.Repository.Response;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
|
||||
namespace TestFramework.Repository
|
||||
{
|
||||
public class CopriCallsCacheMemory001v2NotLoggedIn : ICopriCache
|
||||
{
|
||||
private CopriCallsMemory001v2NotLoggedIn server;
|
||||
|
||||
public CopriCallsCacheMemory001v2NotLoggedIn(string sessionCookie = null)
|
||||
{
|
||||
server = new CopriCallsMemory001v2NotLoggedIn(sessionCookie);
|
||||
}
|
||||
|
||||
public bool IsStationsExpired => true;
|
||||
|
||||
public bool IsBikesAvailableExpired => true;
|
||||
|
||||
public bool IsBikesOccupiedExpired => true;
|
||||
|
||||
public bool IsConnected => server.IsConnected;
|
||||
|
||||
public string SessionCookie => server.SessionCookie;
|
||||
|
||||
public string MerchantId => server.MerchantId;
|
||||
|
||||
public void AddToCache(StationsAvailableResponse stations)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public void AddToCache(BikesAvailableResponse bikes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public void AddToCache(BikesReservedOccupiedResponse bikes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public Task<AuthorizationResponse> DoAuthorizationAsync(string p_strMailAddress, string p_strPassword, string p_strDeviceId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<AuthorizationoutResponse> DoAuthoutAsync()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<ReservationBookingResponse> DoReserveAsync(string bikeId, Uri operatorUri)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<ReservationCancelReturnResponse> DoCancelReservationAsync(string p_iBikeId, Uri operatorUri)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public Task<ReservationBookingResponse> CalculateAuthKeysAsync(string bikeId, Uri operatorUri)
|
||||
=> throw new NotSupportedException();
|
||||
|
||||
public Task<ResponseBase> StartReturningBike(
|
||||
string bikeId,
|
||||
Uri operatorUri)
|
||||
=> null;
|
||||
|
||||
public Task<ReservationBookingResponse> UpdateLockingStateAsync(
|
||||
string bikeId,
|
||||
lock_state state,
|
||||
Uri operatorUri,
|
||||
LocationDto geolocation,
|
||||
double batteryPercentage,
|
||||
IVersionInfo versionInfo)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public Task<ReservationBookingResponse> DoBookAsync(Uri operatorUri, string bikeId, Guid guid, double batteryPercentage, LockingAction? nextAction = null)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public Task<ReservationBookingResponse> BookAvailableAndStartOpeningAsync(string bikeId, Uri operatorUri)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public Task<ReservationBookingResponse> BookReservedAndStartOpeningAsync(string bikeId, Uri operatorUri)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public Task<DoReturnResponse> DoReturn(string bikeId, LocationDto location, Uri operatorUri)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public Task<DoReturnResponse> ReturnAndStartClosingAsync(
|
||||
string bikeId,
|
||||
Uri operatorUri)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public Task<SubmitFeedbackResponse> DoSubmitFeedback(string bikeId, int? currentChargeBars, string message, bool isBikeBroken, Uri operatorUri)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
/// <summary> Submits mini survey to copri server. </summary>
|
||||
/// <param name="answers">Collection of answers.</param>
|
||||
public Task<ResponseBase> DoSubmitMiniSurvey(IDictionary<string, string> answers)
|
||||
=> throw new NotImplementedException();
|
||||
|
||||
public Task<BikesAvailableResponse> GetBikesAvailableAsync()
|
||||
{
|
||||
return server.GetBikesAvailableAsync();
|
||||
}
|
||||
|
||||
public Task<BikesReservedOccupiedResponse> GetBikesOccupiedAsync()
|
||||
{
|
||||
return server.GetBikesOccupiedAsync();
|
||||
}
|
||||
|
||||
public Task<StationsAvailableResponse> GetStationsAsync()
|
||||
{
|
||||
return server.GetStationsAsync();
|
||||
}
|
||||
}
|
||||
}
|
23
TestFramework/Repository/CopriCallsMemory001v2.cs
Normal file
23
TestFramework/Repository/CopriCallsMemory001v2.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using TINK.Repository;
|
||||
|
||||
namespace TestFramework.Repository
|
||||
{
|
||||
/// <summary>
|
||||
/// Holds some COPRI responses for testing purposes.
|
||||
/// </summary>
|
||||
/// <remarks> Holds some demo Mein konrad and LastenradBayern bikes
|
||||
/// </remarks>
|
||||
public class CopriCallsMemory001v2NotLoggedIn : CopriCallMemoryBase, ICopriServer
|
||||
{
|
||||
public CopriCallsMemory001v2NotLoggedIn(string sessionCookie = null, string merchantId = null) : base(
|
||||
bikesAvailableResponseResource: "TestFramework.Repository.CopriCallsMemory001v2NotLoggedIn.BikesAvailableResponse.json",
|
||||
bikesOccupiedResponseResoure: "TestFramework.Repository.CopriCallsMemory001v2NotLoggedIn.BikesOccupiedResponse.json",
|
||||
authResponseResource: "TestFramework.Repository.CopriCallsMemory001v2NotLoggedIn.AuthorizationResponse.json",
|
||||
authOutResponseResource: "TestFramework.Repository.CopriCallsMemory001v2NotLoggedIn.AuthoutResponse.json",
|
||||
stationsResponseResource: "TestFramework.Repository.CopriCallsMemory001v2NotLoggedIn.StationsAvailable.json",
|
||||
sessionCookie: sessionCookie,
|
||||
merchantId: merchantId)
|
||||
{ }
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
{
|
||||
"shareejson": {
|
||||
"clearing_cache": "0",
|
||||
"privacy_html": "site/privacy.html",
|
||||
"user_id": "javaminister@gmail.com",
|
||||
"impress_html": "site/impress.html",
|
||||
"tariff_info_html": "site/tariff_info_1.html",
|
||||
"lang": "DE",
|
||||
"last_used_operator": {
|
||||
"operator_name": "sharee.bike | TeilRad GmbH",
|
||||
"operator_hours": "B<>rozeiten: Montag, Mittwoch, Freitag 9-12 Uhr",
|
||||
"operator_phone": "+49 761 45370097",
|
||||
"operator_email": "hotline@sharee.bike",
|
||||
"operator_color": "#009699"
|
||||
},
|
||||
"response": "authorization",
|
||||
"agb_checked": "0",
|
||||
"agb_html": "site/agb.html",
|
||||
"response_text": "Herzlich willkommen im Fahrradmietsystem",
|
||||
"bike_info_html": "site/bike_info.html",
|
||||
"debuglevel": "1",
|
||||
"uri_primary": "https://shareeapp-primary.copri.eu",
|
||||
"response_state": "OK, nothing todo",
|
||||
"new_authcoo": "1",
|
||||
"user_tour": [],
|
||||
"authcookie": "6103_112e96b36ba33de245943c5ffaf369cd_oiF2kahH",
|
||||
"copri_version": "4.1.8.21",
|
||||
"apiserver": "https://shareeapp-fr01.copri.eu",
|
||||
"user_group": []
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"shareejson": {
|
||||
"copri_version": "4.1.8.21",
|
||||
"authcookie": "1",
|
||||
"user_tour": [],
|
||||
"user_group": null,
|
||||
"apiserver": "https://shareeapp-fr01.copri.eu",
|
||||
"debuglevel": "1",
|
||||
"uri_primary": "https://shareeapp-primary.copri.eu",
|
||||
"bike_info_html": "site/bike_info.html",
|
||||
"response_state": "OK, logout",
|
||||
"new_authcoo": "0",
|
||||
"lang": "DE",
|
||||
"last_used_operator": {
|
||||
"operator_hours": "Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr",
|
||||
"operator_name": "sharee.bike | TeilRad GmbH",
|
||||
"operator_email": "hotline@sharee.bike",
|
||||
"operator_phone": "+49 761 45370097",
|
||||
"operator_color": "#009699"
|
||||
},
|
||||
"tariff_info_html": "site/tariff_info_1.html",
|
||||
"impress_html": "site/impress.html",
|
||||
"response_text": "Auf Wiedersehen.",
|
||||
"agb_html": "site/agb.html",
|
||||
"response": "authout",
|
||||
"agb_checked": "0",
|
||||
"privacy_html": "site/privacy.html",
|
||||
"clearing_cache": "0",
|
||||
"user_id": "javaminister@gmail.com"
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,270 @@
|
|||
{
|
||||
"shareejson": {
|
||||
"agb_checked": "1",
|
||||
"response": "bikes_available",
|
||||
"agb_html": "site/agb.html",
|
||||
"impress_html": "site/impress.html",
|
||||
"tariff_info_html": "site/tariff_info_1.html",
|
||||
"lang": "DE",
|
||||
"last_used_operator": {
|
||||
"operator_color": "#008dd2",
|
||||
"operator_email": "hotline@lastenraddemo.bayern",
|
||||
"operator_phone": "+49 089 / 111111111",
|
||||
"operator_name": "Lastenrad Bayern",
|
||||
"operator_hours": "Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr",
|
||||
"operator_logo": ""
|
||||
},
|
||||
"user_id": "ohauff@posteo.de",
|
||||
"clearing_cache": "0",
|
||||
"privacy_html": "site/privacy.html",
|
||||
"bikes": {
|
||||
// Entry manually created (copy-paste). Might contain dupe entries (2021-11-12).
|
||||
"FR9999": {
|
||||
"system": "Ilockit",
|
||||
"gps": {
|
||||
"longitude": "7.8255321",
|
||||
"latitude": "47.9767121"
|
||||
},
|
||||
"lock_state": "locked",
|
||||
"Ilockit_GUID": "00000000-0000-0000-0000-cc141a6f68bb",
|
||||
"state": "available",
|
||||
"tariff_description": {
|
||||
"free_hours": "0.50",
|
||||
"name": "Tester Basic",
|
||||
"eur_per_hour": "3.00",
|
||||
"number": "5494",
|
||||
"1543": {
|
||||
"operator_agb": "Mit der Mietrad Anmietung wird folgender Betreiber <a href='https://shareeapp-fr01.copri.eu/site/agb.html'>AGB</a> zugestimmt (als Demo sharee AGB)."
|
||||
},
|
||||
"max_eur_per_day": "10.00"
|
||||
},
|
||||
"bike_group": [
|
||||
"FR300103"
|
||||
],
|
||||
"station": "FR103",
|
||||
"description": "Quest Carbon",
|
||||
"Ilockit_ID": "ISHAREIT-9999999",
|
||||
"authed": "1",
|
||||
"bike": "FR9999",
|
||||
"uri_operator": "https://shareeapp-fr01.copri.eu"
|
||||
},
|
||||
// Entry manually created (copy-paste). Might contain dupe entries (2021-11-12).
|
||||
"FR9998": {
|
||||
"system": "Ilockit",
|
||||
"gps": {
|
||||
"longitude": "7.8255321",
|
||||
"latitude": "47.9767121"
|
||||
},
|
||||
"lock_state": "locked",
|
||||
"Ilockit_GUID": "00000000-0000-0000-0000-cc141a6f68bb",
|
||||
"state": "available",
|
||||
"tariff_description": {
|
||||
"free_hours": "0.50",
|
||||
"name": "Bacchetta Giro",
|
||||
"eur_per_hour": "3.00",
|
||||
"number": "5494",
|
||||
"1543": {
|
||||
"operator_agb": "Mit der Mietrad Anmietung wird folgender Betreiber <a href='https://shareeapp-fr01.copri.eu/site/agb.html'>AGB</a> zugestimmt (als Demo sharee AGB)."
|
||||
},
|
||||
"max_eur_per_day": "10.00"
|
||||
},
|
||||
"bike_group": [
|
||||
"FR300103"
|
||||
],
|
||||
"station": "FR103",
|
||||
"description": "Quest Carbon",
|
||||
"Ilockit_ID": "ISHAREIT-9999999",
|
||||
"authed": "1",
|
||||
"bike": "FR9998",
|
||||
"uri_operator": "https://shareeapp-fr01.copri.eu"
|
||||
},
|
||||
"FR1543": {
|
||||
"system": "Ilockit",
|
||||
"gps": {
|
||||
"longitude": "7.8255321",
|
||||
"latitude": "47.9767121"
|
||||
},
|
||||
"lock_state": "locked",
|
||||
"Ilockit_GUID": "00000000-0000-0000-0000-cc141a6f68bb",
|
||||
"state": "available",
|
||||
"tariff_description": {
|
||||
"free_hours": "0.50",
|
||||
"name": "Tester Basic",
|
||||
"eur_per_hour": "3.00",
|
||||
"number": "5494",
|
||||
"1543": {
|
||||
"operator_agb": "Mit der Mietrad Anmietung wird folgender Betreiber <a href='https://shareeapp-fr01.copri.eu/site/agb.html'>AGB</a> zugestimmt (als Demo sharee AGB)."
|
||||
},
|
||||
"max_eur_per_day": "10.00"
|
||||
},
|
||||
"bike_group": [
|
||||
"FR300103"
|
||||
],
|
||||
"station": "FR101",
|
||||
"description": "Contributor-bike Dominik",
|
||||
"Ilockit_ID": "ISHAREIT-2200543",
|
||||
"authed": "1",
|
||||
"bike": "FR1543",
|
||||
"uri_operator": "https://shareeapp-fr01.copri.eu"
|
||||
},
|
||||
"FR1003": {
|
||||
"bike": "FR1003",
|
||||
"authed": "1",
|
||||
"uri_operator": "https://shareeapp-fr01.copri.eu",
|
||||
"bike_group": [
|
||||
"FR300101"
|
||||
],
|
||||
"Ilockit_ID": "ISHAREIT-2200545",
|
||||
"station": "FR101",
|
||||
"description": "Stadtrad",
|
||||
"tariff_description": {
|
||||
"max_eur_per_day": "10.00",
|
||||
"number": "5491",
|
||||
"eur_per_hour": "2.00",
|
||||
"1003": {
|
||||
"operator_agb": "Mit der Mietrad Anmietung wird folgender Betreiber <a href='https://shareeapp-fr01.copri.eu/site/agb.html'>AGB</a> zugestimmt (als Demo sharee AGB)."
|
||||
},
|
||||
"free_hours": "0.50",
|
||||
"name": "Vauban Basic"
|
||||
},
|
||||
"state": "available",
|
||||
"Ilockit_GUID": "00000000-0000-0000-0000-e38bf9d32234",
|
||||
"system": "Ilockit",
|
||||
"gps": {
|
||||
"longitude": "7.8255772",
|
||||
"latitude": "47.9765188"
|
||||
},
|
||||
"lock_state": "locked"
|
||||
},
|
||||
"FR1540": {
|
||||
"bike_group": [
|
||||
"FR300103"
|
||||
],
|
||||
"Ilockit_ID": "ISHAREIT-2200540",
|
||||
"description": "Contributor-bike Dieter",
|
||||
"station": "FR101",
|
||||
"bike": "FR1540",
|
||||
"authed": "1",
|
||||
"uri_operator": "https://shareeapp-fr01.copri.eu",
|
||||
"Ilockit_GUID": "00000000-0000-0000-0000-fc3c002a2add",
|
||||
"system": "Ilockit",
|
||||
"gps": {
|
||||
"longitude": "7.8256267",
|
||||
"latitude": "47.976803"
|
||||
},
|
||||
"lock_state": "locked",
|
||||
"tariff_description": {
|
||||
"1540": {
|
||||
"operator_agb": "Mit der Mietrad Anmietung wird folgender Betreiber <a href='https://shareeapp-fr01.copri.eu/site/agb.html'>AGB</a> zugestimmt (als Demo sharee AGB)."
|
||||
},
|
||||
"free_hours": "0.50",
|
||||
"name": "Tester Basic",
|
||||
"max_eur_per_day": "10.00",
|
||||
"eur_per_hour": "3.00",
|
||||
"number": "5494"
|
||||
},
|
||||
"state": "available"
|
||||
},
|
||||
"FR1002": {
|
||||
"bike_group": [
|
||||
"FR300101"
|
||||
],
|
||||
"description": "Lasten-Dreirad",
|
||||
"station": "FR101",
|
||||
"Ilockit_ID": "ISHAREIT-2200539",
|
||||
"authed": "1",
|
||||
"bike": "FR1002",
|
||||
"uri_operator": "https://shareeapp-fr01.copri.eu",
|
||||
"gps": {
|
||||
"latitude": "47.976552",
|
||||
"longitude": "7.8255068"
|
||||
},
|
||||
"system": "Ilockit",
|
||||
"lock_state": "locked",
|
||||
"Ilockit_GUID": "00000000-0000-0000-0000-f0b4a692e169",
|
||||
"state": "available",
|
||||
"tariff_description": {
|
||||
"max_eur_per_day": "10.00",
|
||||
"1002": {
|
||||
"operator_agb": "Mit der Mietrad Anmietung wird folgender Betreiber <a href='https://shareeapp-fr01.copri.eu/site/agb.html'>AGB</a> zugestimmt (als Demo sharee AGB)."
|
||||
},
|
||||
"eur_per_hour": "2.00",
|
||||
"number": "5491",
|
||||
"free_hours": "0.50",
|
||||
"name": "Vauban Basic"
|
||||
}
|
||||
},
|
||||
"FR1538": {
|
||||
"uri_operator": "https://shareeapp-fr01.copri.eu",
|
||||
"authed": "1",
|
||||
"bike": "FR1538",
|
||||
"station": "FR105",
|
||||
"description": "Contributor-bike Rainer",
|
||||
"Ilockit_ID": "ISHAREIT-2200538",
|
||||
"bike_group": [
|
||||
"FR300103"
|
||||
],
|
||||
"state": "available",
|
||||
"tariff_description": {
|
||||
"max_eur_per_day": "10.00",
|
||||
"eur_per_hour": "3.00",
|
||||
"number": "5494",
|
||||
"1538": {
|
||||
"operator_agb": "Mit der Mietrad Anmietung wird folgender Betreiber <a href='https://shareeapp-fr01.copri.eu/site/agb.html'>AGB</a> zugestimmt (als Demo sharee AGB)."
|
||||
},
|
||||
"free_hours": "0.50",
|
||||
"name": "Tester Basic"
|
||||
},
|
||||
"gps": {
|
||||
"latitude": "47.9275957",
|
||||
"longitude": "7.973976"
|
||||
},
|
||||
"lock_state": "locked",
|
||||
"system": "Ilockit",
|
||||
"Ilockit_GUID": "00000000-0000-0000-0000-db0319a2555b"
|
||||
},
|
||||
"FR1001": {
|
||||
"bike_group": [
|
||||
"FR300101"
|
||||
],
|
||||
"station": "FR101",
|
||||
"description": "Lastenrad",
|
||||
"Ilockit_ID": "ISHAREIT-2200536",
|
||||
"authed": "1",
|
||||
"bike": "FR1001",
|
||||
"uri_operator": "https://shareeapp-fr01.copri.eu",
|
||||
"lock_state": "locked",
|
||||
"gps": {
|
||||
"latitude": "47.9765091",
|
||||
"longitude": "7.8255631"
|
||||
},
|
||||
"system": "Ilockit",
|
||||
"Ilockit_GUID": "00000000-0000-0000-0000-caa87760e53e",
|
||||
"state": "available",
|
||||
"tariff_description": {
|
||||
"free_hours": "0.50",
|
||||
"name": "Vauban Basic",
|
||||
"eur_per_hour": "2.00",
|
||||
"number": "5491",
|
||||
"max_eur_per_day": "10.00",
|
||||
"1001": {
|
||||
"operator_agb": "Mit der Mietrad Anmietung wird folgender Betreiber <a href='https://shareeapp-fr01.copri.eu/site/agb.html'>AGB</a> zugestimmt (als Demo sharee AGB)."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"user_group": [
|
||||
"FR300103",
|
||||
"FR300101"
|
||||
],
|
||||
"apiserver": "https://shareeapp-fr01.copri.eu",
|
||||
"user_tour": [],
|
||||
"authcookie": "6103_112e96b36ba33de245943c5ffaf369cd_oiF2kahH",
|
||||
"copri_version": "4.1.8.21",
|
||||
"response_state": "OK, nothing todo",
|
||||
"new_authcoo": "0",
|
||||
"bike_info_html": "site/bike_info.html",
|
||||
"debuglevel": "1",
|
||||
"uri_primary": "https://shareeapp-primary.copri.eu"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
"shareejson": {
|
||||
"authcookie": "6103_112e96b36ba33de245943c5ffaf369cd_oiF2kahH",
|
||||
"copri_version": "4.1.8.21",
|
||||
"user_tour": [],
|
||||
"user_group": [
|
||||
"FR300103",
|
||||
"FR300101"
|
||||
],
|
||||
"bikes_occupied": {
|
||||
},
|
||||
"apiserver": "https://shareeapp-fr01.copri.eu",
|
||||
"uri_primary": "https://shareeapp-primary.copri.eu",
|
||||
"debuglevel": "1",
|
||||
"bike_info_html": "site/bike_info.html",
|
||||
"new_authcoo": "0",
|
||||
"response_state": "OK, nothing todo",
|
||||
"last_used_operator": {
|
||||
"operator_color": "#008dd2",
|
||||
"operator_phone": "+49 089 / 111111111",
|
||||
"operator_email": "hotline@lastenraddemo.bayern",
|
||||
"operator_hours": "B<>rozeiten: Montag, Mittwoch, Freitag 9-12 Uhr",
|
||||
"operator_name": "Lastenrad Bayern",
|
||||
"operator_logo": ""
|
||||
},
|
||||
"lang": "DE",
|
||||
"impress_html": "site/impress.html",
|
||||
"tariff_info_html": "site/tariff_info_1.html",
|
||||
"agb_html": "site/agb.html",
|
||||
"response": "user_bikes_occupied",
|
||||
"agb_checked": "1",
|
||||
"privacy_html": "site/privacy.html",
|
||||
"clearing_cache": "0",
|
||||
"user_id": "ohauff@posteo.de"
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,4 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
|
@ -6,6 +6,12 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Repository\CopriCallsMemory001v2NotLoggedIn\AuthorizationResponse.json" />
|
||||
<None Remove="Repository\CopriCallsMemory001v2NotLoggedIn\AuthoutResponse.json" />
|
||||
<None Remove="Repository\CopriCallsMemory001v2NotLoggedIn\BikesAvailableResponse.json" />
|
||||
<None Remove="Repository\CopriCallsMemory001v2NotLoggedIn\BikesOccupiedResponse.json" />
|
||||
<None Remove="Repository\CopriCallsMemory001v2NotLoggedIn\StationsAvailable.json" />
|
||||
<None Remove="Repository\CopriCallsMemory001v2NotLoggedIn\StationsAvailableNotLoggedIn.json" />
|
||||
<None Remove="Repository\CopriCallsMemory001\AuthorizationResponse.json" />
|
||||
<None Remove="Repository\CopriCallsMemory001\AuthoutResponse.json" />
|
||||
<None Remove="Repository\CopriCallsMemory001\BikesOccupiedResponse.json" />
|
||||
|
@ -13,6 +19,11 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Repository\CopriCallsMemory001v2NotLoggedIn\AuthorizationResponse.json" />
|
||||
<EmbeddedResource Include="Repository\CopriCallsMemory001v2NotLoggedIn\AuthoutResponse.json" />
|
||||
<EmbeddedResource Include="Repository\CopriCallsMemory001v2NotLoggedIn\BikesAvailableResponse.json" />
|
||||
<EmbeddedResource Include="Repository\CopriCallsMemory001v2NotLoggedIn\BikesOccupiedResponse.json" />
|
||||
<EmbeddedResource Include="Repository\CopriCallsMemory001v2NotLoggedIn\StationsAvailable.json" />
|
||||
<EmbeddedResource Include="Repository\CopriCallsMemory001\AuthorizationResponse.json" />
|
||||
<EmbeddedResource Include="Repository\CopriCallsMemory001\AuthoutResponse.json" />
|
||||
<EmbeddedResource Include="Repository\CopriCallsMemory001\BikesAvailableResponse.json" />
|
||||
|
@ -24,7 +35,6 @@
|
|||
<Folder Include="Model\Device\" />
|
||||
<Folder Include="Model\User\Account\" />
|
||||
<Folder Include="Services\BluetoothLock\" />
|
||||
<Folder Include="Services\CopriApi\" />
|
||||
<Folder Include="Services\Geolocation\" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
@ -121,7 +121,7 @@ namespace TestShareeLib.Model.Connector
|
|||
}
|
||||
|
||||
[Test]
|
||||
public void TestCreate_Available_CorpiLock_FeedbackPending()
|
||||
public void TestCreate_Available_CopriLock_FeedbackPending()
|
||||
{
|
||||
var bikeInfoResponse = JsonConvert.DeserializeObject<BikeInfoAvailable>(
|
||||
@"{
|
||||
|
|
|
@ -32,17 +32,31 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector.Query
|
|||
}
|
||||
}";
|
||||
|
||||
private const string STATIONSALL = @"{
|
||||
/// <summary>
|
||||
/// Holds the response on stations_available request.
|
||||
/// </summary>
|
||||
/// <remarks> V1: Did not hold station_type entry.</remarks>
|
||||
private const string STATIONSALLV2 = @"{
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""stations"" : {
|
||||
""5"" : {
|
||||
""station"" : ""5"",
|
||||
""9"" : {
|
||||
""station"" : ""9"",
|
||||
""bike_soll"" : ""0"",
|
||||
""bike_ist"" : ""7"",
|
||||
""station_group"" : [ ""TINK"" ],
|
||||
""gps"" : { ""latitude"": ""47.66756"", ""longitude"": ""9.16477"" },
|
||||
""state"" : ""available"",
|
||||
""description"" : """"
|
||||
""description"" : """",
|
||||
""station_type"": {
|
||||
""Cargobike"": {
|
||||
""bike_count"": ""1"",
|
||||
""bike_group"": ""TINK""
|
||||
},
|
||||
""Citybike"": {
|
||||
""bike_count"": ""0"",
|
||||
""bike_group"": ""FR300103""
|
||||
}
|
||||
}
|
||||
},
|
||||
""13"" : {
|
||||
""station"" : ""13"",
|
||||
|
@ -91,53 +105,19 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector.Query
|
|||
var server = Substitute.For<ICachedCopriServer>();
|
||||
server.GetStations(false).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL),
|
||||
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALLV2),
|
||||
new GeneralData(),
|
||||
new System.Exception("Bang when getting stations..."))));
|
||||
|
||||
server.GetBikesAvailable(true).Returns(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
|
||||
new GeneralData())));
|
||||
|
||||
var result = await new CachedQuery(server).GetBikesAndStationsAsync();
|
||||
|
||||
Assert.AreEqual(3, result.Response.StationsAll.Count);
|
||||
Assert.AreEqual(1, result.Response.Bikes.Count);
|
||||
Assert.AreEqual(1, result.Response.StationsAll["9"].BikeGroups.AvailableCount);
|
||||
Assert.AreEqual(0, result.Response.BikesOccupied.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.AreEqual("Bang when getting stations...", result.Exception.Message);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetStations_BikesAvailableFromCache()
|
||||
{
|
||||
var server = Substitute.For<ICachedCopriServer>();
|
||||
|
||||
server.GetStations(false).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALLEMPTY),
|
||||
new GeneralData())));
|
||||
|
||||
server.GetBikesAvailable(false).Returns(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
|
||||
new GeneralData(),
|
||||
new System.Exception("Bang when getting bikes..."))));
|
||||
|
||||
server.GetStations(true).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL),
|
||||
new GeneralData())));
|
||||
|
||||
var result = await new CachedQuery(server).GetBikesAndStationsAsync();
|
||||
|
||||
Assert.AreEqual(3, result.Response.StationsAll.Count);
|
||||
Assert.AreEqual(1, result.Response.Bikes.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.AreEqual("Bang when getting bikes...", result.Exception.Message);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public async Task TestGetStations()
|
||||
{
|
||||
|
@ -145,18 +125,14 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector.Query
|
|||
|
||||
server.GetStations(false).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL),
|
||||
new GeneralData())));
|
||||
|
||||
server.GetBikesAvailable(false).Returns(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
|
||||
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALLV2),
|
||||
new GeneralData())));
|
||||
|
||||
var result = await new CachedQuery(server).GetBikesAndStationsAsync();
|
||||
|
||||
Assert.AreEqual(3, result.Response.StationsAll.Count);
|
||||
Assert.AreEqual(1, result.Response.Bikes.Count);
|
||||
Assert.AreEqual(1, result.Response.StationsAll["9"].BikeGroups.AvailableCount);
|
||||
Assert.AreEqual(0, result.Response.BikesOccupied.Count, "There are no reserved or occupied bikes.");
|
||||
Assert.AreEqual(typeof(CopriCallsHttps), result.Source);
|
||||
Assert.IsNull(result.Exception);
|
||||
}
|
||||
|
|
|
@ -398,6 +398,72 @@ namespace TestShareeLib.Model.Connector
|
|||
""apiserver"" : ""https://tinkwwp.copri-bike.de""
|
||||
}";
|
||||
|
||||
/// <summary>
|
||||
/// Response updated (manually edited) combining JSON form responses <see cref="STATIONSALL"/> and <see cref="BIKESOCCUPIED"/>
|
||||
/// </summary>
|
||||
private const string STATIONSALLV2 = @"{
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""stations"" : {
|
||||
""5"" : {
|
||||
""station"" : ""5"",
|
||||
""bike_soll"" : ""0"",
|
||||
""bike_ist"" : ""7"",
|
||||
""station_group"" : [ ""TINK"" ],
|
||||
""gps"" : { ""latitude"": ""47.66756"", ""longitude"": ""9.16477"" },
|
||||
""state"" : ""available"",
|
||||
""description"" : """"
|
||||
},
|
||||
""13"" : {
|
||||
""station"" : ""13"",
|
||||
""bike_soll"" : ""4"",
|
||||
""bike_ist"" : ""1"",
|
||||
""station_group"" : [ ""TINK"" ],
|
||||
""gps"" : { ""latitude"": ""47.657756"", ""longitude"": ""9.176084"" },
|
||||
""state"" : ""available"",
|
||||
""description"" : """"
|
||||
},
|
||||
""30"" : {
|
||||
""station"" : ""30"",
|
||||
""bike_soll"" : ""5"",
|
||||
""bike_ist"" : ""0"",
|
||||
""station_group"" : [ ""TINK"", ""Konrad"" ],
|
||||
""gps"" : { ""latitude"": ""47.657766"", ""longitude"": ""9.176094"" },
|
||||
""state"" : ""available"",
|
||||
""description"" : ""Test für Stadtradstation""
|
||||
}
|
||||
},
|
||||
""bikes_occupied"" : {
|
||||
""89004"" : {
|
||||
""start_time"" : ""2018-01-27 17:33:00.989464+01"",
|
||||
""station"" : ""9"",
|
||||
""unit_price"" : ""2.00"",
|
||||
""tariff_description"": {
|
||||
""free_hours"" : ""0.5"",
|
||||
""name"" : ""TINK Tarif"",
|
||||
""max_eur_per_day"" : ""9.00""
|
||||
},
|
||||
""timeCode"" : ""2061"",
|
||||
""description"" : ""Cargo Long"",
|
||||
""bike"" : ""4"",
|
||||
""total_price"" : ""20.00"",
|
||||
""state"" : ""requested"",
|
||||
""real_hours"" : ""66.05"",
|
||||
""bike_group"" : [ ""TINK"" ],
|
||||
""now_time"" : ""2018-01-30 11:36:45"",
|
||||
""request_time"" : ""2018-01-27 17:33:00.989464+01"",
|
||||
""computed_hours"" : ""10.0""
|
||||
}
|
||||
},
|
||||
|
||||
""user_group"" : [ ""Konrad"", ""TINK"" ],
|
||||
""response_state"" : ""OK"",
|
||||
""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"",
|
||||
""debuglevel"" : ""2"",
|
||||
""response"" : ""stations_all"",
|
||||
""user_id"" : ""javaminister@gmail.com"",
|
||||
""apiserver"" : ""https://tinkwwp.copri-bike.de""
|
||||
}";
|
||||
|
||||
private const string STATIONSALLEMPTY = @"{
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""stations"" : {
|
||||
|
@ -418,101 +484,18 @@ namespace TestShareeLib.Model.Connector
|
|||
|
||||
server.GetStations(false).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL),
|
||||
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALLV2),
|
||||
new GeneralData(),
|
||||
new System.Exception("Bang when getting stations..."))));
|
||||
|
||||
server.GetBikesAvailable(true).Returns(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
|
||||
new GeneralData())));
|
||||
|
||||
server.GetBikesOccupied(true).Returns(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED),
|
||||
new GeneralData())));
|
||||
new Exception("Bang when getting stations..."))));
|
||||
|
||||
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync();
|
||||
|
||||
Assert.AreEqual(3, result.Response.StationsAll.Count);
|
||||
Assert.AreEqual(2, result.Response.Bikes.Count);
|
||||
Assert.AreEqual(1, result.Response.BikesOccupied.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.AreEqual("Bang when getting stations...", result.Exception.Message);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetStations_BikesAvailableFromCache()
|
||||
{
|
||||
var server = Substitute.For<ICachedCopriServer>();
|
||||
|
||||
server.GetStations(false).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALLEMPTY),
|
||||
new GeneralData())));
|
||||
|
||||
server.GetBikesAvailable(false).Returns(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
|
||||
new GeneralData(),
|
||||
new System.Exception("Bang when getting bikes..."))));
|
||||
|
||||
server.GetBikesOccupied(true).Returns(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED),
|
||||
new GeneralData())));
|
||||
|
||||
server.GetStations(true).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL),
|
||||
new GeneralData())));
|
||||
|
||||
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync();
|
||||
|
||||
Assert.AreEqual(3, result.Response.StationsAll.Count);
|
||||
Assert.AreEqual(2, result.Response.Bikes.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.AreEqual("Bang when getting bikes...", result.Exception.Message);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetStations_BikesOccupiedFromCache()
|
||||
{
|
||||
var server = Substitute.For<ICachedCopriServer>();
|
||||
|
||||
server.GetStations(false).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALLEMPTY),
|
||||
new GeneralData())));
|
||||
|
||||
server.GetBikesAvailable(false).Returns(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLEEMPTY),
|
||||
new GeneralData())));
|
||||
|
||||
server.GetBikesOccupied(false).Returns(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED),
|
||||
new GeneralData(),
|
||||
new System.Exception("Bang when getting bikes occupied..."))));
|
||||
|
||||
server.GetBikesAvailable(true).Returns(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
|
||||
new GeneralData())));
|
||||
|
||||
server.GetStations(true).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||
typeof(CopriCallsMonkeyStore),
|
||||
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL),
|
||||
new GeneralData())));
|
||||
|
||||
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync();
|
||||
|
||||
Assert.AreEqual(3, result.Response.StationsAll.Count);
|
||||
Assert.AreEqual(2, result.Response.Bikes.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.AreEqual("Bang when getting bikes occupied...", result.Exception.Message);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetStations()
|
||||
{
|
||||
|
@ -520,23 +503,13 @@ namespace TestShareeLib.Model.Connector
|
|||
|
||||
server.GetStations(false).Returns(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL),
|
||||
new GeneralData())));
|
||||
|
||||
server.GetBikesAvailable(false).Returns(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
|
||||
new GeneralData())));
|
||||
|
||||
server.GetBikesOccupied(false).Returns(Task.Run(() => new Result<BikesReservedOccupiedResponse>(
|
||||
typeof(CopriCallsHttps),
|
||||
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED),
|
||||
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALLV2),
|
||||
new GeneralData())));
|
||||
|
||||
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync();
|
||||
|
||||
Assert.AreEqual(3, result.Response.StationsAll.Count);
|
||||
Assert.AreEqual(2, result.Response.Bikes.Count);
|
||||
Assert.AreEqual(1, result.Response.BikesOccupied.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsHttps), result.Source);
|
||||
Assert.IsNull(result.Exception);
|
||||
}
|
||||
|
|
|
@ -29,17 +29,31 @@ namespace TestTINKLib.Fixtures.ObjectTests.Query
|
|||
}
|
||||
}";
|
||||
|
||||
private const string STATIONSALL = @"{
|
||||
/// <summary>
|
||||
/// Holds the response on stations_available request.
|
||||
/// </summary>
|
||||
/// <remarks> V1: Did not hold station_type entry.</remarks>
|
||||
private const string STATIONSALLV2 = @"{
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""stations"" : {
|
||||
""5"" : {
|
||||
""station"" : ""5"",
|
||||
""9"" : {
|
||||
""station"" : ""9"",
|
||||
""bike_soll"" : ""0"",
|
||||
""bike_ist"" : ""7"",
|
||||
""station_group"" : [ ""TINK"" ],
|
||||
""gps"" : { ""latitude"": ""47.66756"", ""longitude"": ""9.16477"" },
|
||||
""state"" : ""available"",
|
||||
""description"" : """"
|
||||
""description"" : """",
|
||||
""station_type"": {
|
||||
""Cargobike"": {
|
||||
""bike_count"": ""1"",
|
||||
""bike_group"": ""TINK""
|
||||
},
|
||||
""Citybike"": {
|
||||
""bike_count"": ""0"",
|
||||
""bike_group"": ""FR300103""
|
||||
}
|
||||
}
|
||||
},
|
||||
""13"" : {
|
||||
""station"" : ""13"",
|
||||
|
@ -74,13 +88,13 @@ namespace TestTINKLib.Fixtures.ObjectTests.Query
|
|||
{
|
||||
var server = Substitute.For<ICopriServer>();
|
||||
|
||||
server.GetStationsAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL)));
|
||||
server.GetBikesAvailableAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE)));
|
||||
server.GetStationsAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALLV2)));
|
||||
|
||||
var result = await new TINK.Model.Connector.Query(server).GetBikesAndStationsAsync();
|
||||
|
||||
Assert.AreEqual(3, result.Response.StationsAll.Count);
|
||||
Assert.AreEqual(1, result.Response.Bikes.Count);
|
||||
Assert.AreEqual(1, result.Response.StationsAll["9"].BikeGroups.AvailableCount);
|
||||
Assert.AreEqual(0, result.Response.BikesOccupied.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.IsNull(result.Exception);
|
||||
}
|
||||
|
|
|
@ -11,9 +11,9 @@ using TINK.Repository.Response.Stations;
|
|||
namespace TestTINKLib.Fixtures.ObjectTests.Connector
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestQueryLoggedIn
|
||||
{
|
||||
private const string BIKESAVAILABLE = @"{
|
||||
public class TestQueryLoggedIn
|
||||
{
|
||||
private const string BIKESAVAILABLE = @"{
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""bikes"" : {},
|
||||
""response_state"" : ""OK"",
|
||||
|
@ -31,7 +31,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector
|
|||
}
|
||||
}";
|
||||
|
||||
private const string BIKESOCCUPIED = @"{
|
||||
private const string BIKESOCCUPIED = @"{
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"",
|
||||
""debuglevel"" : ""2"",
|
||||
|
@ -65,17 +65,31 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector
|
|||
}
|
||||
}";
|
||||
|
||||
private const string STATIONSALL = @"{
|
||||
/// <summary>
|
||||
/// Holds the response on stations_available request.
|
||||
/// </summary>
|
||||
/// <remarks> V1: Did not hold station_type entry.</remarks>
|
||||
private const string STATIONSALLV2 = @"{
|
||||
""copri_version"" : ""4.1.0.0"",
|
||||
""stations"" : {
|
||||
""5"" : {
|
||||
""station"" : ""5"",
|
||||
""9"" : {
|
||||
""station"" : ""9"",
|
||||
""bike_soll"" : ""0"",
|
||||
""bike_ist"" : ""7"",
|
||||
""station_group"" : [ ""TINK"" ],
|
||||
""gps"" : { ""latitude"": ""47.66756"", ""longitude"": ""9.16477"" },
|
||||
""state"" : ""available"",
|
||||
""description"" : """"
|
||||
""description"" : """",
|
||||
""station_type"": {
|
||||
""Cargobike"": {
|
||||
""bike_count"": ""1"",
|
||||
""bike_group"": ""TINK""
|
||||
},
|
||||
""Citybike"": {
|
||||
""bike_count"": ""0"",
|
||||
""bike_group"": ""FR300103""
|
||||
}
|
||||
}
|
||||
},
|
||||
""13"" : {
|
||||
""station"" : ""13"",
|
||||
|
@ -95,7 +109,29 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector
|
|||
""state"" : ""available"",
|
||||
""description"" : ""Test für Stadtradstation""
|
||||
}
|
||||
},
|
||||
},
|
||||
""bikes_occupied"" : {
|
||||
""89004"" : {
|
||||
""start_time"" : ""2018-01-27 17:33:00.989464+01"",
|
||||
""station"" : ""9"",
|
||||
""unit_price"" : ""2.00"",
|
||||
""tariff_description"": {
|
||||
""free_hours"" : ""0.5"",
|
||||
""name"" : ""TINK Tarif"",
|
||||
""max_eur_per_day"" : ""9.00""
|
||||
},
|
||||
""timeCode"" : ""2061"",
|
||||
""description"" : ""Cargo Long"",
|
||||
""bike"" : ""4"",
|
||||
""total_price"" : ""20.00"",
|
||||
""state"" : ""requested"",
|
||||
""real_hours"" : ""66.05"",
|
||||
""bike_group"" : [ ""TINK"" ],
|
||||
""now_time"" : ""2018-01-30 11:36:45"",
|
||||
""request_time"" : ""2018-01-27 17:33:00.989464+01"",
|
||||
""computed_hours"" : ""10.0""
|
||||
}
|
||||
},
|
||||
""user_group"" : [ ""Konrad"", ""TINK"" ],
|
||||
""response_state"" : ""OK"",
|
||||
""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"",
|
||||
|
@ -105,52 +141,51 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector
|
|||
""apiserver"" : ""https://tinkwwp.copri-bike.de""
|
||||
}";
|
||||
|
||||
[Test]
|
||||
public async Task TestGetStations()
|
||||
{
|
||||
var server = Substitute.For<ICopriServer>();
|
||||
[Test]
|
||||
public async Task TestGetStations()
|
||||
{
|
||||
var server = Substitute.For<ICopriServer>();
|
||||
|
||||
server.GetStationsAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL)));
|
||||
server.GetBikesAvailableAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE)));
|
||||
server.GetBikesOccupiedAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED)));
|
||||
server.GetStationsAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALLV2)));
|
||||
|
||||
var result = await new QueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync();
|
||||
var result = await new QueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync();
|
||||
|
||||
Assert.AreEqual(3, result.Response.StationsAll.Count);
|
||||
Assert.AreEqual(2, result.Response.Bikes.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.IsNull(result.Exception);
|
||||
}
|
||||
Assert.AreEqual(3, result.Response.StationsAll.Count);
|
||||
Assert.AreEqual(1, result.Response.StationsAll["9"].BikeGroups.AvailableCount);
|
||||
Assert.AreEqual(1, result.Response.BikesOccupied.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.IsNull(result.Exception);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetBikes()
|
||||
{
|
||||
var server = Substitute.For<ICopriServer>();
|
||||
[Test]
|
||||
public async Task TestGetBikes()
|
||||
{
|
||||
var server = Substitute.For<ICopriServer>();
|
||||
|
||||
server.GetBikesAvailableAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE)));
|
||||
server.GetBikesOccupiedAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED)));
|
||||
server.GetBikesAvailableAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE)));
|
||||
server.GetBikesOccupiedAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED)));
|
||||
|
||||
var result = await new QueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAsync();
|
||||
var result = await new QueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAsync();
|
||||
|
||||
Assert.AreEqual(2, result.Response.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.IsNull(result.Exception);
|
||||
}
|
||||
Assert.AreEqual(2, result.Response.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.IsNull(result.Exception);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task TestGetBikesOccupied()
|
||||
{
|
||||
var server = Substitute.For<ICopriServer>();
|
||||
[Test]
|
||||
public async Task TestGetBikesOccupied()
|
||||
{
|
||||
var server = Substitute.For<ICopriServer>();
|
||||
|
||||
server.GetBikesAvailableAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<BikesAvailableResponse>("{}")));
|
||||
server.GetBikesAvailableAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<BikesAvailableResponse>("{}")));
|
||||
|
||||
server.GetBikesOccupiedAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED)));
|
||||
server.GetBikesOccupiedAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED)));
|
||||
|
||||
var result = await new QueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesOccupiedAsync();
|
||||
var result = await new QueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesOccupiedAsync();
|
||||
|
||||
Assert.AreEqual(1, result.Response.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.IsNull(result.Exception);
|
||||
}
|
||||
}
|
||||
Assert.AreEqual(1, result.Response.Count);
|
||||
Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source);
|
||||
Assert.IsNull(result.Exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,998 @@
|
|||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using TINK.Repository.Response.Stations;
|
||||
|
||||
namespace TestShareeLib.Repository.Response.Stations
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestStationsAvailableResponse
|
||||
{
|
||||
|
||||
[Test]
|
||||
public void TestStationsAvailableBikesOccupiedBikes()
|
||||
{
|
||||
var response = JsonConvert.DeserializeObject<StationsAvailableResponse>(TestStationAvailalbeResponseCopriVer4_1_23_03_alpha);
|
||||
|
||||
Assert.That(
|
||||
response.bikes_occupied.Count,
|
||||
Is.EqualTo(2));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestStationsAvailableAvailableBikes()
|
||||
{
|
||||
var response = JsonConvert.DeserializeObject<StationsAvailableResponse>(TestStationAvailalbeResponseCopriVer4_1_23_03);
|
||||
|
||||
Assert.That(
|
||||
response.stations["FR101"].bike_count,
|
||||
Is.EqualTo("11"));
|
||||
|
||||
Assert.That(
|
||||
response.stations["FR101"].station_type.FirstOrDefault(x => x.Key == "Citybike").Value.bike_count,
|
||||
Is.EqualTo("1"));
|
||||
|
||||
Assert.That(
|
||||
response.stations["FR101"].station_type.FirstOrDefault(x => x.Key == "Citybike").Value.bike_group,
|
||||
Is.EqualTo("FR300103"));
|
||||
|
||||
Assert.That(
|
||||
response.stations["FR101"].station_type.FirstOrDefault(x => x.Key == "Cargobike").Value.bike_count,
|
||||
Is.EqualTo("10"));
|
||||
|
||||
Assert.That(
|
||||
response.stations["FR101"].station_type.FirstOrDefault(x => x.Key == "Cargobike").Value.bike_group,
|
||||
Is.EqualTo("FR300101"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds a a response on stations available response.
|
||||
/// </summary>
|
||||
private const string TestStationAvailalbeResponseCopriVer4_1_23_03 = @"{ ""clearing_cache"" : ""0"",
|
||||
""tariff_info_html"" : ""site/tariff_info.html"",
|
||||
""aowner"" : ""186"",
|
||||
""bike_info_html"" : ""site/bike_info_sharee_1.html"",
|
||||
""last_used_operator"" : {
|
||||
""operator_email"" : ""hotline@sharee.bike"",
|
||||
""operator_phone"" : ""+49 761 45370097"",
|
||||
""operator_name"" : ""TeilRad GmbH"",
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr""
|
||||
},
|
||||
""bikes_occupied"" : {},
|
||||
""user_group"" : [],
|
||||
""new_authcoo"" : ""0"",
|
||||
""agb_checked"" : ""1"",
|
||||
""uri_primary"" : ""https://shareeapp-primary.copri.eu"",
|
||||
""authcookie"" : ""5781_f172cf59108fe53e7524c841847fee69_shoo0faiNg"",
|
||||
""user_tour"" : [],
|
||||
""impress_html"" : ""site/impress_1.html"",
|
||||
""response_state"" : ""OK, nothing todo"",
|
||||
""user_id"" : ""ohauff@posteo.de"",
|
||||
""agb_html"" : ""site/agb_sharee_2.html"",
|
||||
""merchant_id"" : ""shoo0faiNg"",
|
||||
""apiserver"" : ""https://shareeapp-primary.copri.eu"",
|
||||
""project_id"" : ""Freiburg"",
|
||||
""init_map"" : {
|
||||
""center"" : {
|
||||
""latitude"" : ""47.976634"",
|
||||
""longitude"" : ""7.825490""
|
||||
},
|
||||
""radius"" : ""2.9""
|
||||
},
|
||||
""privacy_html"" : ""site/privacy_sharee_2.html"",
|
||||
""debuglevel"" : ""72"",
|
||||
""copri_version"" : ""4.1.23.03"",
|
||||
""lang"" : ""de"",
|
||||
""stations"" : {
|
||||
""FR105"" : {
|
||||
""authed"" : ""1"",
|
||||
""bike_count"" : ""0"",
|
||||
""station"" : ""FR105"",
|
||||
""gps_radius"" : ""50"",
|
||||
""capacity"" : ""1"",
|
||||
""cached"" : ""1"",
|
||||
""operator_data"" : {
|
||||
""operator_phone"" : ""+49 761 45370097"",
|
||||
""operator_name"" : ""TeilRad GmbH"",
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_email"" : ""hotline@sharee.bike""
|
||||
},
|
||||
""withpub"" : ""0"",
|
||||
""uri_operator"" : ""https://shareeapp-fr01.copri.eu"",
|
||||
""gps"" : {
|
||||
""longitude"" : ""7.973855"",
|
||||
""latitude"" : ""47.927738""
|
||||
},
|
||||
""station_type"" : {
|
||||
""Cargobike"" : {
|
||||
""bike_count"" : ""0"",
|
||||
""bike_group"" : ""FR300101""
|
||||
}
|
||||
},
|
||||
""station_group"" : [
|
||||
""FR300101""
|
||||
],
|
||||
""description"" : ""Contributor-Station Rainer"",
|
||||
""state"" : ""available""
|
||||
},
|
||||
""FR107"" : {
|
||||
""station"" : ""FR107"",
|
||||
""capacity"" : ""2"",
|
||||
""gps_radius"" : ""50"",
|
||||
""withpub"" : ""0"",
|
||||
""cached"" : ""1"",
|
||||
""operator_data"" : {
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_name"" : ""TeilRad GmbH"",
|
||||
""operator_phone"" : ""+49 761 45370097"",
|
||||
""operator_email"" : ""hotline@sharee.bike""
|
||||
},
|
||||
""bike_count"" : ""0"",
|
||||
""authed"" : ""1"",
|
||||
""state"" : ""available"",
|
||||
""uri_operator"" : ""https://shareeapp-fr01.copri.eu"",
|
||||
""gps"" : {
|
||||
""longitude"" : ""7.888761798157405"",
|
||||
""latitude"" : ""47.98830177263789""
|
||||
},
|
||||
""station_type"" : {
|
||||
""Cargobike"" : {
|
||||
""bike_group"" : ""FR300101"",
|
||||
""bike_count"" : ""0""
|
||||
}
|
||||
},
|
||||
""description"" : ""Contributor-Station Svenja"",
|
||||
""station_group"" : [
|
||||
""FR300101""
|
||||
]
|
||||
},
|
||||
""BVB9001"" : {
|
||||
""state"" : ""available"",
|
||||
""gps"" : {
|
||||
""latitude"" : ""48.004394"",
|
||||
""longitude"" : ""7.840146""
|
||||
},
|
||||
""uri_operator"" : ""https://shareeapp-bvb.copri.eu"",
|
||||
""description"" : ""Unicarré"",
|
||||
""station_group"" : [
|
||||
""BVB300101""
|
||||
],
|
||||
""station_type"" : {
|
||||
""Cargobike"" : {
|
||||
""bike_count"" : ""2"",
|
||||
""bike_group"" : ""BVB300101""
|
||||
}
|
||||
},
|
||||
""gps_radius"" : ""75"",
|
||||
""capacity"" : ""2"",
|
||||
""station"" : ""BVB9001"",
|
||||
""withpub"" : ""0"",
|
||||
""operator_data"" : {
|
||||
""operator_email"" : ""hotline@sharee.bike"",
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_name"" : ""TeilRad GmbH"",
|
||||
""operator_phone"" : ""+49 761 45370097""
|
||||
},
|
||||
""cached"" : ""1"",
|
||||
""bike_count"" : ""2"",
|
||||
""authed"" : ""1""
|
||||
},
|
||||
""BVB9002"" : {
|
||||
""station"" : ""BVB9002"",
|
||||
""gps_radius"" : ""75"",
|
||||
""capacity"" : ""2"",
|
||||
""cached"" : ""1"",
|
||||
""operator_data"" : {
|
||||
""operator_name"" : ""TeilRad GmbH"",
|
||||
""operator_phone"" : ""+49 761 45370097"",
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_email"" : ""hotline@sharee.bike""
|
||||
},
|
||||
""withpub"" : ""0"",
|
||||
""authed"" : ""1"",
|
||||
""bike_count"" : ""2"",
|
||||
""state"" : ""available"",
|
||||
""uri_operator"" : ""https://shareeapp-bvb.copri.eu"",
|
||||
""gps"" : {
|
||||
""latitude"" : ""48.005352"",
|
||||
""longitude"" : ""7.823005""
|
||||
},
|
||||
""station_type"" : {
|
||||
""Cargobike"" : {
|
||||
""bike_group"" : ""BVB300101"",
|
||||
""bike_count"" : ""2""
|
||||
}
|
||||
},
|
||||
""description"" : ""Idinger-Hof"",
|
||||
""station_group"" : [
|
||||
""BVB300101""
|
||||
]
|
||||
},
|
||||
""FR102"" : {
|
||||
""cached"" : ""1"",
|
||||
""operator_data"" : {
|
||||
""operator_phone"" : ""+49 761 45370097"",
|
||||
""operator_name"" : ""TeilRad GmbH"",
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_email"" : ""hotline@sharee.bike""
|
||||
},
|
||||
""withpub"" : ""0"",
|
||||
""station"" : ""FR102"",
|
||||
""capacity"" : ""1"",
|
||||
""gps_radius"" : ""50"",
|
||||
""authed"" : ""1"",
|
||||
""bike_count"" : ""0"",
|
||||
""state"" : ""available"",
|
||||
""station_type"" : {
|
||||
""Cargobike"" : {
|
||||
""bike_count"" : ""0"",
|
||||
""bike_group"" : ""FR300101""
|
||||
},
|
||||
""Citybike"" : {
|
||||
""bike_count"" : ""0"",
|
||||
""bike_group"" : ""FR300103""
|
||||
}
|
||||
},
|
||||
""station_group"" : [
|
||||
""FR300101"",
|
||||
""FR300103""
|
||||
],
|
||||
""description"" : ""Ferdinand-Weiß-Str 5"",
|
||||
""uri_operator"" : ""https://shareeapp-fr01.copri.eu"",
|
||||
""gps"" : {
|
||||
""latitude"" : ""47.994371"",
|
||||
""longitude"" : ""7.835669""
|
||||
}
|
||||
},
|
||||
""FR9010"" : {
|
||||
""withpub"" : ""0"",
|
||||
""cached"" : ""1"",
|
||||
""operator_data"" : {
|
||||
""operator_email"" : ""hotline@sharee.bike"",
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_name"" : ""TeilRad GmbH"",
|
||||
""operator_phone"" : ""+49 761 45370097""
|
||||
},
|
||||
""station"" : ""FR9010"",
|
||||
""capacity"" : ""1"",
|
||||
""gps_radius"" : ""100"",
|
||||
""bike_count"" : ""1"",
|
||||
""authed"" : ""1"",
|
||||
""state"" : ""available"",
|
||||
""station_type"" : {
|
||||
""Cargobike"" : {
|
||||
""bike_count"" : ""1"",
|
||||
""bike_group"" : ""FR300101""
|
||||
}
|
||||
},
|
||||
""description"" : ""Contributor-Station Ilockit"",
|
||||
""station_group"" : [
|
||||
""FR300101""
|
||||
],
|
||||
""uri_operator"" : ""https://shareeapp-fr01.copri.eu"",
|
||||
""gps"" : {
|
||||
""latitude"" : ""52.406693917129175"",
|
||||
""longitude"" : ""12.569934014209514""
|
||||
}
|
||||
},
|
||||
""FR108"" : {
|
||||
""state"" : ""available"",
|
||||
""description"" : ""Contributor-Station Anja"",
|
||||
""station_group"" : [
|
||||
""FR300101""
|
||||
],
|
||||
""station_type"" : {
|
||||
""Cargobike"" : {
|
||||
""bike_count"" : ""1"",
|
||||
""bike_group"" : ""FR300101""
|
||||
}
|
||||
},
|
||||
""gps"" : {
|
||||
""longitude"" : ""7.885837789049421"",
|
||||
""latitude"" : ""48.070487906373515""
|
||||
},
|
||||
""uri_operator"" : ""https://shareeapp-fr01.copri.eu"",
|
||||
""operator_data"" : {
|
||||
""operator_email"" : ""hotline@sharee.bike"",
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_phone"" : ""+49 761 45370097"",
|
||||
""operator_name"" : ""TeilRad GmbH""
|
||||
},
|
||||
""cached"" : ""1"",
|
||||
""withpub"" : ""0"",
|
||||
""gps_radius"" : ""100"",
|
||||
""capacity"" : ""1"",
|
||||
""station"" : ""FR108"",
|
||||
""authed"" : ""1"",
|
||||
""bike_count"" : ""1""
|
||||
},
|
||||
""BVB9003"" : {
|
||||
""capacity"" : ""2"",
|
||||
""gps_radius"" : ""75"",
|
||||
""station"" : ""BVB9003"",
|
||||
""operator_data"" : {
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_name"" : ""TeilRad GmbH"",
|
||||
""operator_phone"" : ""+49 761 45370097"",
|
||||
""operator_email"" : ""hotline@sharee.bike""
|
||||
},
|
||||
""cached"" : ""1"",
|
||||
""withpub"" : ""0"",
|
||||
""authed"" : ""1"",
|
||||
""bike_count"" : ""2"",
|
||||
""state"" : ""available"",
|
||||
""gps"" : {
|
||||
""longitude"" : ""7.8269763"",
|
||||
""latitude"" : ""48.0137631""
|
||||
},
|
||||
""uri_operator"" : ""https://shareeapp-bvb.copri.eu"",
|
||||
""station_group"" : [
|
||||
""BVB300101""
|
||||
],
|
||||
""description"" : ""Carl-Sieder-Hof"",
|
||||
""station_type"" : {
|
||||
""Cargobike"" : {
|
||||
""bike_group"" : ""BVB300101"",
|
||||
""bike_count"" : ""2""
|
||||
}
|
||||
}
|
||||
},
|
||||
""REN9002"" : {
|
||||
""station_group"" : [
|
||||
""REN300101"",
|
||||
""REN300103""
|
||||
],
|
||||
""description"" : ""Bikerei-IN"",
|
||||
""gps"" : {
|
||||
""longitude"" : ""11.441289676268319"",
|
||||
""latitude"" : ""48.75089095677469""
|
||||
},
|
||||
""uri_operator"" : ""https://shareeapp-ren.copri.eu"",
|
||||
""state"" : ""available"",
|
||||
""bike_count"" : ""0"",
|
||||
""authed"" : ""1"",
|
||||
""withpub"" : ""1"",
|
||||
""operator_data"" : {
|
||||
""operator_hours"" : ""täglich von 10:00 bis 20:00Uhr"",
|
||||
""operator_phone"" : ""+491774126214"",
|
||||
""operator_name"" : ""Rentamania-Bikes"",
|
||||
""operator_email"" : ""verleih@rentamania.de""
|
||||
},
|
||||
""cached"" : ""1"",
|
||||
""gps_radius"" : ""100"",
|
||||
""capacity"" : ""7"",
|
||||
""station"" : ""REN9002""
|
||||
},
|
||||
""REN9001"" : {
|
||||
""authed"" : ""1"",
|
||||
""bike_count"" : ""0"",
|
||||
""cached"" : ""1"",
|
||||
""operator_data"" : {
|
||||
""operator_hours"" : ""täglich von 10:00 bis 20:00Uhr"",
|
||||
""operator_name"" : ""Rentamania-Bikes"",
|
||||
""operator_phone"" : ""+491774126214"",
|
||||
""operator_email"" : ""verleih@rentamania.de""
|
||||
},
|
||||
""withpub"" : ""1"",
|
||||
""station"" : ""REN9001"",
|
||||
""capacity"" : ""8"",
|
||||
""gps_radius"" : ""100"",
|
||||
""description"" : ""Rentamania-EI"",
|
||||
""station_group"" : [
|
||||
""REN300101"",
|
||||
""REN300103""
|
||||
],
|
||||
""uri_operator"" : ""https://shareeapp-ren.copri.eu"",
|
||||
""gps"" : {
|
||||
""latitude"" : ""48.8975726"",
|
||||
""longitude"" : ""11.170959""
|
||||
},
|
||||
""state"" : ""available""
|
||||
},
|
||||
""FR104"" : {
|
||||
""description"" : ""fahrradspezialitäten"",
|
||||
""station_group"" : [
|
||||
""FR300101"",
|
||||
""FR300103""
|
||||
],
|
||||
""station_type"" : {
|
||||
""Cargobike"" : {
|
||||
""bike_group"" : ""FR300101"",
|
||||
""bike_count"" : ""0""
|
||||
},
|
||||
""Citybike"" : {
|
||||
""bike_group"" : ""FR300103"",
|
||||
""bike_count"" : ""0""
|
||||
}
|
||||
},
|
||||
""gps"" : {
|
||||
""longitude"" : ""7.837621"",
|
||||
""latitude"" : ""47.989807""
|
||||
},
|
||||
""uri_operator"" : ""https://shareeapp-fr01.copri.eu"",
|
||||
""state"" : ""available"",
|
||||
""bike_count"" : ""0"",
|
||||
""authed"" : ""1"",
|
||||
""withpub"" : ""0"",
|
||||
""operator_data"" : {
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_phone"" : ""+49 761 45370097"",
|
||||
""operator_name"" : ""TeilRad GmbH"",
|
||||
""operator_email"" : ""hotline@sharee.bike""
|
||||
},
|
||||
""cached"" : ""1"",
|
||||
""gps_radius"" : ""50"",
|
||||
""capacity"" : ""1"",
|
||||
""station"" : ""FR104""
|
||||
},
|
||||
""FR101"" : {
|
||||
""operator_data"" : {
|
||||
""operator_email"" : ""hotline@sharee.bike"",
|
||||
""operator_phone"" : ""+49 761 45370097"",
|
||||
""operator_name"" : ""TeilRad GmbH"",
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr""
|
||||
},
|
||||
""cached"" : ""1"",
|
||||
""withpub"" : ""0"",
|
||||
""gps_radius"" : ""50"",
|
||||
""capacity"" : ""3"",
|
||||
""station"" : ""FR101"",
|
||||
""authed"" : ""1"",
|
||||
""bike_count"" : ""11"",
|
||||
""state"" : ""available"",
|
||||
""station_group"" : [
|
||||
""FR300101"",
|
||||
""FR300103""
|
||||
],
|
||||
""description"" : ""Villaban sharee Station"",
|
||||
""station_type"" : {
|
||||
""Citybike"" : {
|
||||
""bike_group"" : ""FR300103"",
|
||||
""bike_count"" : ""1""
|
||||
},
|
||||
""Cargobike"" : {
|
||||
""bike_group"" : ""FR300101"",
|
||||
""bike_count"" : ""10""
|
||||
}
|
||||
},
|
||||
""gps"" : {
|
||||
""latitude"" : ""47.976634"",
|
||||
""longitude"" : ""7.825490""
|
||||
},
|
||||
""uri_operator"" : ""https://shareeapp-fr01.copri.eu""
|
||||
},
|
||||
""FR103"" : {
|
||||
""gps_radius"" : ""50"",
|
||||
""capacity"" : ""3"",
|
||||
""station"" : ""FR103"",
|
||||
""withpub"" : ""0"",
|
||||
""operator_data"" : {
|
||||
""operator_name"" : ""TeilRad GmbH"",
|
||||
""operator_phone"" : ""+49 761 45370097"",
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_email"" : ""hotline@sharee.bike""
|
||||
},
|
||||
""cached"" : ""1"",
|
||||
""bike_count"" : ""2"",
|
||||
""authed"" : ""1"",
|
||||
""state"" : ""available"",
|
||||
""gps"" : {
|
||||
""latitude"" : ""47.997922"",
|
||||
""longitude"" : ""7.784941""
|
||||
},
|
||||
""uri_operator"" : ""https://shareeapp-fr01.copri.eu"",
|
||||
""description"" : ""Contributor-Station Oliver"",
|
||||
""station_group"" : [
|
||||
""FR300101""
|
||||
],
|
||||
""station_type"" : {
|
||||
""Cargobike"" : {
|
||||
""bike_group"" : ""FR300101"",
|
||||
""bike_count"" : ""2""
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
""response"" : ""stations_available"",
|
||||
""uri_operator_array"" : [
|
||||
""https://shareeapp-thu.copri.eu"",
|
||||
""https://shareeapp-demo.copri.eu"",
|
||||
""https://shareeapp-lv.copri.eu"",
|
||||
""https://shareeapp-ren.copri.eu"",
|
||||
""https://shareeapp-fr01.copri.eu"",
|
||||
""https://shareeapp-bvb.copri.eu""
|
||||
]
|
||||
}";
|
||||
|
||||
/// <summary>
|
||||
/// Holds a a response on stations available response.
|
||||
/// </summary>
|
||||
private const string TestStationAvailalbeResponseCopriVer4_1_23_03_alpha = @"{
|
||||
""uri_operator_array"" : [
|
||||
""https://shareeapp-bvb.copri.eu"",
|
||||
""https://shareeapp-thu.copri.eu"",
|
||||
""https://shareeapp-lv.copri.eu"",
|
||||
""https://shareeapp-ren.copri.eu"",
|
||||
""https://shareeapp-fr01.copri.eu"",
|
||||
""https://shareeapp-demo.copri.eu""
|
||||
],
|
||||
""agb_html"" : ""site/agb_sharee_2.html"",
|
||||
""lang"" : ""de"",
|
||||
""apiserver"" : ""https://shareeapp-primary.copri.eu"",
|
||||
""project_id"" : ""Freiburg"",
|
||||
""debuglevel"" : ""72"",
|
||||
""privacy_html"" : ""site/privacy_sharee_2.html"",
|
||||
""last_used_operator"" : {
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_email"" : ""hotline@sharee.bike"",
|
||||
""operator_phone"" : ""+49 761 45370097"",
|
||||
""operator_name"" : ""TeilRad GmbH""
|
||||
},
|
||||
""user_id"" : ""ohauff@posteo.de"",
|
||||
""stations"" : {
|
||||
""FR104"" : {
|
||||
""station"" : ""FR104"",
|
||||
""gps_radius"" : ""50"",
|
||||
""gps"" : {
|
||||
""longitude"" : ""7.837621"",
|
||||
""latitude"" : ""47.989807""
|
||||
},
|
||||
""cached"" : ""1"",
|
||||
""bike_count"" : ""0"",
|
||||
""station_group"" : [
|
||||
""FR300101"",
|
||||
""FR300103""
|
||||
],
|
||||
""capacity"" : ""1"",
|
||||
""description"" : ""fahrradspezialitäten"",
|
||||
""state"" : ""available"",
|
||||
""withpub"" : ""1"",
|
||||
""operator_data"" : {
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_email"" : ""hotline@sharee.bike"",
|
||||
""operator_name"" : ""TeilRad GmbH"",
|
||||
""operator_phone"" : ""+49 761 45370097""
|
||||
},
|
||||
""uri_operator"" : ""https://shareeapp-fr01.copri.eu"",
|
||||
""authed"" : ""1""
|
||||
},
|
||||
""FR9010"" : {
|
||||
""authed"" : ""1"",
|
||||
""description"" : ""Contributor-Station Ilockit"",
|
||||
""state"" : ""available"",
|
||||
""operator_data"" : {
|
||||
""operator_email"" : ""hotline@sharee.bike"",
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_phone"" : ""+49 761 45370097"",
|
||||
""operator_name"" : ""TeilRad GmbH""
|
||||
},
|
||||
""withpub"" : ""0"",
|
||||
""uri_operator"" : ""https://shareeapp-fr01.copri.eu"",
|
||||
""gps_radius"" : ""100"",
|
||||
""cached"" : ""1"",
|
||||
""gps"" : {
|
||||
""longitude"" : ""12.569934014209514"",
|
||||
""latitude"" : ""52.406693917129175""
|
||||
},
|
||||
""bike_count"" : ""1"",
|
||||
""station_group"" : [
|
||||
""FR300101""
|
||||
],
|
||||
""capacity"" : ""1"",
|
||||
""station"" : ""FR9010""
|
||||
},
|
||||
""BVB9003"" : {
|
||||
""authed"" : ""1"",
|
||||
""operator_data"" : {
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_email"" : ""hotline@sharee.bike"",
|
||||
""operator_name"" : ""TeilRad GmbH"",
|
||||
""operator_phone"" : ""+49 761 45370097""
|
||||
},
|
||||
""withpub"" : ""0"",
|
||||
""uri_operator"" : ""https://shareeapp-bvb.copri.eu"",
|
||||
""description"" : ""Carl-Sieder-Hof"",
|
||||
""state"" : ""available"",
|
||||
""bike_count"" : ""1"",
|
||||
""station_group"" : [
|
||||
""BVB300101""
|
||||
],
|
||||
""capacity"" : ""2"",
|
||||
""gps_radius"" : ""75"",
|
||||
""gps"" : {
|
||||
""longitude"" : ""7.8269763"",
|
||||
""latitude"" : ""48.0137631""
|
||||
},
|
||||
""cached"" : ""1"",
|
||||
""station"" : ""BVB9003""
|
||||
},
|
||||
""BVB9001"" : {
|
||||
""station"" : ""BVB9001"",
|
||||
""capacity"" : ""2"",
|
||||
""bike_count"" : ""1"",
|
||||
""station_group"" : [
|
||||
""BVB300101""
|
||||
],
|
||||
""gps_radius"" : ""75"",
|
||||
""cached"" : ""1"",
|
||||
""gps"" : {
|
||||
""latitude"" : ""48.004394"",
|
||||
""longitude"" : ""7.840146""
|
||||
},
|
||||
""uri_operator"" : ""https://shareeapp-bvb.copri.eu"",
|
||||
""withpub"" : ""0"",
|
||||
""operator_data"" : {
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_email"" : ""hotline@sharee.bike"",
|
||||
""operator_name"" : ""TeilRad GmbH"",
|
||||
""operator_phone"" : ""+49 761 45370097""
|
||||
},
|
||||
""description"" : ""Unicarré"",
|
||||
""state"" : ""available"",
|
||||
""authed"" : ""1""
|
||||
},
|
||||
""FR103"" : {
|
||||
""station"" : ""FR103"",
|
||||
""gps_radius"" : ""50"",
|
||||
""gps"" : {
|
||||
""latitude"" : ""47.997922"",
|
||||
""longitude"" : ""7.784941""
|
||||
},
|
||||
""cached"" : ""1"",
|
||||
""capacity"" : ""3"",
|
||||
""bike_count"" : ""0"",
|
||||
""station_group"" : [
|
||||
""FR300101""
|
||||
],
|
||||
""description"" : ""Contributor-Station Oliver"",
|
||||
""state"" : ""available"",
|
||||
""uri_operator"" : ""https://shareeapp-fr01.copri.eu"",
|
||||
""operator_data"" : {
|
||||
""operator_name"" : ""TeilRad GmbH"",
|
||||
""operator_phone"" : ""+49 761 45370097"",
|
||||
""operator_email"" : ""hotline@sharee.bike"",
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr""
|
||||
},
|
||||
""withpub"" : ""0"",
|
||||
""authed"" : ""1""
|
||||
},
|
||||
""REN9001"" : {
|
||||
""bike_count"" : ""0"",
|
||||
""station_group"" : [
|
||||
""REN300101"",
|
||||
""REN300103""
|
||||
],
|
||||
""capacity"" : ""8"",
|
||||
""gps_radius"" : ""100"",
|
||||
""gps"" : {
|
||||
""latitude"" : ""48.8975726"",
|
||||
""longitude"" : ""11.170959""
|
||||
},
|
||||
""cached"" : ""1"",
|
||||
""station"" : ""REN9001"",
|
||||
""authed"" : ""1"",
|
||||
""withpub"" : ""1"",
|
||||
""operator_data"" : {
|
||||
""operator_name"" : ""Rentamania-Bikes"",
|
||||
""operator_phone"" : ""+491774126214"",
|
||||
""operator_hours"" : ""täglich von 10:00 bis 20:00Uhr"",
|
||||
""operator_email"" : ""verleih@rentamania.de""
|
||||
},
|
||||
""uri_operator"" : ""https://shareeapp-ren.copri.eu"",
|
||||
""description"" : ""Rentamania-EI"",
|
||||
""state"" : ""available""
|
||||
},
|
||||
""FR107"" : {
|
||||
""state"" : ""available"",
|
||||
""description"" : ""Contributor-Station Svenja"",
|
||||
""uri_operator"" : ""https://shareeapp-fr01.copri.eu"",
|
||||
""operator_data"" : {
|
||||
""operator_email"" : ""hotline@sharee.bike"",
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_phone"" : ""+49 761 45370097"",
|
||||
""operator_name"" : ""TeilRad GmbH""
|
||||
},
|
||||
""withpub"" : ""0"",
|
||||
""authed"" : ""1"",
|
||||
""station"" : ""FR107"",
|
||||
""gps"" : {
|
||||
""longitude"" : ""7.888761798157405"",
|
||||
""latitude"" : ""47.98830177263789""
|
||||
},
|
||||
""cached"" : ""1"",
|
||||
""gps_radius"" : ""50"",
|
||||
""capacity"" : ""2"",
|
||||
""station_group"" : [
|
||||
""FR300101""
|
||||
],
|
||||
""bike_count"" : ""0""
|
||||
},
|
||||
""BVB9002"" : {
|
||||
""station_group"" : [
|
||||
""BVB300101""
|
||||
],
|
||||
""bike_count"" : ""1"",
|
||||
""capacity"" : ""2"",
|
||||
""cached"" : ""1"",
|
||||
""gps"" : {
|
||||
""latitude"" : ""48.005352"",
|
||||
""longitude"" : ""7.823005""
|
||||
},
|
||||
""gps_radius"" : ""75"",
|
||||
""station"" : ""BVB9002"",
|
||||
""authed"" : ""1"",
|
||||
""withpub"" : ""0"",
|
||||
""operator_data"" : {
|
||||
""operator_email"" : ""hotline@sharee.bike"",
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_name"" : ""TeilRad GmbH"",
|
||||
""operator_phone"" : ""+49 761 45370097""
|
||||
},
|
||||
""uri_operator"" : ""https://shareeapp-bvb.copri.eu"",
|
||||
""state"" : ""available"",
|
||||
""description"" : ""Idinger-Hof""
|
||||
},
|
||||
""FR102"" : {
|
||||
""bike_count"" : ""0"",
|
||||
""station_group"" : [
|
||||
""FR300101"",
|
||||
""FR300103""
|
||||
],
|
||||
""capacity"" : ""1"",
|
||||
""gps_radius"" : ""50"",
|
||||
""cached"" : ""1"",
|
||||
""gps"" : {
|
||||
""longitude"" : ""7.835669"",
|
||||
""latitude"" : ""47.994371""
|
||||
},
|
||||
""station"" : ""FR102"",
|
||||
""authed"" : ""1"",
|
||||
""operator_data"" : {
|
||||
""operator_email"" : ""hotline@sharee.bike"",
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_phone"" : ""+49 761 45370097"",
|
||||
""operator_name"" : ""TeilRad GmbH""
|
||||
},
|
||||
""withpub"" : ""1"",
|
||||
""uri_operator"" : ""https://shareeapp-fr01.copri.eu"",
|
||||
""description"" : ""Ferdinand-Weiß-Str 5"",
|
||||
""state"" : ""available""
|
||||
},
|
||||
""FR105"" : {
|
||||
""authed"" : ""1"",
|
||||
""uri_operator"" : ""https://shareeapp-fr01.copri.eu"",
|
||||
""operator_data"" : {
|
||||
""operator_email"" : ""hotline@sharee.bike"",
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_phone"" : ""+49 761 45370097"",
|
||||
""operator_name"" : ""TeilRad GmbH""
|
||||
},
|
||||
""withpub"" : ""0"",
|
||||
""description"" : ""Contributor-Station Rainer"",
|
||||
""state"" : ""available"",
|
||||
""capacity"" : ""1"",
|
||||
""bike_count"" : ""1"",
|
||||
""station_group"" : [
|
||||
""FR300101""
|
||||
],
|
||||
""gps_radius"" : ""50"",
|
||||
""cached"" : ""1"",
|
||||
""gps"" : {
|
||||
""latitude"" : ""47.927738"",
|
||||
""longitude"" : ""7.973855""
|
||||
},
|
||||
""station"" : ""FR105""
|
||||
},
|
||||
""FR108"" : {
|
||||
""uri_operator"" : ""https://shareeapp-fr01.copri.eu"",
|
||||
""withpub"" : ""0"",
|
||||
""operator_data"" : {
|
||||
""operator_email"" : ""hotline@sharee.bike"",
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_phone"" : ""+49 761 45370097"",
|
||||
""operator_name"" : ""TeilRad GmbH""
|
||||
},
|
||||
""description"" : ""Contributor-Station Anja"",
|
||||
""state"" : ""available"",
|
||||
""authed"" : ""1"",
|
||||
""station"" : ""FR108"",
|
||||
""capacity"" : ""1"",
|
||||
""bike_count"" : ""1"",
|
||||
""station_group"" : [
|
||||
""FR300101""
|
||||
],
|
||||
""gps_radius"" : ""100"",
|
||||
""cached"" : ""1"",
|
||||
""gps"" : {
|
||||
""latitude"" : ""48.070487906373515"",
|
||||
""longitude"" : ""7.885837789049421""
|
||||
}
|
||||
},
|
||||
""FR101"" : {
|
||||
""authed"" : ""1"",
|
||||
""uri_operator"" : ""https://shareeapp-fr01.copri.eu"",
|
||||
""withpub"" : ""1"",
|
||||
""operator_data"" : {
|
||||
""operator_phone"" : ""+49 761 45370097"",
|
||||
""operator_name"" : ""TeilRad GmbH"",
|
||||
""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||
""operator_email"" : ""hotline@sharee.bike""
|
||||
},
|
||||
""state"" : ""available"",
|
||||
""description"" : ""Villaban sharee Station"",
|
||||
""capacity"" : ""3"",
|
||||
""station_group"" : [
|
||||
""FR300101"",
|
||||
""FR300103""
|
||||
],
|
||||
""bike_count"" : ""5"",
|
||||
""gps"" : {
|
||||
""latitude"" : ""47.976634"",
|
||||
""longitude"" : ""7.825490""
|
||||
},
|
||||
""cached"" : ""1"",
|
||||
""gps_radius"" : ""50"",
|
||||
""station"" : ""FR101""
|
||||
},
|
||||
""REN9002"" : {
|
||||
""authed"" : ""1"",
|
||||
""state"" : ""available"",
|
||||
""description"" : ""Bikerei-IN"",
|
||||
""withpub"" : ""1"",
|
||||
""operator_data"" : {
|
||||
""operator_email"" : ""verleih@rentamania.de"",
|
||||
""operator_hours"" : ""täglich von 10:00 bis 20:00Uhr"",
|
||||
""operator_name"" : ""Rentamania-Bikes"",
|
||||
""operator_phone"" : ""+491774126214""
|
||||
},
|
||||
""uri_operator"" : ""https://shareeapp-ren.copri.eu"",
|
||||
""cached"" : ""1"",
|
||||
""gps"" : {
|
||||
""longitude"" : ""11.441289676268319"",
|
||||
""latitude"" : ""48.75089095677469""
|
||||
},
|
||||
""gps_radius"" : ""100"",
|
||||
""station_group"" : [
|
||||
""REN300101"",
|
||||
""REN300103""
|
||||
],
|
||||
""bike_count"" : ""0"",
|
||||
""capacity"" : ""7"",
|
||||
""station"" : ""REN9002""
|
||||
}
|
||||
},
|
||||
""response"" : ""stations_available"",
|
||||
""bike_info_html"" : ""site/bike_info_sharee_1.html"",
|
||||
""clearing_cache"" : ""0"",
|
||||
""authcookie"" : ""5781_f172cf59108fe53e7524c841847fee69_shoo0faiNg"",
|
||||
""agb_checked"" : ""1"",
|
||||
""impress_html"" : ""site/impress_1.html"",
|
||||
""init_map"" : {
|
||||
""center"" : {
|
||||
""longitude"" : ""7.825490"",
|
||||
""latitude"" : ""47.976634""
|
||||
},
|
||||
""radius"" : ""2.9""
|
||||
},
|
||||
""response_state"" : ""OK, nothing todo"",
|
||||
""merchant_id"" : ""shoo0faiNg"",
|
||||
""new_authcoo"" : ""0"",
|
||||
""tariff_info_html"" : ""site/tariff_info.html"",
|
||||
""user_group"" : [],
|
||||
""aowner"" : ""186"",
|
||||
""copri_version"" : ""4.1.23.03"",
|
||||
""bikes_occupied"" : {
|
||||
""159154"" : {
|
||||
""gps"" : {
|
||||
""latitude"" : ""47.997873374261"",
|
||||
""longitude"" : ""7.78480782173574""
|
||||
},
|
||||
""request_time"" : ""2023-03-24 19:06:27.110484+01"",
|
||||
""end_time"" : ""2023-03-24 19:06:00+01"",
|
||||
""bike"" : ""FR1011"",
|
||||
""bike_group"" : [
|
||||
""FR300101""
|
||||
],
|
||||
""rentalog"" : """",
|
||||
""tariff_description"" : {
|
||||
""eur_per_hour"" : ""0.00"",
|
||||
""number"" : ""5533"",
|
||||
""name"" : ""E-Lastenrad private"",
|
||||
""max_eur_per_day"" : ""24.00""
|
||||
},
|
||||
""system"" : ""Ilockit"",
|
||||
""station"" : ""FR103"",
|
||||
""unit_price"" : ""2.00"",
|
||||
""total_price"" : ""0.00"",
|
||||
""rental_description"" : {
|
||||
""name"" : ""E-Lastenrad private"",
|
||||
""id"" : ""5533"",
|
||||
""reserve_timerange"" : ""15"",
|
||||
""tarif_elements"" : {
|
||||
""4"" : [
|
||||
""Max. Gebühr"",
|
||||
""24,00 € / Tag""
|
||||
],
|
||||
""1"" : [
|
||||
""Mietgebühr"",
|
||||
""2,00 € / 30 Min ""
|
||||
]
|
||||
}
|
||||
},
|
||||
""real_clock"" : ""00:00"",
|
||||
""discount"" : """",
|
||||
""bike_type"" : {
|
||||
""wheels"" : ""2"",
|
||||
""category"" : ""cargo""
|
||||
},
|
||||
""lock_state"" : ""locked"",
|
||||
""freed_time"" : """",
|
||||
""start_time"" : ""2023-03-24 19:06:27.110484+01"",
|
||||
""description"" : ""Lastenrad Oliver Pieper"",
|
||||
""state"" : ""requested"",
|
||||
""computed_hours"" : ""0"",
|
||||
""uri_operator"" : ""https://shareeapp-fr01.copri.eu"",
|
||||
""Ilockit_ID"" : ""ISHAREIT-2200536""
|
||||
},
|
||||
""159155"" : {
|
||||
""description"" : ""Contributor-bike devel"",
|
||||
""state"" : ""occupied"",
|
||||
""computed_hours"" : ""0"",
|
||||
""freed_time"" : """",
|
||||
""start_time"" : ""2023-03-24 19:06:51.881632+01"",
|
||||
""Ilockit_ID"" : ""ISHAREIT-2309492"",
|
||||
""uri_operator"" : ""https://shareeapp-fr01.copri.eu"",
|
||||
""discount"" : """",
|
||||
""bike_type"" : {
|
||||
""wheels"" : ""2"",
|
||||
""category"" : ""cargo""
|
||||
},
|
||||
""lock_state"" : ""unlocked"",
|
||||
""unit_price"" : ""2.00"",
|
||||
""station"" : ""FR103"",
|
||||
""tariff_description"" : {
|
||||
""number"" : ""5533"",
|
||||
""eur_per_hour"" : ""0.00"",
|
||||
""max_eur_per_day"" : ""24.00"",
|
||||
""name"" : ""E-Lastenrad private""
|
||||
},
|
||||
""system"" : ""Ilockit"",
|
||||
""rental_description"" : {
|
||||
""id"" : ""5533"",
|
||||
""tarif_elements"" : {
|
||||
""4"" : [
|
||||
""Max. Gebühr"",
|
||||
""24,00 € / Tag""
|
||||
],
|
||||
""1"" : [
|
||||
""Mietgebühr"",
|
||||
""2,00 € / 30 Min ""
|
||||
],
|
||||
""7"" : [
|
||||
""Aktuelle Mietzeit"",
|
||||
""1 Min ""
|
||||
]
|
||||
},
|
||||
""reserve_timerange"" : ""15"",
|
||||
""name"" : ""E-Lastenrad private""
|
||||
},
|
||||
""real_clock"" : ""00:01"",
|
||||
""total_price"" : ""0.00"",
|
||||
""request_time"" : ""2023-03-24 19:06:43.046977+01"",
|
||||
""bike"" : ""FR1012"",
|
||||
""end_time"" : ""2023-03-24 19:08:04"",
|
||||
""gps"" : {
|
||||
""longitude"" : ""7.784874"",
|
||||
""latitude"" : ""47.998028""
|
||||
},
|
||||
""rentalog"" : """",
|
||||
""bike_group"" : [
|
||||
""FR300101""
|
||||
]
|
||||
}
|
||||
},
|
||||
""uri_primary"" : ""https://shareeapp-primary.copri.eu"",
|
||||
""user_tour"" : []
|
||||
}";
|
||||
}
|
||||
}
|
|
@ -9,7 +9,6 @@ using TestFramework.Model.Services.Geolocation;
|
|||
using TestFramework.Model.User.Account;
|
||||
using TestFramework.Repository;
|
||||
using TestFramework.Services.BluetoothLock;
|
||||
using TestFramework.Services.CopriApi.Connector;
|
||||
using TINK.Model;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
|
|
|
@ -344,7 +344,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
)); ;
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -411,7 +411,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
connector.Command.DoReturn(bike, Arg.Any<LocationDto>()).Returns<BookingFinishedModel>(x => throw new WebConnectFailureException("Context info", new Exception("hoppla")));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -487,7 +487,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
throw notAtStationException);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -557,7 +557,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
throw noGPSDataException);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -625,7 +625,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
throw new ReturnBikeException(JsonConvert.DeserializeObject<DoReturnResponse>(@"{ ""response_text"" : ""Some invalid data received!""}"), "Outer message."));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -692,7 +692,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
connector.Command.DoReturn(bike, Arg.Any<LocationDto>()).Returns<BookingFinishedModel>(x => throw new Exception("Exception message."));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
|
|
@ -213,7 +213,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
connector.Command.DoReserve(bike).Returns(x => throw new BookingDeclinedException(7)); // Booking must be performed
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -276,7 +276,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
connector.Command.DoReserve(bike).Returns<Task>(x => throw new WebConnectFailureException("Context info.", new Exception("chub")));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -339,7 +339,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
connector.Command.DoReserve(bike).Returns<Task>(x => throw new Exception("Exception message."));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -404,7 +404,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
locks.TimeOut.Returns(timeOuts);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -470,7 +470,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
locks.TimeOut.Returns(timeOuts);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
|
|
@ -136,7 +136,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
|||
|
||||
viewService.DisplayAlert(string.Empty, string.Format("Cancel reservation for bike {0}?", "Nr. 0"), "Yes", "No").Returns(Task.FromResult(true));
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -208,7 +208,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
|||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new InvalidAuthorizationResponseException("mustermann@server.de", response));
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -276,7 +276,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
|||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new WebConnectFailureException("Context info.", new Exception("chub")));
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -344,7 +344,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
|||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new Exception("Exception message."));
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
|
|
@ -132,7 +132,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
viewService.DisplayAlert(string.Empty, string.Format("Cancel reservation for bike {0}?", "Nr. 0"), "Yes", "No").Returns(Task.FromResult(true));
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -202,7 +202,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new InvalidAuthorizationResponseException("mustermann@server.de", l_oResponse));
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -268,7 +268,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new WebConnectFailureException("Context info", new Exception("chub")));
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -334,7 +334,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new Exception("Exception message."));
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
viewService.DisplayAlert(string.Empty, "Rad Nr. 0 abschließen und zurückgeben oder Rad mieten?", "Zurückgeben", "Mieten").Returns(Task.FromResult(false));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Open); // Requsthandler factory queries lock state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Open); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ using TestFramework.Model.Device;
|
|||
using TestFramework.Model.Services.Geolocation;
|
||||
using TestFramework.Model.User.Account;
|
||||
using TestFramework.Repository;
|
||||
using TestFramework.Services.CopriApi.Connector;
|
||||
using TINK.Model;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Model.Device;
|
||||
|
|
|
@ -10,11 +10,14 @@ using TestFramework.Model.Services.Geolocation;
|
|||
using TestFramework.Model.User.Account;
|
||||
using TestFramework.Repository;
|
||||
using TestFramework.Services.BluetoothLock;
|
||||
using TestFramework.Services.CopriApi.Connector;
|
||||
using TINK.Model;
|
||||
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using TINK.Model.Bikes.BikeInfoNS.BikeNS;
|
||||
using TINK.Model.Bikes.BikeInfoNS.DriveNS;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Model.Settings;
|
||||
using TINK.Model.Stations.StationNS;
|
||||
using TINK.Repository;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Services;
|
||||
|
@ -24,6 +27,8 @@ using TINK.View;
|
|||
using TINK.ViewModel.Map;
|
||||
using TINK.ViewModel.Settings;
|
||||
using Xamarin.Forms;
|
||||
using TINK.Model.Bikes.BikeInfoNS;
|
||||
using TINK.Model.Stations.StationNS.Operator;
|
||||
|
||||
namespace TestShareeLib.UseCases.Startup
|
||||
{
|
||||
|
@ -46,7 +51,7 @@ namespace TestShareeLib.UseCases.Startup
|
|||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(),
|
||||
isConnectedFunc: () => true,
|
||||
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(new AppContextInfo("MyMerchId", "MyApp", new Version(1, 2)), null /*UI language */, sessionCookie, mail, server: new CopriCallsMemory001(sessionCookie)),
|
||||
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)),
|
||||
merchantId: "MyMerchId",
|
||||
bluetoothService: Substitute.For<IBluetoothLE>(),
|
||||
locationPermissionsService: Substitute.For<ILocationPermission>(),
|
||||
|
@ -85,11 +90,11 @@ namespace TestShareeLib.UseCases.Startup
|
|||
// Verify pins on map
|
||||
Assert.AreEqual(27, viewModel.Pins.Count); // Were 8 pins when loading from CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)
|
||||
Assert.That(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Green")).Tag,
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Green"))?.Tag,
|
||||
Is.EqualTo("FR101"),
|
||||
"Station FR105 must be marked green because there is are bike.");
|
||||
"Station FR105 must be marked green because there are bikes.");
|
||||
Assert.That(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Red")).Tag,
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Red"))?.Tag,
|
||||
Is.EqualTo("KN12"),
|
||||
"Station KN12 must be marked red because there is no bike."); // Was station id 31
|
||||
|
||||
|
@ -127,7 +132,7 @@ namespace TestShareeLib.UseCases.Startup
|
|||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(),
|
||||
isConnectedFunc: () => true,
|
||||
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(new AppContextInfo("MyMerchId", "MyApp", new Version(1, 2)), null /*UI language */, sessionCookie, mail, server: new CopriCallsMemory001(sessionCookie)),
|
||||
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)),
|
||||
merchantId: "MyMerchId",
|
||||
bluetoothService: Substitute.For<IBluetoothLE>(),
|
||||
locationPermissionsService: Substitute.For<ILocationPermission>(),
|
||||
|
@ -151,8 +156,8 @@ namespace TestShareeLib.UseCases.Startup
|
|||
var viewModel = new MapPageViewModel(
|
||||
tinkApp,
|
||||
locationPermission,
|
||||
NSubstitute.Substitute.For<Plugin.BLE.Abstractions.Contracts.IBluetoothLE>(),
|
||||
NSubstitute.Substitute.For<IGeolocationService>(),
|
||||
Substitute.For<IBluetoothLE>(),
|
||||
Substitute.For<IGeolocationService>(),
|
||||
(mapspan) => { },
|
||||
viewService,
|
||||
navigationService);
|
||||
|
@ -166,11 +171,11 @@ namespace TestShareeLib.UseCases.Startup
|
|||
// Verify pins on map
|
||||
Assert.AreEqual(21, viewModel.Pins.Count); // Were 2 pins when loading from CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)
|
||||
Assert.That(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Green")).Tag, // Was station 5
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Green"))?.Tag, // Was station 5
|
||||
Is.EqualTo("FR103"),
|
||||
"Station FR101 must be marked green because there is are bike.");
|
||||
Assert.That(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Red")).Tag, // Was station 14
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Red"))?.Tag, // Was station 14
|
||||
Is.EqualTo("KN12"),
|
||||
"Station KN12 must be marked red because there is no bike.");
|
||||
|
||||
|
@ -205,7 +210,7 @@ namespace TestShareeLib.UseCases.Startup
|
|||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(),
|
||||
isConnectedFunc: () => true,
|
||||
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(new AppContextInfo("MyMerchId", "MyApp", new Version(1, 2)), null /*UI language */, sessionCookie, mail, server: new CopriCallsMemory001(sessionCookie)),
|
||||
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)),
|
||||
merchantId: "MyMerchId",
|
||||
bluetoothService: Substitute.For<IBluetoothLE>(),
|
||||
locationPermissionsService: Substitute.For<ILocationPermission>(),
|
||||
|
@ -242,11 +247,11 @@ namespace TestShareeLib.UseCases.Startup
|
|||
// Verify pins on map
|
||||
Assert.AreEqual(21, viewModel.Pins.Count); // Were 2 when loading from CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)
|
||||
Assert.That(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Green")).Tag, // Was station id 31
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Green"))?.Tag, // Was station id 31
|
||||
Is.EqualTo("FR103"),
|
||||
"Station FR101 must be marked green because there is are bike.");
|
||||
Assert.That(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Red")).Tag, // Was 14
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Red"))?.Tag, // Was 14
|
||||
Is.EqualTo("KN12"),
|
||||
"Station KN12 must be marked red because there is no bike.");
|
||||
|
||||
|
@ -278,7 +283,7 @@ namespace TestShareeLib.UseCases.Startup
|
|||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(),
|
||||
isConnectedFunc: () => true,
|
||||
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(new AppContextInfo("MyMerchId", "MyApp", new Version(1, 2)), null /*UI language */, sessionCookie, mail, server: new CopriCallsMemory001(sessionCookie)),
|
||||
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)),
|
||||
merchantId: "MyMerchId",
|
||||
bluetoothService: Substitute.For<IBluetoothLE>(),
|
||||
locationPermissionsService: Substitute.For<ILocationPermission>(),
|
||||
|
@ -315,11 +320,11 @@ namespace TestShareeLib.UseCases.Startup
|
|||
// Verify pins on map
|
||||
Assert.AreEqual(27, viewModel.Pins.Count); // Were 8 pin when loading from CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)
|
||||
Assert.That(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Green")).Tag,
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Green"))?.Tag,
|
||||
Is.EqualTo("FR101"), // Was station id 4
|
||||
"Station FR101 must be marked green because there is are bike.");
|
||||
Assert.That(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Red")).Tag, // Was 31
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Red"))?.Tag, // Was 31
|
||||
Is.EqualTo("KN12"), // Was station id 31
|
||||
"Station KN12 must be marked red because there is no bike.");
|
||||
|
||||
|
@ -351,7 +356,7 @@ namespace TestShareeLib.UseCases.Startup
|
|||
activeGeolocationService: typeof(GeolocationMock).FullName),
|
||||
new StoreMock(),
|
||||
isConnectedFunc: () => false,
|
||||
connectorFactory: (isConnected, uri, sessionCookie, mail, expiresAfter) => new ConnectorCache(new AppContextInfo("MyMerchId", "MyApp", new Version(1, 2)), null /*UI language */, sessionCookie, mail, server: new CopriCallsMemory001(sessionCookie)),
|
||||
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)),
|
||||
merchantId: "MyMerchId",
|
||||
bluetoothService: Substitute.For<IBluetoothLE>(),
|
||||
locationPermissionsService: Substitute.For<ILocationPermission>(),
|
||||
|
@ -373,7 +378,7 @@ namespace TestShareeLib.UseCases.Startup
|
|||
var viewModel = new MapPageViewModel(
|
||||
tinkApp,
|
||||
locationPermission,
|
||||
Substitute.For<Plugin.BLE.Abstractions.Contracts.IBluetoothLE>(),
|
||||
Substitute.For<IBluetoothLE>(),
|
||||
Substitute.For<IGeolocationService>(),
|
||||
(mapspan) => { },
|
||||
viewService,
|
||||
|
@ -388,11 +393,11 @@ namespace TestShareeLib.UseCases.Startup
|
|||
// Verify pins on map
|
||||
Assert.AreEqual(27, viewModel.Pins.Count); // Were 8 pins when loading from CopriCallsMemory(SampleSets.Set2, 1, sessionCookie)
|
||||
Assert.That(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Green")).Tag, // Was station id 4
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Green"))?.Tag, // Was station id 4
|
||||
Is.EqualTo("FR101"),
|
||||
"Station FR101 must be marked green because there is are bike.");
|
||||
Assert.That(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Red")).Tag, // Was 31
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Red"))?.Tag, // Was 31
|
||||
Is.EqualTo("KN12"),
|
||||
"Station KN12 must be marked red because there is no bike.");
|
||||
|
||||
|
@ -439,7 +444,7 @@ namespace TestShareeLib.UseCases.Startup
|
|||
new AppContextInfo("oiF2kahH", "sharee.bike.test", new Version(3, 0, 267)),
|
||||
null /*UI language */,
|
||||
sessionCookie: sessionCookie,
|
||||
cacheServer: new CopriCallsCacheMemory001(sessionCookie: sessionCookie),
|
||||
cacheServer: new CopriCallsCacheMemory001v2NotLoggedIn(sessionCookie: sessionCookie),
|
||||
httpsServer: new ExceptionServer((msg) => new WebConnectFailureException(msg, new Exception("Source expection."))))),
|
||||
merchantId: "MyMerchId",
|
||||
bluetoothService: Substitute.For<IBluetoothLE>(),
|
||||
|
@ -479,11 +484,11 @@ namespace TestShareeLib.UseCases.Startup
|
|||
// Verify pins on map
|
||||
Assert.AreEqual(27, viewModel.Pins.Count);
|
||||
Assert.That(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Green")).Tag, // Was station id 4
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Green"))?.Tag, // Was station id 4
|
||||
Is.EqualTo("FR101"),
|
||||
"Station FR101 must be marked green because there is are bike.");
|
||||
Assert.That(
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Red")).Tag, // Was 31
|
||||
viewModel.Pins.FirstOrDefault(pin => pin.Icon.Id.Contains("Open_Red"))?.Tag, // Was 31
|
||||
Is.EqualTo("KN12"),
|
||||
"Station KN12 must be marked red because there is no bike.");
|
||||
|
||||
|
@ -529,7 +534,7 @@ namespace TestShareeLib.UseCases.Startup
|
|||
new AppContextInfo("oiF2kahH", "sharee.bike.test", new Version(3, 0, 267)),
|
||||
null /*UI language */,
|
||||
sessionCookie: sessionCookie,
|
||||
cacheServer: new CopriCallsCacheMemory001(sessionCookie: sessionCookie),
|
||||
cacheServer: new CopriCallsCacheMemory001v2NotLoggedIn(sessionCookie: sessionCookie),
|
||||
httpsServer: new ExceptionServer((msg) => new Exception(msg)))),
|
||||
merchantId: "MyMerchId",
|
||||
bluetoothService: Substitute.For<IBluetoothLE>(),
|
||||
|
@ -591,5 +596,116 @@ namespace TestShareeLib.UseCases.Startup
|
|||
await viewModel.OnDisappearing();
|
||||
}
|
||||
}
|
||||
|
||||
[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)
|
||||
};
|
||||
|
||||
var bikes = new List<TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo> {
|
||||
// Add a reserved bike to station "FR101"
|
||||
new BikeInfo(
|
||||
new Bike("Id1", LockModel.ILockIt),
|
||||
new Drive(),
|
||||
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
|
||||
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" };
|
||||
|
||||
var bikes = new List<TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo> {
|
||||
// Add a reserved bike to station "FR101"
|
||||
new BikeInfo(
|
||||
new Bike("Id1", LockModel.ILockIt),
|
||||
new Drive(),
|
||||
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ using TestFramework.Model.Device;
|
|||
using TestFramework.Model.Services.Geolocation;
|
||||
using TestFramework.Model.User.Account;
|
||||
using TestFramework.Repository;
|
||||
using TestTINKLib.Mocks.Connector;
|
||||
using TINK.Model;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Model.Device;
|
||||
|
|
|
@ -14,8 +14,10 @@ https
|
|||
Namespace
|
||||
offline
|
||||
ok
|
||||
pedelecs
|
||||
popup
|
||||
pwd
|
||||
refactored
|
||||
uri
|
||||
uris
|
||||
Url
|
||||
|
|
Loading…
Reference in a new issue