mirror of
https://dev.azure.com/TeilRad/sharee.bike%20App/_git/Code
synced 2025-01-11 23:54:27 +01:00
Contact page shows operator specific info
This commit is contained in:
parent
e436e83c1d
commit
a58c33f005
51 changed files with 948 additions and 221 deletions
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="preferExternal" package="com.hauffware.sharee" android:versionName="3.0.240" android:versionCode="240">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="preferExternal" package="com.hauffware.sharee" android:versionName="3.0.241" android:versionCode="241">
|
||||||
<uses-sdk android:minSdkVersion="18" android:targetSdkVersion="30" />
|
<uses-sdk android:minSdkVersion="18" android:targetSdkVersion="30" />
|
||||||
<!-- Google Maps related permissions -->
|
<!-- Google Maps related permissions -->
|
||||||
<permission android:name="com.ecs.google.maps.v2.actionbarsherlock.permission.MAPS_RECEIVE" android:protectionLevel="signature" />
|
<permission android:name="com.ecs.google.maps.v2.actionbarsherlock.permission.MAPS_RECEIVE" android:protectionLevel="signature" />
|
||||||
|
|
|
@ -49,8 +49,8 @@
|
||||||
<key>CFBundleDisplayName</key>
|
<key>CFBundleDisplayName</key>
|
||||||
<string>sharee.bike</string>
|
<string>sharee.bike</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>240</string>
|
<string>241</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>3.0.240</string>
|
<string>3.0.241</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
<DependentUpon>ILockItBike.xaml</DependentUpon>
|
<DependentUpon>ILockItBike.xaml</DependentUpon>
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="$(MSBuildThisFileDirectory)View\BoolInverterConverter.cs" />
|
||||||
<Compile Include="$(MSBuildThisFileDirectory)View\FeedbackPopup.xaml.cs">
|
<Compile Include="$(MSBuildThisFileDirectory)View\FeedbackPopup.xaml.cs">
|
||||||
<DependentUpon>FeedbackPopup.xaml</DependentUpon>
|
<DependentUpon>FeedbackPopup.xaml</DependentUpon>
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
x:Class="TINK.View.BikesAtStation.BikesAtStationPage"
|
x:Class="TINK.View.BikesAtStation.BikesAtStationPage"
|
||||||
xmlns:local_bike="clr-namespace:TINK.View.Bike"
|
xmlns:local_bike="clr-namespace:TINK.View.Bike"
|
||||||
|
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
|
||||||
Title="{Binding Title}">
|
Title="{Binding Title}">
|
||||||
<ContentPage.Resources>
|
<ContentPage.Resources>
|
||||||
<ResourceDictionary>
|
<ResourceDictionary>
|
||||||
|
@ -11,7 +12,8 @@
|
||||||
</ContentPage.Resources>
|
</ContentPage.Resources>
|
||||||
<ContentPage.Content>
|
<ContentPage.Content>
|
||||||
<Frame>
|
<Frame>
|
||||||
<StackLayout>
|
<StackLayout
|
||||||
|
Orientation="Vertical">
|
||||||
<ListView
|
<ListView
|
||||||
x:Name="BikesAtStationListView"
|
x:Name="BikesAtStationListView"
|
||||||
SelectionMode="None"
|
SelectionMode="None"
|
||||||
|
@ -20,20 +22,28 @@
|
||||||
IsVisible="{Binding IsBikesListVisible}"
|
IsVisible="{Binding IsBikesListVisible}"
|
||||||
HasUnevenRows="True"
|
HasUnevenRows="True"
|
||||||
ItemTemplate="{StaticResource bikeTemplateSelector}"/>
|
ItemTemplate="{StaticResource bikeTemplateSelector}"/>
|
||||||
<StackLayout
|
|
||||||
VerticalOptions="EndAndExpand"
|
|
||||||
Orientation="Horizontal">
|
|
||||||
<Label
|
<Label
|
||||||
IsVisible="{Binding IsNoBikesAtStationVisible}"
|
IsVisible="{Binding IsNoBikesAtStationVisible}"
|
||||||
VerticalOptions="EndAndExpand"
|
VerticalOptions="EndAndExpand"
|
||||||
Text="{Binding NoBikesAtStationText}"/>
|
Text="{Binding NoBikesAtStationText}"/>
|
||||||
|
<Label
|
||||||
|
TextType="Html"
|
||||||
|
Text="{Binding ContactSupportHintText}">
|
||||||
|
<Label.GestureRecognizers>
|
||||||
|
<TapGestureRecognizer Command="{Binding ContactSupportClickedCommand}"/>
|
||||||
|
</Label.GestureRecognizers>
|
||||||
|
</Label>
|
||||||
<Label
|
<Label
|
||||||
IsVisible="{Binding IsLoginRequiredHintVisible}"
|
IsVisible="{Binding IsLoginRequiredHintVisible}"
|
||||||
FormattedText="{Binding LoginRequiredHintText}">
|
TextType="Html"
|
||||||
|
Text="{Binding LoginRequiredHintText}">
|
||||||
<Label.GestureRecognizers>
|
<Label.GestureRecognizers>
|
||||||
<TapGestureRecognizer Command="{Binding LoginRequiredHintClickedCommand}"/>
|
<TapGestureRecognizer Command="{Binding LoginRequiredHintClickedCommand}"/>
|
||||||
</Label.GestureRecognizers>
|
</Label.GestureRecognizers>
|
||||||
</Label>
|
</Label>
|
||||||
|
<StackLayout
|
||||||
|
VerticalOptions="EndAndExpand"
|
||||||
|
Orientation="Horizontal">
|
||||||
<Label
|
<Label
|
||||||
HeightRequest="20"
|
HeightRequest="20"
|
||||||
Text="{Binding StatusInfoText}"
|
Text="{Binding StatusInfoText}"
|
||||||
|
|
19
TINK/TINK/View/BoolInverterConverter.cs
Normal file
19
TINK/TINK/View/BoolInverterConverter.cs
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace TINK.View
|
||||||
|
{
|
||||||
|
/// <summary> Inverts a bool.</summary>
|
||||||
|
public class BoolInverterConverter : IValueConverter
|
||||||
|
{
|
||||||
|
/// <summary> Inverts a bool.</summary>
|
||||||
|
/// <param name="value">Bool to invert.</param>
|
||||||
|
/// <returns>Inverted bool.</returns>
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
=> value is bool flag && !flag;
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
=> value is bool flag && !flag;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,25 +1,47 @@
|
||||||
<?xml version="1.0" encoding="utf-8" ?>
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||||
|
xmlns:conv="clr-namespace:TINK.View"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||||
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
|
xmlns:resources="clr-namespace:TINK.MultilingualResources;assembly=TINKLib"
|
||||||
x:Class="TINK.View.Contact.ContactPage"
|
x:Class="TINK.View.Contact.ContactPage"
|
||||||
Title="Kontakt">
|
Title="Kontakt">
|
||||||
|
<ContentPage.Resources>
|
||||||
|
<conv:StringNotNullOrEmptyToVisibleConverter x:Key="StringNotNullOrEmpty_Converter"/>
|
||||||
|
<conv:BoolInverterConverter x:Key="BoolInvert_Converter"/>
|
||||||
|
</ContentPage.Resources>
|
||||||
<ContentPage.Content>
|
<ContentPage.Content>
|
||||||
<ScrollView>
|
<ScrollView>
|
||||||
<Frame>
|
<Frame>
|
||||||
<StackLayout x:Name="ContactPageView">
|
<StackLayout x:Name="ContactPageView">
|
||||||
<Frame>
|
<Frame
|
||||||
|
IsVisible="{Binding
|
||||||
|
Path=IsOperatorInfoAvaliable,
|
||||||
|
Converter={StaticResource BoolInvert_Converter}}">
|
||||||
|
<Label
|
||||||
|
TextType="Html"
|
||||||
|
Text="{x:Static resources:AppResources.MarkingContactNoStationInfoAvailableNoButton}"/>
|
||||||
|
</Frame>
|
||||||
|
<Frame
|
||||||
|
IsVisible="{Binding IsOperatorInfoAvaliable}">
|
||||||
<StackLayout>
|
<StackLayout>
|
||||||
<Label FormattedText="{Binding MaliAddressAndMotivationsText}"/>
|
<!--- Mail address -->
|
||||||
<Button Text="{Binding MailAddressText}"
|
<Label
|
||||||
|
IsVisible="{Binding MailAddressText, Converter={StaticResource StringNotNullOrEmpty_Converter}}"
|
||||||
|
FormattedText="{Binding MaliAddressAndMotivationsText}"/>
|
||||||
|
<Button
|
||||||
|
x:Name="MailAddressButton"
|
||||||
|
IsVisible="{Binding MailAddressText, Converter={StaticResource StringNotNullOrEmpty_Converter}}"
|
||||||
|
Text="{Binding MailAddressText}"
|
||||||
IsEnabled="{Binding IsSendMailAvailable}"
|
IsEnabled="{Binding IsSendMailAvailable}"
|
||||||
Command="{Binding OnMailRequest}"/>
|
Command="{Binding OnMailRequest}"/>
|
||||||
</StackLayout>
|
<!--- Mail address -->
|
||||||
</Frame>
|
<Label
|
||||||
<Frame>
|
IsVisible="{Binding PhoneNumberText, Converter={StaticResource StringNotNullOrEmpty_Converter}}"
|
||||||
<StackLayout>
|
FormattedText="{Binding PhoneContactText}"/>
|
||||||
<Label FormattedText="{Binding PhoneContactText}"/>
|
<Button
|
||||||
<Button Text="{Binding PhoneNumberText}"
|
x:Name="PhoneNumberButton"
|
||||||
|
IsVisible="{Binding PhoneNumberText, Converter={StaticResource StringNotNullOrEmpty_Converter}}"
|
||||||
|
Text="{Binding PhoneNumberText}"
|
||||||
IsEnabled="{Binding IsDoPhoncallAvailable}"
|
IsEnabled="{Binding IsDoPhoncallAvailable}"
|
||||||
Command="{Binding OnPhoneRequest}"/>
|
Command="{Binding OnPhoneRequest}"/>
|
||||||
</StackLayout>
|
</StackLayout>
|
||||||
|
|
|
@ -16,6 +16,7 @@ namespace TINK.View.Contact
|
||||||
InitializeComponent ();
|
InitializeComponent ();
|
||||||
|
|
||||||
ContactPageView.BindingContext = new ContactPageViewModel(
|
ContactPageView.BindingContext = new ContactPageViewModel(
|
||||||
|
App.ModelRoot.SelectedStation,
|
||||||
App.ModelRoot.Uris.ActiveUri,
|
App.ModelRoot.Uris.ActiveUri,
|
||||||
() => App.CreateAttachment(),
|
() => App.CreateAttachment(),
|
||||||
() => DependencyService.Get<IExternalBrowserService>().OpenUrl(DependencyService.Get<IAppInfo>().StoreUrl),
|
() => DependencyService.Get<IExternalBrowserService>().OpenUrl(DependencyService.Get<IAppInfo>().StoreUrl),
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using TINK.Model.Station;
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
#if USEMASTERDETAIL || USEFLYOUT
|
#if USEMASTERDETAIL || USEFLYOUT
|
||||||
using TINK.View.MasterDetail;
|
using TINK.View.MasterDetail;
|
||||||
#endif
|
#endif
|
||||||
|
@ -58,9 +55,14 @@ namespace TINK.View.Root
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void OnListViewItemSelected(object sender, SelectedItemChangedEventArgs e)
|
private void OnListViewItemSelected(object sender, SelectedItemChangedEventArgs e)
|
||||||
{
|
{
|
||||||
var item = e.SelectedItem as RootPageFlyoutMenuItem;
|
if (!(e.SelectedItem is RootPageFlyoutMenuItem item))
|
||||||
if (item == null)
|
{
|
||||||
|
// Unexpected argument detected.
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set selected station to new
|
||||||
|
App.ModelRoot.SelectedStation = new NullStation();
|
||||||
|
|
||||||
ShowPage(item.TargetType, item.Title);
|
ShowPage(item.TargetType, item.Title);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using TINK.ViewModel.RootShell;
|
using TINK.ViewModel.RootShell;
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text;
|
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
using TINK.Model.User.Account;
|
using TINK.Model.User.Account;
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
|
|
||||||
namespace TINK.View.Settings
|
namespace TINK.View.Settings
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Text;
|
|
||||||
using Xamarin.Forms;
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace TINK.View
|
namespace TINK.View
|
||||||
|
@ -14,7 +12,7 @@ namespace TINK.View
|
||||||
/// <returns>Boolean value indicating whether object is visible or not.</returns>
|
/// <returns>Boolean value indicating whether object is visible or not.</returns>
|
||||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
return (value != null && value is string text && !string.IsNullOrEmpty(text));
|
return value != null && value is string text && !string.IsNullOrEmpty(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
|
|
@ -44,7 +44,7 @@ namespace TINK.View
|
||||||
case ViewTypes.TabbedPageInfo:
|
case ViewTypes.TabbedPageInfo:
|
||||||
return typeof(TabbedPageInfo);
|
return typeof(TabbedPageInfo);
|
||||||
|
|
||||||
case ViewTypes.TabbedPageHelpContact:
|
case ViewTypes.FeesAndBikesPage:
|
||||||
return typeof(FeesAndBikesPage);
|
return typeof(FeesAndBikesPage);
|
||||||
|
|
||||||
case ViewTypes.ManageAccountPage:
|
case ViewTypes.ManageAccountPage:
|
||||||
|
@ -59,6 +59,9 @@ namespace TINK.View
|
||||||
case ViewTypes.BikesAtStation:
|
case ViewTypes.BikesAtStation:
|
||||||
return typeof(BikesAtStationPage);
|
return typeof(BikesAtStationPage);
|
||||||
|
|
||||||
|
case ViewTypes.ContactPage:
|
||||||
|
return typeof(ContactPage);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return typeof(ContentPage);
|
return typeof(ContentPage);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace TINK.Model.Connector
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="p_oStationInfo">Object to get information from.</param>
|
/// <param name="p_oStationInfo">Object to get information from.</param>
|
||||||
/// <returns>Position information.</returns>
|
/// <returns>Position information.</returns>
|
||||||
public static Station.Position GetPosition(this StationsAllResponse.StationInfo p_oStationInfo)
|
public static Station.Position GetPosition(this StationsAvailableResponse.StationInfo p_oStationInfo)
|
||||||
{
|
{
|
||||||
return GetPosition(p_oStationInfo.gps);
|
return GetPosition(p_oStationInfo.gps);
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ namespace TINK.Model.Connector
|
||||||
/// <summary> Gets the position from StationInfo object. </summary>
|
/// <summary> Gets the position from StationInfo object. </summary>
|
||||||
/// <param name="p_oStationInfo">Object to get information from.</param>
|
/// <param name="p_oStationInfo">Object to get information from.</param>
|
||||||
/// <returns>Position information.</returns>
|
/// <returns>Position information.</returns>
|
||||||
public static IEnumerable<string> GetGroup(this StationsAllResponse.StationInfo p_oStationInfo)
|
public static IEnumerable<string> GetGroup(this StationsAvailableResponse.StationInfo p_oStationInfo)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,6 +11,8 @@ using Serilog;
|
||||||
using BikeInfo = TINK.Model.Bike.BC.BikeInfo;
|
using BikeInfo = TINK.Model.Bike.BC.BikeInfo;
|
||||||
using IBikeInfoMutable = TINK.Model.Bikes.Bike.BC.IBikeInfoMutable;
|
using IBikeInfoMutable = TINK.Model.Bikes.Bike.BC.IBikeInfoMutable;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using TINK.Model.Station.Operator;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace TINK.Model.Connector
|
namespace TINK.Model.Connector
|
||||||
{
|
{
|
||||||
|
@ -34,37 +36,44 @@ namespace TINK.Model.Connector
|
||||||
/// Gets all statsion for station provider and add them into station list.
|
/// Gets all statsion for station provider and add them into station list.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="p_oStationList">List of stations to update.</param>
|
/// <param name="p_oStationList">List of stations to update.</param>
|
||||||
public static StationDictionary GetStationsAllMutable(this StationsAllResponse p_oStationsAllResponse)
|
public static StationDictionary GetStationsAllMutable(this StationsAvailableResponse stationsAllResponse)
|
||||||
{
|
{
|
||||||
// Get stations from Copri/ file/ memory, ....
|
// Get stations from Copri/ file/ memory, ....
|
||||||
if (p_oStationsAllResponse == null
|
if (stationsAllResponse == null
|
||||||
|| p_oStationsAllResponse.stations == null)
|
|| stationsAllResponse.stations == null)
|
||||||
{
|
{
|
||||||
// Latest list of stations could not be retrieved from provider.
|
// Latest list of stations could not be retrieved from provider.
|
||||||
return new StationDictionary();
|
return new StationDictionary();
|
||||||
}
|
}
|
||||||
|
|
||||||
Version.TryParse(p_oStationsAllResponse.copri_version, out Version l_oCopriVersion);
|
Version.TryParse(stationsAllResponse.copri_version, out Version copriVersion);
|
||||||
|
|
||||||
var l_oStations = new StationDictionary(p_oVersion: l_oCopriVersion);
|
var stations = new StationDictionary(p_oVersion: copriVersion);
|
||||||
|
|
||||||
foreach (var l_oStation in p_oStationsAllResponse.stations)
|
foreach (var station in stationsAllResponse.stations)
|
||||||
{
|
{
|
||||||
if (l_oStations.GetById(l_oStation.Value.station) != null)
|
if (stations.GetById(station.Value.station) != null)
|
||||||
{
|
{
|
||||||
// Can not add station to list of station. Id is not unique.
|
// Can not add station to list of station. Id is not unique.
|
||||||
throw new InvalidResponseException<StationsAllResponse>(
|
throw new InvalidResponseException<StationsAvailableResponse>(
|
||||||
string.Format("Station id {0} is not unique.", l_oStation.Value.station), p_oStationsAllResponse);
|
string.Format("Station id {0} is not unique.", station.Value.station), stationsAllResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
l_oStations.Add(new Station.Station(
|
stations.Add(new Station.Station(
|
||||||
l_oStation.Value.station,
|
station.Value.station,
|
||||||
l_oStation.Value.GetGroup(),
|
station.Value.GetGroup(),
|
||||||
l_oStation.Value.GetPosition(),
|
station.Value.GetPosition(),
|
||||||
l_oStation.Value.description));
|
station.Value.description,
|
||||||
|
new Data(station.Value.operator_data?.operator_name,
|
||||||
|
station.Value.operator_data?.operator_phone,
|
||||||
|
station.Value.operator_data?.operator_hours,
|
||||||
|
station.Value.operator_data?.operator_email,
|
||||||
|
!string.IsNullOrEmpty(station.Value.operator_data?.operator_color)
|
||||||
|
? Color.FromHex(station.Value.operator_data?.operator_color)
|
||||||
|
: (Color?)null)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return l_oStations;
|
return stations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Gets account object from login response.</summary>
|
/// <summary> Gets account object from login response.</summary>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using TINK.Model.Station.Operator;
|
||||||
|
|
||||||
namespace TINK.Model.Station
|
namespace TINK.Model.Station
|
||||||
{
|
{
|
||||||
|
@ -15,5 +16,8 @@ namespace TINK.Model.Station
|
||||||
|
|
||||||
/// <summary> Holds the gps- position of the station.</summary>
|
/// <summary> Holds the gps- position of the station.</summary>
|
||||||
Position Position { get; }
|
Position Position { get; }
|
||||||
|
|
||||||
|
/// <summary> Holds operator related data.</summary>
|
||||||
|
IData OperatorData { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using TINK.Model.Station.Operator;
|
||||||
|
|
||||||
namespace TINK.Model.Station
|
namespace TINK.Model.Station
|
||||||
{
|
{
|
||||||
|
@ -16,5 +17,8 @@ namespace TINK.Model.Station
|
||||||
|
|
||||||
/// <summary> Holds the gps- position of the station.</summary>
|
/// <summary> Holds the gps- position of the station.</summary>
|
||||||
public Position Position => new Position(double.NaN, double.NaN);
|
public Position Position => new Position(double.NaN, double.NaN);
|
||||||
|
|
||||||
|
/// <summary> Holds operator related data.</summary>
|
||||||
|
public IData OperatorData => new Data();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
36
TINKLib/Model/Station/Operator/Data.cs
Normal file
36
TINKLib/Model/Station/Operator/Data.cs
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace TINK.Model.Station.Operator
|
||||||
|
{
|
||||||
|
/// <summary> Holds operator related data.</summary>
|
||||||
|
public class Data : IData
|
||||||
|
{
|
||||||
|
public Data(
|
||||||
|
string name = null,
|
||||||
|
string phoneNumberText = null,
|
||||||
|
string hours = null,
|
||||||
|
string mailAddressText = null, Color? color = null)
|
||||||
|
{
|
||||||
|
Name = name ?? string.Empty;
|
||||||
|
PhoneNumberText = phoneNumberText ?? string.Empty;
|
||||||
|
Hours = hours ?? string.Empty;
|
||||||
|
MailAddressText = mailAddressText ?? string.Empty;
|
||||||
|
Color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary> Name of the operator.</summary>
|
||||||
|
public string Name { get; private set; }
|
||||||
|
|
||||||
|
/// <summary> Support phone number of the operator.</summary>
|
||||||
|
public string PhoneNumberText { get; private set; }
|
||||||
|
|
||||||
|
/// <summary> Office times when support is available.</summary>
|
||||||
|
public string Hours { get; private set; }
|
||||||
|
|
||||||
|
/// <summary> Support mails address of the operator.</summary>
|
||||||
|
public string MailAddressText { get; private set; }
|
||||||
|
|
||||||
|
/// <summary> Color of the operator (operator specific skin)</summary>
|
||||||
|
public Color? Color { get; private set; }
|
||||||
|
}
|
||||||
|
}
|
22
TINKLib/Model/Station/Operator/IData.cs
Normal file
22
TINKLib/Model/Station/Operator/IData.cs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
|
namespace TINK.Model.Station.Operator
|
||||||
|
{
|
||||||
|
public interface IData
|
||||||
|
{
|
||||||
|
/// <summary> Name of the operator.</summary>
|
||||||
|
string Name { get; }
|
||||||
|
|
||||||
|
/// <summary> Support phone number of the operator.</summary>
|
||||||
|
string PhoneNumberText { get; }
|
||||||
|
|
||||||
|
/// <summary> Office times when support is available.</summary>
|
||||||
|
string Hours { get; }
|
||||||
|
|
||||||
|
/// <summary> Support mails address of the operator.</summary>
|
||||||
|
string MailAddressText { get; }
|
||||||
|
|
||||||
|
/// <summary> Color of the operator (operator specific skin)</summary>
|
||||||
|
Color? Color { get; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using TINK.Model.Station.Operator;
|
||||||
|
|
||||||
namespace TINK.Model.Station
|
namespace TINK.Model.Station
|
||||||
{
|
{
|
||||||
|
@ -7,20 +8,22 @@ namespace TINK.Model.Station
|
||||||
public class Station : IStation
|
public class Station : IStation
|
||||||
{
|
{
|
||||||
/// <summary> Constructs a station object.</summary>
|
/// <summary> Constructs a station object.</summary>
|
||||||
/// <param name="p_iId">Id of the station.</param>
|
/// <param name="id">Id of the station.</param>
|
||||||
/// <param name="p_oGroup">Group (TINK, Konrad) to which station is related.</param>
|
/// <param name="group">Group (TINK, Konrad) to which station is related.</param>
|
||||||
/// <param name="p_oPosition">GPS- position of the station.</param>
|
/// <param name="position">GPS- position of the station.</param>
|
||||||
/// <param name="p_strStationName">Name of the station.</param>
|
/// <param name="stationName">Name of the station.</param>
|
||||||
public Station(
|
public Station(
|
||||||
string p_iId,
|
string id,
|
||||||
IEnumerable<string> p_oGroup,
|
IEnumerable<string> group,
|
||||||
Position p_oPosition,
|
Position position,
|
||||||
string p_strStationName = "")
|
string stationName = "",
|
||||||
|
Data operatorData = null)
|
||||||
{
|
{
|
||||||
Id = p_iId;
|
Id = id;
|
||||||
Group = p_oGroup ?? throw new ArgumentException("Can not construct station object. Group of stations must not be null.");
|
Group = group ?? throw new ArgumentException("Can not construct station object. Group of stations must not be null.");
|
||||||
Position = p_oPosition;
|
Position = position;
|
||||||
StationName = p_strStationName ?? string.Empty;
|
StationName = stationName ?? string.Empty;
|
||||||
|
OperatorData = operatorData ?? new Data();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Holds the unique id of the station.c</summary>
|
/// <summary> Holds the unique id of the station.c</summary>
|
||||||
|
@ -34,5 +37,8 @@ namespace TINK.Model.Station
|
||||||
|
|
||||||
/// <summary> Holds the gps- position of the station.</summary>
|
/// <summary> Holds the gps- position of the station.</summary>
|
||||||
public Position Position { get; }
|
public Position Position { get; }
|
||||||
|
|
||||||
|
/// <summary> Holds operator related info.</summary>
|
||||||
|
public IData OperatorData { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -322,7 +322,7 @@ namespace TINK.Model
|
||||||
public ICipher Cipher { get; }
|
public ICipher Cipher { get; }
|
||||||
|
|
||||||
/// <summary> Name of the station which is selected. </summary>
|
/// <summary> Name of the station which is selected. </summary>
|
||||||
public IStation SelectedStation { get; set; } = new Station.Station(null, new List<string>(), null);
|
public IStation SelectedStation { get; set; } = new NullStation();
|
||||||
|
|
||||||
/// <summary> Holds the stations availalbe. </summary>
|
/// <summary> Holds the stations availalbe. </summary>
|
||||||
public IEnumerable<IStation> Stations { get; set; } = new List<Station.Station>();
|
public IEnumerable<IStation> Stations { get; set; } = new List<Station.Station>();
|
||||||
|
|
|
@ -413,6 +413,10 @@ namespace TINK.Model
|
||||||
{
|
{
|
||||||
new Version(3, 0, 240),
|
new Version(3, 0, 240),
|
||||||
AppResources.ChangeLog3_0_240
|
AppResources.ChangeLog3_0_240
|
||||||
|
},
|
||||||
|
{
|
||||||
|
new Version(3, 0, 241),
|
||||||
|
AppResources.ChangeLog3_0_241
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -742,6 +742,15 @@ namespace TINK.MultilingualResources {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Bike sharing system operator specific support info displayed on contact page..
|
||||||
|
/// </summary>
|
||||||
|
public static string ChangeLog3_0_241 {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("ChangeLog3_0_241", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Lock of rented bike can not be found..
|
/// Looks up a localized string similar to Lock of rented bike can not be found..
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1047,6 +1056,33 @@ namespace TINK.MultilingualResources {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Please open a bike station page to to contact the bike sharing operator..
|
||||||
|
/// </summary>
|
||||||
|
public static string MarkingContactNoStationInfoAvailableNoButton {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("MarkingContactNoStationInfoAvailableNoButton", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Contact {0}.
|
||||||
|
/// </summary>
|
||||||
|
public static string MarkingContactPageTitle {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("MarkingContactPageTitle", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to <font color="blue"><u>Contact</u></font> {0}..
|
||||||
|
/// </summary>
|
||||||
|
public static string MarkingContactSupport {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("MarkingContactSupport", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Contact.
|
/// Looks up a localized string similar to Contact.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1174,6 +1210,15 @@ namespace TINK.MultilingualResources {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Please login to reserve bikes! Tap <font color="blue"><u>here</u></font> to switch to login page..
|
||||||
|
/// </summary>
|
||||||
|
public static string MarkingLoginRequiredToRerserve {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("MarkingLoginRequiredToRerserve", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Bike Locations.
|
/// Looks up a localized string similar to Bike Locations.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -1517,7 +1562,7 @@ namespace TINK.MultilingualResources {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Urgent question related to {0}? (Monday-Friday: 10:00 18:00).
|
/// Looks up a localized string similar to Urgent question related to {0}?.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string MessagePhoneMail {
|
public static string MessagePhoneMail {
|
||||||
get {
|
get {
|
||||||
|
|
|
@ -158,7 +158,7 @@ Eine Radrückgabe ist nur möglich, wenn das Rad in Reichweite ist und Standorti
|
||||||
<value>Fragen? Hinweise? Kritik?</value>
|
<value>Fragen? Hinweise? Kritik?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessagePhoneMail" xml:space="preserve">
|
<data name="MessagePhoneMail" xml:space="preserve">
|
||||||
<value>Eilige Frage rund um {0}? (Montag-Freitag: 10:00 18:00)</value>
|
<value>Eilige Frage rund um {0}?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageRateMail" xml:space="preserve">
|
<data name="MessageRateMail" xml:space="preserve">
|
||||||
<value>Gefällt die {0}-App?</value>
|
<value>Gefällt die {0}-App?</value>
|
||||||
|
@ -613,4 +613,19 @@ Layout Anzeige Radnamen und nummern verbessert.</value>
|
||||||
<data name="ChangeLog3_0_240" xml:space="preserve">
|
<data name="ChangeLog3_0_240" xml:space="preserve">
|
||||||
<value>Wahl eines Rads über die Radnummer hinzugefügt.</value>
|
<value>Wahl eines Rads über die Radnummer hinzugefügt.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="MarkingContactSupport" xml:space="preserve">
|
||||||
|
<value>{0} <font color="blue"><u>kontaktieren</u></font>.</value>
|
||||||
|
</data>
|
||||||
|
<data name="MarkingLoginRequiredToRerserve" xml:space="preserve">
|
||||||
|
<value>Bitte Anmelden um Fahrräder zu reservieren! <font color="blue"><u>Hier</u></font> tippen, um auf Anmeldeseite zu wechseln.</value>
|
||||||
|
</data>
|
||||||
|
<data name="MarkingContactNoStationInfoAvailableNoButton" xml:space="preserve">
|
||||||
|
<value>Bitte eine Fahrradstationsseite öffen, um den Betreiber zu kontaktieren.</value>
|
||||||
|
</data>
|
||||||
|
<data name="MarkingContactPageTitle" xml:space="preserve">
|
||||||
|
<value>Kontakt {0}</value>
|
||||||
|
</data>
|
||||||
|
<data name="ChangeLog3_0_241" xml:space="preserve">
|
||||||
|
<value>Auf der Kontaktseite werden Kontaktinformationen betreiberspezifisch angezeigt.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -248,7 +248,7 @@ Use of app is restricted to maximu 8 devices per account.
|
||||||
Please login to app once again. In case this fails please check on website if the account is still valid.</value>
|
Please login to app once again. In case this fails please check on website if the account is still valid.</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessagePhoneMail" xml:space="preserve">
|
<data name="MessagePhoneMail" xml:space="preserve">
|
||||||
<value>Urgent question related to {0}? (Monday-Friday: 10:00 18:00)</value>
|
<value>Urgent question related to {0}?</value>
|
||||||
</data>
|
</data>
|
||||||
<data name="MessageRateMail" xml:space="preserve">
|
<data name="MessageRateMail" xml:space="preserve">
|
||||||
<value>Are you enjoying the {0}-App?</value>
|
<value>Are you enjoying the {0}-App?</value>
|
||||||
|
@ -709,4 +709,19 @@ Layout of bike names and id display improved.</value>
|
||||||
<data name="ChangeLog3_0_240" xml:space="preserve">
|
<data name="ChangeLog3_0_240" xml:space="preserve">
|
||||||
<value>Find bike by id functionality added.</value>
|
<value>Find bike by id functionality added.</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="MarkingContactNoStationInfoAvailableNoButton" xml:space="preserve">
|
||||||
|
<value>Please open a bike station page to to contact the bike sharing operator.</value>
|
||||||
|
</data>
|
||||||
|
<data name="MarkingContactSupport" xml:space="preserve">
|
||||||
|
<value><font color="blue"><u>Contact</u></font> {0}.</value>
|
||||||
|
</data>
|
||||||
|
<data name="MarkingLoginRequiredToRerserve" xml:space="preserve">
|
||||||
|
<value>Please login to reserve bikes! Tap <font color="blue"><u>here</u></font> to switch to login page.</value>
|
||||||
|
</data>
|
||||||
|
<data name="MarkingContactPageTitle" xml:space="preserve">
|
||||||
|
<value>Contact {0}</value>
|
||||||
|
</data>
|
||||||
|
<data name="ChangeLog3_0_241" xml:space="preserve">
|
||||||
|
<value>Bike sharing system operator specific support info displayed on contact page.</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
|
@ -203,8 +203,8 @@ Eine Radrückgabe ist nur möglich, wenn das Rad in Reichweite ist und Standorti
|
||||||
<target state="translated">Fragen? Hinweise? Kritik?</target>
|
<target state="translated">Fragen? Hinweise? Kritik?</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="MessagePhoneMail" translate="yes" xml:space="preserve">
|
<trans-unit id="MessagePhoneMail" translate="yes" xml:space="preserve">
|
||||||
<source>Urgent question related to {0}? (Monday-Friday: 10:00 18:00)</source>
|
<source>Urgent question related to {0}?</source>
|
||||||
<target state="translated">Eilige Frage rund um {0}? (Montag-Freitag: 10:00 18:00)</target>
|
<target state="translated">Eilige Frage rund um {0}?</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
<trans-unit id="MessageRateMail" translate="yes" xml:space="preserve">
|
<trans-unit id="MessageRateMail" translate="yes" xml:space="preserve">
|
||||||
<source>Are you enjoying the {0}-App?</source>
|
<source>Are you enjoying the {0}-App?</source>
|
||||||
|
@ -821,6 +821,26 @@ Layout Anzeige Radnamen und nummern verbessert.</target>
|
||||||
<source>Find bike by id functionality added.</source>
|
<source>Find bike by id functionality added.</source>
|
||||||
<target state="translated">Wahl eines Rads über die Radnummer hinzugefügt.</target>
|
<target state="translated">Wahl eines Rads über die Radnummer hinzugefügt.</target>
|
||||||
</trans-unit>
|
</trans-unit>
|
||||||
|
<trans-unit id="MarkingContactSupport" translate="yes" xml:space="preserve">
|
||||||
|
<source><bpt id="1"><font color="blue"></bpt><bpt id="2"><u></bpt>Contact<ept id="2"></u></ept><ept id="1"></font></ept> {0}.</source>
|
||||||
|
<target state="translated">{0} <bpt id="1"><font color="blue"></bpt><bpt id="2"><u></bpt>kontaktieren<ept id="2"></u></ept><ept id="1"></font></ept>.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="MarkingLoginRequiredToRerserve" translate="yes" xml:space="preserve">
|
||||||
|
<source>Please login to reserve bikes! Tap <bpt id="1"><font color="blue"></bpt><bpt id="2"><u></bpt>here<ept id="2"></u></ept><ept id="1"></font></ept> to switch to login page.</source>
|
||||||
|
<target state="translated">Bitte Anmelden um Fahrräder zu reservieren! <bpt id="1"><font color="blue"></bpt><bpt id="2"><u></bpt>Hier<ept id="2"></u></ept><ept id="1"></font></ept> tippen, um auf Anmeldeseite zu wechseln.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="MarkingContactNoStationInfoAvailableNoButton" translate="yes" xml:space="preserve">
|
||||||
|
<source>Please open a bike station page to to contact the bike sharing operator.</source>
|
||||||
|
<target state="translated">Bitte eine Fahrradstationsseite öffen, um den Betreiber zu kontaktieren.</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="MarkingContactPageTitle" translate="yes" xml:space="preserve">
|
||||||
|
<source>Contact {0}</source>
|
||||||
|
<target state="translated">Kontakt {0}</target>
|
||||||
|
</trans-unit>
|
||||||
|
<trans-unit id="ChangeLog3_0_241" translate="yes" xml:space="preserve">
|
||||||
|
<source>Bike sharing system operator specific support info displayed on contact page.</source>
|
||||||
|
<target state="translated">Auf der Kontaktseite werden Kontaktinformationen betreiberspezifisch angezeigt.</target>
|
||||||
|
</trans-unit>
|
||||||
</group>
|
</group>
|
||||||
</body>
|
</body>
|
||||||
</file>
|
</file>
|
||||||
|
|
|
@ -106,7 +106,7 @@ namespace TINK.Repository
|
||||||
|
|
||||||
/// <summary> Get list of stations. </summary>
|
/// <summary> Get list of stations. </summary>
|
||||||
/// <returns>List of files.</returns>
|
/// <returns>List of files.</returns>
|
||||||
public async Task<StationsAllResponse> GetStationsAsync()
|
public async Task<StationsAvailableResponse> GetStationsAsync()
|
||||||
{
|
{
|
||||||
var stations = await GetStationsAsync(m_oCopriHost.AbsoluteUri, requestBuilder.GetStations(), UserAgent);
|
var stations = await GetStationsAsync(m_oCopriHost.AbsoluteUri, requestBuilder.GetStations(), UserAgent);
|
||||||
return stations;
|
return stations;
|
||||||
|
@ -316,7 +316,7 @@ namespace TINK.Repository
|
||||||
/// <param name="p_strCopriHost">URL of the copri host to connect to.</param>
|
/// <param name="p_strCopriHost">URL of the copri host to connect to.</param>
|
||||||
/// <param name="p_oCommand">Command to get stations.</param>
|
/// <param name="p_oCommand">Command to get stations.</param>
|
||||||
/// <returns>List of files.</returns>
|
/// <returns>List of files.</returns>
|
||||||
public static async Task<StationsAllResponse> GetStationsAsync(
|
public static async Task<StationsAvailableResponse> GetStationsAsync(
|
||||||
string p_strCopriHost,
|
string p_strCopriHost,
|
||||||
string p_oCommand,
|
string p_oCommand,
|
||||||
string userAgent = null)
|
string userAgent = null)
|
||||||
|
|
|
@ -120,6 +120,284 @@ namespace TINK.Repository
|
||||||
}
|
}
|
||||||
}";
|
}";
|
||||||
|
|
||||||
|
/// <summary></summary>
|
||||||
|
public const string STATIONS_AVAILABLE_LOGGEDIN_20210720 = @"
|
||||||
|
{
|
||||||
|
""shareejson"": {
|
||||||
|
""lang"": ""DE"",
|
||||||
|
""impress_html"": ""site/impress.html"",
|
||||||
|
""tariff_info_html"": ""site/tariff_info_1.html"",
|
||||||
|
""debuglevel"": ""1"",
|
||||||
|
""user_tour"": [
|
||||||
|
null,
|
||||||
|
""""
|
||||||
|
],
|
||||||
|
""response"": ""stations_available"",
|
||||||
|
""user_id"": ""ohauff@posteo.de"",
|
||||||
|
""stations"": {
|
||||||
|
""LV_3"": {
|
||||||
|
""service_tour"": ""LV_1"",
|
||||||
|
""uri_operator"": ""https://shareeapp-lv.copri.eu"",
|
||||||
|
""authed"": ""1"",
|
||||||
|
""station"": ""LV_3"",
|
||||||
|
""gps"": {
|
||||||
|
""latitude"": ""47.9973"",
|
||||||
|
""longitude"": ""7.8585""
|
||||||
|
},
|
||||||
|
""gps_radius"": ""100"",
|
||||||
|
""description"": ""Katholische Akademie"",
|
||||||
|
""state"": ""available"",
|
||||||
|
""operator_data"": {
|
||||||
|
""operator_color"": ""#006269"",
|
||||||
|
""operator_hours"": """",
|
||||||
|
""operator_name"": ""LastenVelo Freiburg"",
|
||||||
|
""operator_email"": ""info@lastenvelofreiburg.de"",
|
||||||
|
""operator_phone"": """"
|
||||||
|
},
|
||||||
|
""station_group"": [
|
||||||
|
""LV_300005""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
""LV_1"": {
|
||||||
|
""uri_operator"": ""https://shareeapp-lv.copri.eu"",
|
||||||
|
""station"": ""LV_1"",
|
||||||
|
""gps"": {
|
||||||
|
""latitude"": ""47.9848"",
|
||||||
|
""longitude"": ""7.848666""
|
||||||
|
},
|
||||||
|
""authed"": ""1"",
|
||||||
|
""service_tour"": ""LV_1"",
|
||||||
|
""operator_data"": {
|
||||||
|
""operator_hours"": """",
|
||||||
|
""operator_email"": ""info@lastenvelofreiburg.de"",
|
||||||
|
""operator_name"": ""LastenVelo Freiburg"",
|
||||||
|
""operator_color"": ""#006269"",
|
||||||
|
""operator_phone"": """"
|
||||||
|
},
|
||||||
|
""state"": ""available"",
|
||||||
|
""description"": ""Parkplatz Feuerwehr Wiehre"",
|
||||||
|
""station_group"": [
|
||||||
|
""LV_300005""
|
||||||
|
],
|
||||||
|
""gps_radius"": ""100""
|
||||||
|
},
|
||||||
|
""FR_105"": {
|
||||||
|
""gps_radius"": ""50"",
|
||||||
|
""station_group"": [
|
||||||
|
""FR_300029""
|
||||||
|
],
|
||||||
|
""state"": ""available"",
|
||||||
|
""description"": ""Contributor-Station Rainer"",
|
||||||
|
""operator_data"": {
|
||||||
|
""operator_phone"": ""+49 761 45370097"",
|
||||||
|
""operator_hours"": ""B<EFBFBD>rozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||||
|
""operator_name"": ""sharee.bike | TeilRad GmbH"",
|
||||||
|
""operator_email"": ""hotline@sharee.bike"",
|
||||||
|
""operator_color"": ""#009699""
|
||||||
|
},
|
||||||
|
""service_tour"": ""FR_1"",
|
||||||
|
""authed"": ""1"",
|
||||||
|
""station"": ""FR_105"",
|
||||||
|
""gps"": {
|
||||||
|
""longitude"": "" 7.973855"",
|
||||||
|
""latitude"": ""47.927738""
|
||||||
|
},
|
||||||
|
""uri_operator"": ""https://shareeapp-fr01.copri.eu""
|
||||||
|
},
|
||||||
|
""FR_104"": {
|
||||||
|
""gps_radius"": ""50"",
|
||||||
|
""operator_data"": {
|
||||||
|
""operator_phone"": ""+49 761 45370097"",
|
||||||
|
""operator_color"": ""#009699"",
|
||||||
|
""operator_email"": ""hotline@sharee.bike"",
|
||||||
|
""operator_name"": ""sharee.bike | TeilRad GmbH"",
|
||||||
|
""operator_hours"": ""B<EFBFBD>rozeiten: Montag, Mittwoch, Freitag 9-12 Uhr""
|
||||||
|
},
|
||||||
|
""description"": ""Contributor-Station fahrradspezialitäten"",
|
||||||
|
""state"": ""available"",
|
||||||
|
""station_group"": [
|
||||||
|
""FR_300029""
|
||||||
|
],
|
||||||
|
""service_tour"": ""FR_1"",
|
||||||
|
""uri_operator"": ""https://shareeapp-fr01.copri.eu"",
|
||||||
|
""gps"": {
|
||||||
|
""latitude"": ""47.989807"",
|
||||||
|
""longitude"": "" 7.837621""
|
||||||
|
},
|
||||||
|
""station"": ""FR_104"",
|
||||||
|
""authed"": ""1""
|
||||||
|
},
|
||||||
|
""FR_103"": {
|
||||||
|
""uri_operator"": ""https://shareeapp-fr01.copri.eu"",
|
||||||
|
""authed"": ""1"",
|
||||||
|
""gps"": {
|
||||||
|
""longitude"": "" 7.785428"",
|
||||||
|
""latitude"": ""47.997930""
|
||||||
|
},
|
||||||
|
""station"": ""FR_103"",
|
||||||
|
""service_tour"": ""FR_1"",
|
||||||
|
""description"": ""Contributor-Station Oliver"",
|
||||||
|
""state"": ""available"",
|
||||||
|
""operator_data"": {
|
||||||
|
""operator_phone"": ""+49 761 45370097"",
|
||||||
|
""operator_hours"": ""B<EFBFBD>rozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||||
|
""operator_name"": ""sharee.bike | TeilRad GmbH"",
|
||||||
|
""operator_email"": ""hotline@sharee.bike"",
|
||||||
|
""operator_color"": ""#009699""
|
||||||
|
},
|
||||||
|
""station_group"": [
|
||||||
|
""FR_300029""
|
||||||
|
],
|
||||||
|
""gps_radius"": ""50""
|
||||||
|
},
|
||||||
|
""LV_88"": {
|
||||||
|
""station_group"": [
|
||||||
|
""LV_300005""
|
||||||
|
],
|
||||||
|
""state"": ""available"",
|
||||||
|
""description"": ""TINK Test KN"",
|
||||||
|
""operator_data"": {
|
||||||
|
""operator_name"": ""LastenVelo Freiburg"",
|
||||||
|
""operator_email"": ""info@lastenvelofreiburg.de"",
|
||||||
|
""operator_hours"": """",
|
||||||
|
""operator_color"": ""#006269"",
|
||||||
|
""operator_phone"": """"
|
||||||
|
},
|
||||||
|
""gps_radius"": ""50"",
|
||||||
|
""authed"": ""1"",
|
||||||
|
""gps"": {
|
||||||
|
""latitude"": ""47.65934079179006"",
|
||||||
|
""longitude"": "" 9.166126178863573""
|
||||||
|
},
|
||||||
|
""station"": ""LV_88"",
|
||||||
|
""uri_operator"": ""https://shareeapp-lv.copri.eu"",
|
||||||
|
""service_tour"": ""LV_2""
|
||||||
|
},
|
||||||
|
""LV_4"": {
|
||||||
|
""uri_operator"": ""https://shareeapp-lv.copri.eu"",
|
||||||
|
""authed"": ""1"",
|
||||||
|
""station"": ""LV_4"",
|
||||||
|
""gps"": {
|
||||||
|
""latitude"": ""48.01095"",
|
||||||
|
""longitude"": ""7.8553""
|
||||||
|
},
|
||||||
|
""service_tour"": ""LV_1"",
|
||||||
|
""state"": ""available"",
|
||||||
|
""description"": ""Fabrik Habsburger Straße"",
|
||||||
|
""operator_data"": {
|
||||||
|
""operator_phone"": """",
|
||||||
|
""operator_hours"": """",
|
||||||
|
""operator_email"": ""info@lastenvelofreiburg.de"",
|
||||||
|
""operator_name"": ""LastenVelo Freiburg"",
|
||||||
|
""operator_color"": ""#006269""
|
||||||
|
},
|
||||||
|
""station_group"": [
|
||||||
|
""LV_300005""
|
||||||
|
],
|
||||||
|
""gps_radius"": ""100""
|
||||||
|
},
|
||||||
|
""LV_2"": {
|
||||||
|
""uri_operator"": ""https://shareeapp-lv.copri.eu"",
|
||||||
|
""authed"": ""1"",
|
||||||
|
""gps"": {
|
||||||
|
""longitude"": ""7.84795"",
|
||||||
|
""latitude"": ""47.99762""
|
||||||
|
},
|
||||||
|
""station"": ""LV_2"",
|
||||||
|
""service_tour"": ""LV_1"",
|
||||||
|
""description"": ""Predigertor ADAC"",
|
||||||
|
""state"": ""available"",
|
||||||
|
""operator_data"": {
|
||||||
|
""operator_phone"": """",
|
||||||
|
""operator_name"": ""LastenVelo Freiburg"",
|
||||||
|
""operator_email"": ""info@lastenvelofreiburg.de"",
|
||||||
|
""operator_hours"": """",
|
||||||
|
""operator_color"": ""#006269""
|
||||||
|
},
|
||||||
|
""station_group"": [
|
||||||
|
""LV_300005""
|
||||||
|
],
|
||||||
|
""gps_radius"": ""100""
|
||||||
|
},
|
||||||
|
""FR_102"": {
|
||||||
|
""description"": ""Contributor-Station Dieter"",
|
||||||
|
""state"": ""available"",
|
||||||
|
""operator_data"": {
|
||||||
|
""operator_phone"": ""+49 761 45370097"",
|
||||||
|
""operator_hours"": ""B<EFBFBD>rozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||||
|
""operator_email"": ""hotline@sharee.bike"",
|
||||||
|
""operator_name"": ""sharee.bike | TeilRad GmbH"",
|
||||||
|
""operator_color"": ""#009699""
|
||||||
|
},
|
||||||
|
""station_group"": [
|
||||||
|
""FR_300029""
|
||||||
|
],
|
||||||
|
""gps_radius"": ""50"",
|
||||||
|
""uri_operator"": ""https://shareeapp-fr01.copri.eu"",
|
||||||
|
""authed"": ""1"",
|
||||||
|
""station"": ""FR_102"",
|
||||||
|
""gps"": {
|
||||||
|
""longitude"": "" 7.835669"",
|
||||||
|
""latitude"": ""47.994371""
|
||||||
|
},
|
||||||
|
""service_tour"": ""FR_1""
|
||||||
|
},
|
||||||
|
""FR_101"": {
|
||||||
|
""station_group"": [
|
||||||
|
""FR_300001""
|
||||||
|
],
|
||||||
|
""state"": ""available"",
|
||||||
|
""description"": ""Villaban sharee Station"",
|
||||||
|
""operator_data"": {
|
||||||
|
""operator_color"": ""#009699"",
|
||||||
|
""operator_email"": ""hotline@sharee.bike"",
|
||||||
|
""operator_name"": ""sharee.bike | TeilRad GmbH"",
|
||||||
|
""operator_hours"": ""B<EFBFBD>rozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"",
|
||||||
|
""operator_phone"": ""+49 761 45370097""
|
||||||
|
},
|
||||||
|
""gps_radius"": ""50"",
|
||||||
|
""authed"": ""1"",
|
||||||
|
""gps"": {
|
||||||
|
""longitude"": "" 7.825490"",
|
||||||
|
""latitude"": ""47.976634""
|
||||||
|
},
|
||||||
|
""station"": ""FR_101"",
|
||||||
|
""uri_operator"": ""https://shareeapp-fr01.copri.eu"",
|
||||||
|
""service_tour"": ""FR_1""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
""response_state"": ""OK, nothing todo"",
|
||||||
|
""agb_checked"": ""1"",
|
||||||
|
""agb_html"": ""site/agb.html"",
|
||||||
|
""authcookie"": ""5781_f172cf59108fe53e7524c841847fee69_oiF2kahH"",
|
||||||
|
""Ilockit_admin"": ""1"",
|
||||||
|
""copri_version"": ""4.1.0.0"",
|
||||||
|
""bike_info_html"": ""site/bike_info.html"",
|
||||||
|
""uri_operator_array"": [
|
||||||
|
""https://shareeapp-lv.copri.eu"",
|
||||||
|
""https://shareeapp-fr01.copri.eu""
|
||||||
|
],
|
||||||
|
""uri_primary"": ""https://shareeapp-primary.copri.eu"",
|
||||||
|
""apiserver"": ""https://shareeapp-primary.copri.eu"",
|
||||||
|
""last_used_operator"": {
|
||||||
|
""operator_phone"": ""+49 761 45370097"",
|
||||||
|
""operator_color"": ""#009699"",
|
||||||
|
""operator_email"": ""hotline@sharee.bike"",
|
||||||
|
""operator_name"": ""sharee.bike | TeilRad GmbH"",
|
||||||
|
""operator_hours"": ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr""
|
||||||
|
},
|
||||||
|
""clearing_cache"": ""0"",
|
||||||
|
""user_group"": [
|
||||||
|
""LV_300005"",
|
||||||
|
""FR_300029"",
|
||||||
|
""FR_300001""
|
||||||
|
],
|
||||||
|
""privacy_html"": ""site/privacy.html"",
|
||||||
|
""new_authcoo"": ""0""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
";
|
||||||
|
|
||||||
const string BOOKING_REQUEST_SET02_001_FILE = @"
|
const string BOOKING_REQUEST_SET02_001_FILE = @"
|
||||||
{
|
{
|
||||||
""shareejson"" : {
|
""shareejson"" : {
|
||||||
|
@ -1065,7 +1343,7 @@ namespace TINK.Repository
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="p_strCookie">Auto cookie of user if user is logged in.</param>
|
/// <param name="p_strCookie">Auto cookie of user if user is logged in.</param>
|
||||||
/// <returns>List of files.</returns>
|
/// <returns>List of files.</returns>
|
||||||
public async Task<StationsAllResponse> GetStationsAsync()
|
public async Task<StationsAvailableResponse> GetStationsAsync()
|
||||||
{
|
{
|
||||||
return await Task.Run(() => GetStationsAll(null, SessionCookie, ActiveSampleSet, ActiveStageIndex));
|
return await Task.Run(() => GetStationsAll(null, SessionCookie, ActiveSampleSet, ActiveStageIndex));
|
||||||
}
|
}
|
||||||
|
@ -1256,7 +1534,7 @@ namespace TINK.Repository
|
||||||
/// <param name="p_eSampleSet"></param>
|
/// <param name="p_eSampleSet"></param>
|
||||||
/// <param name="p_lStageIndex"></param>
|
/// <param name="p_lStageIndex"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static StationsAllResponse GetStationsAll(
|
public static StationsAvailableResponse GetStationsAll(
|
||||||
string p_strMerchantId,
|
string p_strMerchantId,
|
||||||
string p_strCookie = null,
|
string p_strCookie = null,
|
||||||
SampleSets p_eSampleSet = DEFAULT_SAMPLE_SET,
|
SampleSets p_eSampleSet = DEFAULT_SAMPLE_SET,
|
||||||
|
@ -1268,7 +1546,7 @@ namespace TINK.Repository
|
||||||
switch (p_lStageIndex)
|
switch (p_lStageIndex)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
return JsonConvertRethrow.DeserializeObject<ResponseContainer<StationsAllResponse>>(STATIONS_SET02_001_FILE).shareejson;
|
return JsonConvertRethrow.DeserializeObject<ResponseContainer<StationsAvailableResponse>>(STATIONS_SET02_001_FILE).shareejson;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -95,8 +95,8 @@ namespace TINK.Repository
|
||||||
/// <summary> Gets an empty response. </summary>
|
/// <summary> Gets an empty response. </summary>
|
||||||
/// <param name="copriVersion">Version of empty response.</param>
|
/// <param name="copriVersion">Version of empty response.</param>
|
||||||
/// <returns>Response.</returns>
|
/// <returns>Response.</returns>
|
||||||
public static StationsAllResponse GetEmptyStationsAllResponse(string copriVersion)
|
public static StationsAvailableResponse GetEmptyStationsAllResponse(string copriVersion)
|
||||||
=> JsonConvertRethrow.DeserializeObject<StationsAllResponse>(STATIONSALL.Replace("4.1.0.0", copriVersion));
|
=> JsonConvertRethrow.DeserializeObject<StationsAvailableResponse>(STATIONSALL.Replace("4.1.0.0", copriVersion));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Holds the seconds after which station and bikes info is considered to be invalid.
|
/// Holds the seconds after which station and bikes info is considered to be invalid.
|
||||||
|
@ -141,7 +141,7 @@ namespace TINK.Repository
|
||||||
|
|
||||||
if (!Barrel.Current.Exists(requestBuilder.GetStations()))
|
if (!Barrel.Current.Exists(requestBuilder.GetStations()))
|
||||||
{
|
{
|
||||||
AddToCache(JsonConvertRethrow.DeserializeObject<StationsAllResponse>(STATIONSALL), new TimeSpan(0));
|
AddToCache(JsonConvertRethrow.DeserializeObject<StationsAvailableResponse>(STATIONSALL), new TimeSpan(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,12 +224,12 @@ namespace TINK.Repository
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<StationsAllResponse> GetStationsAsync()
|
public async Task<StationsAvailableResponse> GetStationsAsync()
|
||||||
{
|
{
|
||||||
var l_oStationsAllTask = new TaskCompletionSource<StationsAllResponse>();
|
var l_oStationsAllTask = new TaskCompletionSource<StationsAvailableResponse>();
|
||||||
lock (monkeyLock)
|
lock (monkeyLock)
|
||||||
{
|
{
|
||||||
l_oStationsAllTask.SetResult(Barrel.Current.Get<StationsAllResponse>(requestBuilder.GetStations()));
|
l_oStationsAllTask.SetResult(Barrel.Current.Get<StationsAvailableResponse>(requestBuilder.GetStations()));
|
||||||
}
|
}
|
||||||
return await l_oStationsAllTask.Task;
|
return await l_oStationsAllTask.Task;
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,7 @@ namespace TINK.Repository
|
||||||
|
|
||||||
/// <summary> Adds a stations all response to cache.</summary>
|
/// <summary> Adds a stations all response to cache.</summary>
|
||||||
/// <param name="stations">Stations to add.</param>
|
/// <param name="stations">Stations to add.</param>
|
||||||
public void AddToCache(StationsAllResponse stations)
|
public void AddToCache(StationsAvailableResponse stations)
|
||||||
{
|
{
|
||||||
AddToCache(stations, ExpiresAfter);
|
AddToCache(stations, ExpiresAfter);
|
||||||
}
|
}
|
||||||
|
@ -256,7 +256,7 @@ namespace TINK.Repository
|
||||||
/// <summary> Adds a stations all response to cache.</summary>
|
/// <summary> Adds a stations all response to cache.</summary>
|
||||||
/// <param name="stations">Stations to add.</param>
|
/// <param name="stations">Stations to add.</param>
|
||||||
/// <param name="expiresAfter">Time after which anser is considered to be expired.</param>
|
/// <param name="expiresAfter">Time after which anser is considered to be expired.</param>
|
||||||
private void AddToCache(StationsAllResponse stations, TimeSpan expiresAfter)
|
private void AddToCache(StationsAvailableResponse stations, TimeSpan expiresAfter)
|
||||||
{
|
{
|
||||||
lock (monkeyLock)
|
lock (monkeyLock)
|
||||||
{
|
{
|
||||||
|
|
|
@ -112,7 +112,7 @@ namespace TINK.Repository
|
||||||
{
|
{
|
||||||
/// <summary> Get list of stations. </summary>
|
/// <summary> Get list of stations. </summary>
|
||||||
/// <returns>List of all stations.</returns>
|
/// <returns>List of all stations.</returns>
|
||||||
Task<StationsAllResponse> GetStationsAsync();
|
Task<StationsAvailableResponse> GetStationsAsync();
|
||||||
|
|
||||||
/// <summary> Gets a list of bikes from Copri. </summary>
|
/// <summary> Gets a list of bikes from Copri. </summary>
|
||||||
/// <returns>Response holding list of bikes.</returns>
|
/// <returns>Response holding list of bikes.</returns>
|
||||||
|
|
|
@ -7,7 +7,7 @@ namespace TINK.Repository.Response
|
||||||
/// Holds the information about all stations and is used for deserialization of copri answer.
|
/// Holds the information about all stations and is used for deserialization of copri answer.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataContract]
|
[DataContract]
|
||||||
public class StationsAllResponse : ResponseBase
|
public class StationsAvailableResponse : ResponseBase
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Holds info about a single station.
|
/// Holds info about a single station.
|
||||||
|
@ -15,6 +15,29 @@ namespace TINK.Repository.Response
|
||||||
[DataContract]
|
[DataContract]
|
||||||
public class StationInfo
|
public class StationInfo
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Holds info about opertor data.
|
||||||
|
/// </summary>
|
||||||
|
[DataContract]
|
||||||
|
public class OperatorData
|
||||||
|
{
|
||||||
|
[DataMember]
|
||||||
|
public string operator_name { get; private set; }
|
||||||
|
|
||||||
|
[DataMember]
|
||||||
|
public string operator_phone { get; private set; }
|
||||||
|
|
||||||
|
[DataMember]
|
||||||
|
public string operator_hours { get; private set; }
|
||||||
|
|
||||||
|
[DataMember]
|
||||||
|
public string operator_email { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
|
[DataMember]
|
||||||
|
public string operator_color { get; private set; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Unique id of the station.
|
/// Unique id of the station.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -32,6 +55,9 @@ namespace TINK.Repository.Response
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataMember]
|
[DataMember]
|
||||||
public GpsInfo gps { get; private set; }
|
public GpsInfo gps { get; private set; }
|
||||||
|
|
||||||
|
[DataMember]
|
||||||
|
public OperatorData operator_data { get; private set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
|
@ -109,7 +109,7 @@ namespace TINK.Model.Services.CopriApi
|
||||||
|
|
||||||
/// <summary> Get list of stations. </summary>
|
/// <summary> Get list of stations. </summary>
|
||||||
/// <returns>List of files.</returns>
|
/// <returns>List of files.</returns>
|
||||||
public async Task<Result<StationsAllResponse>> GetStations(bool fromCache = false)
|
public async Task<Result<StationsAvailableResponse>> GetStations(bool fromCache = false)
|
||||||
{
|
{
|
||||||
Log.ForContext<CopriProviderHttps>().Debug($"Request to get stations{(fromCache ? " from cache" : "")}...");
|
Log.ForContext<CopriProviderHttps>().Debug($"Request to get stations{(fromCache ? " from cache" : "")}...");
|
||||||
if (!CacheServer.IsStationsExpired
|
if (!CacheServer.IsStationsExpired
|
||||||
|
@ -117,7 +117,7 @@ namespace TINK.Model.Services.CopriApi
|
||||||
{
|
{
|
||||||
// No need to query because previous answer is not yet outdated.
|
// No need to query because previous answer is not yet outdated.
|
||||||
Log.ForContext<CopriProviderHttps>().Debug($"Returning stations from cache.");
|
Log.ForContext<CopriProviderHttps>().Debug($"Returning stations from cache.");
|
||||||
return new Result<StationsAllResponse>(typeof(CopriCallsMonkeyStore), await CacheServer.GetStationsAsync());
|
return new Result<StationsAvailableResponse>(typeof(CopriCallsMonkeyStore), await CacheServer.GetStationsAsync());
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -126,7 +126,7 @@ namespace TINK.Model.Services.CopriApi
|
||||||
|
|
||||||
var stations = await HttpsServer.GetStationsAsync();
|
var stations = await HttpsServer.GetStationsAsync();
|
||||||
|
|
||||||
return new Result<StationsAllResponse>(
|
return new Result<StationsAvailableResponse>(
|
||||||
typeof(CopriCallsHttps),
|
typeof(CopriCallsHttps),
|
||||||
stations.GetIsResponseOk("Abfrage der Stationen fehlsgeschlagen."));
|
stations.GetIsResponseOk("Abfrage der Stationen fehlsgeschlagen."));
|
||||||
}
|
}
|
||||||
|
@ -134,14 +134,14 @@ namespace TINK.Model.Services.CopriApi
|
||||||
{
|
{
|
||||||
// Return response from cache.
|
// Return response from cache.
|
||||||
Log.ForContext<CopriProviderHttps>().Debug("An error occurred querrying stations. {Exception}.", exception);
|
Log.ForContext<CopriProviderHttps>().Debug("An error occurred querrying stations. {Exception}.", exception);
|
||||||
return new Result<StationsAllResponse>(typeof(CopriCallsMonkeyStore), await CacheServer.GetStationsAsync(), exception);
|
return new Result<StationsAvailableResponse>(typeof(CopriCallsMonkeyStore), await CacheServer.GetStationsAsync(), exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Adds https--response to cache if response is ok. </summary>
|
/// <summary>Adds https--response to cache if response is ok. </summary>
|
||||||
/// <param name="response">Response to add to cache.</param>
|
/// <param name="response">Response to add to cache.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public void AddToCache(Result<StationsAllResponse> result)
|
public void AddToCache(Result<StationsAvailableResponse> result)
|
||||||
{
|
{
|
||||||
Log.ForContext<CopriProviderHttps>().Debug($"Request to add stations all response to cache...");
|
Log.ForContext<CopriProviderHttps>().Debug($"Request to add stations all response to cache...");
|
||||||
if (result.Source == typeof(CopriCallsMonkeyStore)
|
if (result.Source == typeof(CopriCallsMonkeyStore)
|
||||||
|
|
|
@ -83,7 +83,7 @@ namespace TINK.Model.Services.CopriApi
|
||||||
return await monkeyStore.GetBikesOccupiedAsync();
|
return await monkeyStore.GetBikesOccupiedAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<StationsAllResponse> GetStationsAsync()
|
public async Task<StationsAvailableResponse> GetStationsAsync()
|
||||||
{
|
{
|
||||||
return await monkeyStore.GetStationsAsync();
|
return await monkeyStore.GetStationsAsync();
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace TINK.Model.Services.CopriApi
|
||||||
{
|
{
|
||||||
/// <summary> Get list of stations. </summary>
|
/// <summary> Get list of stations. </summary>
|
||||||
/// <returns>List of all stations.</returns>
|
/// <returns>List of all stations.</returns>
|
||||||
Task<Result<StationsAllResponse>> GetStations(bool fromCache = false);
|
Task<Result<StationsAvailableResponse>> GetStations(bool fromCache = false);
|
||||||
|
|
||||||
/// <summary> Gets a list of bikes from Copri. </summary>
|
/// <summary> Gets a list of bikes from Copri. </summary>
|
||||||
/// <returns>Response holding list of bikes.</returns>
|
/// <returns>Response holding list of bikes.</returns>
|
||||||
|
@ -22,7 +22,7 @@ namespace TINK.Model.Services.CopriApi
|
||||||
|
|
||||||
/// <summary>Adds https--response to cache if response is ok. </summary>
|
/// <summary>Adds https--response to cache if response is ok. </summary>
|
||||||
/// <param name="response">Response to add to cache.</param>
|
/// <param name="response">Response to add to cache.</param>
|
||||||
void AddToCache(Result<StationsAllResponse> result);
|
void AddToCache(Result<StationsAvailableResponse> result);
|
||||||
|
|
||||||
/// <summary>Adds https--response to cache if response is ok. </summary>
|
/// <summary>Adds https--response to cache if response is ok. </summary>
|
||||||
/// <param name="response">Response to add to cache.</param>
|
/// <param name="response">Response to add to cache.</param>
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace TINK.Model.Services.CopriApi
|
||||||
|
|
||||||
/// <summary> Adds a stations all response to cache.</summary>
|
/// <summary> Adds a stations all response to cache.</summary>
|
||||||
/// <param name="stations">Stations to add.</param>
|
/// <param name="stations">Stations to add.</param>
|
||||||
void AddToCache(StationsAllResponse stations);
|
void AddToCache(StationsAvailableResponse stations);
|
||||||
|
|
||||||
/// <summary> Gets a value indicating whether stations are expired or not.</summary>
|
/// <summary> Gets a value indicating whether stations are expired or not.</summary>
|
||||||
bool IsBikesAvailableExpired { get; }
|
bool IsBikesAvailableExpired { get; }
|
||||||
|
|
|
@ -113,23 +113,13 @@ namespace TINK.ViewModel.BikesAtStation
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Informs about need to log in before requesting an bike.
|
/// Informs about need to log in before requesting an bike.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public FormattedString LoginRequiredHintText
|
public string LoginRequiredHintText
|
||||||
{
|
=> ActiveUser.IsLoggedIn
|
||||||
get
|
? string.Empty
|
||||||
{
|
: AppResources.MarkingLoginRequiredToRerserve;
|
||||||
if (ActiveUser.IsLoggedIn)
|
|
||||||
{
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
var l_oHint = new FormattedString();
|
public string ContactSupportHintText
|
||||||
l_oHint.Spans.Add(new Span { Text = "Bitte Anmelden um Fahrräder zu reservieren! " });
|
=> string.Format(AppResources.MarkingContactSupport, m_oStation?.OperatorData?.Name ?? "Operator");
|
||||||
l_oHint.Spans.Add(new Span { Text = "Hier", ForegroundColor = ViewModelHelper.LINK_COLOR });
|
|
||||||
l_oHint.Spans.Add(new Span { Text = " tippen um auf Anmeldeseite zu wechseln."});
|
|
||||||
|
|
||||||
return l_oHint;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary> Returns if info about the fact that user did not request or book any bikes is visible or not.<summary>
|
/// <summary> Returns if info about the fact that user did not request or book any bikes is visible or not.<summary>
|
||||||
/// Gets message that logged in user has not booked any bikes.
|
/// Gets message that logged in user has not booked any bikes.
|
||||||
|
@ -154,21 +144,22 @@ namespace TINK.ViewModel.BikesAtStation
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Command object to bind login page redirect link to view model.</summary>
|
/// <summary> Command object to bind login page redirect link to view model.</summary>
|
||||||
public System.Windows.Input.ICommand LoginRequiredHintClickedCommand
|
public System.Windows.Input.ICommand ContactSupportClickedCommand
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
#if USEMASTERDETAIL || USEFLYOUT
|
#if USEMASTERDETAIL || USEFLYOUT
|
||||||
return new Xamarin.Forms.Command(() => OpenLoginPageAsync());
|
=> new Xamarin.Forms.Command(() => OpenSupportPageAsync());
|
||||||
#else
|
#else
|
||||||
return new Xamarin.Forms.Command(async () => await OpenLoginPageAsync());
|
=> new Xamarin.Forms.Command(async () => await OpenLoginPageAsync());
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary> Command object to bind login page redirect link to view model.</summary>
|
||||||
/// Opens login page.
|
public System.Windows.Input.ICommand LoginRequiredHintClickedCommand
|
||||||
/// </summary>
|
#if USEMASTERDETAIL || USEFLYOUT
|
||||||
|
=> new Xamarin.Forms.Command(() => OpenLoginPageAsync());
|
||||||
|
#else
|
||||||
|
=> new Xamarin.Forms.Command(async () => await OpenLoginPageAsync());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// <summary> Opens login page. </summary>
|
||||||
#if USEMASTERDETAIL || USEFLYOUT
|
#if USEMASTERDETAIL || USEFLYOUT
|
||||||
public void OpenLoginPageAsync()
|
public void OpenLoginPageAsync()
|
||||||
#else
|
#else
|
||||||
|
@ -192,6 +183,30 @@ namespace TINK.ViewModel.BikesAtStation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary> Opens login page. </summary>
|
||||||
|
#if USEMASTERDETAIL || USEFLYOUT
|
||||||
|
public void OpenSupportPageAsync()
|
||||||
|
#else
|
||||||
|
public async Task OpenLoginPageAsync()
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Switch to map page
|
||||||
|
|
||||||
|
#if USEMASTERDETAIL || USEFLYOUT
|
||||||
|
ViewService.ShowPage(ViewTypes.ContactPage, m_oStation?.OperatorData?.Name ?? AppResources.MarkingFeedbackAndContact);
|
||||||
|
#else
|
||||||
|
await ViewService.ShowPage("//LoginPage");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
catch (Exception p_oException)
|
||||||
|
{
|
||||||
|
Log.Error("Ein unerwarteter Fehler ist auf der Seite Kontakt aufgetreten. Kontext: Klick auf Hinweistext auf Station N- seite ohne Anmeldung. {@Exception}", p_oException);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when page is shown.
|
/// Invoked when page is shown.
|
||||||
/// Starts update process.
|
/// Starts update process.
|
||||||
|
|
|
@ -5,6 +5,7 @@ using System.Collections.Generic;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using TINK.Model.Services.CopriApi.ServerUris;
|
using TINK.Model.Services.CopriApi.ServerUris;
|
||||||
|
using TINK.Model.Station;
|
||||||
using TINK.MultilingualResources;
|
using TINK.MultilingualResources;
|
||||||
using TINK.View;
|
using TINK.View;
|
||||||
using Xamarin.Essentials;
|
using Xamarin.Essentials;
|
||||||
|
@ -18,6 +19,9 @@ namespace TINK.ViewModel.Info
|
||||||
/// <summary> Reference on view service to show modal notifications and to perform navigation. </summary>
|
/// <summary> Reference on view service to show modal notifications and to perform navigation. </summary>
|
||||||
private IViewService ViewService { get; }
|
private IViewService ViewService { get; }
|
||||||
|
|
||||||
|
/// <summary> Station selected by user. </summary>
|
||||||
|
private IStation SelectedStation;
|
||||||
|
|
||||||
Uri ActiveUri { get; }
|
Uri ActiveUri { get; }
|
||||||
|
|
||||||
/// <summary> Holds a reference to the external trigger service. </summary>
|
/// <summary> Holds a reference to the external trigger service. </summary>
|
||||||
|
@ -29,6 +33,7 @@ namespace TINK.ViewModel.Info
|
||||||
/// <param name="openUrlInExternalBrowser">Action to open an external browser.</param>
|
/// <param name="openUrlInExternalBrowser">Action to open an external browser.</param>
|
||||||
/// <param name="viewService">View service to notify user.</param>
|
/// <param name="viewService">View service to notify user.</param>
|
||||||
public ContactPageViewModel(
|
public ContactPageViewModel(
|
||||||
|
IStation selectedStation,
|
||||||
Uri activeUri,
|
Uri activeUri,
|
||||||
Func<string> createAttachment,
|
Func<string> createAttachment,
|
||||||
Action openUrlInExternalBrowser,
|
Action openUrlInExternalBrowser,
|
||||||
|
@ -45,6 +50,9 @@ namespace TINK.ViewModel.Info
|
||||||
|
|
||||||
OpenUrlInExternalBrowser = openUrlInExternalBrowser
|
OpenUrlInExternalBrowser = openUrlInExternalBrowser
|
||||||
?? throw new ArgumentException("Can not instantiate contact page view model- object. No user external browse service available.");
|
?? throw new ArgumentException("Can not instantiate contact page view model- object. No user external browse service available.");
|
||||||
|
|
||||||
|
// Station might be null-station, if no station info is avialable.
|
||||||
|
SelectedStation = selectedStation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary> Command object to bind login button to view model. </summary>
|
/// <summary> Command object to bind login button to view model. </summary>
|
||||||
|
@ -65,45 +73,19 @@ namespace TINK.ViewModel.Info
|
||||||
|
|
||||||
/// <summary>Holds the mail address to mail to.</summary>
|
/// <summary>Holds the mail address to mail to.</summary>
|
||||||
public string MailAddressText
|
public string MailAddressText
|
||||||
{
|
=> SelectedStation?.OperatorData?.MailAddressText ?? string.Empty;
|
||||||
get
|
|
||||||
{
|
|
||||||
switch (ActiveUri.AbsoluteUri)
|
|
||||||
{
|
|
||||||
case CopriServerUriList.TINK_DEVEL:
|
|
||||||
case CopriServerUriList.TINK_LIVE:
|
|
||||||
return "tink@fahrradspezialitaeten.com";
|
|
||||||
|
|
||||||
case CopriServerUriList.SHAREE_DEVEL:
|
|
||||||
case CopriServerUriList.SHAREE_LIVE:
|
|
||||||
return "hotline@sharee.bike";
|
|
||||||
|
|
||||||
default:
|
|
||||||
return "post@sharee.bike";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>Holds the mail address to send mail to.</summary>
|
/// <summary>Holds the mail address to send mail to.</summary>
|
||||||
public string PhoneNumberText
|
public string PhoneNumberText
|
||||||
{
|
=> SelectedStation?.OperatorData?.PhoneNumberText ?? string.Empty;
|
||||||
get
|
|
||||||
{
|
|
||||||
switch (ActiveUri.AbsoluteUri)
|
|
||||||
{
|
|
||||||
case CopriServerUriList.TINK_DEVEL:
|
|
||||||
case CopriServerUriList.TINK_LIVE:
|
|
||||||
return "+49 7531 - 3694389";
|
|
||||||
|
|
||||||
case CopriServerUriList.SHAREE_DEVEL:
|
/// <summary>Holds the mail address to send mail to.</summary>
|
||||||
case CopriServerUriList.SHAREE_LIVE:
|
public string OfficeHoursText
|
||||||
return "+49 761 - 45370097";
|
=> SelectedStation?.OperatorData?.Hours ?? string.Empty;
|
||||||
|
|
||||||
default:
|
/// <summary> Gets whether any operator support info is avaliable. </summary>
|
||||||
return "+49 761 5158912";
|
public bool IsOperatorInfoAvaliable
|
||||||
}
|
=> MailAddressText.Length > 0 || PhoneNumberText.Length > 0;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary> Request to do a phone call. </summary>
|
/// <summary> Request to do a phone call. </summary>
|
||||||
public async Task DoSendMail()
|
public async Task DoSendMail()
|
||||||
|
@ -256,7 +238,10 @@ namespace TINK.ViewModel.Info
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var l_oHint = new FormattedString();
|
var l_oHint = new FormattedString();
|
||||||
l_oHint.Spans.Add(new Span { Text = string.Format(AppResources.MessagePhoneMail, GetAppName(ActiveUri)) });
|
l_oHint.Spans.Add(new Span
|
||||||
|
{
|
||||||
|
Text = string.Format(AppResources.MessagePhoneMail, GetAppName(ActiveUri)) + $"{(OfficeHoursText.Length > 0 ? $" {OfficeHoursText}" : string.Empty)}"
|
||||||
|
});
|
||||||
return l_oHint;
|
return l_oHint;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,11 @@
|
||||||
MyBikesPage,
|
MyBikesPage,
|
||||||
SettingsPage,
|
SettingsPage,
|
||||||
TabbedPageInfo,
|
TabbedPageInfo,
|
||||||
TabbedPageHelpContact,
|
FeesAndBikesPage,
|
||||||
ManageAccountPage,
|
ManageAccountPage,
|
||||||
AgbPage,
|
AgbPage,
|
||||||
WhatsNewPage,
|
WhatsNewPage,
|
||||||
BikesAtStation
|
BikesAtStation,
|
||||||
|
ContactPage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -305,7 +305,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector
|
||||||
var https = Substitute.For<ICopriServer>();
|
var https = Substitute.For<ICopriServer>();
|
||||||
|
|
||||||
cache.IsStationsExpired.Returns(false);
|
cache.IsStationsExpired.Returns(false);
|
||||||
cache.GetStationsAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL)));
|
cache.GetStationsAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL)));
|
||||||
|
|
||||||
var provider = new CopriProviderHttps(
|
var provider = new CopriProviderHttps(
|
||||||
new Uri("http://1.2.3.4"),
|
new Uri("http://1.2.3.4"),
|
||||||
|
@ -329,7 +329,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector
|
||||||
var https = Substitute.For<ICopriServer>();
|
var https = Substitute.For<ICopriServer>();
|
||||||
|
|
||||||
cache.IsStationsExpired.Returns(true);
|
cache.IsStationsExpired.Returns(true);
|
||||||
cache.GetStationsAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL)));
|
cache.GetStationsAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL)));
|
||||||
|
|
||||||
var provider = new CopriProviderHttps(
|
var provider = new CopriProviderHttps(
|
||||||
new Uri("http://1.2.3.4"),
|
new Uri("http://1.2.3.4"),
|
||||||
|
@ -352,7 +352,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector
|
||||||
var https = Substitute.For<ICopriServer>();
|
var https = Substitute.For<ICopriServer>();
|
||||||
|
|
||||||
cache.IsStationsExpired.Returns(true);
|
cache.IsStationsExpired.Returns(true);
|
||||||
https.GetStationsAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL)));
|
https.GetStationsAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL)));
|
||||||
|
|
||||||
var provider = new CopriProviderHttps(
|
var provider = new CopriProviderHttps(
|
||||||
new Uri("http://1.2.3.4"),
|
new Uri("http://1.2.3.4"),
|
||||||
|
@ -375,8 +375,8 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector
|
||||||
var https = Substitute.For<ICopriServer>();
|
var https = Substitute.For<ICopriServer>();
|
||||||
|
|
||||||
cache.IsStationsExpired.Returns(true);
|
cache.IsStationsExpired.Returns(true);
|
||||||
cache.GetStationsAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL)));
|
cache.GetStationsAsync().Returns(Task.Run(() => JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL)));
|
||||||
https.GetStationsAsync().Returns<StationsAllResponse>(x => { throw new WebConnectFailureException("Bang...", new Exception()); });
|
https.GetStationsAsync().Returns<StationsAvailableResponse>(x => { throw new WebConnectFailureException("Bang...", new Exception()); });
|
||||||
|
|
||||||
var provider = new CopriProviderHttps(
|
var provider = new CopriProviderHttps(
|
||||||
new Uri("http://1.2.3.4"),
|
new Uri("http://1.2.3.4"),
|
||||||
|
@ -411,17 +411,17 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Do not add if an excption occurred
|
// Do not add if an excption occurred
|
||||||
provider.AddToCache(new Result<StationsAllResponse>(typeof(CopriCallsHttps), JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL), new System.Exception("Bang...")));
|
provider.AddToCache(new Result<StationsAvailableResponse>(typeof(CopriCallsHttps), JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL), new System.Exception("Bang...")));
|
||||||
stations = await provider.GetStations(true);
|
stations = await provider.GetStations(true);
|
||||||
Assert.AreEqual(0, stations.Response.stations.Count);
|
Assert.AreEqual(0, stations.Response.stations.Count);
|
||||||
|
|
||||||
// Do not add if results from cache
|
// Do not add if results from cache
|
||||||
provider.AddToCache(new Result<StationsAllResponse>(typeof(CopriCallsMonkeyStore), JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL)));
|
provider.AddToCache(new Result<StationsAvailableResponse>(typeof(CopriCallsMonkeyStore), JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL)));
|
||||||
stations = await provider.GetStations(true);
|
stations = await provider.GetStations(true);
|
||||||
Assert.AreEqual(0, stations.Response.stations.Count);
|
Assert.AreEqual(0, stations.Response.stations.Count);
|
||||||
|
|
||||||
// Add result
|
// Add result
|
||||||
provider.AddToCache(new Result<StationsAllResponse>(typeof(CopriCallsHttps), JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL)));
|
provider.AddToCache(new Result<StationsAvailableResponse>(typeof(CopriCallsHttps), JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL)));
|
||||||
stations = await provider.GetStations(true);
|
stations = await provider.GetStations(true);
|
||||||
Assert.AreEqual(3, stations.Response.stations.Count);
|
Assert.AreEqual(3, stations.Response.stations.Count);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ using static TINK.Repository.CopriCallsMemory;
|
||||||
|
|
||||||
using BikeInfo = TINK.Model.Bike.BluetoothLock.BikeInfo;
|
using BikeInfo = TINK.Model.Bike.BluetoothLock.BikeInfo;
|
||||||
using TINK.Model.User.Account;
|
using TINK.Model.User.Account;
|
||||||
|
using Xamarin.Forms;
|
||||||
|
|
||||||
namespace TestTINKLib.Fixtures.Connector
|
namespace TestTINKLib.Fixtures.Connector
|
||||||
{
|
{
|
||||||
|
@ -42,6 +43,125 @@ namespace TestTINKLib.Fixtures.Connector
|
||||||
Assert.AreEqual("Südstadt Station", l_oStationsTarget.GetById("31").StationName);
|
Assert.AreEqual("Südstadt Station", l_oStationsTarget.GetById("31").StationName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestGetAllStations_OperatorData()
|
||||||
|
{
|
||||||
|
var stations = UpdaterJSON.GetStationsAllMutable(JsonConvert.DeserializeObject<ResponseContainer<StationsAvailableResponse>>(STATIONS_AVAILABLE_LOGGEDIN_20210720).shareejson);
|
||||||
|
|
||||||
|
var station = stations.FirstOrDefault(x => x.Id == "LV_3");
|
||||||
|
Assert.That(
|
||||||
|
station,
|
||||||
|
Is.Not.Null,
|
||||||
|
"Station LV_3 must exist.");
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
station.OperatorData.Color,
|
||||||
|
Is.EqualTo(Color.FromHex("#006269")));
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
station.OperatorData.Hours,
|
||||||
|
Is.EqualTo(string.Empty));
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
station.OperatorData.Name,
|
||||||
|
Is.EqualTo("LastenVelo Freiburg"));
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
station.OperatorData.MailAddressText,
|
||||||
|
Is.EqualTo("info@lastenvelofreiburg.de"));
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
station.OperatorData.PhoneNumberText,
|
||||||
|
Is.EqualTo(string.Empty));
|
||||||
|
|
||||||
|
station = stations.FirstOrDefault(x => x.Id == "FR_105");
|
||||||
|
Assert.That(
|
||||||
|
station,
|
||||||
|
Is.Not.Null,
|
||||||
|
"Station FR_105 must exist.");
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
station.OperatorData.Color,
|
||||||
|
Is.EqualTo(Color.FromHex("#009699")));
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
station.OperatorData.Hours,
|
||||||
|
Is.EqualTo("B<>rozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"));
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
station.OperatorData.Name,
|
||||||
|
Is.EqualTo("sharee.bike | TeilRad GmbH"));
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
station.OperatorData.MailAddressText,
|
||||||
|
Is.EqualTo("hotline@sharee.bike"));
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
station.OperatorData.PhoneNumberText,
|
||||||
|
Is.EqualTo("+49 761 45370097"));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestGetAllStations_OperatorData_NoOperatorData()
|
||||||
|
{
|
||||||
|
var stations = UpdaterJSON.GetStationsAllMutable(JsonConvert.DeserializeObject<ResponseContainer<StationsAvailableResponse>>(@"
|
||||||
|
{
|
||||||
|
""shareejson"": {
|
||||||
|
""lang"": ""DE"",
|
||||||
|
""impress_html"": ""site/impress.html"",
|
||||||
|
""tariff_info_html"": ""site/tariff_info_1.html"",
|
||||||
|
""debuglevel"": ""1"",
|
||||||
|
""user_tour"": [
|
||||||
|
null,
|
||||||
|
""""
|
||||||
|
],
|
||||||
|
""response"": ""stations_available"",
|
||||||
|
""user_id"": ""ohauff@posteo.de"",
|
||||||
|
""stations"": {
|
||||||
|
""LV_3"": {
|
||||||
|
""service_tour"": ""LV_1"",
|
||||||
|
""uri_operator"": ""https://shareeapp-lv.copri.eu"",
|
||||||
|
""authed"": ""1"",
|
||||||
|
""station"": ""LV_3"",
|
||||||
|
""gps"": {
|
||||||
|
""latitude"": ""47.9973"",
|
||||||
|
""longitude"": ""7.8585""
|
||||||
|
},
|
||||||
|
""gps_radius"": ""100"",
|
||||||
|
""description"": ""Katholische Akademie"",
|
||||||
|
""state"": ""available"",
|
||||||
|
""station_group"": [
|
||||||
|
""LV_300005""
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}").shareejson);
|
||||||
|
|
||||||
|
var station = stations.FirstOrDefault(x => x.Id == "LV_3");
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
station.OperatorData.Color,
|
||||||
|
Is.Null);
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
station.OperatorData.Hours,
|
||||||
|
Is.EqualTo(string.Empty));
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
station.OperatorData.Name,
|
||||||
|
Is.EqualTo(string.Empty));
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
station.OperatorData.MailAddressText,
|
||||||
|
Is.EqualTo(string.Empty));
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
station.OperatorData.PhoneNumberText,
|
||||||
|
Is.EqualTo(string.Empty));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestUpdateBikesAvailable_BikeNr5GetBooked()
|
public void TestUpdateBikesAvailable_BikeNr5GetBooked()
|
||||||
{
|
{
|
||||||
|
|
61
TestShareeLib/Model/Station/TestData.cs
Normal file
61
TestShareeLib/Model/Station/TestData.cs
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
using NUnit.Framework;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace TestShareeLib.Model.Station
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TestData
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestCtor()
|
||||||
|
{
|
||||||
|
var data = new TINK.Model.Station.Operator.Data();
|
||||||
|
Assert.That(
|
||||||
|
data.Color,
|
||||||
|
Is.Null);
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
data.Hours,
|
||||||
|
Is.EqualTo(string.Empty));
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
data.Name,
|
||||||
|
Is.EqualTo(string.Empty));
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
data.MailAddressText,
|
||||||
|
Is.EqualTo(string.Empty));
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
data.PhoneNumberText,
|
||||||
|
Is.EqualTo(string.Empty));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestCtor_Null()
|
||||||
|
{
|
||||||
|
var data = new TINK.Model.Station.Operator.Data(null, null, null, null, null);
|
||||||
|
Assert.That(
|
||||||
|
data.Color,
|
||||||
|
Is.Null);
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
data.Hours,
|
||||||
|
Is.EqualTo(string.Empty));
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
data.Name,
|
||||||
|
Is.EqualTo(string.Empty));
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
data.MailAddressText,
|
||||||
|
Is.EqualTo(string.Empty));
|
||||||
|
|
||||||
|
Assert.That(
|
||||||
|
data.PhoneNumberText,
|
||||||
|
Is.EqualTo(string.Empty));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -19,7 +19,7 @@ namespace UITest.Fixtures.ObjectTests.Connector
|
||||||
var bikesOccupied = JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(CopriCallsMonkeyStore.BIKESOCCUPIED);
|
var bikesOccupied = JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(CopriCallsMonkeyStore.BIKESOCCUPIED);
|
||||||
Assert.NotNull(bikesOccupied?.bikes_occupied);
|
Assert.NotNull(bikesOccupied?.bikes_occupied);
|
||||||
|
|
||||||
var stations = JsonConvert.DeserializeObject<StationsAllResponse>(CopriCallsMonkeyStore.STATIONSALL);
|
var stations = JsonConvert.DeserializeObject<StationsAvailableResponse>(CopriCallsMonkeyStore.STATIONSALL);
|
||||||
Assert.NotNull(stations?.stations);
|
Assert.NotNull(stations?.stations);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ namespace UITest.Fixtures.Connector
|
||||||
/// <param name="p_strMerchantId">Id of the merchant.</param>
|
/// <param name="p_strMerchantId">Id of the merchant.</param>
|
||||||
/// <param name="p_strCookie">Auto cookie of user if user is logged in.</param>
|
/// <param name="p_strCookie">Auto cookie of user if user is logged in.</param>
|
||||||
/// <returns>List of files.</returns>
|
/// <returns>List of files.</returns>
|
||||||
public static StationsAllResponse GetStationsAllCall(
|
public static StationsAvailableResponse GetStationsAllCall(
|
||||||
string p_strCopriHost,
|
string p_strCopriHost,
|
||||||
string p_strMerchantId,
|
string p_strMerchantId,
|
||||||
string p_strCookie = null)
|
string p_strCookie = null)
|
||||||
|
@ -100,7 +100,7 @@ namespace UITest.Fixtures.Connector
|
||||||
l_oStationsAllResponse = Post(l_oCommand, p_strCopriHost);
|
l_oStationsAllResponse = Post(l_oCommand, p_strCopriHost);
|
||||||
|
|
||||||
// Extract bikes from response.
|
// Extract bikes from response.
|
||||||
return JsonConvert.DeserializeObject<ResponseContainer<StationsAllResponse>>(l_oStationsAllResponse)?.shareejson;
|
return JsonConvert.DeserializeObject<ResponseContainer<StationsAvailableResponse>>(l_oStationsAllResponse)?.shareejson;
|
||||||
#else
|
#else
|
||||||
return null;
|
return null;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -88,9 +88,9 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector.Query
|
||||||
{
|
{
|
||||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||||
|
|
||||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||||
typeof(CopriCallsMonkeyStore),
|
typeof(CopriCallsMonkeyStore),
|
||||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL),
|
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL),
|
||||||
new System.Exception("Bang when getting stations..."))));
|
new System.Exception("Bang when getting stations..."))));
|
||||||
|
|
||||||
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||||
|
@ -110,18 +110,18 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector.Query
|
||||||
{
|
{
|
||||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||||
|
|
||||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||||
typeof(CopriCallsHttps),
|
typeof(CopriCallsHttps),
|
||||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALLEMPTY))));
|
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALLEMPTY))));
|
||||||
|
|
||||||
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||||
typeof(CopriCallsMonkeyStore),
|
typeof(CopriCallsMonkeyStore),
|
||||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
|
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE),
|
||||||
new System.Exception("Bang when getting bikes..."))));
|
new System.Exception("Bang when getting bikes..."))));
|
||||||
|
|
||||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||||
typeof(CopriCallsMonkeyStore),
|
typeof(CopriCallsMonkeyStore),
|
||||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL))));
|
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL))));
|
||||||
|
|
||||||
var result = await new CachedQuery(server).GetBikesAndStationsAsync();
|
var result = await new CachedQuery(server).GetBikesAndStationsAsync();
|
||||||
|
|
||||||
|
@ -137,15 +137,15 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector.Query
|
||||||
{
|
{
|
||||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||||
|
|
||||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||||
typeof(CopriCallsHttps),
|
typeof(CopriCallsHttps),
|
||||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL))));
|
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL))));
|
||||||
|
|
||||||
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||||
typeof(CopriCallsHttps),
|
typeof(CopriCallsHttps),
|
||||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE))));
|
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE))));
|
||||||
|
|
||||||
server.Stub(x => x.AddToCache(Arg<Result<StationsAllResponse>>.Is.Anything));
|
server.Stub(x => x.AddToCache(Arg<Result<StationsAvailableResponse>>.Is.Anything));
|
||||||
server.Stub(x => x.AddToCache(Arg<Result<BikesAvailableResponse>>.Is.Anything));
|
server.Stub(x => x.AddToCache(Arg<Result<BikesAvailableResponse>>.Is.Anything));
|
||||||
|
|
||||||
var result = await new CachedQuery(server).GetBikesAndStationsAsync();
|
var result = await new CachedQuery(server).GetBikesAndStationsAsync();
|
||||||
|
|
|
@ -134,9 +134,9 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector.Query
|
||||||
{
|
{
|
||||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||||
|
|
||||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||||
typeof(CopriCallsMonkeyStore),
|
typeof(CopriCallsMonkeyStore),
|
||||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL),
|
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL),
|
||||||
new System.Exception("Bang when getting stations..."))));
|
new System.Exception("Bang when getting stations..."))));
|
||||||
|
|
||||||
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||||
|
@ -160,9 +160,9 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector.Query
|
||||||
{
|
{
|
||||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||||
|
|
||||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||||
typeof(CopriCallsHttps),
|
typeof(CopriCallsHttps),
|
||||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALLEMPTY))));
|
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALLEMPTY))));
|
||||||
|
|
||||||
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||||
typeof(CopriCallsMonkeyStore),
|
typeof(CopriCallsMonkeyStore),
|
||||||
|
@ -173,9 +173,9 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector.Query
|
||||||
typeof(CopriCallsMonkeyStore),
|
typeof(CopriCallsMonkeyStore),
|
||||||
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED))));
|
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED))));
|
||||||
|
|
||||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||||
typeof(CopriCallsMonkeyStore),
|
typeof(CopriCallsMonkeyStore),
|
||||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL))));
|
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL))));
|
||||||
|
|
||||||
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync();
|
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync();
|
||||||
|
|
||||||
|
@ -190,9 +190,9 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector.Query
|
||||||
{
|
{
|
||||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||||
|
|
||||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||||
typeof(CopriCallsHttps),
|
typeof(CopriCallsHttps),
|
||||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALLEMPTY))));
|
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALLEMPTY))));
|
||||||
|
|
||||||
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||||
typeof(CopriCallsHttps),
|
typeof(CopriCallsHttps),
|
||||||
|
@ -207,9 +207,9 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector.Query
|
||||||
typeof(CopriCallsMonkeyStore),
|
typeof(CopriCallsMonkeyStore),
|
||||||
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE))));
|
JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE))));
|
||||||
|
|
||||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == true))).Return(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||||
typeof(CopriCallsMonkeyStore),
|
typeof(CopriCallsMonkeyStore),
|
||||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL))));
|
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL))));
|
||||||
|
|
||||||
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync();
|
var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync();
|
||||||
|
|
||||||
|
@ -224,9 +224,9 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector.Query
|
||||||
{
|
{
|
||||||
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
var server = MockRepository.GenerateMock<ICachedCopriServer>();
|
||||||
|
|
||||||
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAllResponse>(
|
server.Stub(x => x.GetStations(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<StationsAvailableResponse>(
|
||||||
typeof(CopriCallsHttps),
|
typeof(CopriCallsHttps),
|
||||||
JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL))));
|
JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL))));
|
||||||
|
|
||||||
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
server.Stub(x => x.GetBikesAvailable(Arg<bool>.Matches(fromCache => fromCache == false))).Return(Task.Run(() => new Result<BikesAvailableResponse>(
|
||||||
typeof(CopriCallsHttps),
|
typeof(CopriCallsHttps),
|
||||||
|
@ -236,7 +236,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector.Query
|
||||||
typeof(CopriCallsHttps),
|
typeof(CopriCallsHttps),
|
||||||
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED))));
|
JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED))));
|
||||||
|
|
||||||
server.Stub(x => x.AddToCache(Arg<Result<StationsAllResponse>>.Is.Anything));
|
server.Stub(x => x.AddToCache(Arg<Result<StationsAvailableResponse>>.Is.Anything));
|
||||||
server.Stub(x => x.AddToCache(Arg<Result<BikesAvailableResponse>>.Is.Anything));
|
server.Stub(x => x.AddToCache(Arg<Result<BikesAvailableResponse>>.Is.Anything));
|
||||||
server.Stub(x => x.AddToCache(Arg<Result<BikesReservedOccupiedResponse>>.Is.Anything));
|
server.Stub(x => x.AddToCache(Arg<Result<BikesReservedOccupiedResponse>>.Is.Anything));
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Query
|
||||||
{
|
{
|
||||||
var server = MockRepository.GenerateMock<ICopriServer>();
|
var server = MockRepository.GenerateMock<ICopriServer>();
|
||||||
|
|
||||||
server.Stub(x => x.GetStationsAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL)));
|
server.Stub(x => x.GetStationsAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL)));
|
||||||
server.Stub(x => x.GetBikesAvailableAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE)));
|
server.Stub(x => x.GetBikesAvailableAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE)));
|
||||||
|
|
||||||
var result = await new TINK.Model.Connector.Query(server).GetBikesAndStationsAsync();
|
var result = await new TINK.Model.Connector.Query(server).GetBikesAndStationsAsync();
|
||||||
|
|
|
@ -108,7 +108,7 @@ namespace TestTINKLib.Fixtures.ObjectTests.Connector
|
||||||
{
|
{
|
||||||
var server = MockRepository.GenerateMock<ICopriServer>();
|
var server = MockRepository.GenerateMock<ICopriServer>();
|
||||||
|
|
||||||
server.Stub(x => x.GetStationsAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<StationsAllResponse>(STATIONSALL)));
|
server.Stub(x => x.GetStationsAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<StationsAvailableResponse>(STATIONSALL)));
|
||||||
server.Stub(x => x.GetBikesAvailableAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE)));
|
server.Stub(x => x.GetBikesAvailableAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<BikesAvailableResponse>(BIKESAVAILABLE)));
|
||||||
server.Stub(x => x.GetBikesOccupiedAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED)));
|
server.Stub(x => x.GetBikesOccupiedAsync()).Return(Task.Run(() => JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(BIKESOCCUPIED)));
|
||||||
|
|
||||||
|
|
|
@ -228,7 +228,7 @@ namespace TestTINKLib.Fixtures.Connector
|
||||||
[Test]
|
[Test]
|
||||||
public void TestGetStationGroup_Invalid()
|
public void TestGetStationGroup_Invalid()
|
||||||
{
|
{
|
||||||
var l_oStation = JsonConvertRethrow.DeserializeObject<StationsAllResponse.StationInfo>(
|
var l_oStation = JsonConvertRethrow.DeserializeObject<StationsAvailableResponse.StationInfo>(
|
||||||
@"{
|
@"{
|
||||||
""station"" : ""4"",
|
""station"" : ""4"",
|
||||||
""gps"" : { ""latitude"": ""47.6586936667"", ""longitude"": ""9.16863116667"" }
|
""gps"" : { ""latitude"": ""47.6586936667"", ""longitude"": ""9.16863116667"" }
|
||||||
|
@ -241,7 +241,7 @@ namespace TestTINKLib.Fixtures.Connector
|
||||||
[Test]
|
[Test]
|
||||||
public void TestGetStationGroup_TINK()
|
public void TestGetStationGroup_TINK()
|
||||||
{
|
{
|
||||||
var l_oStation = JsonConvertRethrow.DeserializeObject<StationsAllResponse.StationInfo>(
|
var l_oStation = JsonConvertRethrow.DeserializeObject<StationsAvailableResponse.StationInfo>(
|
||||||
@"{
|
@"{
|
||||||
""station"" : ""4"",
|
""station"" : ""4"",
|
||||||
""station_group"" : [ ""TINK"" ],
|
""station_group"" : [ ""TINK"" ],
|
||||||
|
@ -254,7 +254,7 @@ namespace TestTINKLib.Fixtures.Connector
|
||||||
[Test]
|
[Test]
|
||||||
public void TestGetStationGroup_TINKAndKonrad()
|
public void TestGetStationGroup_TINKAndKonrad()
|
||||||
{
|
{
|
||||||
var l_oStation = JsonConvertRethrow.DeserializeObject<StationsAllResponse.StationInfo>(
|
var l_oStation = JsonConvertRethrow.DeserializeObject<StationsAvailableResponse.StationInfo>(
|
||||||
@"{
|
@"{
|
||||||
""station"" : ""4"",
|
""station"" : ""4"",
|
||||||
""station_group"": [ ""TINK"", ""Konrad"" ],
|
""station_group"": [ ""TINK"", ""Konrad"" ],
|
||||||
|
|
|
@ -10,17 +10,20 @@ namespace TestTINKLib.Fixtures.ObjectTests.Station
|
||||||
[Test]
|
[Test]
|
||||||
public void TestConstruct()
|
public void TestConstruct()
|
||||||
{
|
{
|
||||||
var l_oNull = new NullStation();
|
var nullStation = new NullStation();
|
||||||
|
|
||||||
// Was -1 before swiching type of id from int to string when switching from COPRI version v4.0 to v4.1
|
// Was -1 before swiching type of id from int to string when switching from COPRI version v4.0 to v4.1
|
||||||
Assert.That(
|
Assert.That(
|
||||||
l_oNull.Id,
|
nullStation.Id,
|
||||||
Is.Null);
|
Is.Null);
|
||||||
|
|
||||||
Assert.AreEqual(0, l_oNull.Group.ToList().Count);
|
Assert.AreEqual(0, nullStation.Group.ToList().Count);
|
||||||
Assert.AreEqual(string.Empty, l_oNull.StationName);
|
Assert.AreEqual(string.Empty, nullStation.StationName);
|
||||||
Assert.IsNaN(l_oNull.Position.Latitude);
|
Assert.IsNaN(nullStation.Position.Latitude);
|
||||||
Assert.IsNaN(l_oNull.Position.Longitude);
|
Assert.IsNaN(nullStation.Position.Longitude);
|
||||||
|
Assert.That(
|
||||||
|
nullStation.OperatorData,
|
||||||
|
Is.Not.Null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,5 +38,13 @@ namespace TestTINKLib.Fixtures.Station
|
||||||
{
|
{
|
||||||
Assert.Throws<ArgumentException>(() => new TINK.Model.Station.Station("7", null, new Position(1, 2), "Hallo"));
|
Assert.Throws<ArgumentException>(() => new TINK.Model.Station.Station("7", null, new Position(1, 2), "Hallo"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestConstruct_NoOperator()
|
||||||
|
{
|
||||||
|
Assert.That(
|
||||||
|
new TINK.Model.Station.Station("7", new List<string>(), new Position(1, 2), "Hallo").OperatorData,
|
||||||
|
Is.Not.Null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace TestTINKLib.Mocks.Connector
|
||||||
|
|
||||||
public string MerchantId => server.MerchantId;
|
public string MerchantId => server.MerchantId;
|
||||||
|
|
||||||
public void AddToCache(StationsAllResponse stations)
|
public void AddToCache(StationsAvailableResponse stations)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ namespace TestTINKLib.Mocks.Connector
|
||||||
return server.GetBikesOccupiedAsync();
|
return server.GetBikesOccupiedAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<StationsAllResponse> GetStationsAsync()
|
public Task<StationsAvailableResponse> GetStationsAsync()
|
||||||
{
|
{
|
||||||
return server.GetStationsAsync();
|
return server.GetStationsAsync();
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ namespace TestTINKLib.Mocks.Connector
|
||||||
throw ExceptionFactory($"Simulated error thrown at {nameof(GetBikesOccupiedAsync)}.");
|
throw ExceptionFactory($"Simulated error thrown at {nameof(GetBikesOccupiedAsync)}.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<StationsAllResponse> GetStationsAsync()
|
public Task<StationsAvailableResponse> GetStationsAsync()
|
||||||
{
|
{
|
||||||
throw ExceptionFactory($"Simulated error thrown at {nameof(GetStationsAsync)}.");
|
throw ExceptionFactory($"Simulated error thrown at {nameof(GetStationsAsync)}.");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue