using System; using System.Threading.Tasks; using Newtonsoft.Json; using NSubstitute; using NUnit.Framework; using TINK.Model.Connector; using TINK.Model.Services.CopriApi; using TINK.Repository; using TINK.Repository.Response; using TINK.Repository.Response.Stations; using TINK.Services.CopriApi; namespace TestShareeLib.Model.Connector { [TestFixture] public class TestCachedQueryLoggedIn { /// /// Verifies that available bikes are not considered to by kind of MyBikes. /// [Test] public async Task TestGetBikesOccupiedAsyncMyBikesNone() { var server = Substitute.For(); var bikesAvailable = JsonConvert.DeserializeObject(@" { ""bikes"": { ""FR1005"": { ""system"": ""Sigo"", ""state"": ""available"", ""bike"": ""FR1005"", ""station"": ""REN0"", } }, ""copri_version"": ""4.1.12.5"", }"); var bikesOccupied = JsonConvert.DeserializeObject(@" { ""bikes_occupied"": { }, ""copri_version"": ""4.1.12.5"", }"); var resultAvailable = new Result( typeof(CopriCallsHttps), // Marks that response was taken from cache bikesAvailable, new GeneralData()); var resultOccupied = new Result( typeof(CopriCallsHttps), bikesOccupied, new GeneralData()); server.GetBikesAvailable(false).Returns(Task.FromResult(resultAvailable)); server.GetBikesOccupied(false).Returns(Task.FromResult(resultOccupied)); var query = new CachedQueryLoggedIn( server, "SessionCookie", "Mail", () => new DateTime(2022, 7, 16)); var bikesResponse = await query.GetBikesOccupiedAsync(); Assert.That( bikesResponse.Response.Count, Is.EqualTo(0)); } /// /// Verifies that available bikes with Co2Saving entry set are considered to by kind of MyBikes. /// [Test] public async Task TestGetBikesOccupiedAsyncMyBikesOneFeedbackPending() { var server = Substitute.For(); var bikesAvailable = JsonConvert.DeserializeObject(@" { ""bikes"": { ""FR1005"": { ""system"": ""Sigo"", ""state"": ""available"", ""bike"": ""FR1005"", ""station"": ""REN0"", ""co2saving"" : """" } }, ""copri_version"": ""4.1.12.5"", }"); var bikesOccupied = JsonConvert.DeserializeObject(@" { ""bikes_occupied"": { }, ""copri_version"": ""4.1.12.5"", }"); var resultAvailable = new Result( typeof(CopriCallsHttps), bikesAvailable, new GeneralData()); var resultOccupied = new Result( typeof(CopriCallsHttps), bikesOccupied, new GeneralData()); server.GetBikesAvailable(false).Returns(Task.FromResult(resultAvailable)); server.GetBikesOccupied(false).Returns(Task.FromResult(resultOccupied)); var query = new CachedQueryLoggedIn( server, "SessionCookie", "Mail", () => new DateTime(2022, 7, 16)); var bikesResponse = await query.GetBikesOccupiedAsync(); Assert.That( bikesResponse.Response.Count, Is.EqualTo(1)); } /// /// . /// [Test] public async Task TestGetBikesOccupiedAsyncMyBikesOneOccupied() { var server = Substitute.For(); var bikesAvailable = JsonConvert.DeserializeObject(@" { ""bikes"": { }, ""copri_version"": ""4.1.12.5"", }"); var bikesOccupied = JsonConvert.DeserializeObject(@" { ""bikes_occupied"": { ""FR1005"": { ""lock_state"": ""occupied"", ""system"": ""Sigo"", ""state"": ""occupied"", ""bike"": ""FR1005"", ""station"": ""REN0"", } }, ""copri_version"": ""4.1.12.5"", }"); var resultAvailable = new Result( typeof(CopriCallsHttps), bikesAvailable, new GeneralData()); var resultOccupied = new Result( typeof(CopriCallsHttps), bikesOccupied, new GeneralData()); server.GetBikesAvailable(false).Returns(Task.FromResult(resultAvailable)); // Get bikes from copri server.GetBikesOccupied(false).Returns(Task.FromResult(resultOccupied)); // Get bikes from cache var query = new CachedQueryLoggedIn( server, "SessionCookie", "Mail", () => new DateTime(2022, 7, 16)); var bikesResponse = await query.GetBikesOccupiedAsync(); Assert.That( bikesResponse.Response.Count, Is.EqualTo(1)); } /// /// Scenario: Call of GetBikesAvailable fails data is taken from cache. /// [Test] public async Task TestGetBikesOccupiedAsyncGetAvailableFailsMyBikeOneFeedbackPending() { var server = Substitute.For(); var bikesAvailable = JsonConvert.DeserializeObject(@" { ""bikes"": { ""FR1005"": { ""system"": ""Sigo"", ""state"": ""available"", ""bike"": ""FR1005"", ""station"": ""REN0"", ""co2saving"" : """" } }, ""copri_version"": ""4.1.12.5"", }"); var bikesOccupied = JsonConvert.DeserializeObject(@" { ""bikes_occupied"": { }, ""copri_version"": ""4.1.12.5"", }"); var resultAvailable = new Result( typeof(CopriCallsMonkeyStore), bikesAvailable, new GeneralData()); var resultOccupied = new Result( typeof(CopriCallsMonkeyStore), bikesOccupied, new GeneralData()); server.GetBikesAvailable(false).Returns(Task.FromResult(resultAvailable)); server.GetBikesOccupied(true).Returns(Task.FromResult(resultOccupied)); var query = new CachedQueryLoggedIn( server, "SessionCookie", "Mail", () => new DateTime(2022, 7, 16)); var bikesResponse = await query.GetBikesOccupiedAsync(); Assert.That( bikesResponse.Response.Count, Is.EqualTo(1)); } /// /// Scenario: Call of GetBikesAvailable succeeds but because call of GetBikesOccupied fails data is taken from cache. /// [Test] public async Task TestGetBikesOccupiedAsyncGetGetBikesOccupiedFailsMyBikeFeedbackPending() { var server = Substitute.For(); var bikesAvailableCopri = JsonConvert.DeserializeObject(@" { ""bikes"": { }, ""copri_version"": ""4.1.12.5"", }"); var bikesAvailableCache = JsonConvert.DeserializeObject(@" { ""bikes"": { ""FR1005"": { ""system"": ""Sigo"", ""state"": ""available"", ""bike"": ""FR1005"", ""station"": ""REN0"", ""co2saving"" : """" } }, ""copri_version"": ""4.1.12.5"", }"); var bikesOccupied = JsonConvert.DeserializeObject(@" { ""bikes_occupied"": { }, ""copri_version"": ""4.1.12.5"", }"); var resultAvailableCopri = new Result( typeof(CopriCallsHttps), // Marks that response was taken from copri bikesAvailableCache, new GeneralData()); var resultAvailableCache = new Result( typeof(CopriCallsMonkeyStore), // Marks that response was taken from cache bikesAvailableCache, new GeneralData()); var resultOccupied = new Result( typeof(CopriCallsMonkeyStore), bikesOccupied, new GeneralData()); server.GetBikesAvailable(false).Returns(Task.FromResult(resultAvailableCopri)); // Get bikes from copri server.GetBikesOccupied(false).Returns(Task.FromResult(resultOccupied)); // Get bikes from copri fails server.GetBikesAvailable(true).Returns(Task.FromResult(resultAvailableCache)); // Get bikes from cache var query = new CachedQueryLoggedIn( server, "SessionCookie", "Mail", () => new DateTime(2022, 7, 16)); var bikesResponse = await query.GetBikesOccupiedAsync(); Assert.That( bikesResponse.Response.Count, Is.EqualTo(1)); } private const string BIKESAVAILABLE = @"{ ""copri_version"" : ""4.1.0.0"", ""bikes"" : {}, ""response_state"" : ""OK"", ""apiserver"" : ""https://app.tink-konstanz.de"", ""authcookie"" : """", ""response"" : ""bikes_available"", ""bikes"" : { ""2352"" : { ""description"" : ""Cargo Long"", ""state"" : ""available"", ""bike"" : ""1"", ""gps"" : { ""latitude"": ""47.669888"", ""longitude"": ""9.167749"" }, ""station"" : ""9"" } } }"; private const string BIKESAVAILABLE2 = @"{ ""lang"" : ""de"", ""user_group"" : [ ""FR300103"", ""FR300101"" ], ""uri_primary"" : ""https://shareeapp-primary.copri.eu"", ""bikes_occupied"" : { ""160317"" : { ""station"" : ""FR101"", ""bike_type"" : { ""category"" : ""cargo"", ""wheels"" : ""2"" }, ""rental_minute_all"" : 2666, ""description"" : ""Lastenrad Oliver Pieper"", ""unit_price"" : ""2.00"", ""end_time"" : ""2023-10-29 12:03:28"", ""total_price"" : ""0.00"", ""K_u"" : ""[72, 41, 3, -121, -121, -40, -125, -92, -70, -78, -12, -73, 11, -31, 108, 63, -22, 28, -73, 35, 0, 0, 0, 0]"", ""real_clock"" : ""1 day 20:26"", ""rentalog"" : """", ""bike"" : ""FR1011"", ""gps"" : { ""latitude"" : ""47.9765599546954"", ""longitude"" : ""7.82557798549533"" }, ""request_time"" : ""2023-10-27 15:37:16.296418+02"", ""aa_ride"" : ""0"", ""state"" : ""occupied"", ""lock_state"" : ""unlocked"", ""K_seed"" : ""[-77, 79, -81, -34, 107, -34, -100, -29, 124, 30, -50, -63, -111, 0, 22, -19]"", ""Ilockit_ID"" : ""ISHAREIT-2200536"", ""system"" : ""Ilockit"", ""computed_hours"" : ""44.1"", ""freed_time"" : ""- 00:20"", ""bike_group"" : [ ""FR300101"" ], ""start_time"" : ""2023-10-27 15:37:24.371987+02"", ""rental_description"" : { ""tarif_elements"" : { ""4"" : [ ""Max. Gebühr"", ""24,00 € / 24 Std"" ], ""1"" : [ ""Mietgebühr"", ""2,00 € / 30 Min "" ], ""7"" : [ ""Aktuelle Mietzeit"", ""1 Tag 20 Std 26 Min "" ], ""2"" : [ ""ab 2. Tag"", ""3,00 € / 30 Min "" ], ""6"" : [ ""Gratis Mietzeit"", ""20 Min / Tag"" ] }, ""reserve_timerange"" : ""15"", ""name"" : ""E-Lastenrad private"", ""id"" : ""5533"" }, ""discount"" : ""-100%"", ""uri_operator"" : ""https://shareeapp-fr01.copri.eu"" } }, ""bike_info_html"" : ""site/bike_info_sharee_230922.html"", ""agb_checked"" : ""1"", ""user_tour"" : [], ""last_used_operator"" : { ""operator_name"" : ""TeilRad GmbH"", ""operator_phone"" : ""+49 761 45370097"", ""operator_email"" : ""hotline@sharee.bike"", ""operator_hours"" : ""Bürozeiten: Montag, Mittwoch, Freitag 9-12 Uhr"" }, ""user_id"" : ""ohauff@posteo.de"", ""impress_html"" : ""site/impress_1.html"", ""authcookie"" : ""5781_f172cf59108fe53e7524c841847fee69_shoo0faiNg"", ""faq_app_fullurl"" : ""https://sharee.bike/faq/fahrrad-nutzung"", ""tariff_info_html"" : ""site/tarif_info_sharee_230922.html"", ""agb_html"" : ""site/agb_sharee_2.html"", ""response"" : ""bikes_available"", ""bikes"" : { ""FR1545"" : { ""Ilockit_GUID"" : ""00000000-0000-0000-0000-e38bf9d32234"", ""description"" : ""C2-02-00545"", ""lock_state"" : ""locked"", ""system"" : ""Ilockit"", ""Ilockit_ID"" : ""ISHAREIT-2200545"", ""state"" : ""available"", ""aa_ride"" : ""0"", ""smartlock_type"" : { ""battery"" : { ""charge_current_percent"" : ""100"" }, ""engine"" : { ""manufacturer"" : ""Ilockit"" } }, ""bike_type"" : { ""battery"" : { ""charge_max_bars"" : ""5"", ""charge_current_bars"" : ""0"", ""charge_current_percent"" : ""0"", ""hidden"" : ""0"", ""backend_accessible"" : ""0"" }, ""engine"" : { ""manufacturer"" : ""dummy"" }, ""category"" : ""cargo"", ""wheels"" : ""2"" }, ""station"" : ""FR101"", ""uri_operator"" : ""https://shareeapp-fr01.copri.eu"", ""gps"" : { ""latitude"" : ""47.9767844"", ""longitude"" : ""7.8258182"" }, ""bike"" : ""FR1545"", ""bike_group"" : [ ""FR300101"" ], ""authed"" : ""1"", ""rental_description"" : { ""id"" : ""5533"", ""reserve_timerange"" : ""15"", ""name"" : ""E-Lastenrad private"", ""tarif_type"" : ""3"", ""tarif_elements"" : { ""6"" : [ ""Gratis Mietzeit"", ""20 Min / Tag"" ], ""2"" : [ ""ab 2. Tag"", ""3,00 € / 30 Min "" ], ""4"" : [ ""Max. Gebühr"", ""24,00 € / 24 Std"" ], ""1"" : [ ""Mietgebühr"", ""2,00 € / 30 Min "" ] } } }, ""FR1012"" : { ""uri_operator"" : ""https://shareeapp-fr01.copri.eu"", ""bike"" : ""FR1012"", ""gps"" : { ""latitude"" : ""47.998034725897"", ""longitude"" : ""7.78498157858849"" }, ""bike_group"" : [ ""FR300101"" ], ""rental_description"" : { ""rental_info"" : { ""1"" : [ ""Tracking"", ""Ich stimme der Speicherung (Tracking) meiner Fahrstrecke zwecks wissenschaftlicher Auswertung und Berechnung der CO2-Einsparung zu!"" ] }, ""tarif_elements"" : { ""1"" : [ ""Mietgebühr"", ""2,00 € / 30 Min "" ], ""4"" : [ ""Max. Gebühr"", ""24,00 € / 24 Std"" ], ""6"" : [ ""Gratis Mietzeit"", ""20 Min / Tag"" ], ""2"" : [ ""ab 2. Tag"", ""3,00 € / 30 Min "" ] }, ""reserve_timerange"" : ""15"", ""name"" : ""E-Lastenrad private"", ""id"" : ""5533"", ""tarif_type"" : ""3"" }, ""authed"" : ""1"", ""description"" : ""Contributor-bike devel"", ""Ilockit_GUID"" : ""00000000-0000-0000-0000-ef6655036de7"", ""lock_state"" : ""locked"", ""system"" : ""Ilockit"", ""Ilockit_ID"" : ""ISHAREIT-2309492"", ""state"" : ""available"", ""bike_type"" : { ""engine"" : { ""manufacturer"" : ""dummy"" }, ""battery"" : { ""charge_current_bars"" : ""5"", ""charge_max_bars"" : ""5"", ""backend_accessible"" : ""0"", ""charge_current_percent"" : ""100"", ""hidden"" : ""0"" }, ""category"" : ""cargo"", ""wheels"" : ""2"" }, ""smartlock_type"" : { ""engine"" : { ""manufacturer"" : ""Ilockit"" }, ""battery"" : { ""charge_current_percent"" : """" } }, ""aa_ride"" : ""0"", ""station"" : ""FR103"" }, }, ""aowner"" : ""186"", ""init_map"" : { ""radius"" : ""2.9"", ""center"" : { ""longitude"" : ""7.825490"", ""latitude"" : ""47.976634"" } }, ""new_authcoo"" : ""0"", ""apiserver"" : ""https://shareeapp-fr01.copri.eu"", ""merchant_id"" : ""shoo0faiNg"", ""privacy_html"" : ""site/privacy_sharee_2.html"", ""response_state"" : ""OK, nothing todo"", ""debuglevel"" : ""104"", ""clearing_cache"" : ""0"", ""copri_version"" : ""4.1.23.20"", ""project_id"" : ""Freiburg"" }"; private const string BIKESAVAILABLEEMPTY = @"{ ""copri_version"" : ""4.1.0.0"", ""bikes"" : {}, ""response_state"" : ""OK"", ""apiserver"" : ""https://app.tink-konstanz.de"", ""authcookie"" : """", ""response"" : ""bikes_available"", ""bikes"" : { } }"; private const string BIKESOCCUPIED = @"{ ""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"", ""debuglevel"" : ""2"", ""user_group"" : [ ""TINK"" ], ""user_id"" : ""javaminister@gmail.com"", ""response"" : ""user_bikes_occupied"", ""response_state"" : ""OK"", ""response_text"" : ""Die Liste der reservierten und gebuchten Fahrräder wurde erfolgreich geladen"", ""apiserver"" : ""https://tinkwwp.copri-bike.de"", ""bikes_occupied"" : { ""89004"" : { ""start_time"" : ""2018-01-27 17:33:00.989464+01"", ""station"" : ""9"", ""unit_price"" : ""2.00"", ""tariff_description"": { ""free_hours"" : ""0.5"", ""name"" : ""TINK Tarif"", ""max_eur_per_day"" : ""9.00"" }, ""timeCode"" : ""2061"", ""description"" : ""Cargo Long"", ""bike"" : ""4"", ""total_price"" : ""20.00"", ""state"" : ""requested"", ""real_hours"" : ""66.05"", ""bike_group"" : [ ""TINK"" ], ""now_time"" : ""2018-01-30 11:36:45"", ""request_time"" : ""2018-01-27 17:33:00.989464+01"", ""computed_hours"" : ""10.0"" } } }"; private const string STATIONSALL = @"{ ""copri_version"" : ""4.1.0.0"", ""stations"" : { ""5"" : { ""station"" : ""5"", ""bike_soll"" : ""0"", ""bike_ist"" : ""7"", ""station_group"" : [ ""TINK"" ], ""gps"" : { ""latitude"": ""47.66756"", ""longitude"": ""9.16477"" }, ""state"" : ""available"", ""description"" : """" }, ""13"" : { ""station"" : ""13"", ""bike_soll"" : ""4"", ""bike_ist"" : ""1"", ""station_group"" : [ ""TINK"" ], ""gps"" : { ""latitude"": ""47.657756"", ""longitude"": ""9.176084"" }, ""state"" : ""available"", ""description"" : """" }, ""30"" : { ""station"" : ""30"", ""bike_soll"" : ""5"", ""bike_ist"" : ""0"", ""station_group"" : [ ""TINK"", ""Konrad"" ], ""gps"" : { ""latitude"": ""47.657766"", ""longitude"": ""9.176094"" }, ""state"" : ""available"", ""description"" : ""Test für Stadtradstation"" } }, ""user_group"" : [ ""Konrad"", ""TINK"" ], ""response_state"" : ""OK"", ""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"", ""debuglevel"" : ""2"", ""response"" : ""stations_all"", ""user_id"" : ""javaminister@gmail.com"", ""apiserver"" : ""https://tinkwwp.copri-bike.de"" }"; /// /// Response updated (manually edited) combining JSON form responses and /// private const string STATIONSALLV2 = @"{ ""copri_version"" : ""4.1.0.0"", ""stations"" : { ""5"" : { ""station"" : ""5"", ""bike_soll"" : ""0"", ""bike_ist"" : ""7"", ""station_group"" : [ ""TINK"" ], ""gps"" : { ""latitude"": ""47.66756"", ""longitude"": ""9.16477"" }, ""state"" : ""available"", ""description"" : """" }, ""13"" : { ""station"" : ""13"", ""bike_soll"" : ""4"", ""bike_ist"" : ""1"", ""station_group"" : [ ""TINK"" ], ""gps"" : { ""latitude"": ""47.657756"", ""longitude"": ""9.176084"" }, ""state"" : ""available"", ""description"" : """" }, ""30"" : { ""station"" : ""30"", ""bike_soll"" : ""5"", ""bike_ist"" : ""0"", ""station_group"" : [ ""TINK"", ""Konrad"" ], ""gps"" : { ""latitude"": ""47.657766"", ""longitude"": ""9.176094"" }, ""state"" : ""available"", ""description"" : ""Test für Stadtradstation"" } }, ""bikes_occupied"" : { ""89004"" : { ""start_time"" : ""2018-01-27 17:33:00.989464+01"", ""station"" : ""9"", ""unit_price"" : ""2.00"", ""tariff_description"": { ""free_hours"" : ""0.5"", ""name"" : ""TINK Tarif"", ""max_eur_per_day"" : ""9.00"" }, ""timeCode"" : ""2061"", ""description"" : ""Cargo Long"", ""bike"" : ""4"", ""total_price"" : ""20.00"", ""state"" : ""requested"", ""real_hours"" : ""66.05"", ""bike_group"" : [ ""TINK"" ], ""now_time"" : ""2018-01-30 11:36:45"", ""request_time"" : ""2018-01-27 17:33:00.989464+01"", ""computed_hours"" : ""10.0"" } }, ""user_group"" : [ ""Konrad"", ""TINK"" ], ""response_state"" : ""OK"", ""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"", ""debuglevel"" : ""2"", ""response"" : ""stations_all"", ""user_id"" : ""javaminister@gmail.com"", ""apiserver"" : ""https://tinkwwp.copri-bike.de"" }"; private const string STATIONSALLEMPTY = @"{ ""copri_version"" : ""4.1.0.0"", ""stations"" : { }, ""user_group"" : [ ""Konrad"", ""TINK"" ], ""response_state"" : ""OK"", ""authcookie"" : ""6103_f782a208d9399291ba8d086b5dcc2509_12345678"", ""debuglevel"" : ""2"", ""response"" : ""stations_all"", ""user_id"" : ""javaminister@gmail.com"", ""apiserver"" : ""https://tinkwwp.copri-bike.de"" }"; [Test] public async Task TestGetStations_StationsFromCache() { var server = Substitute.For(); server.GetStations(false).Returns(Task.Run(() => new Result( typeof(CopriCallsMonkeyStore), JsonConvert.DeserializeObject(STATIONSALLV2), new GeneralData(), new Exception("Bang when getting stations...")))); var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync(); Assert.AreEqual(3, result.Response.StationsAll.Count); Assert.AreEqual(1, result.Response.BikesOccupied.Count); Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source); Assert.AreEqual("Bang when getting stations...", result.Exception.Message); } [Test] public async Task TestGetStations() { var server = Substitute.For(); server.GetStations(false).Returns(Task.Run(() => new Result( typeof(CopriCallsHttps), JsonConvert.DeserializeObject(STATIONSALLV2), new GeneralData()))); var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAndStationsAsync(); Assert.AreEqual(3, result.Response.StationsAll.Count); Assert.AreEqual(1, result.Response.BikesOccupied.Count); Assert.AreEqual(typeof(CopriCallsHttps), result.Source); Assert.IsNull(result.Exception); } [Test] public async Task TestGetBikes_BikesAvailableFromCache() { var server = Substitute.For(); server.GetBikesAvailable().Returns(Task.Run(() => new Result( typeof(CopriCallsMonkeyStore), JsonConvert.DeserializeObject(BIKESAVAILABLE), new GeneralData(), new System.Exception("Bang, bikes avail...")))); server.GetBikesOccupied(true).Returns(Task.Run(() => new Result( typeof(CopriCallsHttps), JsonConvert.DeserializeObject(BIKESOCCUPIED), new GeneralData()))); var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAsync(); Assert.AreEqual(2, result.Response.Count); Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source); Assert.AreEqual("Bang, bikes avail...", result.Exception.Message); } [Test] public async Task TestGetBikes_BikesOccupiedFromCache() { var server = Substitute.For(); server.GetBikesAvailable(false).Returns(Task.Run(() => new Result( typeof(CopriCallsHttps), JsonConvert.DeserializeObject(BIKESAVAILABLEEMPTY), new GeneralData()))); server.GetBikesOccupied(false).Returns(Task.Run(() => new Result( typeof(CopriCallsMonkeyStore), JsonConvert.DeserializeObject(BIKESOCCUPIED), new GeneralData(), new System.Exception("Bang, error bikes occupied")))); server.GetBikesAvailable(true).Returns(Task.Run(() => new Result( typeof(CopriCallsMonkeyStore), JsonConvert.DeserializeObject(BIKESAVAILABLE), new GeneralData()))); var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAsync(); Assert.AreEqual(2, result.Response.Count); Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source); Assert.AreEqual("Bang, error bikes occupied", result.Exception.Message); } [Test] public async Task TestGetBikes() { var server = Substitute.For(); server.GetBikesAvailable().Returns(Task.Run(() => new Result( typeof(CopriCallsHttps), JsonConvert.DeserializeObject(BIKESAVAILABLE), new GeneralData()))); server.GetBikesOccupied().Returns(Task.Run(() => new Result( typeof(CopriCallsHttps), JsonConvert.DeserializeObject(BIKESOCCUPIED), new GeneralData()))); var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAsync(); Assert.AreEqual(2, result.Response.Count); Assert.AreEqual(typeof(CopriCallsHttps), result.Source); Assert.IsNull(result.Exception); } [Test] public async Task TestGetBikesOccupied() { var server = Substitute.For(); server.GetBikesAvailable().Returns(Task.Run(() => new Result( typeof(CopriCallsHttps), JsonConvert.DeserializeObject("{}"), new GeneralData()))); server.GetBikesOccupied().Returns(Task.Run(() => new Result( typeof(CopriCallsHttps), JsonConvert.DeserializeObject(BIKESOCCUPIED), new GeneralData()))); var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesOccupiedAsync(); Assert.AreEqual(1, result.Response.Count); Assert.AreEqual(typeof(CopriCallsHttps), result.Source); Assert.IsNull(result.Exception); } [Test] public async Task TestGetBikesOperratorUri() { var server = Substitute.For(); server.GetBikesAvailable(operatorUri: Arg.Any()).Returns(Task.Run(() => new Result( typeof(CopriCallsHttps), JsonConvert.DeserializeObject(BIKESAVAILABLE2), new GeneralData()))); var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAsync(new Uri("https://shareeapp-fr01.copri.eu//APIjsonserver")); await server.DidNotReceive().GetBikesOccupied(); await server.DidNotReceive().GetBikesOccupied(Arg.Any()); server.Received().AddToCache(Arg.Any>(), Arg.Any()); Assert.AreEqual(3, result.Response.Count); Assert.AreEqual(typeof(CopriCallsHttps), result.Source); Assert.IsNull(result.Exception); } [Test] public async Task TestGetBikesOperratorUriCache() { var server = Substitute.For(); server.GetBikesAvailable(operatorUri: Arg.Any()).Returns(Task.Run(() => new Result( typeof(CopriCallsMonkeyStore), JsonConvert.DeserializeObject(BIKESAVAILABLE2), new GeneralData()))); var result = await new CachedQueryLoggedIn(server, "123", "a@b", () => DateTime.Now).GetBikesAsync(new Uri("https://shareeapp-fr01.copri.eu//APIjsonserver")); await server.DidNotReceive().GetBikesOccupied(); await server.DidNotReceive().GetBikesOccupied(Arg.Any()); server.DidNotReceive().AddToCache(Arg.Any>(), Arg.Any()); Assert.AreEqual(3, result.Response.Count); Assert.AreEqual(typeof(CopriCallsMonkeyStore), result.Source); Assert.IsNull(result.Exception); } } }