mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2024-12-22 06:56:25 +01:00
Version 3.0.366
This commit is contained in:
parent
0eb7362cb8
commit
24cdfbb0ca
84 changed files with 900 additions and 393 deletions
|
@ -12,3 +12,4 @@ sharee
|
|||
tink
|
||||
ui
|
||||
xdoc
|
||||
xml
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.LastenradBayern" android:versionName="3.0.365" android:versionCode="365">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.LastenradBayern" android:versionName="3.0.366" android:versionCode="366">
|
||||
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="31" />
|
||||
<!-- Google Maps related permissions -->
|
||||
<!-- Permission to receive remote notifications from Google Play Services -->
|
||||
|
|
|
@ -56,8 +56,8 @@
|
|||
<key>CFBundleDisplayName</key>
|
||||
<string>LastenradBayern</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>365</string>
|
||||
<string>366</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>3.0.365</string>
|
||||
<string>3.0.366</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html xml:lang="de" lang="de">
|
||||
<title>TINK Konstanz</title>
|
||||
<meta charset="utf-8"/>
|
||||
<body>
|
||||
<h1>WIE FUNKTIONIERT DAS TRANSPORTRAD-MIETEN?</h1>
|
||||
<h2>Erstmalige Registrierung</h2><br>
|
||||
Vor der ersten Anmietung eines Transportrades ist es notwendig, sich
|
||||
kostenlos als Nutzerin oder Nutzer zu registrieren. Das dauert nur
|
||||
wenige Minuten und geht am einfachsten über den <a href="https://tink-konstanz.de/TINK-Konstanz/Mieten">Mieten</a> Button. Sobald der Account freigeschaltet ist, kann es losgehen.<br><br>
|
||||
<h2>Transportrad mieten</h2><br>
|
||||
Einfach zur nächsten TINK Station gehen (freie Räder siehe Karte) und den Code
|
||||
für das Zahlenschloss mittels SMS anfordern. Die Anleitung, wie es genau
|
||||
geht, findet sich direkt an den Stationen, auf den Rädern oder hier: <br><a href="https://tink-konstanz.de/TINK-Konstanz/Anleitungen#3401">
|
||||
<li>Anleitung Mietvorgang</a><br><a href="https://tink-konstanz.de/TINK-Konstanz/Anleitungen#3402">
|
||||
<li>Anleitung TINK Räder</a><br>
|
||||
<span style="font-weight:bold"> <li>Wichtig:</span> Nach der Nutzung das Rad an eine der TINK Stationen zurückbringen, an der Station anschließen und mittels SMS ausloggen.<br><br>
|
||||
Die erste Version der TINK APP ist verfügbar. Wir freuen uns auf konstruktives feedback.
|
||||
<br><br><h2>Preise</h2><br>
|
||||
Die erste Stunde pro Tag ist kostenfrei, danach kostet jede weitere halbe Stunde 1 Euro. Maximal
|
||||
kostet ein Rad pro 24 Stunden 9 Euro. Es kann ein Rad pro Account
|
||||
gemietet werden. Bezahlung per Abbuchung oder Kreditkarte.<br>Servicegebühren:
|
||||
Bei Abstellen eines Rades außerhalb der Stationen werden
|
||||
entfernungsabhängige Gebühren für die Rückführung berechnet. Aktuelle
|
||||
Preisliste siehe AGBs.</div>
|
||||
<h1>WELCHE TRANSPORTRÄDER GIBT ES BEI TINK?</h1>
|
||||
<div class="content2"><span class="content1">Zweirädriges Transportrad mit Platz für zwei Getränkekisten, Zuladung bis 80 kg. <br>Dreirädriges Transportrad sogar mit Platz für vier Getränkekisten, Zuladung bis 100 kg.</span><br>Jedes
|
||||
Rad verfügt über eine leichtgängige Achtgang-Schaltung und einen
|
||||
höhenverstellbaren Sattel. Im Zweirad können 2 Kinder, im Dreirad sogar 4
|
||||
Kinder bis 6 Jahre mitgenommen werden. Die wegklappbaren Kindersitze
|
||||
verfügen über Sicherheitsgurte.<br>Die Räder sind nach etwas Gewöhnung
|
||||
leicht und sicher zu fahren. Vor der ersten Nutzung empfehlen wir ein
|
||||
kurzes Üben ohne Beladung abseits des Straßenverkehrs. Einfach mal
|
||||
ausprobieren, es macht richtig Spaß!
|
||||
</body>
|
||||
</html>
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.Meinkonrad" android:versionName="3.0.365" android:versionCode="365">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.TeilRad.Meinkonrad" android:versionName="3.0.366" android:versionCode="366">
|
||||
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="31" />
|
||||
<!-- Google Maps related permissions -->
|
||||
<!-- Permission to receive remote notifications from Google Play Services -->
|
||||
|
|
|
@ -56,8 +56,8 @@
|
|||
<key>CFBundleDisplayName</key>
|
||||
<string>Mein konrad</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>365</string>
|
||||
<string>366</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>3.0.365</string>
|
||||
<string>3.0.366</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TINK.View.FindBike.FindBikePage"
|
||||
xmlns:conv="clr-namespace:TINK.View"
|
||||
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
|
||||
xmlns:local_bike="clr-namespace:TINK.View.Bike"
|
||||
xmlns:sharedGui="clr-namespace:ShareeSharedGuiLib.View"
|
||||
|
@ -17,6 +18,7 @@
|
|||
<ContentPage.Resources>
|
||||
<ResourceDictionary>
|
||||
<local_bike:BikeViewCellTemplateSelector x:Key="bikeTemplateSelector"/>
|
||||
<conv:StringNotNullOrEmptyToVisibleConverter x:Key="Label_Converter"/>
|
||||
</ResourceDictionary>
|
||||
</ContentPage.Resources>
|
||||
|
||||
|
@ -25,56 +27,101 @@
|
|||
<!--Grid for Bike(s) view and Running process in same row-->
|
||||
<Grid>
|
||||
|
||||
<!-- Grid for Content -->
|
||||
<Grid
|
||||
RowDefinitions="1*,Auto"
|
||||
RowDefinitions="1*,Auto"
|
||||
RowSpacing="0"
|
||||
Grid.Row="0">
|
||||
Grid.Row="0">
|
||||
|
||||
<StackLayout
|
||||
Grid.Row="0"
|
||||
Spacing="0"
|
||||
Orientation="Vertical">
|
||||
Grid.Row="0"
|
||||
Spacing="0"
|
||||
Orientation="Vertical">
|
||||
|
||||
<!--No Network Connection-->
|
||||
<sharedGui:NotConnectedToNetView/>
|
||||
<StackLayout
|
||||
BackgroundColor="White"
|
||||
Padding="20,5,20,0">
|
||||
|
||||
<!--Search bike-->
|
||||
<Frame
|
||||
Padding="10"
|
||||
Margin="0,10,0,5"
|
||||
IsVisible="{Binding IsSelectBikeVisible}"
|
||||
HorizontalOptions="FillAndExpand"
|
||||
BackgroundColor="White">
|
||||
<!--Bike type-->
|
||||
<StackLayout Orientation="Horizontal"
|
||||
HorizontalOptions="Center"
|
||||
IsVisible="{Binding ActiveFilteredBikeType, Converter={StaticResource Label_Converter}}"
|
||||
Spacing="0">
|
||||
<Label
|
||||
TextColor="DimGray"
|
||||
Text="{x:Static resources:AppResources.MarkingFindBikeTypeOfBikeText}"/>
|
||||
<Label
|
||||
TextColor="{DynamicResource primary-back-title-color}"
|
||||
FontAttributes="Bold"
|
||||
Text="{Binding ActiveFilteredBikeType}"/>
|
||||
<Button
|
||||
Command="{Binding ShowFilterBikeTypeInfoCommand}"
|
||||
WidthRequest="24"
|
||||
HeightRequest="24"
|
||||
BackgroundColor="Transparent"
|
||||
BorderWidth="0"
|
||||
Padding="0"
|
||||
Margin="5,0,0,0">
|
||||
<Button.ImageSource>
|
||||
<FontImageSource
|
||||
Glyph="{StaticResource InfoCircle}"
|
||||
Color="DimGray"
|
||||
FontFamily="FA-S"
|
||||
Size="20"/>
|
||||
</Button.ImageSource>
|
||||
</Button>
|
||||
</StackLayout>
|
||||
|
||||
<StackLayout
|
||||
Padding="20">
|
||||
<Grid
|
||||
RowDefinitions="Auto,Auto"
|
||||
ColumnDefinitions="*,Auto">
|
||||
|
||||
<Label Text="{x:Static resources:AppResources.MarkingFindBikeLabel}"
|
||||
Margin="0,0,0,-5">
|
||||
<!--Search bike-->
|
||||
<Label
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Grid.Row="0"
|
||||
Text="{x:Static resources:AppResources.MarkingFindBikeLabel}"
|
||||
Margin="0,5,0,-5">
|
||||
<Label.Triggers>
|
||||
<DataTrigger
|
||||
TargetType="Label"
|
||||
Binding="{Binding Source={x:Reference FindBikeEntry}, Path=Text, TargetNullValue=''}"
|
||||
Value="">
|
||||
TargetType="Label"
|
||||
Binding="{Binding Source={x:Reference FindBikeEntry}, Path=Text, TargetNullValue=''}"
|
||||
Value="">
|
||||
<Setter Property="IsVisible" Value="False" />
|
||||
</DataTrigger>
|
||||
</Label.Triggers>
|
||||
</Label>
|
||||
<Entry
|
||||
Grid.Column="0"
|
||||
Grid.Row="1"
|
||||
x:Name="FindBikeEntry"
|
||||
Placeholder="{x:Static resources:AppResources.PlaceholderFindBike}"
|
||||
MaxLength="10"
|
||||
CursorPosition="0"
|
||||
Text="{Binding BikeIdUserInput}"/>
|
||||
Text="{Binding BikeIdUserInput, Mode=TwoWay}"/>
|
||||
|
||||
<Button
|
||||
Text="{x:Static resources:AppResources.MarkingSearchBike}"
|
||||
Grid.Column="1"
|
||||
Grid.Row="1"
|
||||
WidthRequest="100"
|
||||
Text="{x:Static resources:AppResources.MarkingFindBikeButton}"
|
||||
IsEnabled="{Binding IsSelectBikeEnabled}"
|
||||
Command="{Binding OnSelectBikeRequest}"/>
|
||||
|
||||
</StackLayout>
|
||||
</Grid>
|
||||
|
||||
</Frame>
|
||||
<!--Line-->
|
||||
<BoxView
|
||||
HeightRequest="1"
|
||||
WidthRequest="400"
|
||||
HorizontalOptions="Center"
|
||||
Color="{DynamicResource primary-back-title-color}"/>
|
||||
|
||||
</StackLayout>
|
||||
|
||||
<!--No Network Connection-->
|
||||
<sharedGui:NotConnectedToNetView/>
|
||||
|
||||
<!-- Bike -->
|
||||
<StackLayout
|
||||
|
@ -86,16 +133,16 @@
|
|||
<sharedGui:HintForRefreshingPageView/>
|
||||
|
||||
<ListView
|
||||
x:Name="FindBikeListView"
|
||||
SelectionMode="None"
|
||||
SelectedItem="{Binding SelectedBike}"
|
||||
IsEnabled="{Binding IsIdle}"
|
||||
HasUnevenRows="True"
|
||||
SeparatorVisibility="None"
|
||||
ItemTemplate="{StaticResource bikeTemplateSelector}"
|
||||
IsPullToRefreshEnabled="True"
|
||||
RefreshCommand="{Binding RefreshCommand}"
|
||||
IsRefreshing="{Binding IsRefreshing}"/>
|
||||
x:Name="FindBikeListView"
|
||||
SelectionMode="None"
|
||||
SelectedItem="{Binding SelectedBike}"
|
||||
IsEnabled="{Binding IsIdle}"
|
||||
HasUnevenRows="True"
|
||||
SeparatorVisibility="None"
|
||||
ItemTemplate="{StaticResource bikeTemplateSelector}"
|
||||
IsPullToRefreshEnabled="True"
|
||||
RefreshCommand="{Binding RefreshCommand}"
|
||||
IsRefreshing="{Binding IsRefreshing}"/>
|
||||
|
||||
</StackLayout>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.hauffware.sharee" android:versionName="3.0.365" android:versionCode="365">
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="internalOnly" package="com.hauffware.sharee" android:versionName="3.0.366" android:versionCode="366">
|
||||
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="31" />
|
||||
<!-- Google Maps related permissions -->
|
||||
<!-- Permission to receive remote notifications from Google Play Services -->
|
||||
|
|
|
@ -56,8 +56,8 @@
|
|||
<key>CFBundleDisplayName</key>
|
||||
<string>sharee.bike</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>365</string>
|
||||
<string>366</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>3.0.365</string>
|
||||
<string>3.0.366</string>
|
||||
</dict>
|
||||
</plist>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
x:Class="TINK.View.FindBike.FindBikePage"
|
||||
xmlns:conv="clr-namespace:TINK.View"
|
||||
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
|
||||
xmlns:local_bike="clr-namespace:TINK.View.Bike"
|
||||
xmlns:sharedGui="clr-namespace:ShareeSharedGuiLib.View"
|
||||
|
@ -18,6 +19,7 @@
|
|||
<ContentPage.Resources>
|
||||
<ResourceDictionary>
|
||||
<local_bike:BikeViewCellTemplateSelector x:Key="bikeTemplateSelector"/>
|
||||
<conv:StringNotNullOrEmptyToVisibleConverter x:Key="Label_Converter"/>
|
||||
</ResourceDictionary>
|
||||
</ContentPage.Resources>
|
||||
|
||||
|
@ -26,56 +28,71 @@
|
|||
<!--Grid for Bike(s) view and Running process in same row-->
|
||||
<Grid>
|
||||
|
||||
<!-- Grid for Content -->
|
||||
<Grid
|
||||
RowDefinitions="1*,Auto"
|
||||
RowDefinitions="1*,Auto"
|
||||
RowSpacing="0"
|
||||
Grid.Row="0">
|
||||
Grid.Row="0">
|
||||
|
||||
<StackLayout
|
||||
Grid.Row="0"
|
||||
Spacing="0"
|
||||
Orientation="Vertical">
|
||||
Grid.Row="0"
|
||||
Spacing="0"
|
||||
Orientation="Vertical">
|
||||
|
||||
<!--No Network Connection-->
|
||||
<sharedGui:NotConnectedToNetView/>
|
||||
<StackLayout
|
||||
BackgroundColor="White"
|
||||
Padding="20,0,20,0">
|
||||
|
||||
<!--Search bike-->
|
||||
<Frame
|
||||
Padding="10"
|
||||
Margin="0,10,0,5"
|
||||
IsVisible="{Binding IsSelectBikeVisible}"
|
||||
HorizontalOptions="FillAndExpand"
|
||||
BackgroundColor="White">
|
||||
<Grid
|
||||
RowDefinitions="Auto,Auto"
|
||||
ColumnDefinitions="*,Auto">
|
||||
|
||||
<StackLayout
|
||||
Padding="20">
|
||||
|
||||
<Label Text="{x:Static resources:AppResources.MarkingFindBikeLabel}"
|
||||
Margin="0,0,0,-5">
|
||||
<!--Search bike-->
|
||||
<Label
|
||||
Grid.Column="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Grid.Row="0"
|
||||
Text="{x:Static resources:AppResources.MarkingFindBikeLabel}"
|
||||
Margin="0,5,0,-5">
|
||||
<Label.Triggers>
|
||||
<DataTrigger
|
||||
TargetType="Label"
|
||||
Binding="{Binding Source={x:Reference FindBikeEntry}, Path=Text, TargetNullValue=''}"
|
||||
Value="">
|
||||
TargetType="Label"
|
||||
Binding="{Binding Source={x:Reference FindBikeEntry}, Path=Text, TargetNullValue=''}"
|
||||
Value="">
|
||||
<Setter Property="IsVisible" Value="False" />
|
||||
</DataTrigger>
|
||||
</Label.Triggers>
|
||||
</Label>
|
||||
<Entry
|
||||
Grid.Column="0"
|
||||
Grid.Row="1"
|
||||
x:Name="FindBikeEntry"
|
||||
Placeholder="{x:Static resources:AppResources.PlaceholderFindBike}"
|
||||
MaxLength="10"
|
||||
CursorPosition="0"
|
||||
Text="{Binding BikeIdUserInput}"/>
|
||||
Text="{Binding BikeIdUserInput, Mode=TwoWay}"/>
|
||||
|
||||
<Button
|
||||
Text="{x:Static resources:AppResources.MarkingSearchBike}"
|
||||
Grid.Column="1"
|
||||
Grid.Row="1"
|
||||
WidthRequest="100"
|
||||
Text="{x:Static resources:AppResources.MarkingFindBikeButton}"
|
||||
IsEnabled="{Binding IsSelectBikeEnabled}"
|
||||
Command="{Binding OnSelectBikeRequest}"/>
|
||||
|
||||
</StackLayout>
|
||||
</Grid>
|
||||
|
||||
</Frame>
|
||||
<!--Line-->
|
||||
<BoxView
|
||||
HeightRequest="1"
|
||||
WidthRequest="400"
|
||||
HorizontalOptions="Center"
|
||||
Color="{DynamicResource primary-back-title-color}"/>
|
||||
|
||||
</StackLayout>
|
||||
|
||||
<!--No Network Connection-->
|
||||
<sharedGui:NotConnectedToNetView/>
|
||||
|
||||
<!-- Bike -->
|
||||
<StackLayout
|
||||
|
@ -87,16 +104,16 @@
|
|||
<sharedGui:HintForRefreshingPageView/>
|
||||
|
||||
<ListView
|
||||
x:Name="FindBikeListView"
|
||||
SelectionMode="None"
|
||||
SelectedItem="{Binding SelectedBike}"
|
||||
IsEnabled="{Binding IsIdle}"
|
||||
HasUnevenRows="True"
|
||||
SeparatorVisibility="None"
|
||||
ItemTemplate="{StaticResource bikeTemplateSelector}"
|
||||
IsPullToRefreshEnabled="True"
|
||||
RefreshCommand="{Binding RefreshCommand}"
|
||||
IsRefreshing="{Binding IsRefreshing}"/>
|
||||
x:Name="FindBikeListView"
|
||||
SelectionMode="None"
|
||||
SelectedItem="{Binding SelectedBike}"
|
||||
IsEnabled="{Binding IsIdle}"
|
||||
HasUnevenRows="True"
|
||||
SeparatorVisibility="None"
|
||||
ItemTemplate="{StaticResource bikeTemplateSelector}"
|
||||
IsPullToRefreshEnabled="True"
|
||||
RefreshCommand="{Binding RefreshCommand}"
|
||||
IsRefreshing="{Binding IsRefreshing}"/>
|
||||
|
||||
</StackLayout>
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
|
|||
private readonly StateInfoMutable _StateInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Constructs a bike.
|
||||
/// Constructs a bike info object.
|
||||
/// </summary>
|
||||
/// <param name="isDemo">True if device is demo device, false otherwise.</param>
|
||||
/// <param name="dateTimeProvider">Provider for current date time to calculate remaining time on demand for state of type reserved.</param>
|
||||
|
@ -38,7 +38,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
|
|||
string stationId = null,
|
||||
string stationName = null,
|
||||
Uri operatorUri = null,
|
||||
RentalDescription tariffDescription = null,
|
||||
IRentalDescription tariffDescription = null,
|
||||
Func<DateTime> dateTimeProvider = null,
|
||||
IStateInfo stateInfo = null)
|
||||
{
|
||||
|
@ -65,7 +65,7 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
|
|||
|
||||
/// <summary> Holds description about the tariff. </summary>
|
||||
[DataMember]
|
||||
public RentalDescription TariffDescription { get; private set; }
|
||||
public IRentalDescription TariffDescription { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds the rent state of the bike.
|
||||
|
|
|
@ -64,6 +64,11 @@ namespace TINK.Model.Bikes.BikeInfoNS.BC
|
|||
/// <summary> Gets or sets the information where the data origins from. </summary>
|
||||
DataSource DataSource { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or set the rental description.
|
||||
/// </summary>
|
||||
IRentalDescription TariffDescription { get; }
|
||||
|
||||
event PropertyChangedEventHandler PropertyChanged;
|
||||
}
|
||||
|
||||
|
|
|
@ -83,8 +83,9 @@ namespace TINK.Model.Bikes.BikeInfoNS.BluetoothLock
|
|||
new StateInfo(
|
||||
dateTimeProvider,
|
||||
requestedAt,
|
||||
tariffDescription?.MaxReservationTimeSpan ?? StateRequestedInfo.UNKNOWNMAXRESERVATIONTIMESPAN,
|
||||
mailAddress,
|
||||
""),
|
||||
"" ), // BC code
|
||||
bike != null
|
||||
? new Bike(
|
||||
bike.Id,
|
||||
|
|
|
@ -84,8 +84,9 @@ namespace TINK.Model.Bikes.BikeInfoNS.CopriLock
|
|||
new StateInfo(
|
||||
dateTimeProvider,
|
||||
requestedAt,
|
||||
tariffDescription?.MaxReservationTimeSpan ?? StateRequestedInfo.UNKNOWNMAXRESERVATIONTIMESPAN,
|
||||
mailAddress,
|
||||
""),
|
||||
""), // BC code
|
||||
bike != null
|
||||
? new Bike(
|
||||
bike.Id,
|
||||
|
|
29
TINKLib/Model/Bikes/BikeInfoNS/IRentalDescription.cs
Normal file
29
TINKLib/Model/Bikes/BikeInfoNS/IRentalDescription.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using static TINK.Model.Bikes.BikeInfoNS.RentalDescription;
|
||||
|
||||
namespace TINK.Model.Bikes.BikeInfoNS
|
||||
{
|
||||
public interface IRentalDescription
|
||||
{
|
||||
/// <summary>
|
||||
/// Name of the tariff.
|
||||
/// </summary>
|
||||
string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds the time span for which a bike can be reserved.
|
||||
/// </summary>
|
||||
TimeSpan MaxReservationTimeSpan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Dynamic language aware tariff elements to be displayed to user.
|
||||
/// </summary>
|
||||
Dictionary<string, TariffElement> TariffEntries { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Well known language aware elements (AGB, tracking info, ...) to be displayed to user.
|
||||
/// </summary>
|
||||
Dictionary<string, InfoElement> InfoEntries { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TINK.Model.Bikes.BikeInfoNS
|
||||
|
@ -6,20 +7,20 @@ namespace TINK.Model.Bikes.BikeInfoNS
|
|||
/// Successor of TarifDescription- object.
|
||||
/// Manages tariff- and rental info.
|
||||
/// </summary>
|
||||
public class RentalDescription
|
||||
public class RentalDescription : IRentalDescription
|
||||
{
|
||||
/// <summary>
|
||||
/// The different elements of a tariff (example: "Max Gebühr", )
|
||||
/// The different elements of a tariff (example: "Max Gebühr", ) to be displayed by sharee.bike without processing
|
||||
/// </summary>
|
||||
public class TariffElement
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the tariff element. To be displayed to user (example of elements: "Gratis Mietzeit", "Mietgebühr", "Max Gebühr").
|
||||
/// Describes the tariff element (language aware). To be displayed to user (example of elements: "Gratis Mietzeit", "Mietgebühr", "Max Gebühr").
|
||||
/// </summary>
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Holds the tariff element value. To be displayed to user (example: "9.00 € / Tag").
|
||||
/// Holds the tariff element value (language aware, i.e. value from backend might be english, german, ... depending on smart phone value). To be displayed to user (example: "9.00 € / Tag").
|
||||
/// </summary>
|
||||
public string Value { get; set; } = string.Empty;
|
||||
}
|
||||
|
@ -30,12 +31,12 @@ namespace TINK.Model.Bikes.BikeInfoNS
|
|||
public class InfoElement
|
||||
{
|
||||
/// <summary>
|
||||
/// Key which identyfies the value (required for special processing)
|
||||
/// Key which identifies the value (required for special processing)
|
||||
/// </summary>
|
||||
public string Key { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Text to be displayed to user.
|
||||
/// Text (language aware) to be displayed to user.
|
||||
/// </summary>
|
||||
public string Value { get; set; }
|
||||
}
|
||||
|
@ -50,8 +51,19 @@ namespace TINK.Model.Bikes.BikeInfoNS
|
|||
/// </summary>
|
||||
public int? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds the time span for which a bike can be reserved.
|
||||
/// </summary>
|
||||
public TimeSpan MaxReservationTimeSpan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Dynamic language aware tariff elements to be displayed to user.
|
||||
/// </summary>
|
||||
public Dictionary<string, TariffElement> TariffEntries { get; set; } = new Dictionary<string, TariffElement>();
|
||||
|
||||
/// <summary>
|
||||
/// Well known language aware elements (AGB, tracking info, ...) to be displayed to user.
|
||||
/// </summary>
|
||||
public Dictionary<string, InfoElement> InfoEntries { get; set; } = new Dictionary<string, InfoElement>();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -438,5 +438,20 @@ namespace TINK.Model.Connector
|
|||
name,
|
||||
int.TryParse(bikeGroup?.bike_count ?? "0", out var countCity) ? countCity : 0,
|
||||
bikeGroup?.bike_group ?? string.Empty);
|
||||
|
||||
/// <summary>
|
||||
/// Default value for reserve_timerange.
|
||||
/// </summary>
|
||||
private static int DEFAULTMAXRESERVATIONTIMESPAN = 15;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the reservation time span from response.
|
||||
/// </summary>
|
||||
/// <param name="description">Response to get time span from.</param>
|
||||
/// <returns>Time span.</returns>
|
||||
public static TimeSpan GetMaxReservationTimeSpan(this RentalDescription description) =>
|
||||
TimeSpan.FromMinutes(int.TryParse(description?.reserve_timerange, out int minutes)
|
||||
? minutes
|
||||
: DEFAULTMAXRESERVATIONTIMESPAN );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -313,7 +313,7 @@ namespace TINK.Model.Connector.Updater
|
|||
}
|
||||
catch (ArgumentException ex)
|
||||
{
|
||||
// Contructor reported invalid arguemts (missing lock id, ....).
|
||||
// Constructor reported invalid arguments (missing lock id, ....).
|
||||
Log.Error($"Can not create new {nameof(BikeInfo)}-object from {nameof(BikeInfoReservedOrBooked)} argument. Invalid response detected. Booked bike with id {bikeInfo.bike} skipped. {ex.Message}");
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1,58 +1,56 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TINK.Model.Bikes.BikeInfoNS;
|
||||
|
||||
namespace TINK.Model.Connector.Updater
|
||||
{
|
||||
public static class RentalDescriptionFactory
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates rental description object from JSON- tarif description object.
|
||||
/// Creates rental description object from JSON- tariff description object.
|
||||
/// </summary>
|
||||
/// <param name="rentalDesciption">Source JSON object.</param>
|
||||
/// <returns>Tariff description object.</returns>
|
||||
|
||||
public static Bikes.BikeInfoNS.RentalDescription Create(this Repository.Response.RentalDescription rentalDesciption)
|
||||
public static RentalDescription Create(this Repository.Response.RentalDescription rentalDesciption)
|
||||
{
|
||||
Bikes.BikeInfoNS.RentalDescription.TariffElement CreateTarifEntry(string[] elementValue)
|
||||
{
|
||||
return new Bikes.BikeInfoNS.RentalDescription.TariffElement
|
||||
{
|
||||
Description = elementValue != null && elementValue.Length > 0 ? elementValue[0] : string.Empty,
|
||||
Value = elementValue != null && elementValue.Length > 1 ? elementValue[1] : string.Empty,
|
||||
};
|
||||
}
|
||||
RentalDescription.TariffElement CreateTarifEntry(string[] elementValue) =>
|
||||
new RentalDescription.TariffElement
|
||||
{
|
||||
Description = elementValue != null && elementValue.Length > 0 ? elementValue[0] : string.Empty,
|
||||
Value = elementValue != null && elementValue.Length > 1 ? elementValue[1] : string.Empty,
|
||||
};
|
||||
|
||||
Bikes.BikeInfoNS.RentalDescription.InfoElement CreateInfoElement(string[] elementValue)
|
||||
{
|
||||
return new Bikes.BikeInfoNS.RentalDescription.InfoElement
|
||||
RentalDescription.InfoElement CreateInfoElement(string[] elementValue) =>
|
||||
new RentalDescription.InfoElement
|
||||
{
|
||||
Key = elementValue != null && elementValue.Length > 0 ? elementValue[0] : string.Empty,
|
||||
Value = elementValue != null && elementValue.Length > 1 ? elementValue[1] : string.Empty,
|
||||
};
|
||||
}
|
||||
|
||||
// Read tariff elements.
|
||||
var tarifEntries = rentalDesciption?.tarif_elements != null
|
||||
? rentalDesciption.tarif_elements.Select(x => new
|
||||
{
|
||||
Key = x.Key,
|
||||
x.Key,
|
||||
Value = CreateTarifEntry(x.Value)
|
||||
}).ToLookup(x => x.Key, x => x.Value).ToDictionary(x => x.Key, x => x.First())
|
||||
: new Dictionary<string, Bikes.BikeInfoNS.RentalDescription.TariffElement>();
|
||||
: new Dictionary<string, RentalDescription.TariffElement>();
|
||||
|
||||
// Read info elements.
|
||||
var InfoEntries = rentalDesciption?.rental_info != null
|
||||
? rentalDesciption.rental_info.Select(x => new
|
||||
{
|
||||
Key = x.Key,
|
||||
x.Key,
|
||||
Value = CreateInfoElement(x.Value)
|
||||
}).ToLookup(x => x.Key, x => x.Value).ToDictionary(x => x.Key, x => x.First())
|
||||
: new Dictionary<string, Bikes.BikeInfoNS.RentalDescription.InfoElement>();
|
||||
: new Dictionary<string, RentalDescription.InfoElement>();
|
||||
|
||||
var bike = new Bikes.BikeInfoNS.RentalDescription
|
||||
var bike = new RentalDescription
|
||||
{
|
||||
Name = rentalDesciption?.name ?? string.Empty,
|
||||
Id = int.TryParse(rentalDesciption?.id ?? string.Empty, out int number) ? number : (int?)null,
|
||||
MaxReservationTimeSpan = rentalDesciption.GetMaxReservationTimeSpan(),
|
||||
TariffEntries = tarifEntries,
|
||||
InfoEntries = InfoEntries
|
||||
};
|
||||
|
|
|
@ -2,13 +2,11 @@ using System;
|
|||
using TINK.Model.Bikes.BikeInfoNS.BC;
|
||||
using TINK.Model.State;
|
||||
using TINK.Model.Stations;
|
||||
using TINK.Model.Stations.StationNS.Operator;
|
||||
using TINK.Model.User.Account;
|
||||
using TINK.Repository.Exception;
|
||||
using TINK.Repository.Response;
|
||||
using TINK.Repository.Response.Stations;
|
||||
using TINK.Services.CopriApi;
|
||||
using Xamarin.Forms;
|
||||
using IBikeInfoMutable = TINK.Model.Bikes.BikeInfoNS.BC.IBikeInfoMutable;
|
||||
|
||||
namespace TINK.Model.Connector.Updater
|
||||
|
@ -135,6 +133,7 @@ namespace TINK.Model.Connector.Updater
|
|||
bike.State.Load(
|
||||
InUseStateEnum.Reserved,
|
||||
bikeInfo.GetFrom(),
|
||||
bikeInfo.rental_description.GetMaxReservationTimeSpan(),
|
||||
mailAddress,
|
||||
bikeInfo.timeCode,
|
||||
notifyLevel);
|
||||
|
@ -144,9 +143,9 @@ namespace TINK.Model.Connector.Updater
|
|||
bike.State.Load(
|
||||
InUseStateEnum.Booked,
|
||||
bikeInfo.GetFrom(),
|
||||
mailAddress,
|
||||
bikeInfo.timeCode,
|
||||
notifyLevel);
|
||||
mailAddress: mailAddress,
|
||||
code: bikeInfo.timeCode,
|
||||
notifyLevel: notifyLevel);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System.Runtime.Serialization;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace TINK.Model.State
|
||||
{
|
||||
|
@ -12,7 +12,7 @@ namespace TINK.Model.State
|
|||
[KnownType(typeof(StateOccupiedInfo))]
|
||||
public abstract class BaseState
|
||||
{
|
||||
/// <summary> Constructor for Json serialization. </summary>
|
||||
/// <summary> Constructor for JSON serialization. </summary>
|
||||
/// <param name="value">State value.</param>
|
||||
protected BaseState(InUseStateEnum value) { }
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
|
||||
namespace TINK.Model.State
|
||||
{
|
||||
|
@ -9,8 +9,16 @@ namespace TINK.Model.State
|
|||
{
|
||||
string MailAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Date of request/ booking action.
|
||||
/// </summary>
|
||||
DateTime? From { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Time span for which a bike can be reserved.
|
||||
/// </summary>
|
||||
TimeSpan? MaxReservationTimeSpan { get; }
|
||||
|
||||
string Code { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
|
||||
namespace TINK.Model.State
|
||||
{
|
||||
|
@ -6,15 +6,17 @@ namespace TINK.Model.State
|
|||
{
|
||||
InUseStateEnum Value { get; }
|
||||
|
||||
/// <summary> Updates state from webserver. </summary>
|
||||
/// <summary> Updates state from web server. </summary>
|
||||
/// <param name="state">State of the bike.</param>
|
||||
/// <param name="from">Date time when bike was reserved/ booked.</param>
|
||||
/// <param name="mailAddress">Mailaddress of the one which reserved/ booked.</param>
|
||||
/// <param name="reservationTimeSpan">Time span for which a bike can be reserved.</param>
|
||||
/// <param name="mailAddress">Mail address of the one which reserved/ booked.</param>
|
||||
/// <param name="code">Booking code if bike is booked or reserved.</param>
|
||||
/// <param name="notifyLevel">Controls whether notify property changed events are fired or not.</param>
|
||||
void Load(
|
||||
InUseStateEnum state,
|
||||
DateTime? from = null,
|
||||
TimeSpan? reservationTimeSpan = null,
|
||||
string mailAddress = null,
|
||||
string code = null,
|
||||
Bikes.BikeInfoNS.BC.NotifyPropertyChangedLevel notifyLevel = Bikes.BikeInfoNS.BC.NotifyPropertyChangedLevel.All);
|
||||
|
|
|
@ -52,20 +52,21 @@ namespace TINK.Model.State
|
|||
/// Constructs a state info object when state is requested.
|
||||
/// </summary>
|
||||
/// <param name="requestedAt">Date time when bike was requested</param>
|
||||
/// <param name="maxReservationTimeSpan">Time span for which a bike can be reserved.</param>
|
||||
/// <param name="mailAddress">Mail address of user which requested bike.</param>
|
||||
/// <param name="code">Booking code.</param>
|
||||
/// <param name="dateTimeNowProvider">Date time provider to calculate remaining time.</param>
|
||||
public StateInfo(
|
||||
Func<DateTime> dateTimeNowProvider,
|
||||
DateTime requestedAt,
|
||||
TimeSpan maxReservationTimeSpan,
|
||||
string mailAddress,
|
||||
string code)
|
||||
{
|
||||
// Todo: Handle p_oFrom == null here.
|
||||
// Todo: Handle p_oDuration == null here.
|
||||
_InUseState = new StateRequestedInfo(
|
||||
dateTimeNowProvider ?? (() => DateTime.Now),
|
||||
requestedAt,
|
||||
maxReservationTimeSpan,
|
||||
mailAddress,
|
||||
code);
|
||||
}
|
||||
|
@ -81,9 +82,6 @@ namespace TINK.Model.State
|
|||
string p_strMailAddress,
|
||||
string p_strCode)
|
||||
{
|
||||
// Todo: Handle p_oFrom == null here.
|
||||
// Todo: Clearify question: What to do if code changes form one value to another? This should never happen.
|
||||
// Todo: Clearify question: What to do if from time changes form one value to another? This should never happen.
|
||||
_InUseState = new StateOccupiedInfo(
|
||||
p_oBookedAt,
|
||||
p_strMailAddress,
|
||||
|
@ -114,7 +112,7 @@ namespace TINK.Model.State
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Date of request/ bookeing action.
|
||||
/// Date of request/ booking action.
|
||||
/// </summary>
|
||||
public DateTime? From
|
||||
{
|
||||
|
@ -125,6 +123,14 @@ namespace TINK.Model.State
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Time span for which a bike can be reserved.
|
||||
/// </summary>
|
||||
public TimeSpan? MaxReservationTimeSpan =>
|
||||
_InUseState is StateRequestedInfo reserved
|
||||
? reserved.MaxReservationTimeSpan
|
||||
: (TimeSpan?)null;
|
||||
|
||||
/// <summary>
|
||||
/// Mail address.
|
||||
/// </summary>
|
||||
|
@ -152,7 +158,7 @@ namespace TINK.Model.State
|
|||
/// <summary>
|
||||
/// Tries update
|
||||
/// </summary>
|
||||
/// <returns>True if reservation span has not exeeded and state remains reserved, false otherwise.</returns>
|
||||
/// <returns>True if reservation span has not exceeded and state remains reserved, false otherwise.</returns>
|
||||
/// <todo>Implement logging of time stamps.</todo>
|
||||
public bool GetIsStillReserved(out TimeSpan? p_oRemainingTime)
|
||||
{
|
||||
|
|
|
@ -90,19 +90,18 @@ namespace TINK.Model.State
|
|||
return new StateInfo(state != null ? state.Value == InUseStateEnum.FeedbackPending : false);
|
||||
|
||||
case InUseStateEnum.Reserved:
|
||||
// Todo: Handle p_oFrom == null here.
|
||||
// Todo: Handle p_oDuration == null here.
|
||||
return new StateInfo(
|
||||
dateTimeNowProvider,
|
||||
state.From.Value,
|
||||
state.From.HasValue ? dateTimeNowProvider : (() => DateTime.MaxValue),
|
||||
state.From.HasValue ? state.From.Value : DateTime.MaxValue,
|
||||
state.MaxReservationTimeSpan ?? StateRequestedInfo.UNKNOWNMAXRESERVATIONTIMESPAN,
|
||||
state.MailAddress,
|
||||
state.Code);
|
||||
|
||||
|
||||
case InUseStateEnum.Booked:
|
||||
// Todo: Handle p_oFrom == null here.
|
||||
// Todo: Clearify question: What to do if code changes form one value to another? This should never happen.
|
||||
// Todo: Clearify question: What to do if from time changes form one value to another? This should never happen.
|
||||
// Todo: Clarify question: What to do if code changes form one value to another? This should never happen.
|
||||
// Todo: Clarify question: What to do if from time changes form one value to another? This should never happen.
|
||||
return new StateInfo(
|
||||
state.From.Value,
|
||||
state.MailAddress,
|
||||
|
@ -139,7 +138,7 @@ namespace TINK.Model.State
|
|||
var l_oStateRequested = value as StateRequestedInfo;
|
||||
if (l_oStateRequested != null)
|
||||
{
|
||||
_StateInfo = new StateInfo(_DateTimeNowProvider, l_oStateRequested.From, l_oStateRequested.MailAddress, l_oStateRequested.Code);
|
||||
_StateInfo = new StateInfo(_DateTimeNowProvider, l_oStateRequested.From, l_oStateRequested.MaxReservationTimeSpan, l_oStateRequested.MailAddress, l_oStateRequested.Code);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -158,7 +157,7 @@ namespace TINK.Model.State
|
|||
/// <summary>
|
||||
/// Checks and updates state if required.
|
||||
/// </summary>
|
||||
/// <returns>Value indicating wheter state has changed</returns>
|
||||
/// <returns>Value indicating whether state has changed</returns>
|
||||
public void UpdateOnTimeElapsed()
|
||||
{
|
||||
switch (_StateInfo.Value)
|
||||
|
@ -172,7 +171,7 @@ namespace TINK.Model.State
|
|||
// Check if maximum reserved time has elapsed.
|
||||
if (!_StateInfo.GetIsStillReserved(out _RemainingTime))
|
||||
{
|
||||
// Time has elapsed, switch state to disposable and notfiy client
|
||||
// Time has elapsed, switch state to disposable and notify client
|
||||
_StateInfo = new StateInfo();
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(State)));
|
||||
return;
|
||||
|
@ -181,15 +180,17 @@ namespace TINK.Model.State
|
|||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(RemainingTime)));
|
||||
}
|
||||
|
||||
/// <summary> Updates state from webserver. </summary>
|
||||
/// <summary> Updates state from web server. </summary>
|
||||
/// <param name="state">State of the bike.</param>
|
||||
/// <param name="from">Date time when bike was reserved/ booked.</param>
|
||||
/// <param name="mailAddress">Mailaddress of the one which reserved/ booked.</param>
|
||||
/// <param name="maxReservationTimeSpan">Time span for which a bike can be reserved.</param>
|
||||
/// <param name="mailAddress">Mail address of the one which reserved/ booked.</param>
|
||||
/// <param name="code">Booking code if bike is booked or reserved.</param>
|
||||
/// <param name="supressNotifyPropertyChanged">Controls whether notify property changed events are fired or not.</param>
|
||||
public void Load(
|
||||
InUseStateEnum state,
|
||||
DateTime? from = null,
|
||||
TimeSpan? maxReservationTimeSpan = null,
|
||||
string mailAddress = null,
|
||||
string code = null,
|
||||
Bikes.BikeInfoNS.BC.NotifyPropertyChangedLevel notifyLevel = Bikes.BikeInfoNS.BC.NotifyPropertyChangedLevel.All)
|
||||
|
@ -206,11 +207,10 @@ namespace TINK.Model.State
|
|||
break;
|
||||
|
||||
case InUseStateEnum.Reserved:
|
||||
// Todo: Handle p_oFrom == null here.
|
||||
// Todo: Handle p_oDuration == null here.
|
||||
_StateInfo = new StateInfo(
|
||||
_DateTimeNowProvider,
|
||||
from.Value,
|
||||
from.HasValue ? _DateTimeNowProvider : (() => DateTime.MaxValue),
|
||||
from.HasValue ? from.Value : DateTime.MaxValue,
|
||||
maxReservationTimeSpan.HasValue ? maxReservationTimeSpan.Value : StateRequestedInfo.UNKNOWNMAXRESERVATIONTIMESPAN,
|
||||
mailAddress,
|
||||
code);
|
||||
|
||||
|
@ -245,7 +245,7 @@ namespace TINK.Model.State
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// If bike is reserved time raimaining while bike stays reserved, null otherwise.
|
||||
/// If bike is reserved time remaining while bike stays reserved, null otherwise.
|
||||
/// </summary>
|
||||
public TimeSpan? RemainingTime
|
||||
{
|
||||
|
@ -261,7 +261,7 @@ namespace TINK.Model.State
|
|||
|
||||
if (_RemainingTime.HasValue == false)
|
||||
{
|
||||
// Value was not yet querried.
|
||||
// Value was not yet queried.
|
||||
// Do query before returning object.
|
||||
_StateInfo.GetIsStillReserved(out _RemainingTime);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
|
@ -10,17 +10,25 @@ namespace TINK.Model.State
|
|||
[DataContract]
|
||||
public sealed class StateRequestedInfo : BaseState, IBaseState, INotAvailableState
|
||||
{
|
||||
// Maximum time while reserving request is kept.
|
||||
public static readonly TimeSpan MaximumReserveTime = new TimeSpan(0, 15, 0); // 15 mins
|
||||
/// <summary>
|
||||
/// Holds the value if time span is not known.
|
||||
/// </summary>
|
||||
/// <remarks> Default value see <see cref="TextToTypeHelper.DEFAULTMAXRESERVATIONTIMESPAN"/>. </remarks>
|
||||
public static TimeSpan UNKNOWNMAXRESERVATIONTIMESPAN = TimeSpan.Zero;
|
||||
|
||||
// Reference to date time provider.
|
||||
private Func<DateTime> _DateTimeNowProvider;
|
||||
private readonly Func<DateTime> _DateTimeNowProvider;
|
||||
|
||||
/// <summary>
|
||||
/// Time span for which a bike can be reserved. Default value is zero.
|
||||
/// </summary>
|
||||
public TimeSpan MaxReservationTimeSpan { get; private set; } = UNKNOWNMAXRESERVATIONTIMESPAN;
|
||||
|
||||
/// <summary>
|
||||
/// Prevents an invalid instance to be created.
|
||||
/// Used by serializer only.
|
||||
/// </summary>
|
||||
private StateRequestedInfo() : base(InUseStateEnum.Reserved)
|
||||
internal StateRequestedInfo() : base(InUseStateEnum.Reserved)
|
||||
{
|
||||
// Is called in context of JSON deserialization.
|
||||
_DateTimeNowProvider = () => DateTime.Now;
|
||||
|
@ -28,33 +36,37 @@ namespace TINK.Model.State
|
|||
|
||||
/// <summary>
|
||||
/// Reservation performed with other device/ before start of app.
|
||||
/// Date time info when bike was reserved has been received from webserver.
|
||||
/// Date time info when bike was reserved has been received from web server.
|
||||
/// </summary>
|
||||
/// <param name="p_oRemainingTime">Time span which holds duration how long bike still will be reserved.</param>
|
||||
/// <param name="maxReservationTimeSpan">Time span for which a bike can be reserved.</param>
|
||||
[JsonConstructor]
|
||||
private StateRequestedInfo(
|
||||
InUseStateEnum Value,
|
||||
DateTime From,
|
||||
TimeSpan maxReservationTimeSpan,
|
||||
string MailAddress,
|
||||
string Code) : this(() => DateTime.Now, From, MailAddress, Code)
|
||||
string Code) : this(() => DateTime.Now, From, maxReservationTimeSpan, MailAddress, Code)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reservation performed with other device/ before start of app.
|
||||
/// Date time info when bike was reserved has been received from webserver.
|
||||
/// Date time info when bike was reserved has been received from web server.
|
||||
/// </summary>
|
||||
/// <param name="dateTimeNowProvider">
|
||||
/// Used to to provide current date time information for potential calls of <seealso cref="GetIsStillReserved"/>.
|
||||
/// Not used to calculate remaining time because this duration whould always be shorter as the one received from webserver.
|
||||
/// Used to provide current date time information for potential calls of <seealso cref="GetIsStillReserved"/>.
|
||||
/// Not used to calculate remaining time because this duration would always be shorter as the one received from web server.
|
||||
/// </param>
|
||||
/// <param name="maxReservationTimeSpan">Time span for which a bike can be reserved.</param>
|
||||
public StateRequestedInfo(
|
||||
Func<DateTime> dateTimeNowProvider,
|
||||
DateTime from,
|
||||
TimeSpan maxReservationTimeSpan,
|
||||
string mailAddress,
|
||||
string code) : base(InUseStateEnum.Reserved)
|
||||
{
|
||||
_DateTimeNowProvider = dateTimeNowProvider ?? (() => DateTime.Now);
|
||||
MaxReservationTimeSpan = maxReservationTimeSpan;
|
||||
From = from;
|
||||
MailAddress = mailAddress;
|
||||
Code = code;
|
||||
|
@ -63,34 +75,28 @@ namespace TINK.Model.State
|
|||
/// <summary>
|
||||
/// Tries update
|
||||
/// </summary>
|
||||
/// <returns>True if reservation span has not exeeded and state remains reserved, false otherwise.</returns>
|
||||
/// <returns>True if reservation span has not exceeded and state remains reserved, false otherwise.</returns>
|
||||
/// <todo>Implement logging of time stamps.</todo>
|
||||
public bool GetIsStillReserved(out TimeSpan? p_oRemainingTime)
|
||||
public bool GetIsStillReserved(out TimeSpan? remainingTime)
|
||||
{
|
||||
var l_oTimeReserved = _DateTimeNowProvider().Subtract(From);
|
||||
if (l_oTimeReserved > MaximumReserveTime)
|
||||
var timeReserved = _DateTimeNowProvider().Subtract(From);
|
||||
if (timeReserved > MaxReservationTimeSpan)
|
||||
|
||||
{
|
||||
// Reservation has elapsed. To not update remaining time.
|
||||
p_oRemainingTime = null;
|
||||
// Reservation has elapsed. Do not update remaining time.
|
||||
remainingTime = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
p_oRemainingTime = MaximumReserveTime - l_oTimeReserved;
|
||||
remainingTime = MaxReservationTimeSpan - timeReserved;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// State reserved.
|
||||
/// Setter exists only for serialization purposes.
|
||||
/// </summary>
|
||||
public override InUseStateEnum Value
|
||||
{
|
||||
get
|
||||
{
|
||||
return InUseStateEnum.Reserved;
|
||||
}
|
||||
}
|
||||
public override InUseStateEnum Value =>
|
||||
InUseStateEnum.Reserved;
|
||||
|
||||
/// <summary>
|
||||
/// Date time when bike was reserved.
|
||||
|
|
|
@ -692,6 +692,11 @@ namespace TINK.Model
|
|||
AppResources.ChangeLog_3_0_365_MK_SB,
|
||||
new List<AppFlavor> { AppFlavor.MeinKonrad, AppFlavor.ShareeBike }
|
||||
},
|
||||
{
|
||||
new Version(3, 0, 366),
|
||||
AppResources.ChangeLog_3_0_366_MK_SB,
|
||||
new List<AppFlavor> { AppFlavor.MeinKonrad, AppFlavor.ShareeBike }
|
||||
},
|
||||
};
|
||||
|
||||
/// <summary> Manges the whats new information.</summary>
|
||||
|
|
|
@ -802,6 +802,15 @@ namespace TINK.MultilingualResources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to On the "Select bike" page you can now search and rent several bikes one after the other. Afterwards you will find them under "My bikes"..
|
||||
/// </summary>
|
||||
public static string ChangeLog_3_0_366_MK_SB {
|
||||
get {
|
||||
return ResourceManager.GetString("ChangeLog_3_0_366_MK_SB", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to We have fixed some bugs. Enjoy the ride!.
|
||||
/// </summary>
|
||||
|
@ -2103,7 +2112,16 @@ namespace TINK.MultilingualResources {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Bike ID including prefix.
|
||||
/// Looks up a localized string similar to Search.
|
||||
/// </summary>
|
||||
public static string MarkingFindBikeButton {
|
||||
get {
|
||||
return ResourceManager.GetString("MarkingFindBikeButton", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Bike id.
|
||||
/// </summary>
|
||||
public static string MarkingFindBikeLabel {
|
||||
get {
|
||||
|
@ -2111,6 +2129,15 @@ namespace TINK.MultilingualResources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to You search a .
|
||||
/// </summary>
|
||||
public static string MarkingFindBikeTypeOfBikeText {
|
||||
get {
|
||||
return ResourceManager.GetString("MarkingFindBikeTypeOfBikeText", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Menu.
|
||||
/// </summary>
|
||||
|
@ -2662,6 +2689,24 @@ namespace TINK.MultilingualResources {
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to You can search only the bikes of the selected bike type. Change your selection on the "Bike locations" page..
|
||||
/// </summary>
|
||||
public static string MessageBikeTypeInfoText {
|
||||
get {
|
||||
return ResourceManager.GetString("MessageBikeTypeInfoText", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Selected bike type.
|
||||
/// </summary>
|
||||
public static string MessageBikeTypeInfoTitle {
|
||||
get {
|
||||
return ResourceManager.GetString("MessageBikeTypeInfoTitle", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Connection error when canceling the reservation!.
|
||||
/// </summary>
|
||||
|
@ -3039,7 +3084,7 @@ namespace TINK.MultilingualResources {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Bike ID including prefix e.g. TR15.
|
||||
/// Looks up a localized string similar to Prefix and No., e.g. TR15.
|
||||
/// </summary>
|
||||
public static string PlaceholderFindBike {
|
||||
get {
|
||||
|
@ -3248,7 +3293,7 @@ namespace TINK.MultilingualResources {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Code {0}, location {1}, max. reservation time of {2} min. expired..
|
||||
/// Looks up a localized string similar to Code {0}, location {1}, max. reservation time expired..
|
||||
/// </summary>
|
||||
public static string StatusTextReservationExpiredCodeLocationMaxReservationTime {
|
||||
get {
|
||||
|
@ -3266,7 +3311,7 @@ namespace TINK.MultilingualResources {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Code {0}, max. reservation time of {1} min. expired..
|
||||
/// Looks up a localized string similar to Code {0}, max. reservation time expired..
|
||||
/// </summary>
|
||||
public static string StatusTextReservationExpiredCodeMaxReservationTime {
|
||||
get {
|
||||
|
@ -3284,7 +3329,7 @@ namespace TINK.MultilingualResources {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Location {0}, max. reservation time of {1} min. expired..
|
||||
/// Looks up a localized string similar to Location {0}, max. reservation time expired..
|
||||
/// </summary>
|
||||
public static string StatusTextReservationExpiredLocationMaxReservationTime {
|
||||
get {
|
||||
|
@ -3302,7 +3347,7 @@ namespace TINK.MultilingualResources {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to Max. reservation time of {0} min. expired..
|
||||
/// Looks up a localized string similar to Max. reservation time expired..
|
||||
/// </summary>
|
||||
public static string StatusTextReservationExpiredMaximumReservationTime {
|
||||
get {
|
||||
|
|
|
@ -182,7 +182,7 @@ Die Protokolldatei enthält Ihre App-Nutzungsdaten sowie Systeminformationen. Di
|
|||
Bitte melden Sie sich erneut an.</value>
|
||||
</data>
|
||||
<data name="StatusTextReservationExpiredCodeMaxReservationTime" xml:space="preserve">
|
||||
<value>Code ist {0}, max. Reservierungszeit von {1} Min. abgelaufen.
|
||||
<value>Code ist {0}, max. Reservierungszeit abgelaufen.
|
||||
</value>
|
||||
</data>
|
||||
<data name="StatusTextReservationExpiredCodeRemaining" xml:space="preserve">
|
||||
|
@ -199,13 +199,13 @@ Bitte melden Sie sich erneut an.</value>
|
|||
<value>Noch {0} Min. reserviert.</value>
|
||||
</data>
|
||||
<data name="StatusTextReservationExpiredMaximumReservationTime" xml:space="preserve">
|
||||
<value>Max. Reservierungszeit von {0} Min. abgelaufen.</value>
|
||||
<value>Max. Reservierungszeit abgelaufen.</value>
|
||||
</data>
|
||||
<data name="StatusTextBookedCodeSince" xml:space="preserve">
|
||||
<value>Code ist {0}, gemietet seit {1}.</value>
|
||||
</data>
|
||||
<data name="StatusTextReservationExpiredLocationMaxReservationTime" xml:space="preserve">
|
||||
<value>Standort {0}, max. Reservierungszeit von {1} Min. abgelaufen.
|
||||
<value>Standort {0}, max. Reservierungszeit abgelaufen.
|
||||
</value>
|
||||
</data>
|
||||
<data name="StatusTextAvailable" xml:space="preserve">
|
||||
|
@ -216,7 +216,7 @@ Bitte melden Sie sich erneut an.</value>
|
|||
</value>
|
||||
</data>
|
||||
<data name="StatusTextReservationExpiredCodeLocationMaxReservationTime" xml:space="preserve">
|
||||
<value>Code ist {0}, Standort {1}, max. Reservierungszeit von {2} Min. abgelaufen.
|
||||
<value>Code ist {0}, Standort {1}, max. Reservierungszeit abgelaufen.
|
||||
</value>
|
||||
</data>
|
||||
<data name="StatusTextReservationExpiredCodeLocationReservationTime" xml:space="preserve">
|
||||
|
@ -1007,7 +1007,7 @@ Außerdem: Kleine Grafiken lassen auf einen Blick erkennen um was für einen Rad
|
|||
<value>Einwilligung</value>
|
||||
</data>
|
||||
<data name="PlaceholderFindBike" xml:space="preserve">
|
||||
<value>Rad-ID inklusive Präfix, z.B. TR15</value>
|
||||
<value>Präfix und Nr., z.B. TR15</value>
|
||||
</data>
|
||||
<data name="ChangeLog3_0_339_MK" xml:space="preserve">
|
||||
<value>Die Lastenräder aus den Vororten zeigen nun ihre Heimatstation im Namen an. Diese Räder müssen dort wieder abgeben werden!
|
||||
|
@ -1171,7 +1171,7 @@ Außerdem:<br/>
|
|||
- Paketaktualisierungen</value>
|
||||
</data>
|
||||
<data name="MarkingFindBikeLabel" xml:space="preserve">
|
||||
<value>Rad-ID inklusive Präfix</value>
|
||||
<value>Rad-ID</value>
|
||||
</data>
|
||||
<data name="MarkingSearchBike" xml:space="preserve">
|
||||
<value>Rad suchen</value>
|
||||
|
@ -1188,4 +1188,19 @@ Außerdem:<br/>
|
|||
<data name="ChangeLog_3_0_365_MK_SB" xml:space="preserve">
|
||||
<value>Kleine Verbesserungen in Design und Performance.</value>
|
||||
</data>
|
||||
<data name="MarkingFindBikeTypeOfBikeText" xml:space="preserve">
|
||||
<value>Sie suchen ein </value>
|
||||
</data>
|
||||
<data name="MessageBikeTypeInfoText" xml:space="preserve">
|
||||
<value>Sie können nur die Fahrräder des ausgewählten Fahrradtyps suchen. Ändern Sie Ihre Auswahl auf der Seite "Radstandorte".</value>
|
||||
</data>
|
||||
<data name="MessageBikeTypeInfoTitle" xml:space="preserve">
|
||||
<value>Ausgewählter Fahrradtyp</value>
|
||||
</data>
|
||||
<data name="MarkingFindBikeButton" xml:space="preserve">
|
||||
<value>Suchen</value>
|
||||
</data>
|
||||
<data name="ChangeLog_3_0_366_MK_SB" xml:space="preserve">
|
||||
<value>Auf der Seite "Rad auswählen" können Sie nun nacheinander mehrere Räder suchen und mieten. Im Anschluss finden Sie diese unter "Meine Räder".</value>
|
||||
</data>
|
||||
</root>
|
|
@ -299,7 +299,7 @@ The log file contains your app usage data as well as system information. The dat
|
|||
<value>Rented since {0}.</value>
|
||||
</data>
|
||||
<data name="StatusTextReservationExpiredMaximumReservationTime" xml:space="preserve">
|
||||
<value>Max. reservation time of {0} min. expired.</value>
|
||||
<value>Max. reservation time expired.</value>
|
||||
</data>
|
||||
<data name="StatusTextReservationExpiredCodeRemaining" xml:space="preserve">
|
||||
<value>Code {0}, still {1} min. reserved.</value>
|
||||
|
@ -308,7 +308,7 @@ The log file contains your app usage data as well as system information. The dat
|
|||
<value>Still {0} min. reserved.</value>
|
||||
</data>
|
||||
<data name="StatusTextReservationExpiredCodeMaxReservationTime" xml:space="preserve">
|
||||
<value>Code {0}, max. reservation time of {1} min. expired.</value>
|
||||
<value>Code {0}, max. reservation time expired.</value>
|
||||
</data>
|
||||
<data name="StatusTextAvailable" xml:space="preserve">
|
||||
<value>Available.</value>
|
||||
|
@ -317,13 +317,13 @@ The log file contains your app usage data as well as system information. The dat
|
|||
<value>Code {0}, location {1}, rented since {2}.</value>
|
||||
</data>
|
||||
<data name="StatusTextReservationExpiredCodeLocationMaxReservationTime" xml:space="preserve">
|
||||
<value>Code {0}, location {1}, max. reservation time of {2} min. expired.</value>
|
||||
<value>Code {0}, location {1}, max. reservation time expired.</value>
|
||||
</data>
|
||||
<data name="StatusTextReservationExpiredCodeLocationReservationTime" xml:space="preserve">
|
||||
<value>Code {0}, location {1}, still {2} min. reserved.</value>
|
||||
</data>
|
||||
<data name="StatusTextReservationExpiredLocationMaxReservationTime" xml:space="preserve">
|
||||
<value>Location {0}, max. reservation time of {1} min. expired.</value>
|
||||
<value>Location {0}, max. reservation time expired.</value>
|
||||
</data>
|
||||
<data name="StatusTextReservationExpiredLocationReservationTime" xml:space="preserve">
|
||||
<value>Location {0}, still {1} min. reserved.</value>
|
||||
|
@ -1112,7 +1112,7 @@ In addition: Small graphics let you see at a glance what type of bike it is.</va
|
|||
<value>Consent</value>
|
||||
</data>
|
||||
<data name="PlaceholderFindBike" xml:space="preserve">
|
||||
<value>Bike ID including prefix e.g. TR15</value>
|
||||
<value>Prefix and No., e.g. TR15</value>
|
||||
</data>
|
||||
<data name="ChangeLog3_0_339_MK" xml:space="preserve">
|
||||
<value>The cargo bikes from the suburbs now show their home station in their name. These bikes must be returned there!
|
||||
|
@ -1260,7 +1260,7 @@ Also:<br/>
|
|||
- Package updates</value>
|
||||
</data>
|
||||
<data name="MarkingFindBikeLabel" xml:space="preserve">
|
||||
<value>Bike ID including prefix</value>
|
||||
<value>Bike id</value>
|
||||
</data>
|
||||
<data name="MarkingSearchBike" xml:space="preserve">
|
||||
<value>Search bike</value>
|
||||
|
@ -1277,4 +1277,19 @@ Also:<br/>
|
|||
<data name="ChangeLog_3_0_365_MK_SB" xml:space="preserve">
|
||||
<value>Minor design and performance improvements.</value>
|
||||
</data>
|
||||
<data name="MarkingFindBikeTypeOfBikeText" xml:space="preserve">
|
||||
<value>You search a </value>
|
||||
</data>
|
||||
<data name="MessageBikeTypeInfoText" xml:space="preserve">
|
||||
<value>You can search only the bikes of the selected bike type. Change your selection on the "Bike locations" page.</value>
|
||||
</data>
|
||||
<data name="MessageBikeTypeInfoTitle" xml:space="preserve">
|
||||
<value>Selected bike type</value>
|
||||
</data>
|
||||
<data name="MarkingFindBikeButton" xml:space="preserve">
|
||||
<value>Search</value>
|
||||
</data>
|
||||
<data name="ChangeLog_3_0_366_MK_SB" xml:space="preserve">
|
||||
<value>On the "Select bike" page you can now search and rent several bikes one after the other. Afterwards you will find them under "My bikes".</value>
|
||||
</data>
|
||||
</root>
|
|
@ -237,8 +237,8 @@ Please log in again.</source>
|
|||
Bitte melden Sie sich erneut an.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="StatusTextReservationExpiredCodeMaxReservationTime" translate="yes" xml:space="preserve">
|
||||
<source>Code {0}, max. reservation time of {1} min. expired.</source>
|
||||
<target state="translated">Code ist {0}, max. Reservierungszeit von {1} Min. abgelaufen.
|
||||
<source>Code {0}, max. reservation time expired.</source>
|
||||
<target state="translated">Code ist {0}, max. Reservierungszeit abgelaufen.
|
||||
</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="StatusTextReservationExpiredCodeRemaining" translate="yes" xml:space="preserve">
|
||||
|
@ -259,16 +259,16 @@ Bitte melden Sie sich erneut an.</target>
|
|||
<target state="translated">Noch {0} Min. reserviert.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="StatusTextReservationExpiredMaximumReservationTime" translate="yes" xml:space="preserve">
|
||||
<source>Max. reservation time of {0} min. expired.</source>
|
||||
<target state="translated">Max. Reservierungszeit von {0} Min. abgelaufen.</target>
|
||||
<source>Max. reservation time expired.</source>
|
||||
<target state="translated">Max. Reservierungszeit abgelaufen.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="StatusTextBookedCodeSince" translate="yes" xml:space="preserve">
|
||||
<source>Code {0}, rented since {1}.</source>
|
||||
<target state="translated">Code ist {0}, gemietet seit {1}.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="StatusTextReservationExpiredLocationMaxReservationTime" translate="yes" xml:space="preserve">
|
||||
<source>Location {0}, max. reservation time of {1} min. expired.</source>
|
||||
<target state="translated">Standort {0}, max. Reservierungszeit von {1} Min. abgelaufen.
|
||||
<source>Location {0}, max. reservation time expired.</source>
|
||||
<target state="translated">Standort {0}, max. Reservierungszeit abgelaufen.
|
||||
</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="StatusTextAvailable" translate="yes" xml:space="preserve">
|
||||
|
@ -281,8 +281,8 @@ Bitte melden Sie sich erneut an.</target>
|
|||
</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="StatusTextReservationExpiredCodeLocationMaxReservationTime" translate="yes" xml:space="preserve">
|
||||
<source>Code {0}, location {1}, max. reservation time of {2} min. expired.</source>
|
||||
<target state="translated">Code ist {0}, Standort {1}, max. Reservierungszeit von {2} Min. abgelaufen.
|
||||
<source>Code {0}, location {1}, max. reservation time expired.</source>
|
||||
<target state="translated">Code ist {0}, Standort {1}, max. Reservierungszeit abgelaufen.
|
||||
</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="StatusTextReservationExpiredCodeLocationReservationTime" translate="yes" xml:space="preserve">
|
||||
|
@ -1373,8 +1373,8 @@ Außerdem: Kleine Grafiken lassen auf einen Blick erkennen um was für einen Rad
|
|||
<target state="translated">Einwilligung</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="PlaceholderFindBike" translate="yes" xml:space="preserve">
|
||||
<source>Bike ID including prefix e.g. TR15</source>
|
||||
<target state="translated">Rad-ID inklusive Präfix, z.B. TR15</target>
|
||||
<source>Prefix and No., e.g. TR15</source>
|
||||
<target state="translated">Präfix und Nr., z.B. TR15</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="ChangeLog3_0_339_MK" translate="yes" xml:space="preserve">
|
||||
<source>The cargo bikes from the suburbs now show their home station in their name. These bikes must be returned there!
|
||||
|
@ -1620,8 +1620,8 @@ Außerdem:<br/>
|
|||
- Paketaktualisierungen</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="MarkingFindBikeLabel" translate="yes" xml:space="preserve">
|
||||
<source>Bike ID including prefix</source>
|
||||
<target state="translated">Rad-ID inklusive Präfix</target>
|
||||
<source>Bike id</source>
|
||||
<target state="translated">Rad-ID</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="MarkingSearchBike" translate="yes" xml:space="preserve">
|
||||
<source>Search bike</source>
|
||||
|
@ -1643,6 +1643,26 @@ Außerdem:<br/>
|
|||
<source>Minor design and performance improvements.</source>
|
||||
<target state="translated">Kleine Verbesserungen in Design und Performance.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="MarkingFindBikeTypeOfBikeText" translate="yes" xml:space="preserve">
|
||||
<source>You search a </source>
|
||||
<target state="translated">Sie suchen ein </target>
|
||||
</trans-unit>
|
||||
<trans-unit id="MessageBikeTypeInfoText" translate="yes" xml:space="preserve">
|
||||
<source>You can search only the bikes of the selected bike type. Change your selection on the "Bike locations" page.</source>
|
||||
<target state="translated">Sie können nur die Fahrräder des ausgewählten Fahrradtyps suchen. Ändern Sie Ihre Auswahl auf der Seite "Radstandorte".</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="MessageBikeTypeInfoTitle" translate="yes" xml:space="preserve">
|
||||
<source>Selected bike type</source>
|
||||
<target state="translated">Ausgewählter Fahrradtyp</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="MarkingFindBikeButton" translate="yes" xml:space="preserve">
|
||||
<source>Search</source>
|
||||
<target state="translated">Suchen</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="ChangeLog_3_0_366_MK_SB" translate="yes" xml:space="preserve">
|
||||
<source>On the "Select bike" page you can now search and rent several bikes one after the other. Afterwards you will find them under "My bikes".</source>
|
||||
<target state="translated">Auf der Seite "Rad auswählen" können Sie nun nacheinander mehrere Räder suchen und mieten. Im Anschluss finden Sie diese unter "Meine Räder".</target>
|
||||
</trans-unit>
|
||||
</group>
|
||||
</body>
|
||||
</file>
|
||||
|
|
|
@ -550,7 +550,7 @@ namespace TINK.Repository
|
|||
#endif
|
||||
}
|
||||
|
||||
/// <summary> Gets canel booking request response.</summary>
|
||||
/// <summary> Gets cancel booking request response.</summary>
|
||||
/// <param name="copriHost">Host to connect to. </param>
|
||||
/// <param name="command">Command to log user in.</param>
|
||||
/// <returns>Response on cancel booking request.</returns>
|
||||
|
|
|
@ -1376,7 +1376,7 @@ namespace TINK.Repository
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets canel booking request response.
|
||||
/// Gets cancel booking request response.
|
||||
/// </summary>
|
||||
/// <param name="bikeId">Id of the bike to book.</param>
|
||||
/// <param name="cookie">Cookie of the logged in user.</param>
|
||||
|
@ -1613,7 +1613,7 @@ namespace TINK.Repository
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets canel booking request response.
|
||||
/// Gets cancel booking request response.
|
||||
/// </summary>
|
||||
/// <param name="bikeId">Id of the bike to book.</param>
|
||||
/// <param name="cookie">Cookie of the logged in user.</param>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
namespace TINK.Repository.Exception
|
||||
namespace TINK.Repository.Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Is fired with reqest used a cookie which is not defined.
|
||||
/// Is fired with request used a cookie which is not defined.
|
||||
/// Reasons for cookie to be not defined might be
|
||||
/// - user used more thant 8 different devices (copri invalidates cookies in this case)
|
||||
/// - user used more that 8 different devices (copri invalidates cookies in this case)
|
||||
/// - user account has been deleted?
|
||||
/// </summary>
|
||||
public class AuthcookieNotDefinedException : InvalidResponseException<Response.ResponseBase>
|
||||
|
@ -19,7 +19,7 @@
|
|||
/// Gets whether authcookie is defined or not.
|
||||
/// </summary>
|
||||
/// <param name="reponse">Response to check</param>
|
||||
/// <param name="actionText">Text holding contectin in which authcookie is checked.</param>
|
||||
/// <param name="actionText">Text holding context in which authcookie is checked.</param>
|
||||
/// <param name="exception">Exception thrown if cookie is not defined.</param>
|
||||
/// <returns></returns>
|
||||
public static bool IsAuthcookieNotDefined(
|
||||
|
@ -29,7 +29,7 @@
|
|||
{
|
||||
if (reponse == null || reponse.response_state == null)
|
||||
{
|
||||
// Empty response or response withoud response state is no authcookie not defined exeception.
|
||||
// Empty response or response without response state is no authcookie not defined exception.
|
||||
exception = null;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace TINK.Repository.Response
|
||||
|
@ -22,6 +22,12 @@ namespace TINK.Repository.Response
|
|||
[DataMember]
|
||||
public string id { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Holds the time span in minutes for which a bike can be reserved.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
public string reserve_timerange { get; private set; }
|
||||
|
||||
/// <summary> Holds tariff entires to show to user.</summary>
|
||||
[DataMember]
|
||||
public Dictionary<
|
||||
|
|
|
@ -115,7 +115,7 @@ namespace TINK.Services.CopriApi
|
|||
throw new BikeStillInStationException("Booking was canceled because bike is still in station.");
|
||||
}
|
||||
|
||||
// Upate booking state.
|
||||
// Update booking state.
|
||||
bike.Load(
|
||||
response,
|
||||
mailAddress,
|
||||
|
|
|
@ -95,7 +95,7 @@ namespace TINK.ViewModel.Bikes.Bike.BC
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary> Gets visiblity of the copri command button. </summary>
|
||||
/// <summary> Gets visibility of the copri command button. </summary>
|
||||
public bool IsButtonVisible
|
||||
=> RequestHandler.IsButtonVisible
|
||||
&& Bike.DataSource == Model.Bikes.BikeInfoNS.BC.DataSource.Copri /* do not show button if data is from cache */ ;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Model.Device;
|
||||
using TINK.Model.User;
|
||||
|
@ -62,12 +62,12 @@ namespace TINK.ViewModel.Bikes.Bike.BC.RequestHandler
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary> Gets if the bike has to be remvoed after action has been completed. </summary>
|
||||
/// <summary> Gets if the bike has to be removed after action has been completed. </summary>
|
||||
public bool IsRemoveBikeRequired { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constructs the reqest handler base.
|
||||
/// Constructs the request handler base.
|
||||
/// </summary>
|
||||
/// <param name="selectedBike">Bike which is reserved or for which reservation is canceled.</param>
|
||||
/// <param name="smartDevice">Provides info about the smart device (phone, tablet, ...).</param>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog;
|
||||
using TINK.Model.Bikes.BikeInfoNS.BC;
|
||||
|
@ -55,7 +55,7 @@ namespace TINK.ViewModel.Bikes.Bike.BC.RequestHandler
|
|||
/// <summary>Gets the is connected state. </summary>
|
||||
public bool IsConnected { get; set; }
|
||||
|
||||
/// <summary> Gets if the bike has to be remvoed after action has been completed. </summary>
|
||||
/// <summary> Gets if the bike has to be removed after action has been completed. </summary>
|
||||
public bool IsRemoveBikeRequired => false;
|
||||
|
||||
/// <param name="bikesViewModel">View model to be used for progress report and unlocking/ locking view.</param>
|
||||
|
|
|
@ -37,7 +37,10 @@ namespace TINK.ViewModel.Bikes.Bike.BC.RequestHandler
|
|||
|
||||
var l_oResult = await ViewService.DisplayAlert(
|
||||
string.Empty,
|
||||
string.Format(AppResources.QuestionReserveBike, SelectedBike.GetFullDisplayName(), StateRequestedInfo.MaximumReserveTime.Minutes),
|
||||
string.Format(
|
||||
AppResources.QuestionReserveBike,
|
||||
SelectedBike.GetFullDisplayName(),
|
||||
SelectedBike.TariffDescription?.MaxReservationTimeSpan.TotalMinutes ?? 0),
|
||||
AppResources.MessageAnswerYes,
|
||||
AppResources.MessageAnswerNo);
|
||||
|
||||
|
|
|
@ -177,14 +177,14 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock
|
|||
RaisePropertyChangedEvent(lastHandler);
|
||||
}
|
||||
|
||||
/// <summary> Gets visiblity of the copri command button. </summary>
|
||||
/// <summary> Gets visibility of the copri command button. </summary>
|
||||
public bool IsButtonVisible
|
||||
=> RequestHandler.IsButtonVisible;
|
||||
|
||||
/// <summary> Gets the text of the copri command button. </summary>
|
||||
public string ButtonText => RequestHandler.ButtonText;
|
||||
|
||||
/// <summary> Gets visiblity of the ILockIt command button. </summary>
|
||||
/// <summary> Gets visibility of the ILockIt command button. </summary>
|
||||
public bool IsLockitButtonVisible
|
||||
=> RequestHandler.IsLockitButtonVisible;
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
|||
public abstract class Base : BC.RequestHandler.Base<Model.Bikes.BikeInfoNS.BluetoothLock.IBikeInfoMutable>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs the reqest handler base.
|
||||
/// Constructs the request handler base.
|
||||
/// </summary>
|
||||
/// <param name="selectedBike">Bike which is reserved or for which reservation is canceled.</param>
|
||||
/// <param name="smartDevice">Provides info about the smart device (phone, tablet, ...)</param>
|
||||
|
|
|
@ -62,7 +62,10 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
|||
// Ask whether to really reserve bike?
|
||||
var alertResult = await ViewService.DisplayAlert(
|
||||
string.Empty,
|
||||
string.Format(AppResources.QuestionReserveBike, SelectedBike.GetFullDisplayName(), StateRequestedInfo.MaximumReserveTime.Minutes),
|
||||
string.Format(
|
||||
AppResources.QuestionReserveBike,
|
||||
SelectedBike.GetFullDisplayName(),
|
||||
SelectedBike.TariffDescription?.MaxReservationTimeSpan.TotalMinutes ?? 0),
|
||||
AppResources.MessageAnswerYes,
|
||||
AppResources.MessageAnswerNo);
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
using System.Threading.Tasks;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace TINK.ViewModel.Bikes.Bike.BluetoothLock
|
||||
{
|
||||
public interface IRequestHandler : IRequestHandlerBase
|
||||
{
|
||||
/// <summary> Gets a value indicating whether the ILockIt button which is managed by request hadnler is visible or not. </summary>
|
||||
/// <summary> Gets a value indicating whether the ILockIt button which is managed by request handler is visible or not. </summary>
|
||||
bool IsLockitButtonVisible { get; }
|
||||
|
||||
/// <summary> Gets the text of the ILockIt button which is managed by request handler. </summary>
|
||||
|
@ -13,13 +13,13 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock
|
|||
/// <summary>
|
||||
/// Performs the copri action to be executed when user presses the copri button managed by request handler.
|
||||
/// </summary>
|
||||
/// <returns>New handler object if action suceeded, same handler otherwise.</returns>
|
||||
/// <returns>New handler object if action succeeded, same handler otherwise.</returns>
|
||||
Task<IRequestHandler> HandleRequestOption1();
|
||||
|
||||
Task<IRequestHandler> HandleRequestOption2();
|
||||
|
||||
/// <summary>
|
||||
/// Holds error discription (invalid state).
|
||||
/// Holds error description (invalid state).
|
||||
/// </summary>
|
||||
string ErrorText { get; }
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog;
|
||||
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
|
@ -36,7 +36,7 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
|||
|
||||
public string ButtonText => GetType().Name;
|
||||
|
||||
/// <summary> Gets if the bike has to be remvoed after action has been completed. </summary>
|
||||
/// <summary> Gets if the bike has to be removed after action has been completed. </summary>
|
||||
public bool IsRemoveBikeRequired => false;
|
||||
|
||||
public string ErrorText { get; }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Serilog;
|
||||
using TINK.Model.State;
|
||||
|
@ -38,7 +38,7 @@ namespace TINK.ViewModel.Bikes.Bike.BluetoothLock
|
|||
|
||||
public bool IsConnected => throw new NotImplementedException();
|
||||
|
||||
/// <summary> Gets if the bike has to be remvoed after action has been completed. </summary>
|
||||
/// <summary> Gets if the bike has to be removed after action has been completed. </summary>
|
||||
public bool IsRemoveBikeRequired => false;
|
||||
|
||||
public async Task<IRequestHandler> HandleRequestOption1()
|
||||
|
|
|
@ -136,7 +136,7 @@ namespace TINK.ViewModel.Bikes.Bike.CopriLock
|
|||
RaisePropertyChangedEvent(lastHandler);
|
||||
}
|
||||
|
||||
/// <summary> Gets visiblity of the copri command button. </summary>
|
||||
/// <summary> Gets visibility of the copri command button. </summary>
|
||||
public bool IsButtonVisible
|
||||
=> RequestHandler.IsButtonVisible
|
||||
&& Bike.DataSource == Model.Bikes.BikeInfoNS.BC.DataSource.Copri /* do not show button if data is from cache */ ;
|
||||
|
@ -144,7 +144,7 @@ namespace TINK.ViewModel.Bikes.Bike.CopriLock
|
|||
/// <summary> Gets the text of the copri command button. </summary>
|
||||
public string ButtonText => RequestHandler.ButtonText;
|
||||
|
||||
/// <summary> Gets visiblity of the ILockIt command button. </summary>
|
||||
/// <summary> Gets visibility of the ILockIt command button. </summary>
|
||||
public bool IsLockitButtonVisible
|
||||
=> RequestHandler.IsLockitButtonVisible
|
||||
&& Bike.DataSource == Model.Bikes.BikeInfoNS.BC.DataSource.Copri /* do not show button if data is from cache */ ;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Model.Device;
|
||||
using TINK.Model.User;
|
||||
|
@ -9,7 +9,7 @@ namespace TINK.ViewModel.Bikes.Bike.CopriLock.RequestHandler
|
|||
public abstract class Base : BC.RequestHandler.Base<Model.Bikes.BikeInfoNS.CopriLock.IBikeInfoMutable>
|
||||
{
|
||||
/// <summary>
|
||||
/// Constructs the reqest handler base.
|
||||
/// Constructs the request handler base.
|
||||
/// </summary>
|
||||
/// <param name="selectedBike">Bike which is reserved or for which reservation is canceled.</param>
|
||||
/// <param name="smartDevice">Provides info about the smart device (phone, tablet, ...)</param>
|
||||
|
|
|
@ -132,7 +132,10 @@ namespace TINK.ViewModel.Bikes.Bike.CopriLock.RequestHandler
|
|||
// Ask whether to really reserve bike?
|
||||
var alertResult = await ViewService.DisplayAlert(
|
||||
string.Empty,
|
||||
string.Format(AppResources.QuestionReserveBike, SelectedBike.GetFullDisplayName(), StateRequestedInfo.MaximumReserveTime.Minutes),
|
||||
string.Format(
|
||||
AppResources.QuestionReserveBike,
|
||||
SelectedBike.GetFullDisplayName(),
|
||||
SelectedBike.TariffDescription?.MaxReservationTimeSpan.TotalMinutes ?? 0),
|
||||
AppResources.MessageAnswerYes,
|
||||
AppResources.MessageAnswerNo);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using Serilog;
|
||||
using TINK.Model.Bikes.BikeInfoNS.CopriLock;
|
||||
using TINK.Model.Connector;
|
||||
|
@ -54,7 +54,7 @@ namespace TINK.ViewModel.Bikes.Bike.CopriLock
|
|||
|
||||
case Model.State.InUseStateEnum.Disposable:
|
||||
|
||||
// Bike is reserved, selecte action depending on lock state.
|
||||
// Bike is reserved, selected action depending on lock state.
|
||||
return new DisposableClosed(
|
||||
selectedCopriLock,
|
||||
isConnectedDelegate,
|
||||
|
@ -79,7 +79,7 @@ namespace TINK.ViewModel.Bikes.Bike.CopriLock
|
|||
|
||||
case Model.State.InUseStateEnum.Booked:
|
||||
|
||||
// Bike is booked, selecte action depending on lock state.
|
||||
// Bike is booked, selected action depending on lock state.
|
||||
var lockState = selectedCopriLock.LockInfo.State;
|
||||
switch (lockState)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
namespace TINK.ViewModel.Bikes.Bike
|
||||
namespace TINK.ViewModel.Bikes.Bike
|
||||
{
|
||||
/// <summary>
|
||||
/// Base interface for Copri and ILockIt request handler.
|
||||
|
@ -22,7 +22,7 @@
|
|||
/// <summary>Gets the is connected state. </summary>
|
||||
bool IsConnected { get; }
|
||||
|
||||
/// <summary> Gets if the bike has to be remvoed after action has been completed. </summary>
|
||||
/// <summary> Gets if the bike has to be removed after action has been completed. </summary>
|
||||
bool IsRemoveBikeRequired { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ namespace TINK.ViewModel.Bikes.Bike
|
|||
|
||||
private const string RIDETYPEKEY = "AAFAHRTEN";
|
||||
|
||||
public TariffDescriptionViewModel(RentalDescription tariff)
|
||||
public TariffDescriptionViewModel(IRentalDescription tariff)
|
||||
{
|
||||
Name = tariff?.Name ?? string.Empty;
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
using System;
|
||||
using TINK.Model.State;
|
||||
using System;
|
||||
using TINK.MultilingualResources;
|
||||
using TINK.ViewModel.Bikes.Bike;
|
||||
|
||||
|
@ -8,7 +7,7 @@ namespace TINK.ViewModel
|
|||
public class BikeAtStationInUseStateInfoProvider : IInUseStateInfoProvider
|
||||
{
|
||||
/// <summary> Gets reserved into display text. </summary>
|
||||
/// <todo>Log unexpeced states.</todo>
|
||||
/// <todo>Log unexpected states.</todo>
|
||||
/// <returns>Display text</returns>
|
||||
public string GetReservedInfo(
|
||||
TimeSpan? remainingTime,
|
||||
|
@ -21,10 +20,10 @@ namespace TINK.ViewModel
|
|||
if (string.IsNullOrEmpty(code))
|
||||
{
|
||||
// Reservation code not available
|
||||
return string.Format(AppResources.StatusTextReservationExpiredMaximumReservationTime, StateRequestedInfo.MaximumReserveTime.Minutes);
|
||||
return AppResources.StatusTextReservationExpiredMaximumReservationTime;
|
||||
}
|
||||
|
||||
return string.Format(AppResources.StatusTextReservationExpiredCodeMaxReservationTime, code, StateRequestedInfo.MaximumReserveTime.Minutes);
|
||||
return string.Format(AppResources.StatusTextReservationExpiredCodeMaxReservationTime, code);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(code))
|
||||
|
@ -36,7 +35,7 @@ namespace TINK.ViewModel
|
|||
}
|
||||
|
||||
/// <summary> Gets booked into display text. </summary>
|
||||
/// <todo>Log unexpeced states.</todo>
|
||||
/// <todo>Log unexpected states.</todo>
|
||||
/// <returns>Display text</returns>
|
||||
public string GetBookedInfo(
|
||||
DateTime? from,
|
||||
|
|
|
@ -10,10 +10,13 @@ using Plugin.BLE.Abstractions.Contracts;
|
|||
using Serilog;
|
||||
using TINK.Model;
|
||||
using TINK.Model.Bikes;
|
||||
using TINK.Model.Bikes.BikeInfoNS.BikeNS;
|
||||
using TINK.Model.Bikes.BikeInfoNS.BluetoothLock;
|
||||
using TINK.Model.Connector;
|
||||
using TINK.Model.Connector.Filter;
|
||||
using TINK.Model.Device;
|
||||
using TINK.Model.Services.CopriApi;
|
||||
using TINK.Model.State;
|
||||
using TINK.Model.Stations.StationNS;
|
||||
using TINK.Model.User;
|
||||
using TINK.MultilingualResources;
|
||||
|
@ -25,6 +28,7 @@ using TINK.Services.Permissions;
|
|||
using TINK.Settings;
|
||||
using TINK.View;
|
||||
using TINK.ViewModel.Bikes;
|
||||
using TINK.ViewModel.Map;
|
||||
using Xamarin.Essentials;
|
||||
using Xamarin.Forms;
|
||||
using Command = Xamarin.Forms.Command;
|
||||
|
@ -84,13 +88,13 @@ namespace TINK.ViewModel.FindBike
|
|||
/// <summary>
|
||||
/// True if ListView of Bikes is refreshing after user pulled;
|
||||
/// </summary>
|
||||
private bool _isRefreshing = false;
|
||||
private bool isRefreshing = false;
|
||||
public bool IsRefreshing
|
||||
{
|
||||
get { return _isRefreshing; }
|
||||
get { return isRefreshing; }
|
||||
set
|
||||
{
|
||||
_isRefreshing = value;
|
||||
isRefreshing = value;
|
||||
OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsRefreshing)));
|
||||
}
|
||||
}
|
||||
|
@ -99,6 +103,7 @@ namespace TINK.ViewModel.FindBike
|
|||
/// Holds what should be executed on pull to refresh
|
||||
/// </summary>
|
||||
public Command RefreshCommand { get; }
|
||||
public Command ShowFilterBikeTypeInfoCommand { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Constructs bike collection view model in case information about occupied bikes is available.
|
||||
|
@ -146,6 +151,15 @@ namespace TINK.ViewModel.FindBike
|
|||
await SelectBike();
|
||||
|
||||
});
|
||||
|
||||
ShowFilterBikeTypeInfoCommand = new Xamarin.Forms.Command(async () => {
|
||||
|
||||
await ViewService.DisplayAlert(
|
||||
AppResources.MessageBikeTypeInfoTitle,
|
||||
AppResources.MessageBikeTypeInfoText,
|
||||
AppResources.MessageAnswerOk);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -158,6 +172,8 @@ namespace TINK.ViewModel.FindBike
|
|||
|
||||
Log.ForContext<FindBikePageViewModel>().Information("User request to show page FindBike- page re-appearing");
|
||||
|
||||
ActiveFilteredBikeType = string.Empty;
|
||||
|
||||
IsConnected = IsConnectedDelegate();
|
||||
|
||||
// Stop polling before getting bikes info.
|
||||
|
@ -185,6 +201,19 @@ namespace TINK.ViewModel.FindBike
|
|||
|
||||
ActionText = string.Empty;
|
||||
IsIdle = true;
|
||||
|
||||
var result = await ConnectorFactory(IsConnected).Query.GetBikesAsync();
|
||||
var bikes = result.Response;
|
||||
|
||||
var exception = result.Exception;
|
||||
if (exception != null)
|
||||
{
|
||||
Log.ForContext<MapPageViewModel>().Error("Getting bikes in polling context failed with exception {Exception}.", exception);
|
||||
}
|
||||
|
||||
// Get Active Filtered BikeType
|
||||
GetActiveFilteredBikeType(bikes);
|
||||
|
||||
}
|
||||
|
||||
/// <summary> Command object to bind select bike button to view model. </summary>
|
||||
|
@ -209,7 +238,7 @@ namespace TINK.ViewModel.FindBike
|
|||
if (exception is WebConnectFailureException)
|
||||
{
|
||||
// Copri server is not reachable.
|
||||
Log.ForContext<FindBikePageViewModel>().Information("Getting bikes failed failed (Copri server not reachable).");
|
||||
Log.ForContext<FindBikePageViewModel>().Information("Getting bikes failed (Copri server not reachable).");
|
||||
|
||||
await ViewService.DisplayAdvancedAlert(
|
||||
AppResources.ErrorReturnBikeNoWebTitle,
|
||||
|
@ -402,6 +431,9 @@ namespace TINK.ViewModel.FindBike
|
|||
IsIdle = true;
|
||||
return;
|
||||
}
|
||||
|
||||
BikeIdUserInput = string.Empty;
|
||||
|
||||
}
|
||||
|
||||
/// <summary> Create task which updates my bike view model.</summary>
|
||||
|
@ -417,13 +449,12 @@ namespace TINK.ViewModel.FindBike
|
|||
null);
|
||||
|
||||
var result = ConnectorFactory(IsConnected).Query.GetBikesAsync().Result;
|
||||
|
||||
var bikes = result.Response;
|
||||
|
||||
var exception = result.Exception;
|
||||
if (exception != null)
|
||||
{
|
||||
Log.ForContext<FindBikePageViewModel>().Error("Getting bikes occupied in polling context failed with exception {Exception}.", exception);
|
||||
Log.ForContext<FindBikePageViewModel>().Error("Getting bikes in polling context failed with exception {Exception}.", exception);
|
||||
}
|
||||
|
||||
var selectedBike = bikes.FirstOrDefault(x => x.Id.Equals(BikeIdUserInput.Trim(), StringComparison.OrdinalIgnoreCase));
|
||||
|
@ -441,5 +472,44 @@ namespace TINK.ViewModel.FindBike
|
|||
},
|
||||
null);
|
||||
}
|
||||
|
||||
private string activeFilteredBikeType = string.Empty;
|
||||
/// <summary>
|
||||
/// Selected Bike Type in MapFilter
|
||||
/// </summary>
|
||||
public string ActiveFilteredBikeType
|
||||
{
|
||||
get { return activeFilteredBikeType; }
|
||||
set
|
||||
{
|
||||
if (value == activeFilteredBikeType)
|
||||
{
|
||||
return;
|
||||
}
|
||||
activeFilteredBikeType = value;
|
||||
OnPropertyChanged(new PropertyChangedEventArgs(nameof(ActiveFilteredBikeType)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get Selected Bike Type in MapFilter
|
||||
/// </summary>
|
||||
public void GetActiveFilteredBikeType(BikeCollection bikesAll)
|
||||
{
|
||||
Log.ForContext<FindBikePageViewModel>().Debug($"Bike type of active filter is extracted.");
|
||||
if (bikesAll != null)
|
||||
{
|
||||
var firstOrDefaultBikeType = bikesAll.FirstOrDefault().TypeOfBike;
|
||||
if(firstOrDefaultBikeType == TypeOfBike.Cargo)
|
||||
{
|
||||
ActiveFilteredBikeType = AppResources.MarkingCargoBike;
|
||||
}
|
||||
else if(firstOrDefaultBikeType == TypeOfBike.City)
|
||||
{
|
||||
ActiveFilteredBikeType = AppResources.MarkingCityBike;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
|
||||
namespace TINK.ViewModel
|
||||
{
|
||||
|
|
|
@ -50,7 +50,6 @@ namespace TINK.ViewModel.Map
|
|||
/// </summary>
|
||||
private Exception m_oException;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Service to query/ manage permissions (location) of the app.
|
||||
/// </summary>
|
||||
|
@ -483,10 +482,23 @@ namespace TINK.ViewModel.Map
|
|||
Log.ForContext<MapPageViewModel>().Verbose("Location permissions: {0}.", status);
|
||||
}
|
||||
|
||||
private bool isLocationPermissionGranted = false;
|
||||
/// <summary>
|
||||
/// Exposes IsLocationPermissionGranted.
|
||||
/// </summary>
|
||||
public bool IsLocationPermissionGranted{ get; set;}
|
||||
public bool IsLocationPermissionGranted
|
||||
{
|
||||
get => isLocationPermissionGranted;
|
||||
set
|
||||
{
|
||||
if (value == isLocationPermissionGranted)
|
||||
return;
|
||||
|
||||
Log.ForContext<MapPageViewModel>().Debug($"Switch value of {nameof(isLocationPermissionGranted)} to {value}.");
|
||||
isLocationPermissionGranted = value;
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsLocationPermissionGranted)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoked when the auth cookie is not defined.
|
||||
|
@ -655,6 +667,9 @@ namespace TINK.ViewModel.Map
|
|||
Log.ForContext<MapPageViewModel>().Error("Getting bikes and stations in polling context failed with exception {Exception}.", exception);
|
||||
}
|
||||
|
||||
// Get and expose status of location permission
|
||||
GetLocationPermissionStatus();
|
||||
|
||||
// Load MyBikes Count -> MyBikes Icon/Button
|
||||
GetMyBikesCount(resultStationsAndBikes.Response.BikesOccupied);
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ namespace TINK.ViewModel
|
|||
public class MyBikeInUseStateInfoProvider : IInUseStateInfoProvider
|
||||
{
|
||||
/// <summary> Gets reserved into display text. </summary>
|
||||
/// <todo>Log unexpeced states.</todo>
|
||||
/// <todo>Log unexpected states.</todo>
|
||||
/// <returns>Display text</returns>
|
||||
public string GetReservedInfo(
|
||||
TimeSpan? remainingTime,
|
||||
|
@ -17,25 +17,25 @@ namespace TINK.ViewModel
|
|||
{
|
||||
if (remainingTime == null)
|
||||
{
|
||||
// Reamining time is not available.
|
||||
// Remaining time is not available.
|
||||
if (stationId == null)
|
||||
{
|
||||
|
||||
if (string.IsNullOrEmpty(code))
|
||||
{
|
||||
// Code is not available
|
||||
return string.Format(AppResources.StatusTextReservationExpiredMaximumReservationTime, StateRequestedInfo.MaximumReserveTime.Minutes);
|
||||
return AppResources.StatusTextReservationExpiredMaximumReservationTime;
|
||||
}
|
||||
|
||||
return string.Format(AppResources.StatusTextReservationExpiredCodeMaxReservationTime, code, StateRequestedInfo.MaximumReserveTime.Minutes);
|
||||
return string.Format(AppResources.StatusTextReservationExpiredCodeMaxReservationTime, code);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(code))
|
||||
{
|
||||
return string.Format(AppResources.StatusTextReservationExpiredLocationMaxReservationTime, stationId, StateRequestedInfo.MaximumReserveTime.Minutes);
|
||||
return string.Format(AppResources.StatusTextReservationExpiredLocationMaxReservationTime, stationId);
|
||||
}
|
||||
|
||||
return string.Format(AppResources.StatusTextReservationExpiredCodeLocationMaxReservationTime, code, stationId, StateRequestedInfo.MaximumReserveTime.Minutes);
|
||||
return string.Format(AppResources.StatusTextReservationExpiredCodeLocationMaxReservationTime, code, stationId);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(stationId))
|
||||
|
@ -63,7 +63,7 @@ namespace TINK.ViewModel
|
|||
/// <summary>
|
||||
/// Gets booked into display text.
|
||||
/// </summary>
|
||||
/// <todo>Log unexpeced states.</todo>
|
||||
/// <todo>Log unexpected states.</todo>
|
||||
/// <returns>Display text</returns>
|
||||
public string GetBookedInfo(
|
||||
DateTime? from,
|
||||
|
|
|
@ -12,8 +12,8 @@ namespace TINK.ViewModel
|
|||
/// </summary>
|
||||
public class PollingUpdateTask
|
||||
{
|
||||
/// <summary> Object to control canelling. </summary>
|
||||
private CancellationTokenSource CanellationTokenSource { get; }
|
||||
/// <summary> Object to control canceling. </summary>
|
||||
private CancellationTokenSource CancellationTokenSource { get; }
|
||||
|
||||
/// <summary> Task to perform update. </summary>
|
||||
private Task UpdateTask { get; }
|
||||
|
@ -40,15 +40,15 @@ namespace TINK.ViewModel
|
|||
|
||||
var updatePeriodeSet = polling.Value;
|
||||
|
||||
CanellationTokenSource = new CancellationTokenSource();
|
||||
CancellationTokenSource = new CancellationTokenSource();
|
||||
|
||||
int cycleIndex = 2;
|
||||
UpdateTask = Task.Run(
|
||||
async () =>
|
||||
{
|
||||
while (!CanellationTokenSource.IsCancellationRequested)
|
||||
while (!CancellationTokenSource.IsCancellationRequested)
|
||||
{
|
||||
await Task.Delay(updatePeriodeSet, CanellationTokenSource.Token);
|
||||
await Task.Delay(updatePeriodeSet, CancellationTokenSource.Token);
|
||||
{
|
||||
// N. update cycle
|
||||
Log.ForContext<PollingUpdateTask>().Information($"Actuating {cycleIndex} update cycle, context {GetType().Name} at {DateTime.Now}.");
|
||||
|
@ -60,7 +60,7 @@ namespace TINK.ViewModel
|
|||
}
|
||||
}
|
||||
},
|
||||
CanellationTokenSource.Token);
|
||||
CancellationTokenSource.Token);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -76,13 +76,13 @@ namespace TINK.ViewModel
|
|||
}
|
||||
|
||||
// Cancel update task;
|
||||
if (CanellationTokenSource == null)
|
||||
if (CancellationTokenSource == null)
|
||||
{
|
||||
throw new Exception($"Can not terminate periodical update task, context {GetType().Name} at {DateTime.Now}. No task running.");
|
||||
}
|
||||
|
||||
Log.ForContext<PollingUpdateTask>().Information($"Request to terminate update cycle, context {GetType().Name} at {DateTime.Now}.");
|
||||
CanellationTokenSource.Cancel();
|
||||
CancellationTokenSource.Cancel();
|
||||
|
||||
try
|
||||
{
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace UITest.Fixtures.ViewModel
|
|||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// Tests base class functionality by using child.
|
||||
/// </summary>
|
||||
public static BikeViewModelBase TestStateText_LoggedIn_Reserved(Func<TINK.Model.Bikes.BikeInfoNS.BC.BikeInfoMutable, User, BikeViewModelBase> p_oFactory)
|
||||
{
|
||||
|
@ -67,6 +67,7 @@ namespace UITest.Fixtures.ViewModel
|
|||
l_oBike.State.Load(
|
||||
InUseStateEnum.Reserved, // Copri acknowledges state reserved.
|
||||
new DateTime(1980, 1, 1), // Date when bike was booked.
|
||||
TimeSpan.FromMinutes(15),
|
||||
"ragu@gnu-systems.de"); // Owner from Copri.
|
||||
|
||||
var l_oStoreMock = new StoreMock(new Account("ragu@gnu-systems.de", "123456789" /* password */, false, "987654321" /* session cookie */, new List<string> { "TINK" }));
|
||||
|
@ -87,7 +88,7 @@ namespace UITest.Fixtures.ViewModel
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// Tests base class functionality by using child.
|
||||
/// </summary>
|
||||
public static BikeViewModelBase TestStateText_LoggedIn_ReservedWithCopriConnect(Func<TINK.Model.Bikes.BikeInfoNS.BC.BikeInfoMutable, User, BikeViewModelBase> p_oFactory)
|
||||
{
|
||||
|
@ -109,6 +110,7 @@ namespace UITest.Fixtures.ViewModel
|
|||
l_oBike.State.Load(
|
||||
InUseStateEnum.Reserved, // Copri acknowledges state reserved.
|
||||
new DateTime(1980, 1, 1),
|
||||
TimeSpan.FromMinutes(15),
|
||||
"ragu@gnu-systems.de", // Owner from Copri.
|
||||
"4asdfA"); // Reservation code from Copri
|
||||
|
||||
|
@ -129,7 +131,7 @@ namespace UITest.Fixtures.ViewModel
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// Tests base class functionality by using child.
|
||||
/// </summary>
|
||||
public static BikeViewModelBase TestStateText_LoggedIn_Booked(Func<TINK.Model.Bikes.BikeInfoNS.BC.BikeInfoMutable, User, BikeViewModelBase> p_oFactory)
|
||||
{
|
||||
|
@ -139,6 +141,7 @@ namespace UITest.Fixtures.ViewModel
|
|||
l_oBike.State.Load(
|
||||
InUseStateEnum.Booked,
|
||||
new DateTime(2017, 10, 24, 21, 49, 3),
|
||||
TimeSpan.FromMinutes(15),
|
||||
"ragu@gnu-systems.de",
|
||||
"4asdfA");
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ namespace TestTINKLib
|
|||
public void TestUpdate_Null()
|
||||
{
|
||||
var l_oBikeRequested = new BikeInfoMutable("20", LockModel.ILockIt, false, new List<string> { "TINK" }, WheelType.Trike, TypeOfBike.Allround);
|
||||
l_oBikeRequested.State.Load(new StateInfo(() => DateTime.Now, DateTime.Now, "john@long", "1234"));
|
||||
l_oBikeRequested.State.Load(new StateInfo(() => DateTime.Now, DateTime.Now, TimeSpan.FromMinutes(15), "john@long", "1234"));
|
||||
|
||||
var l_oBikeColl = new BikeCollectionMutable
|
||||
{
|
||||
|
@ -93,7 +93,7 @@ namespace TestTINKLib
|
|||
public void TestUpdate()
|
||||
{
|
||||
var bikeRequested = new BikeInfoMutable("20", LockModel.ILockIt, false, new List<string> { "TINK" }, WheelType.Trike, TypeOfBike.Allround);
|
||||
bikeRequested.State.Load(new StateInfo(() => DateTime.Now, DateTime.Now, "john@long", "1234"));
|
||||
bikeRequested.State.Load(new StateInfo(() => DateTime.Now, DateTime.Now, TimeSpan.FromMinutes(15), "john@long", "1234"));
|
||||
|
||||
var bikeColl = new BikeCollectionMutable
|
||||
{
|
||||
|
|
|
@ -322,5 +322,15 @@ namespace TestShareeLib.Model.Connector
|
|||
Is.EqualTo(TINK.Model.State.InUseStateEnum.FeedbackPending),
|
||||
"Bikes with state booking state available in ");
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestReservationTimeSpan()
|
||||
{
|
||||
var response = JsonConvertRethrow.DeserializeObject<RentalDescription>(TestShareeLib.Repository.Response.TestRentalDescription.RENTALDESCRIPTIONRESPONSE_A_V4_1_23_03);
|
||||
|
||||
var rentalDescription = RentalDescriptionFactory.Create(response);
|
||||
|
||||
Assert.That(rentalDescription.MaxReservationTimeSpan.TotalMinutes, Is.EqualTo(30));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1055,5 +1055,30 @@ namespace TestTINKLib.Fixtures.Connector
|
|||
{
|
||||
}").GetFrom(),
|
||||
Is.EqualTo(DateTime.MinValue));
|
||||
|
||||
[Test]
|
||||
public void TestGetReservationTimeSpan()
|
||||
{
|
||||
var response = JsonConvertRethrow.DeserializeObject<RentalDescription>(TestShareeLib.Repository.Response.TestRentalDescription.RENTALDESCRIPTIONRESPONSE_A_V4_1_23_03);
|
||||
Assert.That(response.GetMaxReservationTimeSpan().TotalMinutes, Is.EqualTo(30));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestGetReservationTimeSpanInvalid()
|
||||
=> Assert.That(
|
||||
JsonConvertRethrow.DeserializeObject<RentalDescription>(@"
|
||||
{
|
||||
""reserve_timerange"": ""abc"",
|
||||
}").GetMaxReservationTimeSpan().TotalMinutes,
|
||||
Is.EqualTo(15));
|
||||
|
||||
[Test]
|
||||
public void TestGetReservationTimeSpanEmpty()
|
||||
=> Assert.That(
|
||||
JsonConvertRethrow.DeserializeObject<RentalDescription>(@"
|
||||
{
|
||||
}").GetMaxReservationTimeSpan().TotalMinutes,
|
||||
Is.EqualTo(15));
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json;
|
||||
using NUnit.Framework;
|
||||
using TINK.Model.Connector.Updater;
|
||||
using TINK.Repository.Response;
|
||||
|
|
|
@ -44,6 +44,7 @@ namespace TestTINKLib
|
|||
l_oSource.From.Returns(new DateTime(2018, 1, 4, 17, 26, 0));
|
||||
l_oSource.MailAddress.Returns("who@the");
|
||||
l_oSource.Code.Returns("323");
|
||||
l_oSource.MaxReservationTimeSpan.Returns(TimeSpan.FromMinutes(15));
|
||||
|
||||
l_oState = new StateInfoMutable(() => new DateTime(2018, 1, 4, 17, 30, 1), l_oSource);
|
||||
|
||||
|
@ -85,6 +86,7 @@ namespace TestTINKLib
|
|||
l_oStateInfo.Load(
|
||||
InUseStateEnum.Reserved, // Copri acknowledges state reserved.
|
||||
l_oDateTimeMock.GetDateTime(),
|
||||
TimeSpan.FromMinutes(15),
|
||||
"heiz@mustermann"); // Owner from Copri.
|
||||
|
||||
// Invoke first update (after simulated 4mns)
|
||||
|
@ -110,7 +112,7 @@ namespace TestTINKLib
|
|||
Func<DateTime> l_oNowMock = () => new DateTime(2017, 09, 21, 23, 40, 0);
|
||||
var l_oStateInfo = new StateInfoMutable(l_oNowMock);
|
||||
|
||||
l_oStateInfo.Load(InUseStateEnum.Booked, new DateTime(2017, 09, 21, 23, 30, 0), "heiz@mustermann", "21");
|
||||
l_oStateInfo.Load(InUseStateEnum.Booked, new DateTime(2017, 09, 21, 23, 30, 0), TimeSpan.FromMinutes(15), "heiz@mustermann", "21");
|
||||
|
||||
Assert.AreEqual(InUseStateEnum.Booked, l_oStateInfo.Value);
|
||||
Assert.AreEqual("Booked", l_oStateInfo.ToString());
|
||||
|
@ -120,7 +122,7 @@ namespace TestTINKLib
|
|||
Assert.AreEqual("21", l_oStateInfo.Code);
|
||||
|
||||
DateTime FROM = new DateTime(2017, 09, 21, 23, 35, 0);
|
||||
l_oStateInfo.Load(InUseStateEnum.Reserved, FROM, "heiz@mustermann", "22");
|
||||
l_oStateInfo.Load(InUseStateEnum.Reserved, FROM, TimeSpan.FromMinutes(15), "heiz@mustermann", "22");
|
||||
|
||||
// Verify initial values of properties.
|
||||
Assert.AreEqual(InUseStateEnum.Reserved, l_oStateInfo.Value);
|
||||
|
@ -130,7 +132,7 @@ namespace TestTINKLib
|
|||
Assert.AreEqual("heiz@mustermann", l_oStateInfo.MailAddress);
|
||||
Assert.AreEqual("22", l_oStateInfo.Code);
|
||||
|
||||
l_oStateInfo.Load(InUseStateEnum.Disposable, new DateTime(1970, 1, 1, 0, 0, 0), "heiz@mustermann", "unused");
|
||||
l_oStateInfo.Load(InUseStateEnum.Disposable, new DateTime(1970, 1, 1, 0, 0, 0), TimeSpan.FromMinutes(15), "heiz@mustermann", "unused");
|
||||
|
||||
// Verify initial values of properties.
|
||||
Assert.AreEqual(InUseStateEnum.Disposable, l_oStateInfo.Value);
|
||||
|
@ -156,6 +158,7 @@ namespace TestTINKLib
|
|||
var l_oSource = new StateInfo(
|
||||
() => new DateTime(2018, 01, 03, 21, 53, 0),
|
||||
new DateTime(2018, 01, 03, 21, 13, 0), // Requested from
|
||||
TimeSpan.FromMinutes(15),
|
||||
"a@b",
|
||||
"123");
|
||||
l_oState.Load(l_oSource);
|
||||
|
@ -184,5 +187,51 @@ namespace TestTINKLib
|
|||
Assert.IsNull(l_oState.MailAddress);
|
||||
Assert.IsNull(l_oState.Code);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLoadFromNull()
|
||||
{
|
||||
var state = new StateInfoMutable(
|
||||
() => new DateTime(2018, 01, 03, 21, 14, 0));
|
||||
|
||||
state.Load(InUseStateEnum.Disposable,
|
||||
null,
|
||||
TimeSpan.FromMinutes(15));
|
||||
|
||||
Assert.That(
|
||||
state.RemainingTime,
|
||||
Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestLoadReservationTimeSpanNull()
|
||||
{
|
||||
var state = new StateInfoMutable(
|
||||
() => new DateTime(2018, 01, 03, 21, 14, 0));
|
||||
|
||||
state.Load(InUseStateEnum.Disposable,
|
||||
DateTime.Now,
|
||||
null);
|
||||
|
||||
Assert.That(
|
||||
state.RemainingTime,
|
||||
Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMaxReservationTimeSpanNullStateAvaialble()
|
||||
=> Assert.That(new StateInfo().MaxReservationTimeSpan, Is.Null);
|
||||
|
||||
[Test]
|
||||
public void TestMaxReservationTimeSpanNullStateFeedbackPending()
|
||||
=> Assert.That(new StateInfo(true).MaxReservationTimeSpan, Is.Null);
|
||||
|
||||
[Test]
|
||||
public void TestMaxReservationTimeSpanNullStateOccupied()
|
||||
=> Assert.That(new StateInfo(new DateTime(2023, 5, 11), "a@b", "").MaxReservationTimeSpan, Is.Null);
|
||||
|
||||
[Test]
|
||||
public void TestMaxReservationTimeSpan()
|
||||
=> Assert.That(new StateInfo(() => DateTime.Now, new DateTime(2023, 5, 11), TimeSpan.FromMinutes(12), "a@b", "").MaxReservationTimeSpan, Is.EqualTo(TimeSpan.FromMinutes(12)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,13 +55,13 @@ namespace TestTINKLib.Fixtures.State
|
|||
public void TestSerializeJSON_Booked()
|
||||
{
|
||||
// Create object to test.
|
||||
var l_oInUseState = new StateInfoMutable(
|
||||
() => new DateTime(2017, 11, 18, 23, 20, 0) // Mocked time stamp returned when StateInfo- object is crated
|
||||
var l_oInUseState = new StateInfoMutable(() => new DateTime(2017, 11, 18, 23, 20, 0) // Mocked time stamp returned when StateInfo- object is crated
|
||||
);
|
||||
|
||||
l_oInUseState.Load(
|
||||
InUseStateEnum.Booked,
|
||||
new DateTime(2017, 11, 18, 23, 19, 0), // Time booked at
|
||||
TimeSpan.FromMinutes(15),
|
||||
"heiz@mustermann",
|
||||
"173"); // Code
|
||||
|
||||
|
@ -111,6 +111,7 @@ namespace TestTINKLib.Fixtures.State
|
|||
l_oInUseState.Load(
|
||||
InUseStateEnum.Reserved,
|
||||
new DateTime(2017, 09, 21, 23, 20, 0),
|
||||
TimeSpan.FromMinutes(15),
|
||||
"heiz@mustermann");
|
||||
|
||||
Assert.AreEqual(InUseStateEnum.Reserved, l_oInUseState.Value);
|
||||
|
@ -167,6 +168,7 @@ namespace TestTINKLib.Fixtures.State
|
|||
l_oInUseState.Load(
|
||||
InUseStateEnum.Reserved,
|
||||
l_oFrom,
|
||||
TimeSpan.FromMinutes(15),
|
||||
"z@C",
|
||||
"01815A");
|
||||
|
||||
|
|
|
@ -15,25 +15,25 @@ namespace TestTINKLib
|
|||
{
|
||||
Assert.AreEqual(
|
||||
InUseStateEnum.Reserved,
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), "a@b", null).Value);
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), TimeSpan.FromMinutes(15), "a@b", null).Value);
|
||||
|
||||
Assert.AreEqual(
|
||||
"a@b",
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), "a@b", null).MailAddress);
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), TimeSpan.FromMinutes(15), "a@b", null).MailAddress);
|
||||
|
||||
Assert.IsNull(
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), "a@b", null).Code);
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), TimeSpan.FromMinutes(15), "a@b", null).Code);
|
||||
|
||||
Assert.AreEqual(
|
||||
new DateTime(2017, 09, 20, 12, 0, 0),
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), "a@b", null).From);
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), TimeSpan.FromMinutes(15), "a@b", null).From);
|
||||
|
||||
Assert.IsTrue(
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), "a@b", null).GetIsStillReserved(out TimeSpan? remainingTime));
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 1, 0), new DateTime(2017, 09, 20, 12, 0, 0), TimeSpan.FromMinutes(15), "a@b", null).GetIsStillReserved(out TimeSpan? l_oRemainigTime));
|
||||
|
||||
Assert.AreEqual(
|
||||
14,
|
||||
remainingTime.Value.Minutes);
|
||||
l_oRemainigTime.Value.Minutes);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -41,26 +41,26 @@ namespace TestTINKLib
|
|||
{
|
||||
Assert.AreEqual(
|
||||
InUseStateEnum.Reserved,
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20), new DateTime(2017, 09, 19), "a@b", "372").Value);
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20), new DateTime(2017, 09, 19), TimeSpan.FromMinutes(15), "a@b", "372").Value);
|
||||
|
||||
Assert.AreEqual(
|
||||
"a@b",
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20), new DateTime(2017, 09, 19), "a@b", "372").MailAddress);
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20), new DateTime(2017, 09, 19), TimeSpan.FromMinutes(15), "a@b", "372").MailAddress);
|
||||
|
||||
Assert.AreEqual(
|
||||
"372",
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20), new DateTime(2017, 09, 19), "a@b", "372").Code);
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20), new DateTime(2017, 09, 19), TimeSpan.FromMinutes(15), "a@b", "372").Code);
|
||||
|
||||
Assert.AreEqual(
|
||||
new DateTime(2017, 09, 19),
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20), new DateTime(2017, 09, 19), "a@b", "372").From);
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20), new DateTime(2017, 09, 19), TimeSpan.FromMinutes(15), "a@b", "372").From);
|
||||
|
||||
Assert.IsTrue(
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 12, 0), new DateTime(2017, 09, 20, 12, 0, 0), "a@b", "372").GetIsStillReserved(out TimeSpan? remainingTime));
|
||||
new StateRequestedInfo(() => new DateTime(2017, 09, 20, 12, 12, 0), new DateTime(2017, 09, 20, 12, 0, 0), TimeSpan.FromMinutes(15), "a@b", "372").GetIsStillReserved(out TimeSpan? l_oRemainigTime));
|
||||
|
||||
Assert.AreEqual(
|
||||
3,
|
||||
remainingTime.Value.Minutes);
|
||||
l_oRemainigTime.Value.Minutes);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@ -72,7 +72,7 @@ namespace TestTINKLib
|
|||
l_oReservedAt.Add(new TimeSpan(0, 16, 0)) // Time elapsed since booking 16 mns
|
||||
});
|
||||
|
||||
var l_oReservedInfo = new StateRequestedInfo(l_oDateTimeMock.GetDateTime, l_oReservedAt, "a@b", null);
|
||||
var l_oReservedInfo = new StateRequestedInfo(l_oDateTimeMock.GetDateTime, l_oReservedAt, TimeSpan.FromMinutes(15), "a@b", null);
|
||||
Assert.AreEqual("a@b", l_oReservedInfo.MailAddress);
|
||||
Assert.AreEqual(new DateTime(2017, 09, 20, 22, 01, 00), l_oReservedInfo.From, "a@b");
|
||||
|
||||
|
@ -86,5 +86,39 @@ namespace TestTINKLib
|
|||
Assert.IsNull(remainingTime);
|
||||
Assert.AreEqual(new DateTime(2017, 09, 20, 22, 01, 00), l_oReservedInfo.From, "a@b");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestReservationTimeSpanCtor() =>
|
||||
Assert.That(new StateRequestedInfo().MaxReservationTimeSpan, Is.EqualTo(TimeSpan.Zero));
|
||||
|
||||
[Test]
|
||||
public void TestGetIsStillReserved() =>
|
||||
Assert.That(new StateRequestedInfo(
|
||||
() => new DateTime(2023, 5, 11, 14, 42, 0, 100), // one hundred millisecond after bike was reserved
|
||||
new DateTime(2023, 5, 11, 14, 42, 0, 0),
|
||||
TimeSpan.FromSeconds(1),
|
||||
"a@b",
|
||||
"").GetIsStillReserved(out _),
|
||||
Is.True);
|
||||
|
||||
[Test]
|
||||
public void TestGetIsStillReservedExpired() =>
|
||||
Assert.That(new StateRequestedInfo(
|
||||
() => new DateTime(2023, 5, 11, 14, 42, 0, 100), // one hundred millisecond after bike was reserved
|
||||
new DateTime(2023, 5, 11, 14, 42, 0, 0),
|
||||
TimeSpan.FromMilliseconds(50),
|
||||
"a@b",
|
||||
"").GetIsStillReserved(out _),
|
||||
Is.False);
|
||||
|
||||
[Test]
|
||||
public void TestGetIsStillReservedInvalidMaxReservationTimeSpan() =>
|
||||
Assert.That(new StateRequestedInfo(
|
||||
() => new DateTime(2023, 5, 11, 14, 42, 0, 1), // one hundred millisecond after bike was reserved
|
||||
new DateTime(2023, 5, 11, 14, 42, 0, 0),
|
||||
TimeSpan.Zero,
|
||||
"a@b",
|
||||
"").GetIsStillReserved(out _),
|
||||
Is.False);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace TestTINKLib.Fixtures.State
|
|||
var l_oReservedInfo = new StateRequestedInfo(
|
||||
() => new DateTime(2017, 09, 20),
|
||||
new DateTime(2017, 09, 19),
|
||||
TimeSpan.FromMinutes(15),
|
||||
"ä@b",
|
||||
"372");
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System.Linq;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using TINK.Repository.Response;
|
||||
|
||||
|
@ -129,7 +129,7 @@ namespace TestShareeLib.Repository.Response
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that unknown elemts in JSON to not lead to firing of exceptions.
|
||||
/// Verifies that unknown elements in JSON to not lead to firing of exceptions.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestDeserialize_NewElement()
|
||||
|
@ -186,7 +186,47 @@ namespace TestShareeLib.Repository.Response
|
|||
Assert.That(
|
||||
tariffDescription.tarif_elements.Count,
|
||||
Is.EqualTo(2),
|
||||
"Dupliate elements are supposed to be ignored.");
|
||||
"Duplicate elements are supposed to be ignored.");
|
||||
}
|
||||
|
||||
public static string RENTALDESCRIPTIONRESPONSE_A_V4_1_23_03 = @"{
|
||||
""tarif_elements"": {
|
||||
""1"": [
|
||||
""Mietgebühr"",
|
||||
""1,50 € / 30 Min ""
|
||||
],
|
||||
""4"": [
|
||||
""Max. Gebühr"",
|
||||
""25,00 € / Tag""
|
||||
],
|
||||
""6"": [
|
||||
""Gratis Mietzeit"",
|
||||
""30 Min / Tag""
|
||||
]
|
||||
},
|
||||
""reserve_timerange"": ""30"",
|
||||
""id"": ""100"",
|
||||
""name"": ""Basis"",
|
||||
""rental_info"": {
|
||||
""1"": [
|
||||
""Tracking"",
|
||||
""Ich stimme der Speicherung (Tracking) meiner Fahrstrecke zwecks wissenschaftlicher Auswertung und Berechnung der CO2-Einsparung zu!""
|
||||
],
|
||||
""2"": [
|
||||
""AAFahrten"",
|
||||
""Dieses E-Lastenrad darf nur an der Station zurück gegeben werden an der es ausgeliehen wurde!""
|
||||
]
|
||||
}
|
||||
}";
|
||||
|
||||
[Test]
|
||||
public void TestReserveTimeRange()
|
||||
{
|
||||
var response = JsonConvertRethrow.DeserializeObject<RentalDescription>(RENTALDESCRIPTIONRESPONSE_A_V4_1_23_03);
|
||||
Assert.That(
|
||||
response.reserve_timerange,
|
||||
Is.EqualTo("30"));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using NUnit.Framework;
|
||||
using NUnit.Framework;
|
||||
using TINK.Repository.Response;
|
||||
|
||||
namespace TestShareeLib.Repository.Response
|
||||
|
@ -73,7 +73,7 @@ namespace TestShareeLib.Repository.Response
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that unknown elemts in JSON to not lead to firing of exceptions.
|
||||
/// Verifies that unknown elements in JSON to not lead to firing of exceptions.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestDeserialize_NewElement()
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace UITest.Fixtures.ViewModel
|
|||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// Tests base class functionality by using child.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestStateText_NotLoggedIn()
|
||||
|
@ -89,7 +89,7 @@ namespace UITest.Fixtures.ViewModel
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// Tests base class functionality by using child.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestStateText_LoggedIn_Reserved()
|
||||
|
@ -112,7 +112,7 @@ namespace UITest.Fixtures.ViewModel
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// Tests base class functionality by using child.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestStateText_LoggedIn_ReservedWithCopriConnect()
|
||||
|
@ -135,7 +135,7 @@ namespace UITest.Fixtures.ViewModel
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// Tests base class functionality by using child.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestStateText_LoggedIn_Booked()
|
||||
|
@ -170,6 +170,7 @@ namespace UITest.Fixtures.ViewModel
|
|||
l_oBike.State.Load(
|
||||
InUseStateEnum.Reserved,
|
||||
new DateTime(2017, 10, 24, 21, 49, 3),
|
||||
TimeSpan.FromMinutes(15),
|
||||
"ragu@gnu-systems.de",
|
||||
"4asdfA");
|
||||
|
||||
|
@ -199,7 +200,7 @@ namespace UITest.Fixtures.ViewModel
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// Tests base class functionality by using child.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestStateText_LoggedIn_BookedBySomeoneElse()
|
||||
|
@ -209,6 +210,7 @@ namespace UITest.Fixtures.ViewModel
|
|||
l_oBike.State.Load(
|
||||
InUseStateEnum.Booked,
|
||||
new DateTime(2017, 10, 24, 21, 49, 3),
|
||||
TimeSpan.FromMinutes(15),
|
||||
"ragu@gnu-systems.de",
|
||||
"4asdfA");
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace UITest.Fixtures.ViewModel
|
|||
public class TestMyBikesPageViewModel
|
||||
{
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// Tests base class functionality by using child.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestStateText_LoggedIn_Reserved()
|
||||
|
@ -36,7 +36,7 @@ namespace UITest.Fixtures.ViewModel
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// Tests base class functionality by using child.
|
||||
/// </summary>
|
||||
[Test]
|
||||
public void TestStateText_LoggedIn_ReservedWithCopriConnect()
|
||||
|
@ -60,7 +60,7 @@ namespace UITest.Fixtures.ViewModel
|
|||
|
||||
|
||||
/// <summary>
|
||||
/// Tests base class functionaltiy by using child.
|
||||
/// Tests base class functionality by using child.
|
||||
/// </summary>
|
||||
///
|
||||
[Test]
|
||||
|
|
|
@ -182,7 +182,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
/// <summary>
|
||||
/// Use case: End rental.
|
||||
/// Comment: User deceide to abort returning bike
|
||||
/// Comment: User decide to abort returning bike
|
||||
/// Final state: Same as initial state.
|
||||
/// </summary>
|
||||
[Test]
|
||||
|
@ -343,7 +343,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
location
|
||||
)); ;
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -410,7 +410,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
connector.Command.DoReturn(bike, Arg.Any<LocationDto>()).Returns<BookingFinishedModel>(x => throw new WebConnectFailureException("Context info", new Exception("hoppla")));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -486,7 +486,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
connector.Command.DoReturn(bike, Arg.Any<LocationDto>()).Returns<BookingFinishedModel>(x =>
|
||||
throw notAtStationException);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -556,7 +556,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
connector.Command.DoReturn(bike, Arg.Any<LocationDto>()).Returns<BookingFinishedModel>(x =>
|
||||
throw noGPSDataException);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -624,7 +624,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
connector.Command.DoReturn(bike, Arg.Any<LocationDto>()).Returns<BookingFinishedModel>(x =>
|
||||
throw new ReturnBikeException(JsonConvert.DeserializeObject<DoReturnResponse>(@"{ ""response_text"" : ""Some invalid data received!""}"), "Outer message."));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -691,7 +691,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
connector.Command.DoReturn(bike, Arg.Any<LocationDto>()).Returns<BookingFinishedModel>(x => throw new Exception("Exception message."));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
|
|
@ -64,6 +64,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
bike.TariffDescription.MaxReservationTimeSpan.Returns(TimeSpan.FromMinutes(15));
|
||||
|
||||
var handler = new DisposableDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
|
@ -115,6 +117,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
var activeUser = Substitute.For<IUser>();
|
||||
var timeOuts = Substitute.For<ITimeOutProvider>();
|
||||
|
||||
bike.TariffDescription.MaxReservationTimeSpan.Returns(TimeSpan.FromMinutes(15));
|
||||
|
||||
var handler = new DisposableDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
|
@ -194,6 +198,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
bike.TariffDescription.MaxReservationTimeSpan.Returns(TimeSpan.FromMinutes(15));
|
||||
|
||||
var handler = new DisposableDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
|
@ -212,7 +218,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
connector.Command.DoReserve(bike).Returns(x => throw new BookingDeclinedException(7)); // Booking must be performed
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -257,6 +263,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
bike.TariffDescription.MaxReservationTimeSpan.Returns(TimeSpan.FromMinutes(15));
|
||||
|
||||
var handler = new DisposableDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
|
@ -275,7 +283,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
connector.Command.DoReserve(bike).Returns<Task>(x => throw new WebConnectFailureException("Context info.", new Exception("chub")));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -320,6 +328,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
bike.TariffDescription.MaxReservationTimeSpan.Returns(TimeSpan.FromMinutes(15));
|
||||
|
||||
var handler = new DisposableDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
|
@ -338,7 +348,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
connector.Command.DoReserve(bike).Returns<Task>(x => throw new Exception("Exception message."));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -384,6 +394,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
var activeUser = Substitute.For<IUser>();
|
||||
var timeOuts = Substitute.For<ITimeOutProvider>();
|
||||
|
||||
bike.TariffDescription.MaxReservationTimeSpan.Returns(TimeSpan.FromMinutes(15));
|
||||
|
||||
var handler = new DisposableDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
|
@ -403,7 +415,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>()).Returns<LockInfoTdo>(x => throw new OutOfReachException());
|
||||
locks.TimeOut.Returns(timeOuts);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -450,6 +462,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
var activeUser = Substitute.For<IUser>();
|
||||
var timeOuts = Substitute.For<ITimeOutProvider>();
|
||||
|
||||
bike.TariffDescription.MaxReservationTimeSpan.Returns(TimeSpan.FromMinutes(15));
|
||||
|
||||
var handler = new DisposableDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
|
@ -469,7 +483,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
locks.ConnectAsync(Arg.Any<LockInfoAuthTdo>(), Arg.Any<TimeSpan>()).Returns<LockInfoTdo>(x => throw new Exception("Exception message."));
|
||||
locks.TimeOut.Returns(timeOuts);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -516,6 +530,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
var activeUser = Substitute.For<IUser>();
|
||||
var timeOuts = Substitute.For<ITimeOutProvider>();
|
||||
|
||||
bike.TariffDescription.MaxReservationTimeSpan.Returns(TimeSpan.FromMinutes(15));
|
||||
|
||||
var handler = new DisposableDisconnected(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
|
@ -534,7 +550,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
locks.TimeOut.Returns(timeOuts);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownFromHardwareError); // Connect did not throw an exception but lock state is still unknown.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
|
|
@ -81,7 +81,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
locks[0].CloseAsync().Returns(Task.FromResult((LockitLockingState?)LockitLockingState.Closed));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -141,7 +141,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
locks[0].CloseAsync().Returns<Task<LockitLockingState?>>(x => throw new OutOfReachException());
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Open);
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -204,7 +204,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
locks[0].CloseAsync().Returns<Task<LockitLockingState?>>(x => throw new Exception("Exception message."));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Open);
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
|
|
@ -52,7 +52,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
|||
|
||||
/// <summary>
|
||||
/// Use case: Cancel reservation.
|
||||
/// Comment: User deceide to abort cancelling (user is ased whether to really cancel)
|
||||
/// Comment: User decide to abort canceling (user is ased whether to really cancel)
|
||||
/// Final state: Same as initial state.
|
||||
/// </summary>
|
||||
[Test]
|
||||
|
@ -135,7 +135,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
|||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, string.Format("Cancel reservation for bike {0}?", "Nr. 0"), "Yes", "No").Returns(Task.FromResult(true));
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -207,7 +207,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
|||
}");
|
||||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new InvalidAuthorizationResponseException("mustermann@server.de", response));
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -275,7 +275,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
|||
viewService.DisplayAlert(string.Empty, string.Format("Cancel reservation for bike {0}?", "Nr. 0"), "Yes", "No").Returns(Task.FromResult(true));
|
||||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new WebConnectFailureException("Context info.", new Exception("chub")));
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -343,7 +343,7 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.BluetoothLock.RequestHandler
|
|||
viewService.DisplayAlert(string.Empty, string.Format("Cancel reservation for bike {0}?", "Nr. 0"), "Yes", "No").Returns(Task.FromResult(true));
|
||||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new Exception("Exception message."));
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Closed); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
|
|
@ -50,7 +50,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
/// <summary>
|
||||
/// Use case: Cancel reservation.
|
||||
/// Comment: User deceide to abort cancelling (user is ased whether to really cancel)
|
||||
/// Comment: User decide to abort canceling (user is ased whether to really cancel)
|
||||
/// Final state: Same as initial state.
|
||||
/// </summary>
|
||||
[Test]
|
||||
|
@ -131,7 +131,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
bike.Id.Returns("0");
|
||||
|
||||
viewService.DisplayAlert(string.Empty, string.Format("Cancel reservation for bike {0}?", "Nr. 0"), "Yes", "No").Returns(Task.FromResult(true));
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -201,7 +201,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
}");
|
||||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new InvalidAuthorizationResponseException("mustermann@server.de", l_oResponse));
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -267,7 +267,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
viewService.DisplayAlert(string.Empty, string.Format("Cancel reservation for bike {0}?", "Nr. 0"), "Yes", "No").Returns(Task.FromResult(true));
|
||||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new WebConnectFailureException("Context info", new Exception("chub")));
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -333,7 +333,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
viewService.DisplayAlert(string.Empty, string.Format("Cancel reservation for bike {0}?", "Nr. 0"), "Yes", "No").Returns(Task.FromResult(true));
|
||||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new Exception("Exception message."));
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.UnknownDisconnected); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
viewService.DisplayAlert(string.Empty, "Rad Nr. 0 abschließen und zurückgeben oder Rad mieten?", "Zurückgeben", "Mieten").Returns(Task.FromResult(false));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Booked); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Open); // Requesthandler factory queries lock state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -143,7 +143,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
locks[0].CloseAsync().Returns(LockitLockingState.Closed);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -212,7 +212,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
locks[0].CloseAsync().Returns(LockitLockingState.Closed);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -278,7 +278,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
locks[0].CloseAsync().Returns(LockitLockingState.Closed);
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -347,7 +347,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
locks[0].CloseAsync()
|
||||
.Returns<Task<LockitLockingState?>>(x => { throw new OutOfReachException(); });
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Open);
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -421,7 +421,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
locks[0].CloseAsync()
|
||||
.Returns<Task<LockitLockingState?>>(x => { throw new Exception("Exception message."); });
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Reserved); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
bike.LockInfo.State.Returns(LockingState.Open);
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
@ -500,7 +500,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new InvalidAuthorizationResponseException("mustermann@server.de", response));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
|
||||
locks.DidNotReceive().DisconnectAsync(Arg.Any<int>(), Arg.Any<Guid>());
|
||||
|
||||
|
@ -571,7 +571,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new WebConnectFailureException("Context info", new Exception("chub")));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
@ -642,7 +642,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel.Bikes.Bike.BluetoothLock.Re
|
|||
|
||||
connector.Command.DoCancelReservation(bike).Returns(x => throw new Exception("Exception message.", new Exception("chub")));
|
||||
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Reqesthandler factory queries state to create appropriate request handler object.
|
||||
bike.State.Value.Returns(InUseStateEnum.Disposable); // Requesthandler factory queries state to create appropriate request handler object.
|
||||
|
||||
var subsequent = handler.HandleRequestOption1().Result;
|
||||
|
||||
|
|
|
@ -312,6 +312,8 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.CopriLock.RequestHandler
|
|||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
bike.TariffDescription.MaxReservationTimeSpan.Returns(TimeSpan.FromMinutes(15));
|
||||
|
||||
var handler = new DisposableClosed(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
|
@ -374,6 +376,8 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.CopriLock.RequestHandler
|
|||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
bike.TariffDescription.MaxReservationTimeSpan.Returns(TimeSpan.FromMinutes(15));
|
||||
|
||||
var handler = new DisposableClosed(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
|
@ -449,6 +453,8 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.CopriLock.RequestHandler
|
|||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
bike.TariffDescription.MaxReservationTimeSpan.Returns(TimeSpan.FromMinutes(15));
|
||||
|
||||
var handler = new DisposableClosed(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
|
@ -525,6 +531,8 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.CopriLock.RequestHandler
|
|||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
bike.TariffDescription.MaxReservationTimeSpan.Returns(TimeSpan.FromMinutes(15));
|
||||
|
||||
var handler = new DisposableClosed(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
|
@ -600,6 +608,8 @@ namespace TestShareeLib.ViewModel.Bikes.Bike.CopriLock.RequestHandler
|
|||
var bikesViewModel = Substitute.For<IBikesViewModel>();
|
||||
var activeUser = Substitute.For<IUser>();
|
||||
|
||||
bike.TariffDescription.MaxReservationTimeSpan.Returns(TimeSpan.FromMinutes(15));
|
||||
|
||||
var handler = new DisposableClosed(
|
||||
bike,
|
||||
() => true, // isConnectedDelegate
|
||||
|
|
|
@ -1040,7 +1040,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
|
|||
|
||||
Assert.AreEqual("Available.", bikesAtStation.FirstOrDefault(x => x.Id == "FR9999").StateText);
|
||||
Assert.AreEqual("Available.", bikesAtStation.FirstOrDefault(x => x.Id == "FR9999").StateText);
|
||||
Assert.AreEqual("Max. reservation time of 15 min. expired.", bikesAtStation.FirstOrDefault(x => x.Id == "FR1004").StateText);
|
||||
Assert.AreEqual("Max. reservation time expired.", bikesAtStation.FirstOrDefault(x => x.Id == "FR1004").StateText);
|
||||
Assert.AreEqual($"Rented since {DateTime.Parse("2021-11-06 18:57:25.445447+01"):dd. MMMM HH:mm}.", bikesAtStation.FirstOrDefault(x => x.Id == "FR1544").StateText); // Was 7
|
||||
|
||||
// Login hint/ no bikes frame
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using TINK.ViewModel;
|
||||
|
||||
|
@ -10,7 +10,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
|
|||
[Test]
|
||||
public void TestGetReservedInfo()
|
||||
{
|
||||
Assert.That(new BikeAtStationInUseStateInfoProvider().GetReservedInfo(null), Is.EqualTo("Max. reservation time of 15 min. expired."));
|
||||
Assert.That(new BikeAtStationInUseStateInfoProvider().GetReservedInfo(null), Is.EqualTo("Max. reservation time expired."));
|
||||
Assert.That(new BikeAtStationInUseStateInfoProvider().GetReservedInfo(null, code: "Code123"), Is.Not.Null);
|
||||
Assert.That(new BikeAtStationInUseStateInfoProvider().GetReservedInfo(TimeSpan.FromSeconds(3), code: "Code123"), Is.Not.Null);
|
||||
Assert.That(new BikeAtStationInUseStateInfoProvider().GetReservedInfo(TimeSpan.FromSeconds(60)), Is.EqualTo("Still 1 min. reserved."));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using TINK.ViewModel;
|
||||
|
||||
|
@ -10,9 +10,9 @@ namespace TestTINKLib.Fixtures.ObjectTests.ViewModel
|
|||
[Test]
|
||||
public void TestGetReservedInfo()
|
||||
{
|
||||
Assert.That(new MyBikeInUseStateInfoProvider().GetReservedInfo(null), Is.EqualTo("Max. reservation time of 15 min. expired."));
|
||||
Assert.That(new MyBikeInUseStateInfoProvider().GetReservedInfo(null), Is.EqualTo("Max. reservation time expired."));
|
||||
Assert.That(new MyBikeInUseStateInfoProvider().GetReservedInfo(null, code: "Code12"), Is.Not.Null);
|
||||
Assert.That(new MyBikeInUseStateInfoProvider().GetReservedInfo(null, "12"), Is.EqualTo("Location 12, max. reservation time of 15 min. expired."));
|
||||
Assert.That(new MyBikeInUseStateInfoProvider().GetReservedInfo(null, "12"), Is.EqualTo("Location 12, max. reservation time expired."));
|
||||
Assert.That(new MyBikeInUseStateInfoProvider().GetReservedInfo(null, "12", "Code12"), Is.Not.Null);
|
||||
Assert.That(new MyBikeInUseStateInfoProvider().GetReservedInfo(TimeSpan.FromSeconds(10)), Is.Not.Null);
|
||||
Assert.That(new MyBikeInUseStateInfoProvider().GetReservedInfo(TimeSpan.FromSeconds(10), "123"), Is.EqualTo("Location Station 123, still 0 min. reserved."));
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
admin
|
||||
app
|
||||
auth
|
||||
backend
|
||||
|
@ -5,19 +6,23 @@ bluetooth
|
|||
bord
|
||||
copri
|
||||
deserialization
|
||||
Deserialize
|
||||
deserialized
|
||||
deserializing
|
||||
flyout
|
||||
Geolocation
|
||||
gps
|
||||
Guid
|
||||
https
|
||||
Namespace
|
||||
nullable
|
||||
offline
|
||||
ok
|
||||
pedelecs
|
||||
popup
|
||||
pwd
|
||||
refactored
|
||||
serializer
|
||||
uri
|
||||
uris
|
||||
Url
|
||||
|
|
Loading…
Reference in a new issue