Version 3.0.357

This commit is contained in:
Anja 2023-01-18 14:22:51 +01:00
parent 5980410182
commit 5c0b2e70c9
84 changed files with 1012 additions and 449 deletions

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?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.356" android:versionCode="356"> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.LastenradBayern" android:versionName="3.0.357" android:versionCode="357">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="31" /> <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="31" />
<!-- Google Maps related permissions --> <!-- Google Maps related permissions -->
<!-- Permission to receive remote notifications from Google Play Services --> <!-- Permission to receive remote notifications from Google Play Services -->

View file

@ -56,8 +56,8 @@
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
<string>LastenradBayern</string> <string>LastenradBayern</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>356</string> <string>357</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>3.0.356</string> <string>3.0.357</string>
</dict> </dict>
</plist> </plist>

View file

@ -97,7 +97,7 @@
<!--While process is running--> <!--While process is running-->
<sharedGui:RunningProcessViewBay <sharedGui:RunningProcessViewBay
IsVisible="{Binding IsRunning}" IsVisible="{Binding IsProcessWithRunningProcessView}"
Grid.Row="1"/> Grid.Row="1"/>
</Grid> </Grid>

View file

@ -36,8 +36,8 @@
FontSize="Small" FontSize="Small"
VerticalOptions="Center" VerticalOptions="Center"
HorizontalOptions="FillAndExpand"/> HorizontalOptions="FillAndExpand"/>
<ActivityIndicator IsRunning="{Binding IsRunning}" <ActivityIndicator IsRunning="{Binding IsProcessWithRunningProcessView}"
IsVisible="{Binding IsRunning}" IsVisible="{Binding IsProcessWithRunningProcessView}"
HeightRequest="20" HeightRequest="20"
VerticalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"
HorizontalOptions="End"> HorizontalOptions="End">

View file

@ -1,4 +1,4 @@

using System.Globalization; using System.Globalization;
using Serilog; using Serilog;
using TINK.ViewModel.CopriWebView; using TINK.ViewModel.CopriWebView;

View file

@ -58,7 +58,7 @@
<!--While process is running--> <!--While process is running-->
<sharedGui:RunningProcessViewBay <sharedGui:RunningProcessViewBay
Grid.Row="0" Grid.Row="0"
IsVisible="{Binding IsRunning}"/> IsVisible="{Binding IsProcessWithRunningProcessView}"/>
</Grid> </Grid>

View file

@ -93,8 +93,8 @@
<ActivityIndicator <ActivityIndicator
Grid.RowSpan="4" Grid.RowSpan="4"
Grid.ColumnSpan="3" Grid.ColumnSpan="3"
IsRunning="{Binding IsRunning}" IsRunning="{Binding IsProcessWithRunningProcessView}"
IsVisible="{Binding IsRunning}" IsVisible="{Binding IsProcessWithRunningProcessView}"
Scale="2" Scale="2"
VerticalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"

View file

@ -55,7 +55,7 @@
<!--While process is running--> <!--While process is running-->
<sharedGui:RunningProcessViewBay <sharedGui:RunningProcessViewBay
Grid.Row="0" Grid.Row="0"
IsVisible="{Binding IsRunning}"/> IsVisible="{Binding IsProcessWithRunningProcessView}"/>
</Grid> </Grid>

View file

@ -1,4 +1,4 @@
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock; using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
namespace TINK.Services.BluetoothLock.Exception namespace TINK.Services.BluetoothLock.Exception
{ {
@ -11,7 +11,9 @@ namespace TINK.Services.BluetoothLock.Exception
/// </remarks> /// </remarks>
public class BluetoothDisconnectedException : StateAwareException public class BluetoothDisconnectedException : StateAwareException
{ {
public BluetoothDisconnectedException() : base(LockingState.UnknownDisconnected, MultilingualResources.Resources.ErrorBluetoothDisconnectedException) public BluetoothDisconnectedException() : base(
LockingState.UnknownDisconnected,
MultilingualResources.Resources.ErrorBluetoothDisconnectedException)
{ {
} }
} }

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?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.356" android:versionCode="356"> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.Meinkonrad" android:versionName="3.0.357" android:versionCode="357">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="31" /> <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="31" />
<!-- Google Maps related permissions --> <!-- Google Maps related permissions -->
<!-- Permission to receive remote notifications from Google Play Services --> <!-- Permission to receive remote notifications from Google Play Services -->

View file

@ -56,8 +56,8 @@
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
<string>Mein konrad</string> <string>Mein konrad</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>356</string> <string>357</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>3.0.356</string> <string>3.0.357</string>
</dict> </dict>
</plist> </plist>

View file

@ -27,6 +27,9 @@
<x:String x:Key="EyeOpen">&#xf06e;</x:String> <x:String x:Key="EyeOpen">&#xf06e;</x:String>
<x:String x:Key="EyeClose">&#xf070;</x:String> <x:String x:Key="EyeClose">&#xf070;</x:String>
<!--Triangle exclamation-->
<x:String x:Key="Attention">&#xf071;</x:String>
<!-- Add more resources here --> <!-- Add more resources here -->
<ResourceDictionary.MergedDictionaries> <ResourceDictionary.MergedDictionaries>
<!-- Add more resource dictionaries here --> <!-- Add more resource dictionaries here -->

View file

@ -75,6 +75,25 @@
IsVisible="{Binding IsLockitButtonVisible}" IsVisible="{Binding IsLockitButtonVisible}"
IsEnabled="{Binding IsIdle}" IsEnabled="{Binding IsIdle}"
Command="{Binding OnLockitButtonClicked}"/> Command="{Binding OnLockitButtonClicked}"/>
<!--Hint for Cache Daten.-->
<StackLayout
Orientation="Horizontal"
HorizontalOptions="CenterAndExpand"
IsVisible="{Binding IsDataFromCache}">
<Image>
<Image.Source>
<FontImageSource
Glyph="{StaticResource Attention}"
Color="Red"
FontFamily="FA-S"
Size="Small"/>
</Image.Source>
</Image>
<Label
TextColor="Red"
FontSize="Small"
Text="{x:Static resources:AppResources.MarkingDataIsFromCache}"/>
</StackLayout>
<!-- Rental description (tarif name, options and rental info --> <!-- Rental description (tarif name, options and rental info -->
<Grid <Grid
RowSpacing="0" RowSpacing="0"

View file

@ -61,7 +61,10 @@
IsEnabled="{Binding IsIdle}" IsEnabled="{Binding IsIdle}"
IsVisible="{Binding IsBikesListVisible}" IsVisible="{Binding IsBikesListVisible}"
HasUnevenRows="True" HasUnevenRows="True"
ItemTemplate="{StaticResource bikeTemplateSelector}"/> ItemTemplate="{StaticResource bikeTemplateSelector}"
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsRefreshing}"/>
<!--No Bikes--> <!--No Bikes-->
<Label Grid.Row="1" <Label Grid.Row="1"
@ -72,7 +75,7 @@
<Label <Label
Grid.Row="2" Grid.Row="2"
Text="{Binding StatusInfoText}" Text="{Binding StatusInfoText}"
IsVisible="{Binding Path=IsRunning, Converter={StaticResource InvertedBoolConverter}}" IsVisible="{Binding Path=IsProcessWithRunningProcessView, Converter={StaticResource InvertedBoolConverter}}"
FontSize="Small" FontSize="Small"
HorizontalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/> VerticalOptions="CenterAndExpand"/>
@ -114,7 +117,7 @@
<!--While process is running--> <!--While process is running-->
<sharedGui:RunningProcessView <sharedGui:RunningProcessView
IsVisible="{Binding IsRunning}" IsVisible="{Binding IsProcessWithRunningProcessView}"
Grid.Row="0"/> Grid.Row="0"/>
</Grid> </Grid>

View file

@ -118,7 +118,7 @@
Grid.Row="3" Grid.Row="3"
Grid.ColumnSpan="3" Grid.ColumnSpan="3"
Text="{Binding StatusInfoText}" Text="{Binding StatusInfoText}"
IsVisible="{Binding Path=IsRunning, Converter={StaticResource InvertedBoolConverter}}" IsVisible="{Binding Path=IsProcessWithRunningProcessView, Converter={StaticResource InvertedBoolConverter}}"
TextColor="White" TextColor="White"
FontSize="Small" FontSize="Small"
HorizontalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"
@ -126,7 +126,7 @@
<!--While process is running--> <!--While process is running-->
<sharedGui:RunningProcessView <sharedGui:RunningProcessView
IsVisible="{Binding IsRunning}" IsVisible="{Binding IsProcessWithRunningProcessView}"
Grid.RowSpan="4" Grid.RowSpan="4"
Grid.ColumnSpan="3"/> Grid.ColumnSpan="3"/>

View file

@ -52,7 +52,10 @@
IsEnabled="{Binding IsIdle}" IsEnabled="{Binding IsIdle}"
IsVisible="{Binding IsBikesListVisible}" IsVisible="{Binding IsBikesListVisible}"
HasUnevenRows="True" HasUnevenRows="True"
ItemTemplate="{StaticResource bikeTemplateSelector}"/> ItemTemplate="{StaticResource bikeTemplateSelector}"
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsRefreshing}"/>
</StackLayout> </StackLayout>
@ -60,7 +63,7 @@
<Label <Label
Grid.Row="1" Grid.Row="1"
Text="{Binding StatusInfoText}" Text="{Binding StatusInfoText}"
IsVisible="{Binding Path=IsRunning, Converter={StaticResource InvertedBoolConverter}}" IsVisible="{Binding Path=IsProcessWithRunningProcessView, Converter={StaticResource InvertedBoolConverter}}"
FontSize="Small" FontSize="Small"
HorizontalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/> VerticalOptions="CenterAndExpand"/>
@ -72,7 +75,7 @@
<!--While process is running--> <!--While process is running-->
<sharedGui:RunningProcessView <sharedGui:RunningProcessView
Grid.Row="0" Grid.Row="0"
IsVisible="{Binding IsRunning}"/> IsVisible="{Binding IsProcessWithRunningProcessView}"/>
</Grid> </Grid>

View file

@ -100,7 +100,7 @@
Grid.Row="3" Grid.Row="3"
Grid.ColumnSpan="3" Grid.ColumnSpan="3"
Text="{Binding StatusInfoText}" Text="{Binding StatusInfoText}"
IsVisible="{Binding Path=IsRunning, Converter={StaticResource InvertedBoolConverter}}" IsVisible="{Binding Path=IsProcessWithRunningProcessView, Converter={StaticResource InvertedBoolConverter}}"
TextColor="White" TextColor="White"
FontSize="Small" FontSize="Small"
HorizontalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"
@ -108,7 +108,7 @@
<!--While process is running--> <!--While process is running-->
<sharedGui:RunningProcessView <sharedGui:RunningProcessView
IsVisible="{Binding IsRunning}" IsVisible="{Binding IsProcessWithRunningProcessView}"
Grid.RowSpan="4" Grid.RowSpan="4"
Grid.ColumnSpan="3"/> Grid.ColumnSpan="3"/>

View file

@ -43,7 +43,10 @@
IsEnabled="{Binding IsIdle}" IsEnabled="{Binding IsIdle}"
IsVisible="{Binding IsBikesListVisible}" IsVisible="{Binding IsBikesListVisible}"
HasUnevenRows="True" HasUnevenRows="True"
ItemTemplate="{StaticResource bikeTemplateSelector}"/> ItemTemplate="{StaticResource bikeTemplateSelector}"
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsRefreshing}"/>
<!--No Bikes--> <!--No Bikes-->
<Label <Label
@ -55,7 +58,7 @@
<Label <Label
Grid.Row="1" Grid.Row="1"
Text="{Binding StatusInfoText}" Text="{Binding StatusInfoText}"
IsVisible="{Binding Path=IsRunning, Converter={StaticResource InvertedBoolConverter}}" IsVisible="{Binding Path=IsProcessWithRunningProcessView, Converter={StaticResource InvertedBoolConverter}}"
FontSize="Small" FontSize="Small"
HorizontalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/> VerticalOptions="CenterAndExpand"/>
@ -67,7 +70,7 @@
<!--While process is running--> <!--While process is running-->
<sharedGui:RunningProcessView <sharedGui:RunningProcessView
Grid.Row="0" Grid.Row="0"
IsVisible="{Binding IsRunning}"/> IsVisible="{Binding IsProcessWithRunningProcessView}"/>
</Grid> </Grid>

View file

@ -35,7 +35,7 @@
<!--Spinner--> <!--Spinner-->
<ActivityIndicator <ActivityIndicator
IsRunning="{Binding IsRunning}" IsRunning="{Binding IsProcessWithRunningProcessView}"
Scale="2" Scale="2"
VerticalOptions="Center" VerticalOptions="Center"
HorizontalOptions="Center" HorizontalOptions="Center"

View file

@ -25,8 +25,8 @@
<!--Spinner--> <!--Spinner-->
<ActivityIndicator <ActivityIndicator
Grid.Row="0" Grid.Row="0"
IsRunning="{Binding IsRunning}" IsRunning="{Binding IsProcessWithRunningProcessView}"
IsVisible="{Binding IsRunning}" IsVisible="{Binding IsProcessWithRunningProcessView}"
Scale="2" Scale="2"
VerticalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?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.356" android:versionCode="356"> <manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.hauffware.sharee" android:versionName="3.0.357" android:versionCode="357">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="31" /> <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="31" />
<!-- Google Maps related permissions --> <!-- Google Maps related permissions -->
<!-- Permission to receive remote notifications from Google Play Services --> <!-- Permission to receive remote notifications from Google Play Services -->

View file

@ -56,8 +56,8 @@
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
<string>sharee.bike</string> <string>sharee.bike</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>356</string> <string>357</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>3.0.356</string> <string>3.0.357</string>
</dict> </dict>
</plist> </plist>

View file

@ -27,6 +27,9 @@
<x:String x:Key="EyeOpen">&#xf06e;</x:String> <x:String x:Key="EyeOpen">&#xf06e;</x:String>
<x:String x:Key="EyeClose">&#xf070;</x:String> <x:String x:Key="EyeClose">&#xf070;</x:String>
<!--Triangle exclamation-->
<x:String x:Key="Attention">&#xf071;</x:String>
<!-- Add more resources here --> <!-- Add more resources here -->
<ResourceDictionary.MergedDictionaries> <ResourceDictionary.MergedDictionaries>
<!-- Add more resource dictionaries here --> <!-- Add more resource dictionaries here -->

View file

@ -61,14 +61,31 @@
<Button <Button
Text="{Binding ButtonText}" Text="{Binding ButtonText}"
IsVisible="{Binding IsButtonVisible}" IsVisible="{Binding IsButtonVisible}"
IsEnabled="{Binding IsIdle}"
Command="{Binding OnButtonClicked}"/> Command="{Binding OnButtonClicked}"/>
<Button <Button
Style="{StaticResource SecondaryButton}" Style="{StaticResource SecondaryButton}"
Text="{Binding LockitButtonText}" Text="{Binding LockitButtonText}"
IsVisible="{Binding IsLockitButtonVisible}" IsVisible="{Binding IsLockitButtonVisible}"
IsEnabled="{Binding IsIdle}"
Command="{Binding OnLockitButtonClicked}"/> Command="{Binding OnLockitButtonClicked}"/>
<!--Hint for Cache Daten.-->
<StackLayout
Orientation="Horizontal"
HorizontalOptions="CenterAndExpand"
IsVisible="{Binding IsDataFromCache}">
<Image>
<Image.Source>
<FontImageSource
Glyph="{StaticResource Attention}"
Color="Red"
FontFamily="FA-S"
Size="Small"/>
</Image.Source>
</Image>
<Label
TextColor="Red"
FontSize="Small"
Text="{x:Static resources:AppResources.MarkingDataIsFromCache}"/>
</StackLayout>
<!-- Rental description (tarif name, options and rental info --> <!-- Rental description (tarif name, options and rental info -->
<Grid <Grid
RowSpacing="0" RowSpacing="0"

View file

@ -61,7 +61,10 @@
IsEnabled="{Binding IsIdle}" IsEnabled="{Binding IsIdle}"
IsVisible="{Binding IsBikesListVisible}" IsVisible="{Binding IsBikesListVisible}"
HasUnevenRows="True" HasUnevenRows="True"
ItemTemplate="{StaticResource bikeTemplateSelector}"/> ItemTemplate="{StaticResource bikeTemplateSelector}"
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsRefreshing}"/>
<!--No Bikes--> <!--No Bikes-->
<Label Grid.Row="1" <Label Grid.Row="1"
@ -72,7 +75,7 @@
<Label <Label
Grid.Row="2" Grid.Row="2"
Text="{Binding StatusInfoText}" Text="{Binding StatusInfoText}"
IsVisible="{Binding Path=IsRunning, Converter={StaticResource InvertedBoolConverter}}" IsVisible="{Binding Path=IsProcessWithRunningProcessView, Converter={StaticResource InvertedBoolConverter}}"
FontSize="Small" FontSize="Small"
HorizontalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/> VerticalOptions="CenterAndExpand"/>
@ -114,7 +117,7 @@
<!--While process is running--> <!--While process is running-->
<sharedGui:RunningProcessView <sharedGui:RunningProcessView
IsVisible="{Binding IsRunning}" IsVisible="{Binding IsProcessWithRunningProcessView}"
Grid.Row="0"/> Grid.Row="0"/>
</Grid> </Grid>

View file

@ -117,7 +117,7 @@
Grid.Row="3" Grid.Row="3"
Grid.ColumnSpan="3" Grid.ColumnSpan="3"
Text="{Binding StatusInfoText}" Text="{Binding StatusInfoText}"
IsVisible="{Binding Path=IsRunning, Converter={StaticResource InvertedBoolConverter}}" IsVisible="{Binding Path=IsProcessWithRunningProcessView, Converter={StaticResource InvertedBoolConverter}}"
TextColor="White" TextColor="White"
FontSize="Small" FontSize="Small"
HorizontalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"
@ -125,7 +125,7 @@
<!--While process is running--> <!--While process is running-->
<sharedGui:RunningProcessView <sharedGui:RunningProcessView
IsVisible="{Binding IsRunning}" IsVisible="{Binding IsProcessWithRunningProcessView}"
Grid.RowSpan="4" Grid.RowSpan="4"
Grid.ColumnSpan="3"/> Grid.ColumnSpan="3"/>

View file

@ -1,4 +1,4 @@

using System.Globalization; using System.Globalization;
using Serilog; using Serilog;
using TINK.ViewModel.CopriWebView; using TINK.ViewModel.CopriWebView;

View file

@ -53,7 +53,10 @@
IsEnabled="{Binding IsIdle}" IsEnabled="{Binding IsIdle}"
IsVisible="{Binding IsBikesListVisible}" IsVisible="{Binding IsBikesListVisible}"
HasUnevenRows="True" HasUnevenRows="True"
ItemTemplate="{StaticResource bikeTemplateSelector}"/> ItemTemplate="{StaticResource bikeTemplateSelector}"
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsRefreshing}"/>
</StackLayout> </StackLayout>
@ -61,7 +64,7 @@
<Label <Label
Grid.Row="1" Grid.Row="1"
Text="{Binding StatusInfoText}" Text="{Binding StatusInfoText}"
IsVisible="{Binding Path=IsRunning, Converter={StaticResource InvertedBoolConverter}}" IsVisible="{Binding Path=IsProcessWithRunningProcessView, Converter={StaticResource InvertedBoolConverter}}"
FontSize="Small" FontSize="Small"
HorizontalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/> VerticalOptions="CenterAndExpand"/>
@ -73,7 +76,7 @@
<!--While process is running--> <!--While process is running-->
<sharedGui:RunningProcessView <sharedGui:RunningProcessView
Grid.Row="0" Grid.Row="0"
IsVisible="{Binding IsRunning}"/> IsVisible="{Binding IsProcessWithRunningProcessView}"/>
</Grid> </Grid>

View file

@ -99,7 +99,7 @@
Grid.Row="3" Grid.Row="3"
Grid.ColumnSpan="3" Grid.ColumnSpan="3"
Text="{Binding StatusInfoText}" Text="{Binding StatusInfoText}"
IsVisible="{Binding Path=IsRunning, Converter={StaticResource InvertedBoolConverter}}" IsVisible="{Binding Path=IsProcessWithRunningProcessView, Converter={StaticResource InvertedBoolConverter}}"
TextColor="White" TextColor="White"
FontSize="Small" FontSize="Small"
HorizontalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"
@ -107,7 +107,7 @@
<!--While process is running--> <!--While process is running-->
<sharedGui:RunningProcessView <sharedGui:RunningProcessView
IsVisible="{Binding IsRunning}" IsVisible="{Binding IsProcessWithRunningProcessView}"
Grid.RowSpan="4" Grid.RowSpan="4"
Grid.ColumnSpan="3"/> Grid.ColumnSpan="3"/>

View file

@ -42,7 +42,10 @@
IsEnabled="{Binding IsIdle}" IsEnabled="{Binding IsIdle}"
IsVisible="{Binding IsBikesListVisible}" IsVisible="{Binding IsBikesListVisible}"
HasUnevenRows="True" HasUnevenRows="True"
ItemTemplate="{StaticResource bikeTemplateSelector}"/> ItemTemplate="{StaticResource bikeTemplateSelector}"
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsRefreshing}"/>
<!--No Bikes--> <!--No Bikes-->
<Label <Label
@ -54,7 +57,7 @@
<Label <Label
Grid.Row="1" Grid.Row="1"
Text="{Binding StatusInfoText}" Text="{Binding StatusInfoText}"
IsVisible="{Binding Path=IsRunning, Converter={StaticResource InvertedBoolConverter}}" IsVisible="{Binding Path=IsProcessWithRunningProcessView, Converter={StaticResource InvertedBoolConverter}}"
FontSize="Small" FontSize="Small"
HorizontalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"
VerticalOptions="CenterAndExpand"/> VerticalOptions="CenterAndExpand"/>
@ -66,7 +69,7 @@
<!--While process is running--> <!--While process is running-->
<sharedGui:RunningProcessView <sharedGui:RunningProcessView
Grid.Row="0" Grid.Row="0"
IsVisible="{Binding IsRunning}"/> IsVisible="{Binding IsProcessWithRunningProcessView}"/>
</Grid> </Grid>

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Linq; using System.Linq;
@ -26,7 +26,8 @@ namespace TINK.Model.Bikes
/// <param name="bikesAll"> Object holding bikes info from copri to update from. Holds station id but not station name.</param> /// <param name="bikesAll"> Object holding bikes info from copri to update from. Holds station id but not station name.</param>
/// <param name="stations"> All stations to get station names from.</param> /// <param name="stations"> All stations to get station names from.</param>
/// <param name="p_oDateTimeProvider">Provices date time information.</param> /// <param name="p_oDateTimeProvider">Provices date time information.</param>
public void Update(IEnumerable<BikeInfo> bikesAll, public void Update(
IEnumerable<BikeInfo> bikesAll,
IEnumerable<IStation> stations) IEnumerable<IStation> stations)
{ {
// Get list of current bikes by state(s) to update. // Get list of current bikes by state(s) to update.
@ -54,7 +55,9 @@ namespace TINK.Model.Bikes
} }
// Update bike. // Update bike.
GetById(bikeInfo.Id).State.Load(bikeInfo.State); var updateTarget = GetById(bikeInfo.Id);
updateTarget.State.Load(bikeInfo.State);
updateTarget.DataSource = bikeInfo.DataSource;
if (bikesToBeRemoved.Contains<string>(bikeInfo.Id)) if (bikesToBeRemoved.Contains<string>(bikeInfo.Id))
{ {
@ -109,11 +112,7 @@ namespace TINK.Model.Bikes
/// <param name="id"></param> /// <param name="id"></param>
/// <returns></returns> /// <returns></returns>
public BikeInfoMutable GetById(string id) public BikeInfoMutable GetById(string id)
{ => this.FirstOrDefault(bike => bike.Id == id);
{
return this.FirstOrDefault(bike => bike.Id == id);
}
}
/// <summary> /// <summary>
/// Deteermines whether a bike by given key exists. /// Deteermines whether a bike by given key exists.
@ -121,9 +120,7 @@ namespace TINK.Model.Bikes
/// <param name="p_strKey">Key to check.</param> /// <param name="p_strKey">Key to check.</param>
/// <returns>True if bike exists.</returns> /// <returns>True if bike exists.</returns>
public bool ContainsKey(string id) public bool ContainsKey(string id)
{ => GetById(id) != null;
return GetById(id) != null;
}
/// <summary> /// <summary>
/// Removes a bike by its id. /// Removes a bike by its id.
@ -150,9 +147,9 @@ namespace TINK.Model.Bikes
BikeInfo bikeInfo, BikeInfo bikeInfo,
string stationName) string stationName)
{ {
if (bikeInfo is Bikes.BikeInfoNS.BluetoothLock.BikeInfo btBikeInfo) if (bikeInfo is BikeInfoNS.BluetoothLock.BikeInfo btBikeInfo)
{ {
return new Bikes.BikeInfoNS.BluetoothLock.BikeInfoMutable(btBikeInfo, stationName); return new BikeInfoNS.BluetoothLock.BikeInfoMutable(btBikeInfo, stationName);
} }
else if (bikeInfo is BikeInfoNS.CopriLock.BikeInfo copriBikeInfo) else if (bikeInfo is BikeInfoNS.CopriLock.BikeInfo copriBikeInfo)
{ {

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using TINK.Model.Bikes.BikeInfoNS.BikeNS; using TINK.Model.Bikes.BikeInfoNS.BikeNS;
using TINK.Model.Bikes.BikeInfoNS.DriveNS; using TINK.Model.Bikes.BikeInfoNS.DriveNS;
@ -17,18 +17,23 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
/// <summary> /// <summary>
/// Holds the bike object. /// Holds the bike object.
/// </summary> /// </summary>
public BikeNS.Bike Bike { get; } public Bike Bike { get; }
/// <summary> /// <summary>
/// Holds the drive object. /// Holds the drive object.
/// </summary> /// </summary>
public Drive Drive { get; } public Drive Drive { get; }
/// <summary> Gets the information where the data origins from. </summary>
public DataSource DataSource { get; }
/// <summary> Constructs a bike object.</summary> /// <summary> Constructs a bike object.</summary>
/// <param name="dataSource">Specified the source of the data.</param>
protected BikeInfo( protected BikeInfo(
IStateInfo stateInfo, IStateInfo stateInfo,
BikeNS.Bike bike, Bike bike,
Drive drive, Drive drive,
DataSource dataSource,
bool? isDemo = DEFAULTVALUEISDEMO, bool? isDemo = DEFAULTVALUEISDEMO,
IEnumerable<string> group = null, IEnumerable<string> group = null,
string stationId = null, string stationId = null,
@ -37,6 +42,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
{ {
Bike = bike ?? throw new ArgumentNullException(nameof(bike)); Bike = bike ?? throw new ArgumentNullException(nameof(bike));
Drive = drive ?? throw new ArgumentNullException(nameof(drive)); Drive = drive ?? throw new ArgumentNullException(nameof(drive));
DataSource = dataSource;
_StateInfo = stateInfo; _StateInfo = stateInfo;
IsDemo = isDemo ?? DEFAULTVALUEISDEMO; IsDemo = isDemo ?? DEFAULTVALUEISDEMO;
@ -50,6 +56,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
bikeInfo != null ? bikeInfo?.State : throw new ArgumentNullException(nameof(bikeInfo)), bikeInfo != null ? bikeInfo?.State : throw new ArgumentNullException(nameof(bikeInfo)),
bikeInfo.Bike, bikeInfo.Bike,
bikeInfo.Drive, bikeInfo.Drive,
bikeInfo.DataSource,
bikeInfo.IsDemo, bikeInfo.IsDemo,
bikeInfo.Group, bikeInfo.Group,
bikeInfo.StationId, bikeInfo.StationId,
@ -60,12 +67,14 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
/// <summary> /// <summary>
/// Constructs a bike info object for a available bike. /// Constructs a bike info object for a available bike.
/// </summary> /// </summary>
/// <param name="dataSource">Specified the source of the data.</param>
/// <param name="stationId">Id of station where bike is located.</param> /// <param name="stationId">Id of station where bike is located.</param>
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param> /// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
/// <param name="tariffDescription">Hold tariff description of bike.</param> /// <param name="tariffDescription">Hold tariff description of bike.</param>
public BikeInfo( public BikeInfo(
BikeNS.Bike bike, Bike bike,
Drive drive, Drive drive,
DataSource dataSource,
string stationId, string stationId,
Uri operatorUri = null, Uri operatorUri = null,
RentalDescription tariffDescription = null, RentalDescription tariffDescription = null,
@ -74,6 +83,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
new StateInfo(), new StateInfo(),
bike, bike,
drive, drive,
dataSource,
isDemo, isDemo,
group, group,
stationId, stationId,
@ -85,6 +95,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
/// <summary> /// <summary>
/// Constructs a bike info object for a booked bike. /// Constructs a bike info object for a booked bike.
/// </summary> /// </summary>
/// <param name="dataSource">Specified the source of the data.</param>
/// <param name="dateTimeProvider">Provider for current date time to calculate remainig time on demand for state of type reserved.</param> /// <param name="dateTimeProvider">Provider for current date time to calculate remainig time on demand for state of type reserved.</param>
/// <param name="currentStationId">Name of station where bike is located, null if bike is on the road.</param> /// <param name="currentStationId">Name of station where bike is located, null if bike is on the road.</param>
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param> /// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
@ -93,8 +104,9 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
/// <param name="mailAddress">Mail address of user which booked bike.</param> /// <param name="mailAddress">Mail address of user which booked bike.</param>
/// <param name="code">Booking code.</param> /// <param name="code">Booking code.</param>
public BikeInfo( public BikeInfo(
BikeNS.Bike bike, Bike bike,
Drive drive, Drive drive,
DataSource dataSource,
bool? isDemo, bool? isDemo,
IEnumerable<string> group, IEnumerable<string> group,
string currentStationId, string currentStationId,
@ -109,6 +121,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
code), code),
bike, bike,
drive, drive,
dataSource,
isDemo, isDemo,
group, group,
currentStationId, currentStationId,
@ -131,7 +144,6 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
/// <summary> Holds description about the tarif. </summary> /// <summary> Holds description about the tarif. </summary>
public RentalDescription TariffDescription { get; } public RentalDescription TariffDescription { get; }
/// Holds the rent state of the bike. /// Holds the rent state of the bike.
/// </summary> /// </summary>
public IStateInfo State public IStateInfo State

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Runtime.Serialization; using System.Runtime.Serialization;
@ -12,7 +12,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
public class BikeInfoMutable : IBikeInfoMutable, INotifyPropertyChanged public class BikeInfoMutable : IBikeInfoMutable, INotifyPropertyChanged
{ {
/// <summary> Holds the bike. </summary> /// <summary> Holds the bike. </summary>
private readonly BikeNS.Bike _Bike; private readonly Bike _Bike;
/// <summary> Holds the drive of the bike. </summary> /// <summary> Holds the drive of the bike. </summary>
private readonly Drive _Drive; private readonly Drive _Drive;
@ -30,8 +30,9 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
/// <param name="tariffDescription">Hold tariff description of bike.</param> /// <param name="tariffDescription">Hold tariff description of bike.</param>
/// <param name="stateInfo">Bike state info.</param> /// <param name="stateInfo">Bike state info.</param>
protected BikeInfoMutable( protected BikeInfoMutable(
BikeNS.Bike bike, Bike bike,
Drive drive, Drive drive,
DataSource dataSource,
bool isDemo = BikeInfo.DEFAULTVALUEISDEMO, bool isDemo = BikeInfo.DEFAULTVALUEISDEMO,
IEnumerable<string> group = null, IEnumerable<string> group = null,
string stationId = null, string stationId = null,
@ -45,6 +46,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
Group = group; Group = group;
_Bike = bike; _Bike = bike;
_Drive = drive; _Drive = drive;
DataSource = dataSource;
_StateInfo = new StateInfoMutable(dateTimeProvider, stateInfo); _StateInfo = new StateInfoMutable(dateTimeProvider, stateInfo);
_StateInfo.PropertyChanged += (sender, eventargs) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(eventargs.PropertyName)); _StateInfo.PropertyChanged += (sender, eventargs) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(eventargs.PropertyName));
StationId = stationId; StationId = stationId;
@ -59,6 +61,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
? bike.Bike ? bike.Bike
: throw new ArgumentNullException(nameof(bike)), : throw new ArgumentNullException(nameof(bike)),
bike.Drive, bike.Drive,
bike.DataSource,
bike.IsDemo, bike.IsDemo,
bike.Group, bike.Group,
bike.StationId, bike.StationId,
@ -121,6 +124,22 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
/// </summary> /// </summary>
public event PropertyChangedEventHandler PropertyChanged; public event PropertyChangedEventHandler PropertyChanged;
private DataSource _DataSource = DataSource.Copri;
/// <summary> Gets or sets the information where the data origins from. </summary>
public DataSource DataSource
{
get => _DataSource;
set
{
if (_DataSource == value)
return;
_DataSource = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(DataSource)));
}
}
/// <summary> /// <summary>
/// Converts the instance to text. /// Converts the instance to text.
/// </summary> /// </summary>

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using TINK.Model.Bikes.BikeInfoNS.DriveNS; using TINK.Model.Bikes.BikeInfoNS.DriveNS;
using TINK.Model.State; using TINK.Model.State;
@ -20,6 +20,9 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
/// </summary> /// </summary>
Drive Drive { get; } Drive Drive { get; }
/// <summary> Gets or sets the information where the data origins from. </summary>
DataSource DataSource { get; }
/// <summary> True if bike is a demo bike. </summary> /// <summary> True if bike is a demo bike. </summary>
bool IsDemo { get; } bool IsDemo { get; }
@ -44,4 +47,19 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
/// </summary> /// </summary>
IStateInfo State { get; } IStateInfo State { get; }
} }
/// <summary>
/// Origin of the data.
/// </summary>
public enum DataSource
{
/// <summary>
/// Data source corpi.
/// </summary>
Copri,
/// <summary>
/// Data source cache.
/// </summary>
Cache
}
} }

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using TINK.Model.Bikes.BikeInfoNS.BikeNS; using TINK.Model.Bikes.BikeInfoNS.BikeNS;
@ -56,6 +56,9 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
/// </summary> /// </summary>
Drive Drive { get; } Drive Drive { get; }
/// <summary> Gets or sets the information where the data origins from. </summary>
DataSource DataSource { get; set; }
event PropertyChangedEventHandler PropertyChanged; event PropertyChangedEventHandler PropertyChanged;
} }

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using TINK.Model.Bikes.BikeInfoNS.BC;
using TINK.Model.Bikes.BikeInfoNS.BikeNS; using TINK.Model.Bikes.BikeInfoNS.BikeNS;
using TINK.Model.Bikes.BikeInfoNS.DriveNS; using TINK.Model.Bikes.BikeInfoNS.DriveNS;
using TINK.Model.State; using TINK.Model.State;
@ -11,6 +12,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
/// <summary> /// <summary>
/// Constructs a bike info object for a available bike. /// Constructs a bike info object for a available bike.
/// </summary> /// </summary>
/// <param name="dataSource">Specified the source of the data.</param>
/// <param name="lockId">Id of the lock.</param> /// <param name="lockId">Id of the lock.</param>
/// <param name="lockGuid">GUID specifying the lock.</param> /// <param name="lockGuid">GUID specifying the lock.</param>
/// <param name="currentStationId">Id of station where bike is located.</param> /// <param name="currentStationId">Id of station where bike is located.</param>
@ -19,6 +21,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
public BikeInfo( public BikeInfo(
Bike bike, Bike bike,
Drive drive, Drive drive,
DataSource dataSource,
int lockId, int lockId,
Guid lockGuid, Guid lockGuid,
string currentStationId, string currentStationId,
@ -36,6 +39,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
bike.Description) bike.Description)
: throw new ArgumentNullException(nameof(bike)), : throw new ArgumentNullException(nameof(bike)),
drive, drive,
dataSource,
isDemo, isDemo,
group, group,
currentStationId, currentStationId,
@ -48,6 +52,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
/// <summary> /// <summary>
/// Constructs a bike info object for a requested bike. /// Constructs a bike info object for a requested bike.
/// </summary> /// </summary>
/// <param name="dataSource">Specified the source of the data.</param>
/// <param name="dateTimeProvider">Provider for current date time to calculate remainig time on demand for state of type reserved.</param> /// <param name="dateTimeProvider">Provider for current date time to calculate remainig time on demand for state of type reserved.</param>
/// <param name="lockId">Id of the lock.</param> /// <param name="lockId">Id of the lock.</param>
/// <param name="lockGuid">GUID specifying the lock.</param> /// <param name="lockGuid">GUID specifying the lock.</param>
@ -60,6 +65,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
public BikeInfo( public BikeInfo(
Bike bike, Bike bike,
Drive drive, Drive drive,
DataSource dataSource,
int lockId, int lockId,
Guid lockGuid, Guid lockGuid,
byte[] userKey, byte[] userKey,
@ -87,6 +93,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
bike.Description) bike.Description)
: throw new ArgumentNullException(nameof(bike)), : throw new ArgumentNullException(nameof(bike)),
drive, drive,
dataSource,
isDemo, isDemo,
group, group,
currentStationId, currentStationId,
@ -99,7 +106,8 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
/// <summary> /// <summary>
/// Constructs a bike info object for a booked bike. /// Constructs a bike info object for a booked bike.
/// </summary> /// </summary>
/// <param name="id">Unique id of bike.</param> /// <param name="bike">Unique id of bike.</param>
/// <param name="dataSource">Specified the source of the data.</param>
/// <param name="lockId">Id of the lock.</param> /// <param name="lockId">Id of the lock.</param>
/// <param name="lockGuid">GUID specifying the lock.</param> /// <param name="lockGuid">GUID specifying the lock.</param>
/// <param name="bookedAt">Date time when bike was booked</param> /// <param name="bookedAt">Date time when bike was booked</param>
@ -111,6 +119,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
public BikeInfo( public BikeInfo(
Bike bike, Bike bike,
Drive drive, Drive drive,
DataSource dataSource,
int lockId, int lockId,
Guid lockGuid, Guid lockGuid,
byte[] userKey, byte[] userKey,
@ -136,6 +145,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
bike.Description) bike.Description)
: throw new ArgumentNullException(), : throw new ArgumentNullException(),
drive, drive,
dataSource,
isDemo, isDemo,
group, group,
currentStationId, currentStationId,

View file

@ -1,8 +1,8 @@
using System; using System;
namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
{ {
public class BikeInfoMutable : Model.Bikes.BikeInfoNS.BC.BikeInfoMutable, IBikeInfoMutable public class BikeInfoMutable : BC.BikeInfoMutable, IBikeInfoMutable
{ {
/// <summary> Constructs a bike object from source. </summary> /// <summary> Constructs a bike object from source. </summary>
public BikeInfoMutable(BikeInfo bike, string stationName) : base( public BikeInfoMutable(BikeInfo bike, string stationName) : base(
@ -10,6 +10,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
? bike.Bike ? bike.Bike
: throw new ArgumentNullException(nameof(bike)), : throw new ArgumentNullException(nameof(bike)),
bike.Drive, bike.Drive,
bike.DataSource,
bike.IsDemo, bike.IsDemo,
bike.Group, bike.Group,
bike.StationId, bike.StationId,

View file

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using TINK.Model.Bikes.BikeInfoNS.BC;
using TINK.Model.Bikes.BikeInfoNS.BikeNS; using TINK.Model.Bikes.BikeInfoNS.BikeNS;
using TINK.Model.Bikes.BikeInfoNS.DriveNS; using TINK.Model.Bikes.BikeInfoNS.DriveNS;
using TINK.Model.MiniSurvey; using TINK.Model.MiniSurvey;
@ -13,14 +14,16 @@ namespace TINK.Model.Bikes.BikeInfoNS.CopriLock
/// Constructs a bike info object for a available bike or bike for which feed back is pending. /// Constructs a bike info object for a available bike or bike for which feed back is pending.
/// </summary> /// </summary>
/// <param name="bike">Bike object.</param> /// <param name="bike">Bike object.</param>
/// <param name="dataSource">Specified the source of the data.</param>
/// <param name="currentStationId">Id of station where bike is located.</param> /// <param name="currentStationId">Id of station where bike is located.</param>
/// <param name="lockInfo">Lock info.</param> /// <param name="lockInfo">Lock info.</param>
/// <param name="isFeedbackPending">If true user has not yet given feedback after returning bike.</param> /// <param name="isFeedbackPending">If true user has not yet given feedback after returning bike.</param>
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param> /// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
/// <param name="tariffDescription">Hold tariff description of bike.</param> /// <param name="tariffDescription">Hold tariff description of bike.</param>
public BikeInfo( public BikeInfo(
BikeNS.Bike bike, Bike bike,
Drive drive, Drive drive,
DataSource dataSource,
string currentStationId, string currentStationId,
LockInfo lockInfo, LockInfo lockInfo,
bool isFeedbackPending = false, bool isFeedbackPending = false,
@ -40,6 +43,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.CopriLock
bike.Description) bike.Description)
: throw new ArgumentNullException(nameof(bike)), : throw new ArgumentNullException(nameof(bike)),
drive, drive,
dataSource,
isDemo, isDemo,
group, group,
currentStationId, currentStationId,
@ -55,6 +59,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.CopriLock
/// Constructs a bike info object for a requested bike. /// Constructs a bike info object for a requested bike.
/// </summary> /// </summary>
/// <param name="bike">Bike object.</param> /// <param name="bike">Bike object.</param>
/// <param name="dataSource">Specified the source of the data.</param>
/// <param name="requestedAt">Date time when bike was requested</param> /// <param name="requestedAt">Date time when bike was requested</param>
/// <param name="mailAddress">Mail address of user which requested bike.</param> /// <param name="mailAddress">Mail address of user which requested bike.</param>
/// <param name="currentStationId">Name of station where bike is located, null if bike is on the road.</param> /// <param name="currentStationId">Name of station where bike is located, null if bike is on the road.</param>
@ -63,8 +68,9 @@ namespace TINK.Model.Bikes.BikeInfoNS.CopriLock
/// <param name="tariffDescription">Hold tariff description of bike.</param> /// <param name="tariffDescription">Hold tariff description of bike.</param>
/// <param name="dateTimeProvider">Provider for current date time to calculate remainig time on demand for state of type reserved.</param> /// <param name="dateTimeProvider">Provider for current date time to calculate remainig time on demand for state of type reserved.</param>
public BikeInfo( public BikeInfo(
BikeNS.Bike bike, Bike bike,
Drive drive, Drive drive,
DataSource dataSource,
DateTime requestedAt, DateTime requestedAt,
string mailAddress, string mailAddress,
string currentStationId, string currentStationId,
@ -80,7 +86,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.CopriLock
mailAddress, mailAddress,
""), ""),
bike != null bike != null
? new BikeNS.Bike( ? new Bike(
bike.Id, bike.Id,
LockModel.Sigo /* Ensure consistend lock model value */, LockModel.Sigo /* Ensure consistend lock model value */,
bike.WheelType, bike.WheelType,
@ -88,6 +94,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.CopriLock
bike.Description) bike.Description)
: throw new ArgumentNullException(nameof(bike)), : throw new ArgumentNullException(nameof(bike)),
drive, drive,
dataSource,
isDemo, isDemo,
group, group,
currentStationId, currentStationId,
@ -103,6 +110,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.CopriLock
/// Constructs a bike info object for a booked bike. /// Constructs a bike info object for a booked bike.
/// </summary> /// </summary>
/// <param name="bike">Bike object.</param> /// <param name="bike">Bike object.</param>
/// <param name="dataSource">Specified the source of the data.</param>
/// <param name="bookedAt">Date time when bike was booked</param> /// <param name="bookedAt">Date time when bike was booked</param>
/// <param name="mailAddress">Mail address of user which booked bike.</param> /// <param name="mailAddress">Mail address of user which booked bike.</param>
/// <param name="currentStationId">Name of station where bike is located, null if bike is on the road.</param> /// <param name="currentStationId">Name of station where bike is located, null if bike is on the road.</param>
@ -110,8 +118,9 @@ namespace TINK.Model.Bikes.BikeInfoNS.CopriLock
/// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param> /// <param name="operatorUri">Holds the uri of the operator or null, in case of single operator setup.</param>
/// <param name="tariffDescription">Hold tariff description of bike.</param> /// <param name="tariffDescription">Hold tariff description of bike.</param>
public BikeInfo( public BikeInfo(
BikeNS.Bike bike, Bike bike,
Drive drive, Drive drive,
DataSource dataSource,
DateTime bookedAt, DateTime bookedAt,
string mailAddress, string mailAddress,
string currentStationId, string currentStationId,
@ -125,7 +134,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.CopriLock
mailAddress, mailAddress,
""), ""),
bike != null bike != null
? new BikeNS.Bike( ? new Bike(
bike.Id, bike.Id,
LockModel.Sigo /* Ensure consistend lock model value */, LockModel.Sigo /* Ensure consistend lock model value */,
bike.WheelType, bike.WheelType,
@ -133,6 +142,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.CopriLock
bike.Description) bike.Description)
: throw new ArgumentNullException(nameof(bike)), : throw new ArgumentNullException(nameof(bike)),
drive, drive,
dataSource,
isDemo, isDemo,
group, group,
currentStationId, currentStationId,
@ -143,7 +153,6 @@ namespace TINK.Model.Bikes.BikeInfoNS.CopriLock
MiniSurvey = new MiniSurveyModel(); MiniSurvey = new MiniSurveyModel();
Co2Saving = string.Empty; Co2Saving = string.Empty;
} }
public BikeInfo(BC.BikeInfo bikeInfo, LockInfo lockInfo) : base( public BikeInfo(BC.BikeInfo bikeInfo, LockInfo lockInfo) : base(
bikeInfo ?? throw new ArgumentException($"Can not copy-construct {typeof(BikeInfo).Name}-object. Source bike info must not be null.")) bikeInfo ?? throw new ArgumentException($"Can not copy-construct {typeof(BikeInfo).Name}-object. Source bike info must not be null."))
{ {

View file

@ -1,4 +1,4 @@
using System; using System;
namespace TINK.Model.Bikes.BikeInfoNS.CopriLock namespace TINK.Model.Bikes.BikeInfoNS.CopriLock
{ {
@ -10,6 +10,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.CopriLock
? bike.Bike ? bike.Bike
: throw new ArgumentNullException(nameof(bike)), : throw new ArgumentNullException(nameof(bike)),
bike.Drive, bike.Drive,
bike.DataSource,
bike.IsDemo, bike.IsDemo,
bike.Group, bike.Group,
bike.StationId, bike.StationId,

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Serilog; using Serilog;
@ -11,9 +11,10 @@ using BikeInfo = TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo;
namespace TINK.Model.Connector namespace TINK.Model.Connector
{ {
/// <summary> Provides query functionality for use without log in. </summary>
public class CachedQuery : Base, IQuery public class CachedQuery : Base, IQuery
{ {
/// <summary> Cached copri server. </summary> /// <summary> Cached copri server (connection to copri backed up by cache). </summary>
private readonly ICachedCopriServer server; private readonly ICachedCopriServer server;
/// <summary>Constructs a copri query object.</summary> /// <summary>Constructs a copri query object.</summary>
@ -40,7 +41,7 @@ namespace TINK.Model.Connector
resultStations.Source, resultStations.Source,
new StationsAndBikesContainer( new StationsAndBikesContainer(
resultStations.Response.GetStationsAllMutable(), resultStations.Response.GetStationsAllMutable(),
(await server.GetBikesAvailable(true)).Response.GetBikesAvailable()), (await server.GetBikesAvailable(true)).Response.GetBikesAvailable(Bikes.BikeInfoNS.BC.DataSource.Cache)),
resultStations.GeneralData, resultStations.GeneralData,
resultStations.Exception); resultStations.Exception);
} }
@ -53,7 +54,7 @@ namespace TINK.Model.Connector
resultBikes.Source, resultBikes.Source,
new StationsAndBikesContainer( new StationsAndBikesContainer(
(await server.GetStations(true)).Response.GetStationsAllMutable(), (await server.GetStations(true)).Response.GetStationsAllMutable(),
resultBikes.Response.GetBikesAvailable()), resultBikes.Response.GetBikesAvailable(Bikes.BikeInfoNS.BC.DataSource.Cache)),
resultBikes.GeneralData, resultBikes.GeneralData,
resultBikes.Exception); resultBikes.Exception);
} }
@ -64,7 +65,7 @@ namespace TINK.Model.Connector
return new Result<StationsAndBikesContainer>( return new Result<StationsAndBikesContainer>(
resultStations.Source, resultStations.Source,
new StationsAndBikesContainer(resultStations.Response.GetStationsAllMutable(), resultBikes.Response.GetBikesAvailable()), new StationsAndBikesContainer(resultStations.Response.GetStationsAllMutable(), resultBikes.Response.GetBikesAvailable(Bikes.BikeInfoNS.BC.DataSource.Copri)),
resultStations.GeneralData); resultStations.GeneralData);
} }
@ -73,6 +74,7 @@ namespace TINK.Model.Connector
public async Task<Result<BikeCollection>> GetBikesOccupiedAsync() public async Task<Result<BikeCollection>> GetBikesOccupiedAsync()
{ {
Log.ForContext<CachedQuery>().Error("Unexpected call to get be bikes occpied detected. No user is logged in."); Log.ForContext<CachedQuery>().Error("Unexpected call to get be bikes occpied detected. No user is logged in.");
return new Result<BikeCollection>( return new Result<BikeCollection>(
typeof(CopriCallsMonkeyStore), typeof(CopriCallsMonkeyStore),
await Task.FromResult(new BikeCollection(new Dictionary<string, BikeInfo>())), await Task.FromResult(new BikeCollection(new Dictionary<string, BikeInfo>())),
@ -85,8 +87,20 @@ namespace TINK.Model.Connector
public async Task<Result<BikeCollection>> GetBikesAsync() public async Task<Result<BikeCollection>> GetBikesAsync()
{ {
var result = await server.GetBikesAvailable(); var result = await server.GetBikesAvailable();
if (result.Source != typeof(CopriCallsMonkeyStore))
{
server.AddToCache(result); server.AddToCache(result);
return new Result<BikeCollection>(result.Source, result.Response.GetBikesAvailable(), result.GeneralData, result.Exception); }
return new Result<BikeCollection>(
result.Source,
result.Response.GetBikesAvailable(result.Source == typeof(CopriCallsMonkeyStore)
? Bikes.BikeInfoNS.BC.DataSource.Cache
: Bikes.BikeInfoNS.BC.DataSource.Copri),
result.GeneralData,
result.Exception);
} }
} }
} }

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Serilog; using Serilog;
@ -12,7 +12,7 @@ namespace TINK.Model.Connector
/// <summary> Provides query functionality for a logged in user. </summary> /// <summary> Provides query functionality for a logged in user. </summary>
public class CachedQueryLoggedIn : BaseLoggedIn, IQuery public class CachedQueryLoggedIn : BaseLoggedIn, IQuery
{ {
/// <summary> Cached copri server. </summary> /// <summary> Cached copri server (connection to copri backed up by cache). </summary>
private ICachedCopriServer Server { get; } private ICachedCopriServer Server { get; }
/// <summary>Constructs a copri query object.</summary> /// <summary>Constructs a copri query object.</summary>
@ -42,11 +42,12 @@ namespace TINK.Model.Connector
stationsResponse.Source, stationsResponse.Source,
new StationsAndBikesContainer( new StationsAndBikesContainer(
stationsResponse.Response.GetStationsAllMutable(), stationsResponse.Response.GetStationsAllMutable(),
UpdaterJSON.GetBikesAll( BikeCollectionFactory.GetBikesAll(
(await Server.GetBikesAvailable(true)).Response?.bikes?.Values, (await Server.GetBikesAvailable(true)).Response?.bikes?.Values,
(await Server.GetBikesOccupied(true)).Response?.bikes_occupied?.Values, (await Server.GetBikesOccupied(true)).Response?.bikes_occupied?.Values,
Mail, Mail,
DateTimeProvider)), DateTimeProvider,
Bikes.BikeInfoNS.BC.DataSource.Cache)),
stationsResponse.GeneralData, stationsResponse.GeneralData,
stationsResponse.Exception); stationsResponse.Exception);
} }
@ -60,10 +61,11 @@ namespace TINK.Model.Connector
bikesAvailableResponse.Source, bikesAvailableResponse.Source,
new StationsAndBikesContainer( new StationsAndBikesContainer(
(await Server.GetStations(true)).Response.GetStationsAllMutable(), (await Server.GetStations(true)).Response.GetStationsAllMutable(),
UpdaterJSON.GetBikesAll(bikesAvailableResponse.Response?.bikes?.Values, BikeCollectionFactory.GetBikesAll(bikesAvailableResponse.Response?.bikes?.Values,
(await Server.GetBikesOccupied(true)).Response?.bikes_occupied?.Values, (await Server.GetBikesOccupied(true)).Response?.bikes_occupied?.Values,
Mail, Mail,
DateTimeProvider)), DateTimeProvider,
Bikes.BikeInfoNS.BC.DataSource.Cache)),
bikesAvailableResponse.GeneralData, bikesAvailableResponse.GeneralData,
bikesAvailableResponse.Exception); bikesAvailableResponse.Exception);
} }
@ -77,11 +79,12 @@ namespace TINK.Model.Connector
bikesOccupiedResponse.Source, bikesOccupiedResponse.Source,
new StationsAndBikesContainer( new StationsAndBikesContainer(
(await Server.GetStations(true)).Response.GetStationsAllMutable(), (await Server.GetStations(true)).Response.GetStationsAllMutable(),
UpdaterJSON.GetBikesAll( BikeCollectionFactory.GetBikesAll(
(await Server.GetBikesAvailable(true)).Response?.bikes?.Values, (await Server.GetBikesAvailable(true)).Response?.bikes?.Values,
bikesOccupiedResponse.Response?.bikes_occupied?.Values, bikesOccupiedResponse.Response?.bikes_occupied?.Values,
Mail, Mail,
DateTimeProvider)), DateTimeProvider,
Bikes.BikeInfoNS.BC.DataSource.Cache)),
bikesOccupiedResponse.GeneralData, bikesOccupiedResponse.GeneralData,
bikesOccupiedResponse.Exception); bikesOccupiedResponse.Exception);
} }
@ -94,11 +97,12 @@ namespace TINK.Model.Connector
var exceptions = new[] { stationsResponse?.Exception, bikesAvailableResponse?.Exception, bikesOccupiedResponse?.Exception }.Where(x => x != null).ToArray(); var exceptions = new[] { stationsResponse?.Exception, bikesAvailableResponse?.Exception, bikesOccupiedResponse?.Exception }.Where(x => x != null).ToArray();
var stationsMutable = stationsResponse.Response.GetStationsAllMutable(); var stationsMutable = stationsResponse.Response.GetStationsAllMutable();
var bikesMutable = UpdaterJSON.GetBikesAll( var bikesMutable = BikeCollectionFactory.GetBikesAll(
bikesAvailableResponse.Response?.bikes?.Values, bikesAvailableResponse.Response?.bikes?.Values,
bikesOccupiedResponse.Response?.bikes_occupied?.Values, bikesOccupiedResponse.Response?.bikes_occupied?.Values,
Mail, Mail,
DateTimeProvider); DateTimeProvider,
Bikes.BikeInfoNS.BC.DataSource.Copri);
return new Result<StationsAndBikesContainer>( return new Result<StationsAndBikesContainer>(
stationsResponse.Source, stationsResponse.Source,
@ -119,11 +123,12 @@ namespace TINK.Model.Connector
Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes available read from cache. Reading bikes occupied from cache as well."); Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes available read from cache. Reading bikes occupied from cache as well.");
return new Result<BikeCollection>( return new Result<BikeCollection>(
bikesAvailableResponse.Source, bikesAvailableResponse.Source,
UpdaterJSON.GetBikesAll( BikeCollectionFactory.GetBikesAll(
bikesAvailableResponse.Response?.bikes?.Values?.Where(bike => bike.GetState() == State.InUseStateEnum.FeedbackPending), bikesAvailableResponse.Response?.bikes?.Values?.Where(bike => bike.GetState() == State.InUseStateEnum.FeedbackPending),
(await Server.GetBikesOccupied(true))?.Response?.bikes_occupied?.Values, (await Server.GetBikesOccupied(true))?.Response?.bikes_occupied?.Values,
Mail, Mail,
DateTimeProvider), DateTimeProvider,
Bikes.BikeInfoNS.BC.DataSource.Cache),
bikesAvailableResponse.GeneralData, bikesAvailableResponse.GeneralData,
bikesAvailableResponse.Exception); bikesAvailableResponse.Exception);
} }
@ -136,11 +141,12 @@ namespace TINK.Model.Connector
Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes occupied read from cache. Reread bikes available from cache as well."); Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes occupied read from cache. Reread bikes available from cache as well.");
return new Result<BikeCollection>( return new Result<BikeCollection>(
bikesOccupiedResponse.Source, bikesOccupiedResponse.Source,
UpdaterJSON.GetBikesAll( BikeCollectionFactory.GetBikesAll(
(await Server.GetBikesAvailable(true)).Response?.bikes?.Values?.Where(bike => bike.GetState() == State.InUseStateEnum.FeedbackPending), (await Server.GetBikesAvailable(true)).Response?.bikes?.Values?.Where(bike => bike.GetState() == State.InUseStateEnum.FeedbackPending),
bikesOccupiedResponse.Response?.bikes_occupied?.Values, bikesOccupiedResponse.Response?.bikes_occupied?.Values,
Mail, Mail,
DateTimeProvider), DateTimeProvider,
Bikes.BikeInfoNS.BC.DataSource.Cache),
bikesOccupiedResponse.GeneralData, bikesOccupiedResponse.GeneralData,
bikesOccupiedResponse.Exception); bikesOccupiedResponse.Exception);
} }
@ -151,11 +157,12 @@ namespace TINK.Model.Connector
return new Result<BikeCollection>( return new Result<BikeCollection>(
bikesOccupiedResponse.Source, bikesOccupiedResponse.Source,
UpdaterJSON.GetBikesAll( BikeCollectionFactory.GetBikesAll(
bikesAvailableResponse?.Response.bikes?.Values?.Select(bike => bike)?.Where(bike => bike.GetState() == State.InUseStateEnum.FeedbackPending), bikesAvailableResponse?.Response.bikes?.Values?.Select(bike => bike)?.Where(bike => bike.GetState() == State.InUseStateEnum.FeedbackPending),
bikesOccupiedResponse?.Response?.bikes_occupied?.Values, bikesOccupiedResponse?.Response?.bikes_occupied?.Values,
Mail, Mail,
DateTimeProvider), DateTimeProvider,
Bikes.BikeInfoNS.BC.DataSource.Copri),
bikesOccupiedResponse.GeneralData, bikesOccupiedResponse.GeneralData,
bikesOccupiedResponse.Exception); bikesOccupiedResponse.Exception);
} }
@ -173,11 +180,12 @@ namespace TINK.Model.Connector
Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes available read from cache. Reading bikes occupied from cache as well."); Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes available read from cache. Reading bikes occupied from cache as well.");
return new Result<BikeCollection>( return new Result<BikeCollection>(
bikesAvailableResponse.Source, bikesAvailableResponse.Source,
UpdaterJSON.GetBikesAll( BikeCollectionFactory.GetBikesAll(
bikesAvailableResponse.Response?.bikes?.Values, bikesAvailableResponse.Response?.bikes?.Values,
(await Server.GetBikesOccupied(true)).Response?.bikes_occupied?.Values, (await Server.GetBikesOccupied(true)).Response?.bikes_occupied?.Values,
Mail, Mail,
DateTimeProvider), DateTimeProvider,
Bikes.BikeInfoNS.BC.DataSource.Cache),
bikesAvailableResponse.GeneralData, bikesAvailableResponse.GeneralData,
bikesAvailableResponse.Exception); bikesAvailableResponse.Exception);
} }
@ -190,11 +198,12 @@ namespace TINK.Model.Connector
Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes occupied read from cache. Reread bikes available from cache as well."); Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes occupied read from cache. Reread bikes available from cache as well.");
return new Result<BikeCollection>( return new Result<BikeCollection>(
bikesOccupiedResponse.Source, bikesOccupiedResponse.Source,
UpdaterJSON.GetBikesAll( BikeCollectionFactory.GetBikesAll(
(await Server.GetBikesAvailable(true)).Response?.bikes?.Values, (await Server.GetBikesAvailable(true)).Response?.bikes?.Values,
bikesOccupiedResponse.Response?.bikes_occupied?.Values, bikesOccupiedResponse.Response?.bikes_occupied?.Values,
Mail, Mail,
DateTimeProvider), DateTimeProvider,
Bikes.BikeInfoNS.BC.DataSource.Cache),
bikesOccupiedResponse.GeneralData, bikesOccupiedResponse.GeneralData,
bikesOccupiedResponse.Exception); bikesOccupiedResponse.Exception);
} }
@ -206,11 +215,12 @@ namespace TINK.Model.Connector
Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes available and occupied read successfully from server."); Log.ForContext<CachedQueryLoggedIn>().Debug("Bikes available and occupied read successfully from server.");
return new Result<BikeCollection>( return new Result<BikeCollection>(
bikesAvailableResponse.Source, bikesAvailableResponse.Source,
UpdaterJSON.GetBikesAll( BikeCollectionFactory.GetBikesAll(
bikesAvailableResponse.Response?.bikes?.Values, bikesAvailableResponse.Response?.bikes?.Values,
bikesOccupiedResponse.Response?.bikes_occupied?.Values, bikesOccupiedResponse.Response?.bikes_occupied?.Values,
Mail, Mail,
DateTimeProvider), DateTimeProvider,
Bikes.BikeInfoNS.BC.DataSource.Copri),
bikesAvailableResponse.GeneralData, bikesAvailableResponse.GeneralData,
bikesAvailableResponse.Exception != null || bikesOccupiedResponse.Exception != null ? new AggregateException(new[] { bikesAvailableResponse.Exception, bikesOccupiedResponse.Exception }) : null); bikesAvailableResponse.Exception != null || bikesOccupiedResponse.Exception != null ? new AggregateException(new[] { bikesAvailableResponse.Exception, bikesOccupiedResponse.Exception }) : null);
} }

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Serilog; using Serilog;
@ -11,20 +11,20 @@ using BikeInfo = TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo;
namespace TINK.Model.Connector namespace TINK.Model.Connector
{ {
/// <summary> Provides query functionality without login. </summary> /// <summary> Provides query functionality from cache without login. </summary>
public class Query : Base, IQuery public class Query : Base, IQuery
{ {
/// <summary> Cached copri server. </summary> /// <summary> Cached copri server. </summary>
private readonly ICopriServer server; private readonly ICopriServer server;
/// <summary>Constructs a copri query object.</summary> /// <summary>Constructs a copri query object.</summary>
/// <param name="p_oCopriServer">Server which implements communication.</param> /// <param name="copriServer">Server which implements communication.</param>
public Query(ICopriServerBase p_oCopriServer) : base(p_oCopriServer) public Query(ICopriServerBase copriServer) : base(copriServer)
{ {
server = p_oCopriServer as ICopriServer; server = copriServer as ICopriServer;
if (server == null) if (server == null)
{ {
throw new ArgumentException($"Copri server is not of expected typ. Type detected is {p_oCopriServer.GetType()}."); throw new ArgumentException($"Copri server is not of expected typ. Type detected is {copriServer.GetType()}.");
} }
} }
@ -36,7 +36,7 @@ namespace TINK.Model.Connector
return new Result<StationsAndBikesContainer>( return new Result<StationsAndBikesContainer>(
typeof(CopriCallsMonkeyStore), typeof(CopriCallsMonkeyStore),
new StationsAndBikesContainer(stationsAllResponse.GetStationsAllMutable(), bikesAvailableResponse.GetBikesAvailable()), new StationsAndBikesContainer(stationsAllResponse.GetStationsAllMutable(), bikesAvailableResponse.GetBikesAvailable(Bikes.BikeInfoNS.BC.DataSource.Cache)),
stationsAllResponse.GetGeneralData()); stationsAllResponse.GetGeneralData());
} }
@ -59,7 +59,7 @@ namespace TINK.Model.Connector
var bikesAvailableResponse = await server.GetBikesAvailableAsync(); var bikesAvailableResponse = await server.GetBikesAvailableAsync();
return new Result<BikeCollection>( return new Result<BikeCollection>(
typeof(CopriCallsMonkeyStore), typeof(CopriCallsMonkeyStore),
bikesAvailableResponse.GetBikesAvailable(), bikesAvailableResponse.GetBikesAvailable(Bikes.BikeInfoNS.BC.DataSource.Cache),
bikesAvailableResponse.GetGeneralData()); bikesAvailableResponse.GetGeneralData());
} }
} }

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using TINK.Model.Bikes; using TINK.Model.Bikes;
@ -8,7 +8,7 @@ using TINK.Repository;
namespace TINK.Model.Connector namespace TINK.Model.Connector
{ {
/// <summary> Provides query functionality for a logged in user. </summary> /// <summary> Provides query functionality from cache for a logged in user. </summary>
public class QueryLoggedIn : BaseLoggedIn, IQuery public class QueryLoggedIn : BaseLoggedIn, IQuery
{ {
/// <summary> Copri server. </summary> /// <summary> Copri server. </summary>
@ -41,11 +41,12 @@ namespace TINK.Model.Connector
typeof(CopriCallsMonkeyStore), typeof(CopriCallsMonkeyStore),
new StationsAndBikesContainer( new StationsAndBikesContainer(
stationResponse.GetStationsAllMutable(), stationResponse.GetStationsAllMutable(),
UpdaterJSON.GetBikesAll( BikeCollectionFactory.GetBikesAll(
bikesAvailableResponse?.bikes?.Values, bikesAvailableResponse?.bikes?.Values,
bikesOccupiedResponse?.bikes_occupied?.Values, bikesOccupiedResponse?.bikes_occupied?.Values,
Mail, Mail,
DateTimeProvider)), DateTimeProvider,
Bikes.BikeInfoNS.BC.DataSource.Cache)),
stationResponse.GetGeneralData()); stationResponse.GetGeneralData());
} }
@ -58,11 +59,12 @@ namespace TINK.Model.Connector
return new Result<BikeCollection>( return new Result<BikeCollection>(
typeof(CopriCallsMonkeyStore), typeof(CopriCallsMonkeyStore),
UpdaterJSON.GetBikesAll( BikeCollectionFactory.GetBikesAll(
bikesFeedbackRequired.bikes?.Values?.Select(bike => bike)?.Where(bike => bike.GetState() == State.InUseStateEnum.FeedbackPending), bikesFeedbackRequired.bikes?.Values?.Select(bike => bike)?.Where(bike => bike.GetState() == State.InUseStateEnum.FeedbackPending),
bikesOccupiedResponse?.bikes_occupied?.Values, bikesOccupiedResponse?.bikes_occupied?.Values,
Mail, Mail,
DateTimeProvider), DateTimeProvider,
Bikes.BikeInfoNS.BC.DataSource.Cache),
bikesOccupiedResponse.GetGeneralData()); bikesOccupiedResponse.GetGeneralData());
} }
@ -75,11 +77,12 @@ namespace TINK.Model.Connector
return new Result<BikeCollection>( return new Result<BikeCollection>(
typeof(CopriCallsMonkeyStore), typeof(CopriCallsMonkeyStore),
UpdaterJSON.GetBikesAll( BikeCollectionFactory.GetBikesAll(
bikesAvailableResponse?.bikes?.Values, bikesAvailableResponse?.bikes?.Values,
bikesOccupiedResponse?.bikes_occupied?.Values, bikesOccupiedResponse?.bikes_occupied?.Values,
Mail, Mail,
DateTimeProvider), DateTimeProvider,
Bikes.BikeInfoNS.BC.DataSource.Cache),
bikesAvailableResponse.GetGeneralData()); bikesAvailableResponse.GetGeneralData());
} }
} }

View file

@ -0,0 +1,129 @@
using System;
using System.Collections.Generic;
using System.Text;
using TINK.Model.Bikes.BikeInfoNS.BC;
using TINK.Model.Bikes;
using TINK.Repository.Response;
using Serilog;
namespace TINK.Model.Connector.Updater
{
public static class BikeCollectionFactory
{
/// <summary> Gets bikes available from copri server response.</summary>
/// <param name="bikesAvailableResponse">Response to create collection from.</param>
/// <param name="dataSource">Specified the data source</param>
/// <returns>New collection of available bikes.</returns>
public static BikeCollection GetBikesAvailable(
this BikesAvailableResponse bikesAvailableResponse,
DataSource dataSource)
=> GetBikesAll(
bikesAvailableResponse?.bikes?.Values,
new BikesReservedOccupiedResponse()?.bikes_occupied?.Values, // There are no occupied bikes.
string.Empty,
() => DateTime.Now,
dataSource);
/// <summary> Gets bikes occupied from copri server response. </summary>
/// <param name="bikesOccupiedResponse">Response to create bikes from.</param>
/// <param name="dataSource">Specified the data source</param>
/// <returns>New collection of occupied bikes.</returns>
public static BikeCollection GetBikesOccupied(
this BikesReservedOccupiedResponse bikesOccupiedResponse,
string mail,
Func<DateTime> dateTimeProvider,
DataSource dataSource)
=> GetBikesAll(
new BikesAvailableResponse()?.bikes?.Values,
bikesOccupiedResponse?.bikes_occupied?.Values,
mail,
dateTimeProvider,
dataSource);
/// <summary> Gets bikes occupied from copri server response. </summary>
/// <param name="bikesAvailable">Response to create bikes available from.</param>
/// <param name="bikesOccupied">Response to create bikes occupied from.</param>
/// <returns>New collection of occupied bikes.</returns>
public static BikeCollection GetBikesAll(
IEnumerable<BikeInfoAvailable> bikesAvailable,
IEnumerable<BikeInfoReservedOrBooked> bikesOccupied,
string mail,
Func<DateTime> dateTimeProvider,
DataSource dataSource)
{
var bikesDictionary = new Dictionary<string, BikeInfo>();
var duplicates = new Dictionary<string, BikeInfo>();
// Get bikes from Copri/ file/ memory, ....
if (bikesAvailable != null)
{
foreach (var bikeInfoResponse in bikesAvailable)
{
var bikeInfo = BikeInfoFactory.Create(bikeInfoResponse, dataSource);
if (bikeInfo == null)
{
// Response is not valid.
continue;
}
if (bikesDictionary.ContainsKey(bikeInfo.Id))
{
// Duplicates are not allowed.
Log.Error($"Duplicate bike with id {bikeInfo.Id} detected evaluating bikes available. Bike status is {bikeInfo.State.Value}.");
if (!duplicates.ContainsKey(bikeInfo.Id))
{
duplicates.Add(bikeInfo.Id, bikeInfo);
}
continue;
}
bikesDictionary.Add(bikeInfo.Id, bikeInfo);
}
}
// Get bikes from Copri/ file/ memory, ....
if (bikesOccupied != null)
{
foreach (var bikeInfoResponse in bikesOccupied)
{
BikeInfo bikeInfo = BikeInfoFactory.Create(
bikeInfoResponse,
mail,
dateTimeProvider,
dataSource);
if (bikeInfo == null)
{
continue;
}
if (bikesDictionary.ContainsKey(bikeInfo.Id))
{
// Duplicates are not allowed.
Log.Error($"Duplicate bike with id {bikeInfo.Id} detected evaluating bikes occupied. Bike status is {bikeInfo.State.Value}.");
if (!duplicates.ContainsKey(bikeInfo.Id))
{
duplicates.Add(bikeInfo.Id, bikeInfo);
}
continue;
}
bikesDictionary.Add(bikeInfo.Id, bikeInfo);
}
}
// Remove entries which are not unique.
foreach (var l_oDuplicate in duplicates)
{
bikesDictionary.Remove(l_oDuplicate.Key);
}
return new BikeCollection(bikesDictionary);
}
}
}

View file

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Serilog; using Serilog;
using TINK.Model.Bikes.BikeInfoNS.BC;
using TINK.Model.Bikes.BikeInfoNS.BikeNS; using TINK.Model.Bikes.BikeInfoNS.BikeNS;
using TINK.Model.MiniSurvey; using TINK.Model.MiniSurvey;
using TINK.Model.State; using TINK.Model.State;
@ -20,7 +21,10 @@ namespace TINK.Model.Connector.Updater
/// <summary> Creates a bike info object from copri response. </summary> /// <summary> Creates a bike info object from copri response. </summary>
/// <param name="bikeInfo">Copri response for a disposable bike. </param> /// <param name="bikeInfo">Copri response for a disposable bike. </param>
public static BikeInfo Create(BikeInfoAvailable bikeInfo) /// <param name="dataSource">Specifies the data source.</param>
public static BikeInfo Create(
BikeInfoAvailable bikeInfo,
DataSource dataSource)
{ {
if (bikeInfo == null) throw new ArgumentNullException(nameof(bikeInfo)); if (bikeInfo == null) throw new ArgumentNullException(nameof(bikeInfo));
@ -74,6 +78,7 @@ namespace TINK.Model.Connector.Updater
bikeInfo.GetTypeOfBike(), bikeInfo.GetTypeOfBike(),
bikeInfo.description), bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type), DriveFactory.Create(bikeInfo?.bike_type),
dataSource,
bikeInfo.station, bikeInfo.station,
new Bikes.BikeInfoNS.CopriLock.LockInfo.Builder { State = bikeInfo.GetCopriLockingState() }.Build(), new Bikes.BikeInfoNS.CopriLock.LockInfo.Builder { State = bikeInfo.GetCopriLockingState() }.Build(),
bikeInfo.GetState() == InUseStateEnum.FeedbackPending, bikeInfo.GetState() == InUseStateEnum.FeedbackPending,
@ -103,6 +108,7 @@ namespace TINK.Model.Connector.Updater
bikeInfo.GetTypeOfBike(), bikeInfo.GetTypeOfBike(),
bikeInfo.description), bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type), DriveFactory.Create(bikeInfo?.bike_type),
dataSource,
bikeInfo.GetBluetoothLockId(), bikeInfo.GetBluetoothLockId(),
bikeInfo.GetBluetoothLockGuid(), bikeInfo.GetBluetoothLockGuid(),
bikeInfo.station, bikeInfo.station,
@ -133,10 +139,12 @@ namespace TINK.Model.Connector.Updater
/// <param name="bikeInfo">Copri response. </param> /// <param name="bikeInfo">Copri response. </param>
/// <param name="mailAddress">Mail address of user.</param> /// <param name="mailAddress">Mail address of user.</param>
/// <param name="dateTimeProvider">Date and time provider function.</param> /// <param name="dateTimeProvider">Date and time provider function.</param>
/// <param name="dataSource">Specified the source of the data.</param>
public static BikeInfo Create( public static BikeInfo Create(
BikeInfoReservedOrBooked bikeInfo, BikeInfoReservedOrBooked bikeInfo,
string mailAddress, string mailAddress,
Func<DateTime> dateTimeProvider) Func<DateTime> dateTimeProvider,
DataSource dataSource)
{ {
if (bikeInfo == null) throw new ArgumentNullException(nameof(bikeInfo)); if (bikeInfo == null) throw new ArgumentNullException(nameof(bikeInfo));
@ -178,6 +186,7 @@ namespace TINK.Model.Connector.Updater
bikeInfo.GetTypeOfBike(), bikeInfo.GetTypeOfBike(),
bikeInfo.description), bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type), DriveFactory.Create(bikeInfo?.bike_type),
dataSource,
lockSerial, lockSerial,
lockGuid, lockGuid,
bikeInfo.GetUserKey(), bikeInfo.GetUserKey(),
@ -207,6 +216,7 @@ namespace TINK.Model.Connector.Updater
bikeInfo.GetTypeOfBike(), bikeInfo.GetTypeOfBike(),
bikeInfo.description), bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type), DriveFactory.Create(bikeInfo?.bike_type),
dataSource,
bikeInfo.GetFrom(), bikeInfo.GetFrom(),
mailAddress, mailAddress,
bikeInfo.station, bikeInfo.station,
@ -247,6 +257,7 @@ namespace TINK.Model.Connector.Updater
bikeInfo.GetTypeOfBike(), bikeInfo.GetTypeOfBike(),
bikeInfo.description), bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type), DriveFactory.Create(bikeInfo?.bike_type),
dataSource,
lockSerial, lockSerial,
bikeInfo.GetBluetoothLockGuid(), bikeInfo.GetBluetoothLockGuid(),
bikeInfo.GetUserKey(), bikeInfo.GetUserKey(),
@ -275,6 +286,7 @@ namespace TINK.Model.Connector.Updater
bikeInfo.GetTypeOfBike(), bikeInfo.GetTypeOfBike(),
bikeInfo.description), bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type), DriveFactory.Create(bikeInfo?.bike_type),
dataSource,
bikeInfo.GetIsDemo(), bikeInfo.GetIsDemo(),
bikeInfo.GetGroup(), bikeInfo.GetGroup(),
bikeInfo.station, bikeInfo.station,
@ -298,6 +310,7 @@ namespace TINK.Model.Connector.Updater
bikeInfo.GetTypeOfBike(), bikeInfo.GetTypeOfBike(),
bikeInfo.description), bikeInfo.description),
DriveFactory.Create(bikeInfo?.bike_type), DriveFactory.Create(bikeInfo?.bike_type),
DataSource.Copri,
bikeInfo.GetFrom(), bikeInfo.GetFrom(),
mailAddress, mailAddress,
bikeInfo.station, bikeInfo.station,

View file

@ -1,7 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Serilog; using Serilog;
using TINK.Model.Bikes; using TINK.Model.Bikes;
using TINK.Model.Bikes.BikeInfoNS.BC;
using TINK.Model.State; using TINK.Model.State;
using TINK.Model.Station; using TINK.Model.Station;
using TINK.Model.Station.Operator; using TINK.Model.Station.Operator;
@ -26,11 +27,8 @@ namespace TINK.Model.Connector.Updater
/// <param name="notifyLevel">Controls whether notify property changed events are fired or not.</param> /// <param name="notifyLevel">Controls whether notify property changed events are fired or not.</param>
public static void Load( public static void Load(
this IBikeInfoMutable bike, this IBikeInfoMutable bike,
Bikes.BikeInfoNS.BC.NotifyPropertyChangedLevel notifyLevel) NotifyPropertyChangedLevel notifyLevel)
{ => bike.State.Load(InUseStateEnum.Disposable, notifyLevel: notifyLevel);
bike.State.Load(InUseStateEnum.Disposable, notifyLevel: notifyLevel);
}
/// <summary> /// <summary>
/// Gets all statsion for station provider and add them into station list. /// Gets all statsion for station provider and add them into station list.
@ -126,7 +124,7 @@ namespace TINK.Model.Connector.Updater
this IBikeInfoMutable bike, this IBikeInfoMutable bike,
BikeInfoReservedOrBooked bikeInfo, BikeInfoReservedOrBooked bikeInfo,
string mailAddress, string mailAddress,
Bikes.BikeInfoNS.BC.NotifyPropertyChangedLevel notifyLevel = Bikes.BikeInfoNS.BC.NotifyPropertyChangedLevel.All) NotifyPropertyChangedLevel notifyLevel = NotifyPropertyChangedLevel.All)
{ {
if (bike is Bikes.BikeInfoNS.BluetoothLock.BikeInfoMutable btBikeInfo) if (bike is Bikes.BikeInfoNS.BluetoothLock.BikeInfoMutable btBikeInfo)
{ {
@ -170,113 +168,5 @@ namespace TINK.Model.Connector.Updater
} }
} }
/// <summary> Gets bikes available from copri server response.</summary>
/// <param name="bikesAvailableResponse">Response to create collection from.</param>
/// <returns>New collection of available bikes.</returns>
public static BikeCollection GetBikesAvailable(
this BikesAvailableResponse bikesAvailableResponse)
=> GetBikesAll(
bikesAvailableResponse?.bikes?.Values,
new BikesReservedOccupiedResponse()?.bikes_occupied?.Values, // There are no occupied bikes.
string.Empty,
() => DateTime.Now);
/// <summary> Gets bikes occupied from copri server response. </summary>
/// <param name="p_oBikesAvailable">Response to create bikes from.</param>
/// <returns>New collection of occupied bikes.</returns>
public static BikeCollection GetBikesOccupied(
this BikesReservedOccupiedResponse bikesOccupiedResponse,
string mail,
Func<DateTime> dateTimeProvider)
{
return GetBikesAll(
new BikesAvailableResponse()?.bikes?.Values,
bikesOccupiedResponse?.bikes_occupied?.Values,
mail,
dateTimeProvider);
}
/// <summary> Gets bikes occupied from copri server response. </summary>
/// <param name="bikesAvailable">Response to create bikes available from.</param>
/// <param name="bikesOccupied">Response to create bikes occupied from.</param>
/// <returns>New collection of occupied bikes.</returns>
public static BikeCollection GetBikesAll(
IEnumerable<BikeInfoAvailable> bikesAvailable,
IEnumerable<BikeInfoReservedOrBooked> bikesOccupied,
string mail,
Func<DateTime> dateTimeProvider)
{
var bikesDictionary = new Dictionary<string, BikeInfo>();
var duplicates = new Dictionary<string, BikeInfo>();
// Get bikes from Copri/ file/ memory, ....
if (bikesAvailable != null)
{
foreach (var bikeInfoResponse in bikesAvailable)
{
var bikeInfo = BikeInfoFactory.Create(bikeInfoResponse);
if (bikeInfo == null)
{
// Response is not valid.
continue;
}
if (bikesDictionary.ContainsKey(bikeInfo.Id))
{
// Duplicates are not allowed.
Log.Error($"Duplicate bike with id {bikeInfo.Id} detected evaluating bikes available. Bike status is {bikeInfo.State.Value}.");
if (!duplicates.ContainsKey(bikeInfo.Id))
{
duplicates.Add(bikeInfo.Id, bikeInfo);
}
continue;
}
bikesDictionary.Add(bikeInfo.Id, bikeInfo);
}
}
// Get bikes from Copri/ file/ memory, ....
if (bikesOccupied != null)
{
foreach (var bikeInfoResponse in bikesOccupied)
{
BikeInfo bikeInfo = BikeInfoFactory.Create(
bikeInfoResponse,
mail,
dateTimeProvider);
if (bikeInfo == null)
{
continue;
}
if (bikesDictionary.ContainsKey(bikeInfo.Id))
{
// Duplicates are not allowed.
Log.Error($"Duplicate bike with id {bikeInfo.Id} detected evaluating bikes occupied. Bike status is {bikeInfo.State.Value}.");
if (!duplicates.ContainsKey(bikeInfo.Id))
{
duplicates.Add(bikeInfo.Id, bikeInfo);
}
continue;
}
bikesDictionary.Add(bikeInfo.Id, bikeInfo);
}
}
// Remove entries which are not unique.
foreach (var l_oDuplicate in duplicates)
{
bikesDictionary.Remove(l_oDuplicate.Key);
}
return new BikeCollection(bikesDictionary);
}
} }
} }

View file

@ -671,6 +671,11 @@ namespace TINK.Model
{ {
new Version(3, 0, 356), new Version(3, 0, 356),
AppResources.ChangeLog3_0_231 AppResources.ChangeLog3_0_231
},
{
new Version(3, 0, 357),
AppResources.ChangeLog_3_0_357_MK_SB,
new List<AppFlavor> { AppFlavor.MeinKonrad, AppFlavor.ShareeBike }
}, },
}; };

View file

@ -747,6 +747,15 @@ namespace TINK.MultilingualResources {
} }
} }
/// <summary>
/// Looks up a localized string similar to You can only start or end a rent with network reception. Turn on mobile data or wifi and drag the page downward with the finger to refresh the page..
/// </summary>
public static string ChangeLog_3_0_357_MK_SB {
get {
return ResourceManager.GetString("ChangeLog_3_0_357_MK_SB", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to We have fixed some bugs. Enjoy the ride!. /// Looks up a localized string similar to We have fixed some bugs. Enjoy the ride!.
/// </summary> /// </summary>
@ -765,6 +774,15 @@ namespace TINK.MultilingualResources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Minor improvements..
/// </summary>
public static string ChangeLog_MinorImprovements {
get {
return ResourceManager.GetString("ChangeLog_MinorImprovements", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Software packages were updated.. /// Looks up a localized string similar to Software packages were updated..
/// </summary> /// </summary>
@ -1840,6 +1858,15 @@ namespace TINK.MultilingualResources {
} }
} }
/// <summary>
/// Looks up a localized string similar to There are currently no bicycles available at this station..
/// </summary>
public static string MarkingBikesAtStationNoBikesAvailable {
get {
return ResourceManager.GetString("MarkingBikesAtStationNoBikesAvailable", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Station id: {0}. /// Looks up a localized string similar to Station id: {0}.
/// </summary> /// </summary>
@ -1930,6 +1957,15 @@ namespace TINK.MultilingualResources {
} }
} }
/// <summary>
/// Looks up a localized string similar to No network, data is outdated..
/// </summary>
public static string MarkingDataIsFromCache {
get {
return ResourceManager.GetString("MarkingDataIsFromCache", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Charging level: {0}/{1} bars. /// Looks up a localized string similar to Charging level: {0}/{1} bars.
/// </summary> /// </summary>
@ -2147,6 +2183,15 @@ namespace TINK.MultilingualResources {
} }
} }
/// <summary>
/// Looks up a localized string similar to There are currently no bicycles reserved/booked on user {0}..
/// </summary>
public static string MarkingMyBikesNoBikesReservedRented {
get {
return ResourceManager.GetString("MarkingMyBikesNoBikesReservedRented", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Bike is ok. /// Looks up a localized string similar to Bike is ok.
/// </summary> /// </summary>
@ -2821,6 +2866,15 @@ namespace TINK.MultilingualResources {
} }
} }
/// <summary>
/// Looks up a localized string similar to Information.
/// </summary>
public static string MessageTitleInformation {
get {
return ResourceManager.GetString("MessageTitleInformation", resourceCulture);
}
}
/// <summary> /// <summary>
/// Looks up a localized string similar to Warning. /// Looks up a localized string similar to Warning.
/// </summary> /// </summary>

View file

@ -1114,4 +1114,22 @@ Probieren Sie es aus!</value>
<data name="ChangeLog_3_0_355_MK_SB_iOS" xml:space="preserve"> <data name="ChangeLog_3_0_355_MK_SB_iOS" xml:space="preserve">
<value>Bluetooth-Kommunikation verbessert.</value> <value>Bluetooth-Kommunikation verbessert.</value>
</data> </data>
<data name="MarkingDataIsFromCache" xml:space="preserve">
<value>Kein Netz, Daten sind veraltet.</value>
</data>
<data name="MarkingBikesAtStationNoBikesAvailable" xml:space="preserve">
<value>Momentan sind keine Fahrräder an dieser Station verfügbar.</value>
</data>
<data name="MarkingMyBikesNoBikesReservedRented" xml:space="preserve">
<value>Momentan sind keine Fahrräder auf Benutzer {0} reserviert/ gebucht.</value>
</data>
<data name="MessageTitleInformation" xml:space="preserve">
<value>Information</value>
</data>
<data name="ChangeLog_3_0_357_MK_SB" xml:space="preserve">
<value>Sie können eine Miete nur bei Netzempfang beginnen oder beenden. Schalten Sie mobile Daten oder WLAN ein und ziehen Sie die Seite mit dem Finger nach unten, um Ihre Ansicht zu aktualisieren.</value>
</data>
<data name="ChangeLog_MinorImprovements" xml:space="preserve">
<value>Kleine Verbesserungen.</value>
</data>
</root> </root>

View file

@ -1204,4 +1204,22 @@ Try it out!</value>
<data name="ChangeLog_3_0_355_MK_SB_iOS" xml:space="preserve"> <data name="ChangeLog_3_0_355_MK_SB_iOS" xml:space="preserve">
<value>Bluetooth communication improved.</value> <value>Bluetooth communication improved.</value>
</data> </data>
<data name="MarkingDataIsFromCache" xml:space="preserve">
<value>No network, data is outdated.</value>
</data>
<data name="MarkingBikesAtStationNoBikesAvailable" xml:space="preserve">
<value>There are currently no bicycles available at this station.</value>
</data>
<data name="MarkingMyBikesNoBikesReservedRented" xml:space="preserve">
<value>There are currently no bicycles reserved/booked on user {0}.</value>
</data>
<data name="MessageTitleInformation" xml:space="preserve">
<value>Information</value>
</data>
<data name="ChangeLog_3_0_357_MK_SB" xml:space="preserve">
<value>You can only start or end a rent with network reception. Turn on mobile data or wifi and drag the page downward with the finger to refresh the page.</value>
</data>
<data name="ChangeLog_MinorImprovements" xml:space="preserve">
<value>Minor improvements.</value>
</data>
</root> </root>

View file

@ -1524,6 +1524,30 @@ Probieren Sie es aus!</target>
<source>Bluetooth communication improved.</source> <source>Bluetooth communication improved.</source>
<target state="translated">Bluetooth-Kommunikation verbessert.</target> <target state="translated">Bluetooth-Kommunikation verbessert.</target>
</trans-unit> </trans-unit>
<trans-unit id="MarkingDataIsFromCache" translate="yes" xml:space="preserve">
<source>No network, data is outdated.</source>
<target state="translated">Kein Netz, Daten sind veraltet.</target>
</trans-unit>
<trans-unit id="MarkingBikesAtStationNoBikesAvailable" translate="yes" xml:space="preserve">
<source>There are currently no bicycles available at this station.</source>
<target state="translated">Momentan sind keine Fahrräder an dieser Station verfügbar.</target>
</trans-unit>
<trans-unit id="MarkingMyBikesNoBikesReservedRented" translate="yes" xml:space="preserve">
<source>There are currently no bicycles reserved/booked on user {0}.</source>
<target state="translated">Momentan sind keine Fahrräder auf Benutzer {0} reserviert/ gebucht.</target>
</trans-unit>
<trans-unit id="MessageTitleInformation" translate="yes" xml:space="preserve">
<source>Information</source>
<target state="translated">Information</target>
</trans-unit>
<trans-unit id="ChangeLog_3_0_357_MK_SB" translate="yes" xml:space="preserve">
<source>You can only start or end a rent with network reception. Turn on mobile data or wifi and drag the page downward with the finger to refresh the page.</source>
<target state="translated">Sie können eine Miete nur bei Netzempfang beginnen oder beenden. Schalten Sie mobile Daten oder WLAN ein und ziehen Sie die Seite mit dem Finger nach unten, um Ihre Ansicht zu aktualisieren.</target>
</trans-unit>
<trans-unit id="ChangeLog_MinorImprovements" translate="yes" xml:space="preserve">
<source>Minor improvements.</source>
<target state="translated">Kleine Verbesserungen.</target>
</trans-unit>
</group> </group>
</body> </body>
</file> </file>

View file

@ -12,7 +12,7 @@ namespace TINK.Repository.Request
public class RequestBuilder : IRequestBuilder public class RequestBuilder : IRequestBuilder
{ {
/// <summary> Constructs a object for building requests. </summary> /// <summary> Constructs a object for building requests. </summary>
/// <param name="merchantId"></param> /// <param name="merchantId">Holds the id denoting the merchant.</param>
/// <param name="uiIsoLangugageName">Two letter ISO language name.</param> /// <param name="uiIsoLangugageName">Two letter ISO language name.</param>
public RequestBuilder( public RequestBuilder(
string merchantId, string merchantId,
@ -22,12 +22,12 @@ namespace TINK.Repository.Request
? merchantId ? merchantId
: throw new ArgumentException("Merchant id must not be null.", nameof(merchantId)); : throw new ArgumentException("Merchant id must not be null.", nameof(merchantId));
UiIsoLanguageNameParameter = RequestBuilderHelper.GetLanguageParameter(uiIsoLangugageName); UiIsoLanguageNameParameter = RequestBuilderHelper.GetLanguageParameter(WebUtility.UrlEncode(uiIsoLangugageName));
AuthCookieParameter = $"&authcookie={MerchantId}"; AuthCookieParameter = $"&authcookie={WebUtility.UrlEncode(MerchantId)}";
} }
/// <summary> Parameter specifying current ui language. </summary> /// <summary>Holds the id denoting the merchant.</summary>
public string MerchantId { get; } public string MerchantId { get; }
/// <summary> Holds the session cookie if a user is logged in. </summary> /// <summary> Holds the session cookie if a user is logged in. </summary>
@ -52,7 +52,7 @@ namespace TINK.Repository.Request
$"&merchant_id={MerchantId}" + $"&merchant_id={MerchantId}" +
$"&user_id={WebUtility.UrlEncode(mailAddress)}" + $"&user_id={WebUtility.UrlEncode(mailAddress)}" +
$"&user_pw={WebUtility.UrlEncode(password)}" + $"&user_pw={WebUtility.UrlEncode(password)}" +
$"&hw_id={deviceId}" + $"&hw_id={WebUtility.UrlEncode(deviceId)}" +
UiIsoLanguageNameParameter; UiIsoLanguageNameParameter;
/// <summary> Logs user out. </summary> /// <summary> Logs user out. </summary>

View file

@ -15,7 +15,7 @@ namespace TINK.Repository.Request
public class RequestBuilderLoggedIn : IRequestBuilder public class RequestBuilderLoggedIn : IRequestBuilder
{ {
/// <summary> Constructs a object for building requests. </summary> /// <summary> Constructs a object for building requests. </summary>
/// <param name="merchantId"></param> /// <param name="merchantId">Holds the id denoting the merchant.</param>
/// <param name="uiIsoLangugageName">Two letter ISO language name.</param> /// <param name="uiIsoLangugageName">Two letter ISO language name.</param>
public RequestBuilderLoggedIn( public RequestBuilderLoggedIn(
string merchantId, string merchantId,
@ -30,12 +30,12 @@ namespace TINK.Repository.Request
? sessionCookie ? sessionCookie
: throw new ArgumentException("Session cookie must not be null.", nameof(sessionCookie)); : throw new ArgumentException("Session cookie must not be null.", nameof(sessionCookie));
UiIsoLanguageNameParameter = RequestBuilderHelper.GetLanguageParameter(uiIsoLangugageName); UiIsoLanguageNameParameter = RequestBuilderHelper.GetLanguageParameter(WebUtility.UrlEncode(uiIsoLangugageName));
AuthCookieParameter = $"&authcookie={SessionCookie}{MerchantId}"; AuthCookieParameter = $"&authcookie={WebUtility.UrlEncode(SessionCookie)}{WebUtility.UrlEncode(MerchantId)}";
} }
/// <summary> Holds the id denoting the merchant (TINK app). </summary> /// <summary> Holds the id denoting the merchant. </summary>
public string MerchantId { get; } public string MerchantId { get; }
/// <summary> Holds the session cookie if a user is logged in. </summary> /// <summary> Holds the session cookie if a user is logged in. </summary>
@ -268,25 +268,42 @@ namespace TINK.Repository.Request
UiIsoLanguageNameParameter; UiIsoLanguageNameParameter;
} }
/// <summary>
/// Gets bike id parameter.
/// </summary>
/// <param name="bikeId">Id of bike.</param>
/// <returns>bike id parameter in a format which is urlencode invariant.</returns>
private static string GetBikeIdParameter(string bikeId) private static string GetBikeIdParameter(string bikeId)
=> $"&bike={bikeId}"; => $"&bike={WebUtility.UrlEncode(bikeId)}";
/// <summary>
/// Gets parameter holding lock state or null if state is unknown.
/// </summary>
/// <param name="lockState">Null or state of lock.</param>
/// <returns>Lock state in a format which is urlencode invariant.</returns>
private static string GetLockStateParameter(lock_state? lockState) private static string GetLockStateParameter(lock_state? lockState)
=> lockState.HasValue ? $"&lock_state={lockState}" : string.Empty; => lockState.HasValue ? $"&lock_state={lockState}" : string.Empty;
/// <summary> /// <summary>
/// Gets the battery level percentage parameter if percentage is not NaN an empty string otherwise. /// Gets the battery level percentage parameter if percentage is not NaN an empty string otherwise.
/// </summary> /// </summary>
/// <returns>Gets battery percentage parameters in a format which is urlencode invariant or an empty string if percentage percentge is NaN.</returns>
private static string GetBatteryPercentageParameters(double batteryPercentage) => !double.IsNaN(batteryPercentage) private static string GetBatteryPercentageParameters(double batteryPercentage) => !double.IsNaN(batteryPercentage)
? $"&voltage={batteryPercentage.ToString(CultureInfo.InvariantCulture)}" ? $"&voltage={batteryPercentage.ToString(CultureInfo.InvariantCulture)}"
: string.Empty; : string.Empty;
/// <summary>
/// Gets the version info parameter or an empty string if version info is not available.
/// </summary>
/// <param name="versionInfo">Lock version info.</param>
/// <returns>Version info in a format which is urlencode invariant or empty. </returns>
private static string GetVersionInfoParameter(IVersionInfo versionInfo) => versionInfo?.FirmwareVersion > 0 || versionInfo?.HardwareVersion > 0 || versionInfo?.LockVersion > 0 private static string GetVersionInfoParameter(IVersionInfo versionInfo) => versionInfo?.FirmwareVersion > 0 || versionInfo?.HardwareVersion > 0 || versionInfo?.LockVersion > 0
? $"&firmware=HW%20{versionInfo.HardwareVersion}%3BFW%20{versionInfo.FirmwareVersion}%3BLock%20{versionInfo.LockVersion}" ? $"&firmware=HW%20{versionInfo.HardwareVersion}%3BFW%20{versionInfo.FirmwareVersion}%3BLock%20{versionInfo.LockVersion}"
: string.Empty; : string.Empty;
/// <summary> Gets the geolocation parameter. </summary> /// <summary> Gets the geolocation parameter. </summary>
/// <param name="geolocation">Geolocation or null.</param> /// <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>
private static string GetLocationParameters(LocationDto geolocation) private static string GetLocationParameters(LocationDto geolocation)
{ {
if (geolocation == null) if (geolocation == null)
@ -299,14 +316,14 @@ namespace TINK.Repository.Request
} }
/// <summary> Gets the geolocation parameter. </summary> /// <summary> Gets the geolocation parameter. </summary>
/// <param name="geolocation">Geolocation or null.</param> /// <returns>in a format which is urlencode invariant.</returns>
private static string GetSmartDeviceParameters(ISmartDevice smartDevice) private static string GetSmartDeviceParameters(ISmartDevice smartDevice)
=> smartDevice != null => smartDevice != null
? $"{(!string.IsNullOrEmpty(smartDevice.Manufacturer) ? $"&user_device_manufaturer={smartDevice.Manufacturer})" : string.Empty)}" + ? $"{(!string.IsNullOrEmpty(smartDevice.Manufacturer) ? $"&user_device_manufaturer={WebUtility.UrlEncode(smartDevice.Manufacturer)})" : string.Empty)}" +
$"{(!string.IsNullOrEmpty(smartDevice.Model) ? $"&user_device_model={smartDevice.Model}" : string.Empty)}" + $"{(!string.IsNullOrEmpty(smartDevice.Model) ? $"&user_device_model={WebUtility.UrlEncode(smartDevice.Model)}" : string.Empty)}" +
$"{(!string.IsNullOrEmpty(smartDevice.Platform.ToString()) ? $"&user_device_platform={smartDevice.Platform.ToString()}" : string.Empty)}" + $"{(!string.IsNullOrEmpty(smartDevice.Platform.ToString()) ? $"&user_device_platform={WebUtility.UrlEncode(smartDevice.Platform.ToString())}" : string.Empty)}" +
$"{(!string.IsNullOrEmpty(smartDevice.VersionText) ? $"&user_device_version={smartDevice.VersionText}" : string.Empty)}" + $"{(!string.IsNullOrEmpty(smartDevice.VersionText) ? $"&user_device_version={WebUtility.UrlEncode(smartDevice.VersionText)}" : string.Empty)}" +
$"{(!string.IsNullOrEmpty(smartDevice.Identifier) ? $"&user_device_id={smartDevice.Identifier}" : string.Empty)}" $"{(!string.IsNullOrEmpty(smartDevice.Identifier) ? $"&user_device_id={WebUtility.UrlEncode(smartDevice.Identifier)}" : string.Empty)}"
: string.Empty; : string.Empty;
/// <summary> /// <summary>

View file

@ -1,4 +1,4 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using TINK.Model.Connector; using TINK.Model.Connector;
using TINK.Model.Device; using TINK.Model.Device;
@ -65,6 +65,8 @@ namespace TINK.ViewModel.Bikes.Bike.BC
viewService, viewService,
bikesViewModel, bikesViewModel,
ActiveUser); ActiveUser);
selectedBike.PropertyChanged += (sender, ev) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsButtonVisible)));
} }
/// <summary> /// <summary>
@ -94,7 +96,9 @@ namespace TINK.ViewModel.Bikes.Bike.BC
} }
/// <summary> Gets visiblity of the copri command button. </summary> /// <summary> Gets visiblity of the copri command button. </summary>
public bool IsButtonVisible => RequestHandler.IsButtonVisible; public bool IsButtonVisible
=> RequestHandler.IsButtonVisible
&& Bike.DataSource == Model.Bikes.BikeInfoNS.BC.DataSource.Copri /* do not show button if data is from cache */ ;
/// <summary> Gets the text of the copri command button. </summary> /// <summary> Gets the text of the copri command button. </summary>
public string ButtonText => RequestHandler.ButtonText; public string ButtonText => RequestHandler.ButtonText;

View file

@ -1,4 +1,4 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -39,6 +39,12 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock
string lastStateText = null, string lastStateText = null,
Xamarin.Forms.Color? lastStateColor = null) Xamarin.Forms.Color? lastStateColor = null)
{ {
if (IsDataFromCache != IsDataFromCache)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsDataFromCache)));
}
if (lastHandler.ButtonText != ButtonText) if (lastHandler.ButtonText != ButtonText)
{ {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ButtonText))); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(ButtonText)));
@ -121,6 +127,15 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock
LockService = lockService LockService = lockService
?? throw new ArgumentException($"Can not instantiate {this.GetType().Name}-object. Parameter {nameof(lockService)} can not be null."); ?? throw new ArgumentException($"Can not instantiate {this.GetType().Name}-object. Parameter {nameof(lockService)} can not be null.");
selectedBike.PropertyChanged += (sender, ev) =>
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsButtonVisible)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsLockitButtonVisible)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsDataFromCache)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(OnButtonClicked)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(OnLockitButtonClicked)));
};
} }
/// <summary> /// <summary>
@ -147,22 +162,28 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock
} }
/// <summary> Gets visiblity of the copri command button. </summary> /// <summary> Gets visiblity of the copri command button. </summary>
public bool IsButtonVisible => RequestHandler.IsButtonVisible; public bool IsButtonVisible
=> RequestHandler.IsButtonVisible;
/// <summary> Gets the text of the copri command button. </summary> /// <summary> Gets the text of the copri command button. </summary>
public string ButtonText => RequestHandler.ButtonText; public string ButtonText => RequestHandler.ButtonText;
/// <summary> Gets visiblity of the ILockIt command button. </summary> /// <summary> Gets visiblity of the ILockIt command button. </summary>
public bool IsLockitButtonVisible => RequestHandler.IsLockitButtonVisible; public bool IsLockitButtonVisible
=> RequestHandler.IsLockitButtonVisible;
/// <summary> Gets the text of the ILockIt command button. </summary> /// <summary> Gets the text of the ILockIt command button. </summary>
public string LockitButtonText => RequestHandler.LockitButtonText; public string LockitButtonText => RequestHandler.LockitButtonText;
/// <summary> True if Data is from Cache. </summary>
public bool IsDataFromCache
=> Bike.DataSource == Model.Bikes.BikeInfoNS.BC.DataSource.Cache;
/// <summary> Processes request to perform a copri action (reserve bike and cancel reservation). </summary> /// <summary> Processes request to perform a copri action (reserve bike and cancel reservation). </summary>
public System.Windows.Input.ICommand OnButtonClicked => new Xamarin.Forms.Command(async () => await ClickButton(RequestHandler.HandleRequestOption1())); public System.Windows.Input.ICommand OnButtonClicked => new Xamarin.Forms.Command(async () => await ClickButton(RequestHandler.HandleRequestOption1()), () => !IsDataFromCache);
/// <summary> Processes request to perform a ILockIt action (unlock bike and lock bike). </summary> /// <summary> Processes request to perform a ILockIt action (unlock bike and lock bike). </summary>
public System.Windows.Input.ICommand OnLockitButtonClicked => new Xamarin.Forms.Command(async () => await ClickButton(RequestHandler.HandleRequestOption2())); public System.Windows.Input.ICommand OnLockitButtonClicked => new Xamarin.Forms.Command(async () => await ClickButton(RequestHandler.HandleRequestOption2()), () => !IsDataFromCache);
/// <summary> Processes request to perform a copri action (reserve bike and cancel reservation). </summary> /// <summary> Processes request to perform a copri action (reserve bike and cancel reservation). </summary>
private async Task ClickButton(Task<IRequestHandler> handleRequest) private async Task ClickButton(Task<IRequestHandler> handleRequest)

View file

@ -584,6 +584,7 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
AppResources.MessageAnswerOk); AppResources.MessageAnswerOk);
} }
// Update current state from exception
SelectedBike.LockInfo.State = exception is StateAwareException stateAwareException SelectedBike.LockInfo.State = exception is StateAwareException stateAwareException
? stateAwareException.State ? stateAwareException.State
: LockingState.UnknownDisconnected; : LockingState.UnknownDisconnected;

View file

@ -1,4 +1,4 @@
using System; using System;
using System.ComponentModel; using System.ComponentModel;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -107,6 +107,12 @@ namespace TINK.ViewModel.Bikes.Bike.CopriLock
selectedBike.State.Value, selectedBike.State.Value,
viewService, viewService,
bikesViewModel); bikesViewModel);
selectedBike.PropertyChanged += (sender, ev) =>
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsButtonVisible)));
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsLockitButtonVisible)));
};
} }
/// <summary> /// <summary>
@ -131,13 +137,17 @@ namespace TINK.ViewModel.Bikes.Bike.CopriLock
} }
/// <summary> Gets visiblity of the copri command button. </summary> /// <summary> Gets visiblity of the copri command button. </summary>
public bool IsButtonVisible => RequestHandler.IsButtonVisible; public bool IsButtonVisible
=> RequestHandler.IsButtonVisible
&& Bike.DataSource == Model.Bikes.BikeInfoNS.BC.DataSource.Copri /* do not show button if data is from cache */ ;
/// <summary> Gets the text of the copri command button. </summary> /// <summary> Gets the text of the copri command button. </summary>
public string ButtonText => RequestHandler.ButtonText; public string ButtonText => RequestHandler.ButtonText;
/// <summary> Gets visiblity of the ILockIt command button. </summary> /// <summary> Gets visiblity of the ILockIt command button. </summary>
public bool IsLockitButtonVisible => RequestHandler.IsLockitButtonVisible; public bool IsLockitButtonVisible
=> RequestHandler.IsLockitButtonVisible
&& Bike.DataSource == Model.Bikes.BikeInfoNS.BC.DataSource.Copri /* do not show button if data is from cache */ ;
/// <summary> Gets the text of the ILockIt command button. </summary> /// <summary> Gets the text of the ILockIt command button. </summary>
public string LockitButtonText => RequestHandler.LockitButtonText; public string LockitButtonText => RequestHandler.LockitButtonText;

View file

@ -327,11 +327,11 @@ namespace TINK.ViewModel.Bikes
Log.ForContext<BikesViewModel>().Debug($"Switch value of {nameof(IsIdle)} to {value}."); Log.ForContext<BikesViewModel>().Debug($"Switch value of {nameof(IsIdle)} to {value}.");
isIdle = value; isIdle = value;
base.OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsIdle))); base.OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsIdle)));
base.OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsRunning))); base.OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsProcessWithRunningProcessView)));
} }
} }
public bool IsRunning => !isIdle; public bool IsProcessWithRunningProcessView => !isIdle;
/// <summary> Holds info about current action. </summary> /// <summary> Holds info about current action. </summary>
private string actionText; private string actionText;
@ -479,5 +479,6 @@ namespace TINK.ViewModel.Bikes
/// </summary> /// </summary>
public virtual async Task OnDisappearing() public virtual async Task OnDisappearing()
=> await m_oViewUpdateManager.StopUpdatePeridically(); => await m_oViewUpdateManager.StopUpdatePeridically();
} }
} }

View file

@ -23,6 +23,7 @@ using TINK.Settings;
using TINK.View; using TINK.View;
using TINK.ViewModel.Bikes; using TINK.ViewModel.Bikes;
using Xamarin.Forms; using Xamarin.Forms;
using Command = Xamarin.Forms.Command;
namespace TINK.ViewModel.BikesAtStation namespace TINK.ViewModel.BikesAtStation
{ {
@ -36,6 +37,22 @@ namespace TINK.ViewModel.BikesAtStation
/// </summary> /// </summary>
private IStation Station { get; } private IStation Station { get; }
/// <summary>
/// True if ListView of Bikes is refreshing after user pulled;
/// </summary>
private bool _isRefreshing = false;
public bool IsRefreshing
{
get { return _isRefreshing; }
set
{
_isRefreshing = value;
OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsRefreshing)));
}
}
public Command RefreshCommand { get; }
/// <summary> /// <summary>
/// Constructs bike collection view model. /// Constructs bike collection view model.
/// </summary> /// </summary>
@ -75,11 +92,23 @@ namespace TINK.ViewModel.BikesAtStation
? string.Format(AppResources.MarkingBikesAtStationStationId, Station.Id) ? string.Format(AppResources.MarkingBikesAtStationStationId, Station.Id)
: string.Empty; : string.Empty;
/// <summary>
/// Holds what should be executed on pull to refresh
/// </summary>
RefreshCommand = new Command(async () => {
IsRefreshing = true;
await OnAppearing();
IsRefreshing = false;
});
CollectionChanged += (sender, eventargs) => CollectionChanged += (sender, eventargs) =>
{ {
OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsNoBikesAtStationVisible))); OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsNoBikesAtStationVisible)));
OnPropertyChanged(new PropertyChangedEventArgs(nameof(NoBikesAtStationText))); OnPropertyChanged(new PropertyChangedEventArgs(nameof(NoBikesAtStationText)));
OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsLoginRequiredHintVisible))); OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsLoginRequiredHintVisible)));
OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsRefreshing)));
}; };
} }
@ -131,7 +160,7 @@ namespace TINK.ViewModel.BikesAtStation
get get
{ {
return IsNoBikesAtStationVisible return IsNoBikesAtStationVisible
? $"Momentan sind keine Fahrräder an dieser Station verfügbar." ? AppResources.MarkingBikesAtStationNoBikesAvailable
: string.Empty; : string.Empty;
} }
} }
@ -215,6 +244,8 @@ namespace TINK.ViewModel.BikesAtStation
/// </summary> /// </summary>
public async Task OnAppearing() public async Task OnAppearing()
{ {
IsIdle = false;
Log.ForContext<BikesAtStationPageViewModel>().Information($"Bikes at station {Station.StationName} is appearing, either due to tap on a station or to app being shown again."); Log.ForContext<BikesAtStationPageViewModel>().Information($"Bikes at station {Station.StationName} is appearing, either due to tap on a station or to app being shown again.");
ActionText = AppResources.ActivityTextOneMomentPlease; ActionText = AppResources.ActivityTextOneMomentPlease;
@ -334,7 +365,7 @@ namespace TINK.ViewModel.BikesAtStation
} }
/// <summary> Create task which updates my bike view model.</summary> /// <summary> Create task which updates my bike view model.</summary>
private void UpdateTask() public void UpdateTask()
{ {
PostAction( PostAction(
unused => unused =>

View file

@ -271,7 +271,7 @@ namespace TINK.ViewModel.Contact
{ {
try try
{ {
IsRunning = true; IsProcessWithRunningProcessView = true;
// Process map page. // Process map page.
Log.ForContext<SelectStationPageViewModel>().Information( Log.ForContext<SelectStationPageViewModel>().Information(
@ -300,7 +300,7 @@ namespace TINK.ViewModel.Contact
// User decided to give access to locations permissions. // User decided to give access to locations permissions.
PermissionsService.OpenAppSettings(); PermissionsService.OpenAppSettings();
ActionText = ""; ActionText = "";
IsRunning = false; IsProcessWithRunningProcessView = false;
IsMapPageEnabled = true; IsMapPageEnabled = true;
return; return;
} }
@ -406,14 +406,14 @@ namespace TINK.ViewModel.Contact
Exception = resultStationsAndBikes.Exception; Exception = resultStationsAndBikes.Exception;
ActionText = ""; ActionText = "";
IsRunning = false; IsProcessWithRunningProcessView = false;
IsMapPageEnabled = true; IsMapPageEnabled = true;
} }
catch (Exception l_oException) catch (Exception l_oException)
{ {
Log.ForContext<SelectStationPageViewModel>().Error($"An error occurred opening select station page.\r\n{l_oException.Message}"); Log.ForContext<SelectStationPageViewModel>().Error($"An error occurred opening select station page.\r\n{l_oException.Message}");
IsRunning = false; IsProcessWithRunningProcessView = false;
await ViewService.DisplayAlert( await ViewService.DisplayAlert(
"Fehler", "Fehler",
@ -582,22 +582,22 @@ namespace TINK.ViewModel.Contact
} }
/// <summary> Used to block more than on copri requests at a given time.</summary> /// <summary> Used to block more than on copri requests at a given time.</summary>
private bool isRunning = false; private bool isProcessWithRunningProcessView = false;
/// <summary> /// <summary>
/// True if any action can be performed (request and cancel request) /// True if any action can be performed (request and cancel request)
/// </summary> /// </summary>
public bool IsRunning public bool IsProcessWithRunningProcessView
{ {
get => isRunning; get => isProcessWithRunningProcessView;
set set
{ {
if (value == isRunning) if (value == isProcessWithRunningProcessView)
return; return;
Log.ForContext<SelectStationPageViewModel>().Debug($"Switch value of {nameof(isRunning)} to {value}."); Log.ForContext<SelectStationPageViewModel>().Debug($"Switch value of {nameof(isProcessWithRunningProcessView)} to {value}.");
isRunning = value; isProcessWithRunningProcessView = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsRunning))); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsProcessWithRunningProcessView)));
} }
} }

View file

@ -26,6 +26,7 @@ using TINK.Settings;
using TINK.View; using TINK.View;
using TINK.ViewModel.Bikes; using TINK.ViewModel.Bikes;
using Xamarin.Forms; using Xamarin.Forms;
using Command = Xamarin.Forms.Command;
namespace TINK.ViewModel.FindBike namespace TINK.ViewModel.FindBike
{ {
@ -79,6 +80,22 @@ namespace TINK.ViewModel.FindBike
/// <summary> Holds the stations to get station names form station ids. </summary> /// <summary> Holds the stations to get station names form station ids. </summary>
private IEnumerable<IStation> Stations { get; } private IEnumerable<IStation> Stations { get; }
/// <summary>
/// True if ListView of Bikes is refreshing after user pulled;
/// </summary>
private bool _isRefreshing = false;
public bool IsRefreshing
{
get { return _isRefreshing; }
set
{
_isRefreshing = value;
OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsRefreshing)));
}
}
public Command RefreshCommand { get; }
/// <summary> /// <summary>
/// Constructs bike collection view model in case information about occupied bikes is available. /// Constructs bike collection view model in case information about occupied bikes is available.
/// </summary> /// </summary>
@ -118,6 +135,17 @@ namespace TINK.ViewModel.FindBike
}; };
Stations = stations ?? throw new ArgumentException(nameof(stations)); Stations = stations ?? throw new ArgumentException(nameof(stations));
/// <summary>
/// Holds what should be executed on pull to refresh
/// </summary>
RefreshCommand = new Command(async () => {
IsRefreshing = true;
await OnAppearing();
IsRefreshing = false;
});
} }
/// <summary> /// <summary>

View file

@ -313,7 +313,7 @@ namespace TINK.ViewModel.Map
var status = await PermissionsService.RequestAsync(); var status = await PermissionsService.RequestAsync();
} }
IsRunning = true; IsProcessWithRunningProcessView = true;
IsNavBarVisible = false; IsNavBarVisible = false;
// Process map page. // Process map page.
Polling = TinkApp.Polling; Polling = TinkApp.Polling;
@ -332,11 +332,13 @@ namespace TINK.ViewModel.Map
TinkApp.Stations = resultStationsAndBikes.Response.StationsAll; TinkApp.Stations = resultStationsAndBikes.Response.StationsAll;
TinkApp.ResourceUrls = resultStationsAndBikes.GeneralData.ResourceUrls; TinkApp.ResourceUrls = resultStationsAndBikes.GeneralData.ResourceUrls;
// Check if there is a message from COPRI ("merchant_message") to be shown to user.
if (!string.IsNullOrEmpty(resultStationsAndBikes?.GeneralData?.MerchantMessage) if (!string.IsNullOrEmpty(resultStationsAndBikes?.GeneralData?.MerchantMessage)
&& !WasMerchantMessageAlreadyShown) && !WasMerchantMessageAlreadyShown)
{ {
// Show COPRI message once.
await ViewService.DisplayAlert( await ViewService.DisplayAlert(
"Information", AppResources.MessageTitleInformation,
resultStationsAndBikes.GeneralData.MerchantMessage, resultStationsAndBikes.GeneralData.MerchantMessage,
AppResources.MessageAnswerOk); AppResources.MessageAnswerOk);
WasMerchantMessageAlreadyShown = true; WasMerchantMessageAlreadyShown = true;
@ -404,7 +406,7 @@ namespace TINK.ViewModel.Map
Exception = resultStationsAndBikes.Exception; Exception = resultStationsAndBikes.Exception;
ActionText = ""; ActionText = "";
IsRunning = false; IsProcessWithRunningProcessView = false;
IsNavBarVisible = true; IsNavBarVisible = true;
IsMapPageEnabled = true; IsMapPageEnabled = true;
} }
@ -412,7 +414,7 @@ namespace TINK.ViewModel.Map
{ {
Log.ForContext<MapPageViewModel>().Error($"An error occurred showing bike stations page.\r\n{l_oException.Message}"); Log.ForContext<MapPageViewModel>().Error($"An error occurred showing bike stations page.\r\n{l_oException.Message}");
IsRunning = false; IsProcessWithRunningProcessView = false;
IsNavBarVisible = true; IsNavBarVisible = true;
await ViewService.DisplayAlert( await ViewService.DisplayAlert(
@ -541,7 +543,7 @@ namespace TINK.ViewModel.Map
// User decided to give access to locations permissions. // User decided to give access to locations permissions.
PermissionsService.OpenAppSettings(); PermissionsService.OpenAppSettings();
ActionText = ""; ActionText = "";
IsRunning = false; IsProcessWithRunningProcessView = false;
IsNavBarVisible = true; IsNavBarVisible = true;
IsMapPageEnabled = true; IsMapPageEnabled = true;
} }
@ -782,22 +784,22 @@ namespace TINK.ViewModel.Map
} }
/// <summary> Used to block more than on copri requests at a given time.</summary> /// <summary> Used to block more than on copri requests at a given time.</summary>
private bool isRunning = false; private bool isProcessWithRunningProcessView = false;
/// <summary> /// <summary>
/// True if any action can be performed (request and cancel request) /// True if any action can be performed (request and cancel request)
/// </summary> /// </summary>
public bool IsRunning public bool IsProcessWithRunningProcessView
{ {
get => isRunning; get => isProcessWithRunningProcessView;
set set
{ {
if (value == isRunning) if (value == isProcessWithRunningProcessView)
return; return;
Log.ForContext<MapPageViewModel>().Debug($"Switch value of {nameof(isRunning)} to {value}."); Log.ForContext<MapPageViewModel>().Debug($"Switch value of {nameof(isProcessWithRunningProcessView)} to {value}.");
isRunning = value; isProcessWithRunningProcessView = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsRunning))); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsProcessWithRunningProcessView)));
} }
} }
@ -900,7 +902,7 @@ namespace TINK.ViewModel.Map
try try
{ {
IsMapPageEnabled = false; IsMapPageEnabled = false;
IsRunning = true; IsProcessWithRunningProcessView = true;
IsNavBarVisible = false; IsNavBarVisible = false;
Log.ForContext<MapPageViewModel>().Information($"Request to toggle to \"{selectedFilter}\"."); Log.ForContext<MapPageViewModel>().Information($"Request to toggle to \"{selectedFilter}\".");
@ -954,7 +956,7 @@ namespace TINK.ViewModel.Map
} }
ActionText = ""; ActionText = "";
IsRunning = false; IsProcessWithRunningProcessView = false;
IsNavBarVisible = true; IsNavBarVisible = true;
IsMapPageEnabled = true; IsMapPageEnabled = true;
Log.ForContext<MapPageViewModel>().Information($"Toggle to \"{selectedFilter}\" done."); Log.ForContext<MapPageViewModel>().Information($"Toggle to \"{selectedFilter}\" done.");
@ -963,7 +965,7 @@ namespace TINK.ViewModel.Map
{ {
Log.ForContext<MapPageViewModel>().Error("An error occurred switching view Cargobike/ Citybike.{}"); Log.ForContext<MapPageViewModel>().Error("An error occurred switching view Cargobike/ Citybike.{}");
ActionText = ""; ActionText = "";
IsRunning = false; IsProcessWithRunningProcessView = false;
IsNavBarVisible = true; IsNavBarVisible = true;
await ViewService.DisplayAlert( await ViewService.DisplayAlert(

View file

@ -23,6 +23,7 @@ using TINK.Settings;
using TINK.View; using TINK.View;
using TINK.ViewModel.Bikes; using TINK.ViewModel.Bikes;
using Xamarin.Forms; using Xamarin.Forms;
using Command = Xamarin.Forms.Command;
namespace TINK.ViewModel.MyBikes namespace TINK.ViewModel.MyBikes
{ {
@ -31,6 +32,20 @@ namespace TINK.ViewModel.MyBikes
/// <summary> Holds the stations to get station names form station ids. </summary> /// <summary> Holds the stations to get station names form station ids. </summary>
private IEnumerable<IStation> Stations { get; } private IEnumerable<IStation> Stations { get; }
/// <summary>
/// True if ListView of Bikes is refreshing after user pulled;
/// </summary>
private bool _isRefreshing = false;
public bool IsRefreshing
{
get { return _isRefreshing; }
set
{
_isRefreshing = value;
OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsRefreshing)));
}
}
/// <summary> /// <summary>
/// Constructs bike collection view model in case information about occupied bikes is available. /// Constructs bike collection view model in case information about occupied bikes is available.
/// </summary> /// </summary>
@ -71,8 +86,21 @@ namespace TINK.ViewModel.MyBikes
}; };
Stations = stations ?? throw new ArgumentException(nameof(stations)); Stations = stations ?? throw new ArgumentException(nameof(stations));
/// <summary>
/// Holds what should be executed on pull to refresh
/// </summary>
RefreshCommand = new Command(async () => {
IsRefreshing = true;
await OnAppearing();
IsRefreshing = false;
});
} }
public Command RefreshCommand { get; }
/// <summary> Returns if info about the fact that user did not request or book any bikes is visible or not.<summary> /// <summary> Returns if info about the fact that user did not request or book any bikes is visible or not.<summary>
/// Gets message that logged in user has not booked any bikes. /// Gets message that logged in user has not booked any bikes.
/// </summary> /// </summary>
@ -90,7 +118,7 @@ namespace TINK.ViewModel.MyBikes
get get
{ {
return IsNoBikesOccupiedVisible return IsNoBikesOccupiedVisible
? $"Momentan sind keine Fahrräder auf Benutzer {ActiveUser?.Mail} reserviert/ gebucht." ? string.Format(AppResources.MarkingMyBikesNoBikesReservedRented, ActiveUser?.Mail)
: string.Empty; : string.Empty;
} }
} }
@ -101,6 +129,8 @@ namespace TINK.ViewModel.MyBikes
/// </summary> /// </summary>
public async Task OnAppearing() public async Task OnAppearing()
{ {
IsIdle = false;
// Get my bikes from COPRI // Get my bikes from COPRI
Log.ForContext<MyBikesPageViewModel>().Information("User request to show page MyBikes/ page re-appearing"); Log.ForContext<MyBikesPageViewModel>().Information("User request to show page MyBikes/ page re-appearing");

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using NUnit.Framework; using NUnit.Framework;
using TINK.Model.Bikes.BikeInfoNS; using TINK.Model.Bikes.BikeInfoNS;
@ -29,6 +29,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Bike.BC
stateInfo, stateInfo,
bike, bike,
drive, drive,
DataSource.Copri,
isDemo, isDemo,
group, group,
stationId, stationId,

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using NUnit.Framework; using NUnit.Framework;
using TINK.Model.Bikes.BikeInfoNS; using TINK.Model.Bikes.BikeInfoNS;
@ -28,6 +28,7 @@ namespace TestTINKLib
IStateInfo stateInfo = null) : base( IStateInfo stateInfo = null) : base(
new Bike(id, lockType, wheelType, typeOfBike, description), new Bike(id, lockType, wheelType, typeOfBike, description),
new TINK.Model.Bikes.BikeInfoNS.DriveNS.Drive(), new TINK.Model.Bikes.BikeInfoNS.DriveNS.Drive(),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
isDemo, isDemo,
group, group,
stationId, stationId,

View file

@ -1,4 +1,5 @@
using System; using System;
using NSubstitute.ExceptionExtensions;
using NUnit.Framework; using NUnit.Framework;
using TINK.Model.Bikes.BikeInfoNS.BikeNS; using TINK.Model.Bikes.BikeInfoNS.BikeNS;
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock; using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
@ -18,16 +19,16 @@ namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
"Verify that no unspecific reference not set to... exception is thrown"); "Verify that no unspecific reference not set to... exception is thrown");
Assert.Throws<ArgumentException>( Assert.Throws<ArgumentException>(
() => new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), "1"), null), () => new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, "1"), null),
"Verify that no unspecific reference not set to... exception is thrown"); "Verify that no unspecific reference not set to... exception is thrown");
} }
[Test] [Test]
public void TestCtorAvailable() public void TestCtorAvailable()
{ {
Assert.AreEqual("12", new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "13").Id); Assert.AreEqual("12", new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "13").Id);
Assert.AreEqual("13", new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "13").StationId); Assert.AreEqual("13", new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "13").StationId);
Assert.AreEqual(InUseStateEnum.Disposable, new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "13").State.Value); Assert.AreEqual(InUseStateEnum.Disposable, new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "13").State.Value);
} }
[Test] [Test]
@ -37,6 +38,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
() => new BikeInfo( () => new BikeInfo(
null, null,
new Drive(), new Drive(),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
5200544, 5200544,
new Guid("00000000-0000-0000-0000-000000000001"), new Guid("00000000-0000-0000-0000-000000000001"),
"13"), "13"),
@ -46,9 +48,9 @@ namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
[Test] [Test]
public void TestCtorRequested() public void TestCtorRequested()
{ {
Assert.AreEqual("12", new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", "13", null, null, dateTimeProvider: () => new DateTime(2019, 1, 1), false /*isDemo*/, null /*group*/).Id); Assert.AreEqual("12", new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", "13", null, null, dateTimeProvider: () => new DateTime(2019, 1, 1), false /*isDemo*/, null /*group*/).Id);
Assert.AreEqual(112, new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", "13", null, null, dateTimeProvider: () => new DateTime(2019, 1, 1), false /*isDemo*/, null /*group*/).LockInfo.Id); Assert.AreEqual(112, new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", "13", null, null, dateTimeProvider: () => new DateTime(2019, 1, 1), false /*isDemo*/, null /*group*/).LockInfo.Id);
Assert.AreEqual(InUseStateEnum.Reserved, new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", "13", null, null, dateTimeProvider: () => new DateTime(2019, 1, 1), false /*isDemo*/, null /*group*/).State.Value); Assert.AreEqual(InUseStateEnum.Reserved, new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", "13", null, null, dateTimeProvider: () => new DateTime(2019, 1, 1), false /*isDemo*/, null /*group*/).State.Value);
} }
[Test] [Test]
@ -57,7 +59,9 @@ namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
Assert.That( Assert.That(
() => new BikeInfo( () => new BikeInfo(
null, null,
new Drive(), 112, new Drive(),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
112,
new Guid(), new Guid(),
null, null,
null, null,
@ -76,9 +80,9 @@ namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
[Test] [Test]
public void TestCtorBooked() public void TestCtorBooked()
{ {
Assert.AreEqual("12", new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", "13", null /*operator uri*/).Id); Assert.AreEqual("12", new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", "13", null /*operator uri*/).Id);
Assert.AreEqual(112, new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", "13", null /*operator uri*/).LockInfo.Id); Assert.AreEqual(112, new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", "13", null /*operator uri*/).LockInfo.Id);
Assert.AreEqual(InUseStateEnum.Booked, new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", "13", null /*operator uri*/).State.Value); Assert.AreEqual(InUseStateEnum.Booked, new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("12", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 112, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b", "13", null /*operator uri*/).State.Value);
} }
[Test] [Test]
@ -88,6 +92,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
() => new BikeInfo( () => new BikeInfo(
null, null,
new Drive(), new Drive(),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
112, 112,
new Guid(), new Guid(),
null, null,

View file

@ -1,4 +1,4 @@
using System; using System;
using NUnit.Framework; using NUnit.Framework;
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock; using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
using TINK.Model.Bikes.BikeInfoNS.DriveNS; using TINK.Model.Bikes.BikeInfoNS.DriveNS;
@ -12,7 +12,7 @@ namespace TestShareeLib.Model.Bike.BluetoothLock
public void TestCtor() public void TestCtor()
{ {
Assert.That( Assert.That(
new BikeInfoMutable(new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("MyBikeId", TINK.Model.Bikes.BikeInfoNS.BikeNS.LockModel.ILockIt), new Drive(), 42, new Guid(), "17"), "My Station Name").StationName, new BikeInfoMutable(new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("MyBikeId", TINK.Model.Bikes.BikeInfoNS.BikeNS.LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 42, new Guid(), "17"), "My Station Name").StationName,
Is.EqualTo("My Station Name")); Is.EqualTo("My Station Name"));
} }

View file

@ -1,6 +1,7 @@
using System; using System;
using NUnit.Framework; using NUnit.Framework;
using TINK.Model.Bikes.BikeInfoNS; using TINK.Model.Bikes.BikeInfoNS;
using TINK.Model.Bikes.BikeInfoNS.BC;
using TINK.Model.Bikes.BikeInfoNS.BikeNS; using TINK.Model.Bikes.BikeInfoNS.BikeNS;
using TINK.Model.Bikes.BikeInfoNS.DriveNS; using TINK.Model.Bikes.BikeInfoNS.DriveNS;
@ -15,6 +16,7 @@ namespace TestShareeLib.Model.Bike.CopriLock
var bike = new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo( var bike = new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo(
new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("bikeId", LockModel.Sigo), new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("bikeId", LockModel.Sigo),
new Drive(), new Drive(),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
"stationId", "stationId",
new TINK.Model.Bikes.BikeInfoNS.CopriLock.LockInfo()); new TINK.Model.Bikes.BikeInfoNS.CopriLock.LockInfo());
@ -31,6 +33,7 @@ namespace TestShareeLib.Model.Bike.CopriLock
() => new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo( () => new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo(
null, null,
new Drive(), new Drive(),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
"stationId", "stationId",
new TINK.Model.Bikes.BikeInfoNS.CopriLock.LockInfo()), new TINK.Model.Bikes.BikeInfoNS.CopriLock.LockInfo()),
Throws.ArgumentNullException); Throws.ArgumentNullException);
@ -42,6 +45,7 @@ namespace TestShareeLib.Model.Bike.CopriLock
var bike = new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo( var bike = new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo(
new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("bikeId", LockModel.Sigo), new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("bikeId", LockModel.Sigo),
new Drive(), new Drive(),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
"stationId", "stationId",
new TINK.Model.Bikes.BikeInfoNS.CopriLock.LockInfo(), new TINK.Model.Bikes.BikeInfoNS.CopriLock.LockInfo(),
true); true);
@ -58,6 +62,7 @@ namespace TestShareeLib.Model.Bike.CopriLock
() => new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo( () => new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo(
null, null,
new Drive(), new Drive(),
DataSource.Copri,
DateTime.Now, DateTime.Now,
"a@b", "a@b",
"stationId", "stationId",
@ -75,6 +80,7 @@ namespace TestShareeLib.Model.Bike.CopriLock
() => new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo( () => new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo(
null, null,
new Drive(), new Drive(),
DataSource.Copri,
DateTime.Now, DateTime.Now,
"a@b", "a@b",
"stationId", "stationId",

View file

@ -1,4 +1,4 @@
using NUnit.Framework; using NUnit.Framework;
using TINK.Model.Bikes.BikeInfoNS.BC; using TINK.Model.Bikes.BikeInfoNS.BC;
using TINK.Model.Bikes.BikeInfoNS.DriveNS; using TINK.Model.Bikes.BikeInfoNS.DriveNS;
@ -25,6 +25,7 @@ namespace TestShareeLib.Model.Bike.CopriLock
var bikeInfo = new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo( var bikeInfo = new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo(
bike, bike,
new Drive(new TINK.Model.Bikes.BikeInfoNS.DriveNS.EngineNS.Engine("BackendLock")), new Drive(new TINK.Model.Bikes.BikeInfoNS.DriveNS.EngineNS.Engine("BackendLock")),
DataSource.Copri,
"StationId", "StationId",
new TINK.Model.Bikes.BikeInfoNS.CopriLock.LockInfo()); new TINK.Model.Bikes.BikeInfoNS.CopriLock.LockInfo());

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Newtonsoft.Json; using Newtonsoft.Json;
using NUnit.Framework; using NUnit.Framework;
@ -34,7 +34,8 @@ namespace TestTINKLib
Func<DateTime> dateTimeProvider = null, Func<DateTime> dateTimeProvider = null,
IStateInfo stateInfo = null) : base( IStateInfo stateInfo = null) : base(
new Bike(id, lockType, wheelType, typeOfBike, description), new Bike(id, lockType, wheelType, typeOfBike, description),
new TINK.Model.Bikes.BikeInfoNS.DriveNS.Drive(), new Drive(),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
isDemo, isDemo,
group, group,
stationId, stationId,
@ -110,6 +111,7 @@ namespace TestTINKLib
new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo( new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo(
new Bike("57", LockModel.ILockIt), new Bike("57", LockModel.ILockIt),
new Drive(), new Drive(),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
DateTime.Now, DateTime.Now,
"john@long", "john@long",
"7" /*station id*/, "7" /*station id*/,
@ -118,13 +120,16 @@ namespace TestTINKLib
new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo( new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo(
new Bike("20", LockModel.ILockIt), new Bike("20", LockModel.ILockIt),
new Drive(), new Drive(),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
DateTime.Now, DateTime.Now,
"john@long", "john@long",
"7", "7",
new TINK.Model.Bikes.BikeInfoNS.CopriLock.LockInfo(), new TINK.Model.Bikes.BikeInfoNS.CopriLock.LockInfo(),
null), null),
new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo( new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo(
new Bike("33", LockModel.Sigo), new Drive(), new Bike("33", LockModel.Sigo),
new Drive(),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
"7", "7",
new TINK.Model.Bikes.BikeInfoNS.CopriLock.LockInfo()), new TINK.Model.Bikes.BikeInfoNS.CopriLock.LockInfo()),
}; };
@ -153,7 +158,9 @@ namespace TestTINKLib
var l_oBikeResponse = new List<BikeInfo> var l_oBikeResponse = new List<BikeInfo>
{ {
new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo( new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo(
new Bike("57", LockModel.Sigo), new Drive(), new Bike("57", LockModel.Sigo),
new Drive(),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
"7" /*station id*/, "7" /*station id*/,
new TINK.Model.Bikes.BikeInfoNS.CopriLock.LockInfo()), new TINK.Model.Bikes.BikeInfoNS.CopriLock.LockInfo()),
}; };
@ -185,7 +192,7 @@ namespace TestTINKLib
var bikeResponse = new List<BikeInfo> var bikeResponse = new List<BikeInfo>
{ {
new BikeInfo(new Bike("57" /* bike id*/, LockModel.ILockIt, WheelType.Trike, TypeOfBike.Allround, "Test description"), new Drive(), false, new List<string> {"TINK" }, "7" /*station id*/, null /*operator uri*/, null, DateTime.Now, "john@long,", "1234"), new BikeInfo(new Bike("57" /* bike id*/, LockModel.ILockIt, WheelType.Trike, TypeOfBike.Allround, "Test description"), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, false, new List<string> {"TINK" }, "7" /*station id*/, null /*operator uri*/, null, DateTime.Now, "john@long,", "1234"),
}; };
var stations = new List<IStation> var stations = new List<IStation>
@ -210,7 +217,9 @@ namespace TestTINKLib
var bikeResponse = new List<BikeInfo> var bikeResponse = new List<BikeInfo>
{ {
new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo( new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo(
new Bike("57", LockModel.Sigo), new Drive(), new Bike("57", LockModel.Sigo),
new Drive(),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
"7" /*station id*/, "7" /*station id*/,
new TINK.Model.Bikes.BikeInfoNS.CopriLock.LockInfo(), new TINK.Model.Bikes.BikeInfoNS.CopriLock.LockInfo(),
operatorUri: null /*operator uri*/), operatorUri: null /*operator uri*/),
@ -234,7 +243,8 @@ namespace TestTINKLib
""gps"" : { ""latitude"": ""47.669888"", ""longitude"": ""9.167749"" }, ""gps"" : { ""latitude"": ""47.669888"", ""longitude"": ""9.167749"" },
""station"" : ""9"", ""station"" : ""9"",
""system"" : ""Ilockit"" ""system"" : ""Ilockit""
}")); }"),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri);
Assert.That( Assert.That(
BikeCollectionMutable.BikeInfoMutableFactory.Create(bikeInfo, "Stat1").GetType(), BikeCollectionMutable.BikeInfoMutableFactory.Create(bikeInfo, "Stat1").GetType(),
@ -252,7 +262,8 @@ namespace TestTINKLib
""gps"" : { ""latitude"": ""47.669888"", ""longitude"": ""9.167749"" }, ""gps"" : { ""latitude"": ""47.669888"", ""longitude"": ""9.167749"" },
""station"" : ""9"", ""station"" : ""9"",
""system"" : ""SIGO"" ""system"" : ""SIGO""
}")); }"),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri);
Assert.That( Assert.That(
BikeCollectionMutable.BikeInfoMutableFactory.Create(bikeInfo, "Stat1").GetType(), BikeCollectionMutable.BikeInfoMutableFactory.Create(bikeInfo, "Stat1").GetType(),
@ -271,7 +282,8 @@ namespace TestTINKLib
""gps"" : { ""latitude"": ""47.669888"", ""longitude"": ""9.167749"" }, ""gps"" : { ""latitude"": ""47.669888"", ""longitude"": ""9.167749"" },
""station"" : ""9"", ""station"" : ""9"",
""system"" : ""LOCK"" ""system"" : ""LOCK""
}")); }"),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri);
Assert.That( Assert.That(
BikeCollectionMutable.BikeInfoMutableFactory.Create(bikeInfo, "Stat1"), BikeCollectionMutable.BikeInfoMutableFactory.Create(bikeInfo, "Stat1"),

View file

@ -1,4 +1,4 @@
using Newtonsoft.Json; using Newtonsoft.Json;
using NUnit.Framework; using NUnit.Framework;
using TINK.Model.Connector.Updater; using TINK.Model.Connector.Updater;
using TINK.Repository.Response; using TINK.Repository.Response;
@ -22,7 +22,7 @@ namespace TestShareeLib.Model.Connector
}"); }");
Assert.That( Assert.That(
BikeInfoFactory.Create(bikeInfoResponse), BikeInfoFactory.Create(bikeInfoResponse, TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri),
Is.Null, Is.Null,
"BC- bikes (\"system\" : \"LOCK\") are no more supported."); "BC- bikes (\"system\" : \"LOCK\") are no more supported.");
} }
@ -41,7 +41,7 @@ namespace TestShareeLib.Model.Connector
}"); }");
Assert.That( Assert.That(
BikeInfoFactory.Create(bikeInfoResponse), BikeInfoFactory.Create(bikeInfoResponse, TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri),
Is.Null, Is.Null,
"Invalid (\"state\" : \"reserved\") detected."); "Invalid (\"state\" : \"reserved\") detected.");
} }
@ -60,7 +60,7 @@ namespace TestShareeLib.Model.Connector
}"); }");
Assert.That( Assert.That(
BikeInfoFactory.Create(bikeInfoResponse), BikeInfoFactory.Create(bikeInfoResponse, TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri),
Is.Null, Is.Null,
"Station must not be null."); "Station must not be null.");
} }
@ -79,7 +79,7 @@ namespace TestShareeLib.Model.Connector
}"); }");
Assert.That( Assert.That(
BikeInfoFactory.Create(bikeInfoResponse).GetType(), BikeInfoFactory.Create(bikeInfoResponse, TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri).GetType(),
Is.EqualTo(typeof(TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo)), Is.EqualTo(typeof(TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo)),
"Default lock by is BackendLock."); "Default lock by is BackendLock.");
} }
@ -98,7 +98,7 @@ namespace TestShareeLib.Model.Connector
}"); }");
Assert.That( Assert.That(
BikeInfoFactory.Create(bikeInfoResponse).GetType(), BikeInfoFactory.Create(bikeInfoResponse, TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri).GetType(),
Is.EqualTo(typeof(TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo))); Is.EqualTo(typeof(TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo)));
} }
@ -116,7 +116,7 @@ namespace TestShareeLib.Model.Connector
}"); }");
Assert.That( Assert.That(
BikeInfoFactory.Create(bikeInfoResponse).GetType(), BikeInfoFactory.Create(bikeInfoResponse, TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri).GetType(),
Is.EqualTo(typeof(TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo))); Is.EqualTo(typeof(TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo)));
} }
@ -173,7 +173,7 @@ namespace TestShareeLib.Model.Connector
} }
}"); }");
var bike = BikeInfoFactory.Create(bikeInfoResponse) as TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo; var bike = BikeInfoFactory.Create(bikeInfoResponse, TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri) as TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo;
Assert.That( Assert.That(
bike, bike,
@ -195,7 +195,7 @@ namespace TestShareeLib.Model.Connector
}"); }");
Assert.That( Assert.That(
BikeInfoFactory.Create(bikeInfoResponse, "a@b", () => new System.DateTime()), BikeInfoFactory.Create(bikeInfoResponse, "a@b", () => new System.DateTime(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri),
Is.Null, Is.Null,
"BC- bikes (\"system\" : \"LOCK\") are no more supported."); "BC- bikes (\"system\" : \"LOCK\") are no more supported.");
} }
@ -215,7 +215,7 @@ namespace TestShareeLib.Model.Connector
}"); }");
Assert.That( Assert.That(
BikeInfoFactory.Create(bikeInfoResponse, "a@b", () => new System.DateTime()).GetType(), BikeInfoFactory.Create(bikeInfoResponse, "a@b", () => new System.DateTime(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri).GetType(),
Is.EqualTo(typeof(TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo))); Is.EqualTo(typeof(TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo)));
} }
@ -234,7 +234,7 @@ namespace TestShareeLib.Model.Connector
}"); }");
Assert.That( Assert.That(
BikeInfoFactory.Create(bikeInfoResponse, "a@b", () => new System.DateTime()).GetType(), BikeInfoFactory.Create(bikeInfoResponse, "a@b", () => new System.DateTime(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri).GetType(),
Is.EqualTo(typeof(TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo))); Is.EqualTo(typeof(TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo)));
} }
@ -254,7 +254,7 @@ namespace TestShareeLib.Model.Connector
}"); }");
Assert.That( Assert.That(
BikeInfoFactory.Create(bikeInfoResponse, "a@b", () => new System.DateTime()).GetType(), BikeInfoFactory.Create(bikeInfoResponse, "a@b", () => new System.DateTime(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri).GetType(),
Is.EqualTo(typeof(TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo))); Is.EqualTo(typeof(TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo)));
} }
@ -318,7 +318,7 @@ namespace TestShareeLib.Model.Connector
}"); }");
Assert.That( Assert.That(
BikeInfoFactory.Create(bikeInfoResponse)?.State?.Value, BikeInfoFactory.Create(bikeInfoResponse, TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri)?.State?.Value,
Is.EqualTo(TINK.Model.State.InUseStateEnum.FeedbackPending), Is.EqualTo(TINK.Model.State.InUseStateEnum.FeedbackPending),
"Bikes with state booking state available in "); "Bikes with state booking state available in ");
} }

View file

@ -1,8 +1,10 @@
using System; using System;
using System.Linq; using System.Linq;
using Newtonsoft.Json; using Newtonsoft.Json;
using NUnit.Framework; using NUnit.Framework;
using TINK.Model; using TINK.Model;
using TINK.Model.Bikes;
using TINK.Model.Bikes.BikeInfoNS.BC;
using TINK.Model.Bikes.BikeInfoNS.BikeNS; using TINK.Model.Bikes.BikeInfoNS.BikeNS;
using TINK.Model.Bikes.BikeInfoNS.DriveNS; using TINK.Model.Bikes.BikeInfoNS.DriveNS;
using TINK.Model.Connector.Updater; using TINK.Model.Connector.Updater;
@ -164,8 +166,7 @@ namespace TestShareeLib.Model.Connector.Updater
public void TestUpdateBikesAvailable_BikeNr5GetBooked() public void TestUpdateBikesAvailable_BikeNr5GetBooked()
{ {
// Bike 5 is availalbe. // Bike 5 is availalbe.
var l_oBikesTarget = GetBikesAvailable(TinkApp.MerchantId, sampleSet: SampleSets.Set2, stageIndex: 1).GetBikesAvailable( var l_oBikesTarget = GetBikesAvailable(TinkApp.MerchantId, sampleSet: SampleSets.Set2, stageIndex: 1).GetBikesAvailable(DataSource.Copri);
);
Assert.AreEqual(12, l_oBikesTarget.Count, "Bike 5 is available an must be part of available bikes collection"); Assert.AreEqual(12, l_oBikesTarget.Count, "Bike 5 is available an must be part of available bikes collection");
@ -180,16 +181,14 @@ namespace TestShareeLib.Model.Connector.Updater
// Bike 5 is reserved. // Bike 5 is reserved.
// Count of bikes must decrease and bike #5 no more in list of bikes. // Count of bikes must decrease and bike #5 no more in list of bikes.
l_oBikesTarget = GetBikesAvailable(TinkApp.MerchantId, sampleSet: SampleSets.Set2, stageIndex: 2).GetBikesAvailable( l_oBikesTarget = GetBikesAvailable(TinkApp.MerchantId, sampleSet: SampleSets.Set2, stageIndex: 2).GetBikesAvailable(DataSource.Copri);
);
Assert.AreEqual(11, l_oBikesTarget.Count, "One bike (nr. 5) got reserved"); Assert.AreEqual(11, l_oBikesTarget.Count, "One bike (nr. 5) got reserved");
Assert.Null(l_oBikesTarget.GetById("5"), "Bike 5 got requested and must not be part of available bikes collection"); Assert.Null(l_oBikesTarget.GetById("5"), "Bike 5 got requested and must not be part of available bikes collection");
// Bike 5 is booked. // Bike 5 is booked.
// Count of bikes must decrease and bike #5 no more in list of bikes. // Count of bikes must decrease and bike #5 no more in list of bikes.
l_oBikesTarget = GetBikesAvailable(TinkApp.MerchantId, sampleSet: SampleSets.Set2, stageIndex: 3).GetBikesAvailable( l_oBikesTarget = GetBikesAvailable(TinkApp.MerchantId, sampleSet: SampleSets.Set2, stageIndex: 3).GetBikesAvailable(DataSource.Copri);
);
Assert.Null(l_oBikesTarget.GetById("5"), "Bike 5 got booked and must not be part of available bikes collection"); Assert.Null(l_oBikesTarget.GetById("5"), "Bike 5 got booked and must not be part of available bikes collection");
Assert.IsNull(l_oBikesTarget.GetById("5")); Assert.IsNull(l_oBikesTarget.GetById("5"));
@ -200,7 +199,8 @@ namespace TestShareeLib.Model.Connector.Updater
{ {
var l_oBikesTarget = GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 1).GetBikesOccupied( var l_oBikesTarget = GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 1).GetBikesOccupied(
"a@B", "a@B",
() => new DateTime(2017, 11, 28, 14, 8, 14)); // Date time now for bikes which are reserved () => new DateTime(2017, 11, 28, 14, 8, 14), // Date time now for bikes which are reserved
DataSource.Copri);
// Check initial count of bikes. // Check initial count of bikes.
Assert.AreEqual( Assert.AreEqual(
@ -210,7 +210,8 @@ namespace TestShareeLib.Model.Connector.Updater
// Bike 5 is reserved // Bike 5 is reserved
l_oBikesTarget = GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 2).GetBikesOccupied( l_oBikesTarget = GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 2).GetBikesOccupied(
"a@B", "a@B",
() => new DateTime(2017, 11, 28, 14, 08, 36).Add(new TimeSpan(0, 2, 0))); // Date time now for bikes which are reserved () => new DateTime(2017, 11, 28, 14, 08, 36).Add(new TimeSpan(0, 2, 0)), // Date time now for bikes which are reserved
DataSource.Copri);
Assert.AreEqual(3, l_oBikesTarget.Count, "One bike (nr. 5) got reserved"); Assert.AreEqual(3, l_oBikesTarget.Count, "One bike (nr. 5) got reserved");
@ -225,7 +226,8 @@ namespace TestShareeLib.Model.Connector.Updater
// Bike 5 is booked // Bike 5 is booked
l_oBikesTarget = GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 3).GetBikesOccupied( l_oBikesTarget = GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 3).GetBikesOccupied(
"a@B", "a@B",
() => DateTime.Now); () => DateTime.Now,
DataSource.Copri);
Assert.AreEqual(3, l_oBikesTarget.Count, "One bike (nr. 5) got booked"); Assert.AreEqual(3, l_oBikesTarget.Count, "One bike (nr. 5) got booked");
@ -240,7 +242,7 @@ namespace TestShareeLib.Model.Connector.Updater
public void TestGetBikesAvailable_BikeNr5GetBooked() public void TestGetBikesAvailable_BikeNr5GetBooked()
{ {
// Bike 5 is availalbe. // Bike 5 is availalbe.
var l_oBikesTarget = GetBikesAvailable(TinkApp.MerchantId, sampleSet: SampleSets.Set2, stageIndex: 1).GetBikesAvailable(); var l_oBikesTarget = GetBikesAvailable(TinkApp.MerchantId, sampleSet: SampleSets.Set2, stageIndex: 1).GetBikesAvailable(DataSource.Copri);
Assert.AreEqual(11, l_oBikesTarget.Count, "Bike 5 is available an must be part of available bikes collection"); Assert.AreEqual(11, l_oBikesTarget.Count, "Bike 5 is available an must be part of available bikes collection");
@ -255,14 +257,14 @@ namespace TestShareeLib.Model.Connector.Updater
// Bike 5 is reserved. // Bike 5 is reserved.
// Count of bikes must decrease and bike #5 no more in list of bikes. // Count of bikes must decrease and bike #5 no more in list of bikes.
l_oBikesTarget = GetBikesAvailable(TinkApp.MerchantId, sampleSet: SampleSets.Set2, stageIndex: 2).GetBikesAvailable(); l_oBikesTarget = GetBikesAvailable(TinkApp.MerchantId, sampleSet: SampleSets.Set2, stageIndex: 2).GetBikesAvailable(DataSource.Copri);
Assert.AreEqual(10, l_oBikesTarget.Count, "One bike (nr. 5) got reserved"); Assert.AreEqual(10, l_oBikesTarget.Count, "One bike (nr. 5) got reserved");
Assert.Null(l_oBikesTarget.GetById("5"), "Bike 5 got requested and must not be part of available bikes collection"); Assert.Null(l_oBikesTarget.GetById("5"), "Bike 5 got requested and must not be part of available bikes collection");
// Bike 5 is booked. // Bike 5 is booked.
// Count of bikes must decrease and bike #5 no more in list of bikes. // Count of bikes must decrease and bike #5 no more in list of bikes.
l_oBikesTarget = GetBikesAvailable(TinkApp.MerchantId, sampleSet: SampleSets.Set2, stageIndex: 3).GetBikesAvailable(); l_oBikesTarget = GetBikesAvailable(TinkApp.MerchantId, sampleSet: SampleSets.Set2, stageIndex: 3).GetBikesAvailable(DataSource.Copri);
Assert.Null(l_oBikesTarget.GetById("5"), "Bike 5 got booked and must not be part of available bikes collection"); Assert.Null(l_oBikesTarget.GetById("5"), "Bike 5 got booked and must not be part of available bikes collection");
Assert.IsNull(l_oBikesTarget.GetById("5")); Assert.IsNull(l_oBikesTarget.GetById("5"));
@ -273,7 +275,8 @@ namespace TestShareeLib.Model.Connector.Updater
{ {
var bikesTarget = GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 1).GetBikesOccupied( var bikesTarget = GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 1).GetBikesOccupied(
"a@B", "a@B",
() => new DateTime(2017, 11, 28, 14, 8, 14)); // Date time now for bikes which are reserved () => new DateTime(2017, 11, 28, 14, 8, 14), // Date time now for bikes which are reserved
DataSource.Copri);
// Check initial count of bikes. // Check initial count of bikes.
Assert.AreEqual(2, bikesTarget.Count); Assert.AreEqual(2, bikesTarget.Count);
@ -281,7 +284,8 @@ namespace TestShareeLib.Model.Connector.Updater
// Bike 5 is reserved // Bike 5 is reserved
bikesTarget = GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 2).GetBikesOccupied( bikesTarget = GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 2).GetBikesOccupied(
"a@B", "a@B",
() => new DateTime(2017, 11, 28, 14, 08, 36).Add(new TimeSpan(0, 2, 0))); // Date time now for bikes which are reserved () => new DateTime(2017, 11, 28, 14, 08, 36).Add(new TimeSpan(0, 2, 0)), // Date time now for bikes which are reserved
DataSource.Copri);
Assert.AreEqual(3, bikesTarget.Count, "One bike (nr. 5) got reserved"); Assert.AreEqual(3, bikesTarget.Count, "One bike (nr. 5) got reserved");
@ -296,7 +300,8 @@ namespace TestShareeLib.Model.Connector.Updater
// Bike 5 is booked // Bike 5 is booked
bikesTarget = GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 3).GetBikesOccupied( bikesTarget = GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 3).GetBikesOccupied(
"a@B", "a@B",
() => DateTime.Now); () => DateTime.Now,
DataSource.Copri);
Assert.AreEqual(3, bikesTarget.Count, "One bike (nr. 5) got booked"); Assert.AreEqual(3, bikesTarget.Count, "One bike (nr. 5) got booked");
@ -314,7 +319,8 @@ namespace TestShareeLib.Model.Connector.Updater
{ {
var bikesTarget = GetBikesOccupied("5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH", SampleSets.ShareeFr01_Set1, 1).GetBikesOccupied( var bikesTarget = GetBikesOccupied("5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH", SampleSets.ShareeFr01_Set1, 1).GetBikesOccupied(
"a@B", "a@B",
() => new DateTime(2017, 11, 28, 14, 8, 14)); // Date time now for bikes which are reserved () => new DateTime(2017, 11, 28, 14, 8, 14), // Date time now for bikes which are reserved
DataSource.Copri);
// Check initial count of bikes. // Check initial count of bikes.
Assert.AreEqual(2, bikesTarget.Count); Assert.AreEqual(2, bikesTarget.Count);
@ -322,7 +328,8 @@ namespace TestShareeLib.Model.Connector.Updater
// Bike 5 is reserved // Bike 5 is reserved
bikesTarget = GetBikesOccupied("5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH", SampleSets.ShareeFr01_Set1, 2).GetBikesOccupied( bikesTarget = GetBikesOccupied("5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH", SampleSets.ShareeFr01_Set1, 2).GetBikesOccupied(
"a@B", "a@B",
() => new DateTime(2017, 11, 28, 14, 08, 36).Add(new TimeSpan(0, 2, 0))); // Date time now for bikes which are reserved () => new DateTime(2017, 11, 28, 14, 08, 36).Add(new TimeSpan(0, 2, 0)), // Date time now for bikes which are reserved
DataSource.Copri);
Assert.AreEqual(3, bikesTarget.Count, "One bike (nr. 5) got reserved"); Assert.AreEqual(3, bikesTarget.Count, "One bike (nr. 5) got reserved");
@ -379,8 +386,7 @@ namespace TestShareeLib.Model.Connector.Updater
[Test] [Test]
public void TestGetBikesAvailable() public void TestGetBikesAvailable()
{ {
var bikesTarget = GetBikesAvailable(TinkApp.MerchantId, sampleSet: SampleSets.Set2, stageIndex: 1).GetBikesAvailable( var bikesTarget = GetBikesAvailable(TinkApp.MerchantId, sampleSet: SampleSets.Set2, stageIndex: 1).GetBikesAvailable(DataSource.Copri);
);
// Verify count of bikes // Verify count of bikes
Assert.AreEqual(12, bikesTarget.Count); Assert.AreEqual(12, bikesTarget.Count);
@ -406,7 +412,8 @@ namespace TestShareeLib.Model.Connector.Updater
{ {
var l_oBikesTarget = GetBikesOccupied(TinkApp.MerchantId, SampleSets.Set2, 1).GetBikesOccupied( var l_oBikesTarget = GetBikesOccupied(TinkApp.MerchantId, SampleSets.Set2, 1).GetBikesOccupied(
"a@b", "a@b",
() => DateTime.Now); () => DateTime.Now,
DataSource.Copri);
// Verify count of bikes // Verify count of bikes
Assert.AreEqual(2, l_oBikesTarget.Count); Assert.AreEqual(2, l_oBikesTarget.Count);
@ -436,11 +443,12 @@ namespace TestShareeLib.Model.Connector.Updater
} }
}"); }");
var bikes = UpdaterJSON.GetBikesAll( var bikes = BikeCollectionFactory.GetBikesAll(
availableResponse?.bikes?.Values, availableResponse?.bikes?.Values,
null, null,
"Heinz.Mustermann@posteo.de", "Heinz.Mustermann@posteo.de",
() => DateTime.Now); () => DateTime.Now,
DataSource.Copri);
Assert.AreEqual( Assert.AreEqual(
2, 2,
@ -467,11 +475,12 @@ namespace TestShareeLib.Model.Connector.Updater
} }
}"); }");
var bikes = UpdaterJSON.GetBikesAll( var bikes = BikeCollectionFactory.GetBikesAll(
availableResponse?.bikes?.Values, availableResponse?.bikes?.Values,
null, null,
"Heinz.Mustermann@posteo.de", "Heinz.Mustermann@posteo.de",
() => DateTime.Now); () => DateTime.Now,
DataSource.Copri);
Assert.AreEqual( Assert.AreEqual(
0, 0,
@ -495,11 +504,12 @@ namespace TestShareeLib.Model.Connector.Updater
} }
}"); }");
var bikes = UpdaterJSON.GetBikesAll( var bikes = BikeCollectionFactory.GetBikesAll(
availableResponse?.bikes?.Values, availableResponse?.bikes?.Values,
null, null,
"Heinz.Mustermann@posteo.de", "Heinz.Mustermann@posteo.de",
() => DateTime.Now); () => DateTime.Now,
DataSource.Copri);
Assert.AreEqual( Assert.AreEqual(
0, 0,
@ -530,11 +540,12 @@ namespace TestShareeLib.Model.Connector.Updater
} }
}"); }");
var bikes = UpdaterJSON.GetBikesAll( var bikes = BikeCollectionFactory.GetBikesAll(
availableResponse?.bikes?.Values, availableResponse?.bikes?.Values,
null, null,
"Heinz.Mustermann@posteo.de", "Heinz.Mustermann@posteo.de",
() => DateTime.Now); () => DateTime.Now,
DataSource.Copri);
Assert.AreEqual( Assert.AreEqual(
0, 0,
@ -567,11 +578,12 @@ namespace TestShareeLib.Model.Connector.Updater
} }
}"); }");
var bikes = UpdaterJSON.GetBikesAll( var bikes = BikeCollectionFactory.GetBikesAll(
null, null,
reservedOccupiedResponse?.bikes_occupied?.Values, reservedOccupiedResponse?.bikes_occupied?.Values,
"Heinz.Mustermann@posteo.de", "Heinz.Mustermann@posteo.de",
() => DateTime.Now); () => DateTime.Now,
DataSource.Copri);
Assert.AreEqual( Assert.AreEqual(
0, 0,
@ -605,11 +617,12 @@ namespace TestShareeLib.Model.Connector.Updater
} }
}"); }");
var bikes = UpdaterJSON.GetBikesAll( var bikes = BikeCollectionFactory.GetBikesAll(
null, null,
reservedOccupiedResponse?.bikes_occupied?.Values, reservedOccupiedResponse?.bikes_occupied?.Values,
"Heinz.Mustermann@posteo.de", "Heinz.Mustermann@posteo.de",
() => DateTime.Now); () => DateTime.Now,
DataSource.Copri);
Assert.AreEqual( Assert.AreEqual(
2, 2,
@ -629,6 +642,7 @@ namespace TestShareeLib.Model.Connector.Updater
var bike = new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfoMutable(new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo( var bike = new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfoMutable(new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo(
new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("17", LockModel.ILockIt), new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("17", LockModel.ILockIt),
new Drive(), new Drive(),
DataSource.Copri,
22, 22,
new Guid("0000f00d-1212-efde-1523-785fef13d123"), new Guid("0000f00d-1212-efde-1523-785fef13d123"),
new[] { (byte)1, (byte)3, (byte)4 }, new[] { (byte)1, (byte)3, (byte)4 },
@ -666,7 +680,9 @@ namespace TestShareeLib.Model.Connector.Updater
{ {
// Construct occupied bike. // Construct occupied bike.
var bike = new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfoMutable(new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo( var bike = new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfoMutable(new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo(
new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("17", LockModel.ILockIt), new Drive(), new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("17", LockModel.ILockIt),
new Drive(),
DataSource.Copri,
22, 22,
new Guid("0000f00d-1212-efde-1523-785fef13d123"), new Guid("0000f00d-1212-efde-1523-785fef13d123"),
new[] { (byte)1, (byte)3, (byte)4 }, new[] { (byte)1, (byte)3, (byte)4 },
@ -702,6 +718,7 @@ namespace TestShareeLib.Model.Connector.Updater
var bike = new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfoMutable(new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo( var bike = new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfoMutable(new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo(
new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("17", LockModel.ILockIt), new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("17", LockModel.ILockIt),
new Drive(), new Drive(),
DataSource.Copri,
22, 22,
new Guid("0000f00d-1212-efde-1523-785fef13d123"), new Guid("0000f00d-1212-efde-1523-785fef13d123"),
new[] { (byte)1, (byte)3, (byte)4 }, new[] { (byte)1, (byte)3, (byte)4 },

View file

@ -1,8 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using NUnit.Framework; using NUnit.Framework;
using TINK.Model; using TINK.Model;
using TINK.Model.Bikes; using TINK.Model.Bikes;
using TINK.Model.Bikes.BikeInfoNS.BC;
using TINK.Model.Bikes.BikeInfoNS.BikeNS; using TINK.Model.Bikes.BikeInfoNS.BikeNS;
using TINK.Model.Bikes.BikeInfoNS.DriveNS; using TINK.Model.Bikes.BikeInfoNS.DriveNS;
@ -17,9 +18,9 @@ namespace TestTINKLib.Fixtures.ObjectTests.Bike
var coll = new BikeCollection( var coll = new BikeCollection(
new Dictionary<string, TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo> new Dictionary<string, TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo>
{ {
{"3", new TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("7", LockModel.ILockIt), new Drive(), "3" /* Stadion id */) }, {"3", new TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("7", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,"3" /* Stadion id */) },
{"7", new TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("8", LockModel.ILockIt), new Drive(), "12" /* Stadion id */) }, {"7", new TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("8", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,"12" /* Stadion id */) },
{"12", new TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("33", LockModel.ILockIt), new Drive(), "12" /* Stadion id */) } {"12", new TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("33", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,"12" /* Stadion id */) }
}); });
Assert.AreEqual( Assert.AreEqual(
@ -58,8 +59,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.Bike
var coll = new BikeCollection( var coll = new BikeCollection(
new Dictionary<string, TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo> new Dictionary<string, TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo>
{ {
{"7", new TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("8", LockModel.ILockIt), new Drive(), "12" /* Stadion id */) }, {"7", new TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("8", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,"12" /* Stadion id */) },
{"12", new TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("33", LockModel.ILockIt), new Drive(), "12" /* Stadion id */) } {"12", new TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("33", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,"12" /* Stadion id */) }
}); });
Assert.AreEqual( Assert.AreEqual(
@ -75,9 +76,9 @@ namespace TestTINKLib.Fixtures.ObjectTests.Bike
var coll = new BikeCollection( var coll = new BikeCollection(
new Dictionary<string, TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo> new Dictionary<string, TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo>
{ {
{"7", new TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("8", LockModel.ILockIt), new Drive(), "12" /* Stadion id */) }, {"7", new TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("8", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,"12" /* Stadion id */) },
{"11", new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("33", LockModel.ILockIt), new Drive(), 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "12" /* Stadion id */) }, {"11", new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("33", LockModel.ILockIt), new Drive(), DataSource.Copri, 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "12" /* Stadion id */) },
{"12", new TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("33", LockModel.ILockIt), new Drive(), "12" /* Stadion id */) } {"12", new TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("33", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,"12" /* Stadion id */) }
}); });
Assert.AreEqual( Assert.AreEqual(

View file

@ -1,4 +1,4 @@
using System; using System;
using NUnit.Framework; using NUnit.Framework;
using TINK.Repository.Exception; using TINK.Repository.Exception;
using TINK.Repository.Request; using TINK.Repository.Request;
@ -62,11 +62,13 @@ namespace TestShareeLib.Repository.Request
} }
[Test] [Test]
public void TestGetStationsLangDe() public void TestGetStationsLangOes()
{ {
Assert.That( Assert.That(
new RequestBuilder("123", "de").GetStations(), new RequestBuilder(
Is.EqualTo("request=stations_available&authcookie=123&lang=de")); "MärchantId",
"öe" /* this non exisiting language id verifies urlencoding */).GetStations(),
Is.EqualTo("request=stations_available&authcookie=M%C3%A4rchantId&lang=%C3%B6e"));
} }
[Test] [Test]

View file

@ -1,8 +1,10 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net; using System.Net;
using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
using TINK.Model.Connector; using TINK.Model.Connector;
using TINK.Model.Device;
using TINK.Repository.Exception; using TINK.Repository.Exception;
using TINK.Repository.Request; using TINK.Repository.Request;
@ -22,8 +24,8 @@ namespace TestShareeLib.Repository.Request
public void TestDoAuthout() public void TestDoAuthout()
{ {
Assert.AreEqual( Assert.AreEqual(
"request=authout&authcookie=456123", "request=authout&authcookie=K%C3%A4ksM%C3%B6rchantId&lang=%C3%B6e",
new RequestBuilderLoggedIn("123", null /*UI language */, "456").DoAuthout()); new RequestBuilderLoggedIn("MörchantId", "öe" /* fictive UI language */, "Käks").DoAuthout());
} }
[Test] [Test]
@ -90,8 +92,8 @@ namespace TestShareeLib.Repository.Request
public void TestDoReserve() public void TestDoReserve()
{ {
Assert.AreEqual( Assert.AreEqual(
"request=booking_request&bike=42&authcookie=456123", "request=booking_request&bike=M%C3%BChleNr42&authcookie=456123",
new RequestBuilderLoggedIn("123", null /*UI language */, "456").DoReserve("42")); new RequestBuilderLoggedIn("123", null /*UI language */, "456").DoReserve("MühleNr42"));
} }
[Test] [Test]
@ -255,11 +257,11 @@ namespace TestShareeLib.Repository.Request
[Test] [Test]
public void TestDoReturnGeolocationIsNull() public void TestDoReturn()
{ {
var builder = new RequestBuilderLoggedIn("MyMeranctIt", null /*UI language */, "MySessionCookie"); var builder = new RequestBuilderLoggedIn("MyMeranctIt", null /*UI language */, "MySessionCookie");
Assert.That( Assert.That(
builder.DoReturn("12", null, null), builder.DoReturn("12", null /* Geolocation */, null /* Smart device */),
Is.EqualTo("request=booking_update&bike=12&authcookie=MySessionCookieMyMeranctIt&state=available&lock_state=locked")); Is.EqualTo("request=booking_update&bike=12&authcookie=MySessionCookieMyMeranctIt&state=available&lock_state=locked"));
} }
@ -271,7 +273,7 @@ namespace TestShareeLib.Repository.Request
builder.DoReturn( builder.DoReturn(
"12", "12",
new LocationDto.Builder { Latitude = 21, Longitude = 17, Age = new TimeSpan(0, 0, 0, 0, 70) }.Build(), new LocationDto.Builder { Latitude = 21, Longitude = 17, Age = new TimeSpan(0, 0, 0, 0, 70) }.Build(),
null), null /* Smart device */),
Is.EqualTo("request=booking_update&bike=12&authcookie=MySessionCookieMyMeranctIt&state=available&gps=21,17&gps_age=0.07&lock_state=locked")); Is.EqualTo("request=booking_update&bike=12&authcookie=MySessionCookieMyMeranctIt&state=available&gps=21,17&gps_age=0.07&lock_state=locked"));
} }
@ -283,10 +285,66 @@ namespace TestShareeLib.Repository.Request
builder.DoReturn( builder.DoReturn(
"12", "12",
new LocationDto.Builder { Latitude = 21, Longitude = 17, Accuracy = 5.7, Age = new TimeSpan(0, 0, 0, 0, 70) }.Build(), new LocationDto.Builder { Latitude = 21, Longitude = 17, Accuracy = 5.7, Age = new TimeSpan(0, 0, 0, 0, 70) }.Build(),
null), null /* Smart device */),
Is.EqualTo("request=booking_update&bike=12&authcookie=MySessionCookieMyMeranctIt&state=available&gps=21,17&gps_accuracy=5.7&gps_age=0.07&lock_state=locked")); Is.EqualTo("request=booking_update&bike=12&authcookie=MySessionCookieMyMeranctIt&state=available&gps=21,17&gps_accuracy=5.7&gps_age=0.07&lock_state=locked"));
} }
[Test]
public void TestDoReturnSmartDeviceManufacturer()
{
var sd = Substitute.For<ISmartDevice>();
sd.Manufacturer.Returns("Färphone");
var builder = new RequestBuilderLoggedIn("MyMeranctIt", null /*UI language */, "MySessionCookie");
Assert.That(
builder.DoReturn(
"12",
null, // Geolocation
sd),
Is.EqualTo("request=booking_update&bike=12&authcookie=MySessionCookieMyMeranctIt&state=available&lock_state=locked&user_device_manufaturer=F%C3%A4rphone)"));
}
[Test]
public void TestDoReturnSmartDeviceModel()
{
var sd = Substitute.For<ISmartDevice>();
sd.Model.Returns("Fön");
var builder = new RequestBuilderLoggedIn("MyMeranctIt", null /*UI language */, "MySessionCookie");
Assert.That(
builder.DoReturn(
"12",
null, // Geolocation
sd),
Is.EqualTo("request=booking_update&bike=12&authcookie=MySessionCookieMyMeranctIt&state=available&lock_state=locked&user_device_model=F%C3%B6n"));
}
[Test]
public void TestDoReturnSmartDeviceVersion()
{
var sd = Substitute.For<ISmartDevice>();
sd.VersionText.Returns("ß1");
var builder = new RequestBuilderLoggedIn("MyMeranctIt", null /*UI language */, "MySessionCookie");
Assert.That(
builder.DoReturn(
"12",
null, // Geolocation
sd),
Is.EqualTo("request=booking_update&bike=12&authcookie=MySessionCookieMyMeranctIt&state=available&lock_state=locked&user_device_version=%C3%9F1"));
}
[Test]
public void TestDoReturnSmartDeviceIdentifier()
{
var sd = Substitute.For<ISmartDevice>();
sd.Identifier.Returns("ß9");
var builder = new RequestBuilderLoggedIn("MyMeranctIt", null /*UI language */, "MySessionCookie");
Assert.That(
builder.DoReturn(
"12",
null, // Geolocation
sd),
Is.EqualTo("request=booking_update&bike=12&authcookie=MySessionCookieMyMeranctIt&state=available&lock_state=locked&user_device_id=%C3%9F9"));
}
[Test] [Test]
public void TestDoSubmitFeedback_Ok() public void TestDoSubmitFeedback_Ok()
{ {
@ -311,7 +369,7 @@ namespace TestShareeLib.Repository.Request
var builder = new RequestBuilderLoggedIn("MyMeranctIt", null /*UI language */, "MySessionCookie"); var builder = new RequestBuilderLoggedIn("MyMeranctIt", null /*UI language */, "MySessionCookie");
Assert.That( Assert.That(
builder.DoSubmitFeedback("Mühle", null, "Uno due tre"), builder.DoSubmitFeedback("Mühle", null, "Uno due tre"),
Is.EqualTo("request=user_feedback&bike=Mühle&message=Uno+due+tre&authcookie=MySessionCookieMyMeranctIt")); Is.EqualTo("request=user_feedback&bike=M%C3%BChle&message=Uno+due+tre&authcookie=MySessionCookieMyMeranctIt"));
} }
[Test] [Test]

View file

@ -186,7 +186,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
// Login hint/ no bikes frame // Login hint/ no bikes frame
Assert.IsFalse(bikesAtStation.IsLoginRequiredHintVisible); Assert.IsFalse(bikesAtStation.IsLoginRequiredHintVisible);
Assert.IsTrue(bikesAtStation.IsNoBikesAtStationVisible); Assert.IsTrue(bikesAtStation.IsNoBikesAtStationVisible);
Assert.AreEqual("Momentan sind keine Fahrräder an dieser Station verfügbar.", bikesAtStation.NoBikesAtStationText); Assert.AreEqual("There are currently no bicycles available at this station.", bikesAtStation.NoBikesAtStationText);
} }
[Test] [Test]
@ -965,7 +965,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
// Login hint/ no bikes frame // Login hint/ no bikes frame
Assert.IsFalse(bikesAtStation.IsLoginRequiredHintVisible); Assert.IsFalse(bikesAtStation.IsLoginRequiredHintVisible);
Assert.IsTrue(bikesAtStation.IsNoBikesAtStationVisible); Assert.IsTrue(bikesAtStation.IsNoBikesAtStationVisible);
Assert.AreEqual("Momentan sind keine Fahrräder an dieser Station verfügbar.", bikesAtStation.NoBikesAtStationText); Assert.AreEqual("There are currently no bicycles available at this station.", bikesAtStation.NoBikesAtStationText);
} }
[Test] [Test]

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using NSubstitute; using NSubstitute;
using NUnit.Framework; using NUnit.Framework;
@ -30,6 +30,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Bike
IStateInfo stateInfo = null) : base( IStateInfo stateInfo = null) : base(
new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike(id, lockModel, wheelType, typeOfBike, description), new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike(id, lockModel, wheelType, typeOfBike, description),
new TINK.Model.Bikes.BikeInfoNS.DriveNS.Drive(), new TINK.Model.Bikes.BikeInfoNS.DriveNS.Drive(),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
isDemo, isDemo,
group, group,
stationId, stationId,

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using NUnit.Framework; using NUnit.Framework;
@ -20,8 +20,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.Service.LockService
var bikes = new BikeCollection(new Dictionary<string, TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo>() var bikes = new BikeCollection(new Dictionary<string, TINK.Model.Bikes.BikeInfoNS.BC.BikeInfo>()
{ {
{ "42", new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("42", LockModel.ILockIt), new Drive(), 1, new Guid(),new byte[] { 1, 4 }, new byte[] { 3, 4 }, new byte[] { 3, 4 }, DateTime.Now, "a@b", "1" , null /*operator uri*/) }, { "42", new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("42", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 1, new Guid(),new byte[] { 1, 4 }, new byte[] { 3, 4 }, new byte[] { 3, 4 }, DateTime.Now, "a@b", "1" , null /*operator uri*/) },
{ "43", new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("43", LockModel.ILockIt), new Drive(), 3, new Guid(),new byte[] { 4, 4 }, new byte[] { 4, 7 }, new byte[] { 5, 4 }, DateTime.Now, "c@b", "1" , null /*operator uri*/) } { "43", new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("43", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 3, new Guid(),new byte[] { 4, 4 }, new byte[] { 4, 7 }, new byte[] { 5, 4 }, DateTime.Now, "c@b", "1" , null /*operator uri*/) }
} }
); );

View file

@ -1,4 +1,4 @@
using System; using System;
using Newtonsoft.Json; using Newtonsoft.Json;
using NUnit.Framework; using NUnit.Framework;
using TINK.Model.State; using TINK.Model.State;
@ -17,14 +17,14 @@ namespace TestTINKLib.Fixtures.State
var l_oReservedInfo = new StateRequestedInfo( var l_oReservedInfo = new StateRequestedInfo(
() => new DateTime(2017, 09, 20), () => new DateTime(2017, 09, 20),
new DateTime(2017, 09, 19), new DateTime(2017, 09, 19),
"a@b", "ä@b",
"372"); "372");
// Serialize object // Serialize object
// Serialize object and verify. // Serialize object and verify.
var l_oDetected = JsonConvert.SerializeObject(l_oReservedInfo); var l_oDetected = JsonConvert.SerializeObject(l_oReservedInfo);
// Verify xml // Verify xml
const string EXPECTED = @"{""From"":""2017 - 09 - 19T00: 00:00"",""MailAddress"":""a @b"",""Code"":""372""}"; const string EXPECTED = @"{""From"":""2017 - 09 - 19T00: 00:00"",""MailAddress"":""ä @b"",""Code"":""372""}";
Assert.AreEqual( Assert.AreEqual(
TestHelper.PrepareXmlForStringCompare(EXPECTED), TestHelper.PrepareXmlForStringCompare(EXPECTED),
TestHelper.PrepareXmlForStringCompare(l_oDetected)); TestHelper.PrepareXmlForStringCompare(l_oDetected));
@ -34,7 +34,7 @@ namespace TestTINKLib.Fixtures.State
// Verify state. // Verify state.
Assert.AreEqual(InUseStateEnum.Reserved, l_oInfoTarge.Value); Assert.AreEqual(InUseStateEnum.Reserved, l_oInfoTarge.Value);
Assert.AreEqual("a@b", l_oInfoTarge.MailAddress); Assert.AreEqual("ä@b", l_oInfoTarge.MailAddress);
Assert.AreEqual("372", l_oInfoTarge.Code); Assert.AreEqual("372", l_oInfoTarge.Code);
Assert.AreEqual(new DateTime(2017, 9, 19, 0, 0, 0), l_oInfoTarge.From); Assert.AreEqual(new DateTime(2017, 9, 19, 0, 0, 0), l_oInfoTarge.From);
} }

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using NUnit.Framework; using NUnit.Framework;
using Rhino.Mocks; using Rhino.Mocks;
@ -27,7 +27,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
{ {
// Verify handler for disposable bike. // Verify handler for disposable bike.
var bike = new BikeInfoMutable( var bike = new BikeInfoMutable(
new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("22", TINK.Model.Bikes.BikeInfoNS.BikeNS.LockModel.ILockIt), new Drive(), 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "12"), new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("22", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "12"),
"My Station Name"); "My Station Name");
Assert.AreEqual(InUseStateEnum.Disposable, bike.State.Value); Assert.AreEqual(InUseStateEnum.Disposable, bike.State.Value);
Assert.AreEqual(LockingState.UnknownDisconnected, bike.LockInfo.State); Assert.AreEqual(LockingState.UnknownDisconnected, bike.LockInfo.State);
@ -47,7 +47,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
// Verify handler for requested bike with state unknown. // Verify handler for requested bike with state unknown.
bike = new BikeInfoMutable( bike = new BikeInfoMutable(
new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("22", LockModel.ILockIt, WheelType.Mono, TypeOfBike.Allround), new Drive(), 0 /* lock Id */, new Guid(), /*K User*/ null, /*K Admin*/ null, /*K Seed*/ null, new DateTime(2020, 1, 1), "a@b.com", "12", null, null, () => new DateTime(2020, 1, 1), false, new List<string>()), new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("22", LockModel.ILockIt, WheelType.Mono, TypeOfBike.Allround), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 0 /* lock Id */, new Guid(), /*K User*/ null, /*K Admin*/ null, /*K Seed*/ null, new DateTime(2020, 1, 1), "a@b.com", "12", null, null, () => new DateTime(2020, 1, 1), false, new List<string>()),
"My Station Name"); "My Station Name");
Assert.AreEqual( Assert.AreEqual(
typeof(ReservedDisconnected), typeof(ReservedDisconnected),
@ -65,7 +65,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
// Verify handler for requested bike with state closed. // Verify handler for requested bike with state closed.
bike = new BikeInfoMutable( bike = new BikeInfoMutable(
new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("22", LockModel.ILockIt, WheelType.Mono, TypeOfBike.Allround), new Drive(), 0 /* lock Id*/, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b.com", "12", null, null, () => new DateTime(2020, 1, 1), false, new List<string>()), new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("22", LockModel.ILockIt, WheelType.Mono, TypeOfBike.Allround), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 0 /* lock Id*/, new Guid(), null, null, null, new DateTime(2020, 1, 1), "a@b.com", "12", null, null, () => new DateTime(2020, 1, 1), false, new List<string>()),
"My Station Name"); "My Station Name");
bike.LockInfo.State = LockingState.Closed; bike.LockInfo.State = LockingState.Closed;
Assert.AreEqual( Assert.AreEqual(
@ -84,7 +84,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
// Verify handler for requested bike with state open. // Verify handler for requested bike with state open.
bike = new BikeInfoMutable( bike = new BikeInfoMutable(
new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("22", LockModel.ILockIt, WheelType.Mono, TypeOfBike.Allround), new Drive(), 0 /* lock Id*/, new Guid(), null /* user key */, null, null, new DateTime(2020, 1, 1), "a@b.com", "12", null, null, () => new DateTime(2020, 1, 1), false, new List<string>()), new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("22", LockModel.ILockIt, WheelType.Mono, TypeOfBike.Allround), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 0 /* lock Id*/, new Guid(), null /* user key */, null, null, new DateTime(2020, 1, 1), "a@b.com", "12", null, null, () => new DateTime(2020, 1, 1), false, new List<string>()),
"My Station Name"); "My Station Name");
bike.LockInfo.State = LockingState.Open; bike.LockInfo.State = LockingState.Open;
Assert.AreEqual( Assert.AreEqual(
@ -103,7 +103,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
// Verify handler for booked bike with state closed. // Verify handler for booked bike with state closed.
bike = new BikeInfoMutable( bike = new BikeInfoMutable(
new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("22", LockModel.ILockIt, WheelType.Mono, TypeOfBike.Allround), new Drive(), 0 /* lock Id*/, new Guid(), null, null, null, new System.DateTime(2020, 1, 1), "a@b.com", "12", null /*operator uri*/, null, false, new List<string>()), new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("22", LockModel.ILockIt, WheelType.Mono, TypeOfBike.Allround), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 0 /* lock Id*/, new Guid(), null, null, null, new System.DateTime(2020, 1, 1), "a@b.com", "12", null /*operator uri*/, null, false, new List<string>()),
"My Station Name"); "My Station Name");
bike.LockInfo.State = LockingState.Closed; bike.LockInfo.State = LockingState.Closed;
Assert.AreEqual( Assert.AreEqual(
@ -122,7 +122,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
// Verify handler for booked bike with state open. // Verify handler for booked bike with state open.
bike = new BikeInfoMutable( bike = new BikeInfoMutable(
new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("22", LockModel.ILockIt, WheelType.Mono, TypeOfBike.Allround), new Drive(), 0 /* lock Id*/, new Guid(), null, null, null, new System.DateTime(2020, 1, 1), "a@b.com", "12", null /*operator uri*/, null, false, new List<string>()), new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("22", LockModel.ILockIt, WheelType.Mono, TypeOfBike.Allround), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 0 /* lock Id*/, new Guid(), null, null, null, new System.DateTime(2020, 1, 1), "a@b.com", "12", null /*operator uri*/, null, false, new List<string>()),
"My Station Name"); "My Station Name");
bike.LockInfo.State = LockingState.Open; bike.LockInfo.State = LockingState.Open;
Assert.AreEqual( Assert.AreEqual(
@ -141,7 +141,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Bike.BluetoothLock
// Verify handler for booked bike with state unknown. // Verify handler for booked bike with state unknown.
bike = new BikeInfoMutable( bike = new BikeInfoMutable(
new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("22", LockModel.ILockIt, WheelType.Mono, TypeOfBike.Allround), new Drive(), 0 /* lock Id*/, new Guid(), null, null, null, new System.DateTime(2020, 1, 1), "a@b.com", "12", null /*operator uri*/, null, false, new List<string>()), new BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("22", LockModel.ILockIt, WheelType.Mono, TypeOfBike.Allround), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, 0 /* lock Id*/, new Guid(), null, null, null, new System.DateTime(2020, 1, 1), "a@b.com", "12", null /*operator uri*/, null, false, new List<string>()),
"My Station Name"); "My Station Name");
Assert.AreEqual( Assert.AreEqual(

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using NUnit.Framework; using NUnit.Framework;
using Rhino.Mocks; using Rhino.Mocks;
@ -36,6 +36,7 @@ namespace UITest.Fixtures.ViewModel
IStateInfo stateInfo = null) : base( IStateInfo stateInfo = null) : base(
new Bike(id, lockModel, wheelType, typeOfBike, description), new Bike(id, lockModel, wheelType, typeOfBike, description),
new Drive(), new Drive(),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
isDemo, isDemo,
group, group,
stationId, stationId,

View file

@ -1,4 +1,4 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using NUnit.Framework; using NUnit.Framework;
using TestFramework.Model.User.Account; using TestFramework.Model.User.Account;
@ -31,6 +31,7 @@ namespace UITest.Fixtures.ViewModel
IStateInfo stateInfo = null) : base( IStateInfo stateInfo = null) : base(
new Bike(id, lockModel, wheelType, typeOfBike, description), new Bike(id, lockModel, wheelType, typeOfBike, description),
new TINK.Model.Bikes.BikeInfoNS.DriveNS.Drive(), new TINK.Model.Bikes.BikeInfoNS.DriveNS.Drive(),
TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri,
pisDemo, pisDemo,
group, group,
stationId, stationId,

View file

@ -1,8 +1,9 @@
using System; using System;
using NUnit.Framework; using NUnit.Framework;
using Rhino.Mocks; using Rhino.Mocks;
using TestFramework.Model.Services.Geolocation; using TestFramework.Model.Services.Geolocation;
using TestFramework.Services.BluetoothLock; using TestFramework.Services.BluetoothLock;
using TINK.Model.Bikes.BikeInfoNS.BC;
using TINK.Model.Bikes.BikeInfoNS.BikeNS; using TINK.Model.Bikes.BikeInfoNS.BikeNS;
using TINK.Model.Bikes.BikeInfoNS.DriveNS; using TINK.Model.Bikes.BikeInfoNS.DriveNS;
using TINK.Model.Device; using TINK.Model.Device;
@ -30,7 +31,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
null, // viewUpdateManager null, // viewUpdateManager
NSubstitute.Substitute.For<ISmartDevice>(), NSubstitute.Substitute.For<ISmartDevice>(),
null, // viewService null, // viewService
new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfoMutable(new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("42", TINK.Model.Bikes.BikeInfoNS.BikeNS.LockModel.ILockIt), new Drive(), 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "42"), "My Station Name"), new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfoMutable(new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("42", LockModel.ILockIt), new Drive(), DataSource.Copri, 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "42"), "My Station Name"),
MockRepository.GenerateStub<IUser>(), // user MockRepository.GenerateStub<IUser>(), // user
MockRepository.GenerateStub<IInUseStateInfoProvider>(), MockRepository.GenerateStub<IInUseStateInfoProvider>(),
MockRepository.GenerateStub<IBikesViewModel>(), MockRepository.GenerateStub<IBikesViewModel>(),
@ -51,7 +52,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
null, // viewUpdateManager null, // viewUpdateManager
NSubstitute.Substitute.For<ISmartDevice>(), NSubstitute.Substitute.For<ISmartDevice>(),
null, // viewService null, // viewService
new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfoMutable(new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("42", LockModel.ILockIt), new Drive(), "17", new TINK.Model.Bikes.BikeInfoNS.CopriLock.LockInfo.Builder { State = TINK.Model.Bikes.BikeInfoNS.CopriLock.LockingState.Closed }.Build()), "My Station Name"), new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfoMutable(new TINK.Model.Bikes.BikeInfoNS.CopriLock.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("42", LockModel.ILockIt), new Drive(), TINK.Model.Bikes.BikeInfoNS.BC.DataSource.Copri, "17", new TINK.Model.Bikes.BikeInfoNS.CopriLock.LockInfo.Builder { State = TINK.Model.Bikes.BikeInfoNS.CopriLock.LockingState.Closed }.Build()), "My Station Name"),
MockRepository.GenerateStub<IUser>(), // user MockRepository.GenerateStub<IUser>(), // user
MockRepository.GenerateStub<IInUseStateInfoProvider>(), MockRepository.GenerateStub<IInUseStateInfoProvider>(),
MockRepository.GenerateStub<IBikesViewModel>(), MockRepository.GenerateStub<IBikesViewModel>(),
@ -71,7 +72,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
null, // viewUpdateManager null, // viewUpdateManager
NSubstitute.Substitute.For<ISmartDevice>(), NSubstitute.Substitute.For<ISmartDevice>(),
null, // viewService null, // viewService
new TINK.Model.Bikes.BikeInfoNS.BC.BikeInfoMutable(new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("42", TINK.Model.Bikes.BikeInfoNS.BikeNS.LockModel.ILockIt), new Drive(), 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "42"), "My Station Name"), new TINK.Model.Bikes.BikeInfoNS.BC.BikeInfoMutable(new TINK.Model.Bikes.BikeInfoNS.BluetoothLock.BikeInfo(new TINK.Model.Bikes.BikeInfoNS.BikeNS.Bike("42", TINK.Model.Bikes.BikeInfoNS.BikeNS.LockModel.ILockIt), new Drive(), DataSource.Copri, 5200544, new Guid("00000000-0000-0000-0000-000000000001"), "42"), "My Station Name"),
MockRepository.GenerateStub<IUser>(), // user MockRepository.GenerateStub<IUser>(), // user
MockRepository.GenerateStub<IInUseStateInfoProvider>(), MockRepository.GenerateStub<IInUseStateInfoProvider>(),
MockRepository.GenerateStub<IBikesViewModel>(), MockRepository.GenerateStub<IBikesViewModel>(),

View file

@ -605,7 +605,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
Assert.IsFalse(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible."); Assert.IsFalse(myBikes.IsBikesListVisible, "If there are any bikes, list must be visible.");
Assert.IsTrue(myBikes.IsNoBikesOccupiedVisible); Assert.IsTrue(myBikes.IsNoBikesOccupiedVisible);
Assert.AreEqual("Momentan sind keine Fahrräder auf Benutzer a@b reserviert/ gebucht.", myBikes.NoBikesOccupiedText); Assert.AreEqual("There are currently no bicycles reserved/booked on user a@b.", myBikes.NoBikesOccupiedText);
} }
[Test] [Test]