using Newtonsoft.Json;
using NUnit.Framework;
using System;
using System.Linq;
using TINK.Model;
using TINK.Model.Bike;
using TINK.Model.Connector;
using TINK.Repository.Response;
using TINK.Model.State;
using TINK.Repository;

using static TINK.Repository.CopriCallsMemory;

using BikeInfo = TINK.Model.Bike.BluetoothLock.BikeInfo;
using TINK.Model.User.Account;
using Xamarin.Forms;
using TINK.Model.MiniSurvey;

namespace TestTINKLib.Fixtures.Connector
{

    [TestFixture]
    public class TestUpdaterJSON
    {
        [Test]
        public void TestGetAllStations()
        {           
            var l_oStationsTarget = UpdaterJSON.GetStationsAllMutable(new CopriCallsMemory(SampleSets.Set2, 1).GetStationsAsync().Result);

            Assert.AreEqual(9, l_oStationsTarget.Count);

            // Check first entry.
            Assert.NotNull(l_oStationsTarget.GetById("4"));
            Assert.AreEqual("TINK", String.Join(",", l_oStationsTarget.GetById("4").Group.ToArray()));
            Assert.AreEqual("4", l_oStationsTarget.GetById("4").Id);
            Assert.AreEqual(47.6586936667, l_oStationsTarget.GetById("4").Position.Latitude);
            Assert.AreEqual(9.16863116667, l_oStationsTarget.GetById("4").Position.Longitude);

            Assert.NotNull(l_oStationsTarget.GetById("14"));
            Assert.AreEqual("Konrad", String.Join(",", l_oStationsTarget.GetById("14").Group.ToArray()));

            Assert.NotNull(l_oStationsTarget.GetById("31"));
            Assert.AreEqual("TINK,Konrad", String.Join(",", l_oStationsTarget.GetById("31").Group.ToArray()));
            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]
        public void TestUpdateBikesAvailable_BikeNr5GetBooked()
        {
            // Bike 5 is availalbe.
            var l_oBikesTarget = UpdaterJSON.GetBikesAvailable(
                GetBikesAvailable(TinkApp.MerchantId, p_eSampleSet: SampleSets.Set2, p_lStageIndex: 1));

            Assert.AreEqual(12, l_oBikesTarget.Count, "Bike 5 is available an must be part of available bikes collection");

            // Verify state of bike 5.
            Assert.NotNull(l_oBikesTarget.GetById("5"));
            Assert.AreEqual("5", l_oBikesTarget.GetById("5").Id);
            Assert.AreEqual(TypeOfBike.Cargo, l_oBikesTarget.GetById("5").TypeOfBike);
            Assert.AreEqual(WheelType.Two, l_oBikesTarget.GetById("5").WheelType);
            Assert.AreEqual(InUseStateEnum.Disposable, l_oBikesTarget.GetById("5").State.Value);
            Assert.IsNull(l_oBikesTarget.GetById("5").State.From); // Sommer/ Winterzeit!
            Assert.IsNull(l_oBikesTarget.GetById("5").State.Code);

            // Bike 5 is reserved.
            // Count of bikes must decrease and bike #5 no more in list of bikes.
            l_oBikesTarget = UpdaterJSON.GetBikesAvailable(
                GetBikesAvailable(TinkApp.MerchantId, p_eSampleSet: SampleSets.Set2, p_lStageIndex: 2));

            Assert.AreEqual(11, l_oBikesTarget.Count, "One bike (nr. 5) got reserved");
            Assert.Null(l_oBikesTarget.GetById("5"), "Bike 5 got requested and must not be part of available bikes collection");

            // Bike 5 is booked.  
            // Count of bikes must decrease and bike #5 no more in list of bikes.
            l_oBikesTarget = UpdaterJSON.GetBikesAvailable(
                GetBikesAvailable(TinkApp.MerchantId, p_eSampleSet: SampleSets.Set2, p_lStageIndex: 3));

            Assert.Null(l_oBikesTarget.GetById("5"), "Bike 5 got booked and must not be part of available bikes collection");
            Assert.IsNull(l_oBikesTarget.GetById("5"));
        }

        [Test]
        public void TestUpdateBikesOccupied_BikeNr5GetBooked()
        {
            var l_oBikesTarget = UpdaterJSON.GetBikesOccupied(
                GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 1),
                "a@B",
                () => new DateTime(2017, 11, 28, 14, 8, 14)); // Date time now for bikes which are reserved

            // Check initial count of bikes.
            Assert.AreEqual(2, l_oBikesTarget.Count);

            // Bike 5 is reserved
            l_oBikesTarget = UpdaterJSON.GetBikesOccupied(
                GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 2),
                "a@B",
                () => new DateTime(2017, 11, 28, 14, 08, 36).Add(new TimeSpan(0, 2, 0))); // Date time now for bikes which are reserved

            Assert.AreEqual(3, l_oBikesTarget.Count, "One bike (nr. 5) got reserved");

            Assert.NotNull(l_oBikesTarget.GetById("5"));
            Assert.AreEqual(InUseStateEnum.Reserved, l_oBikesTarget.GetById("5").State.Value);
            Assert.AreEqual("5", l_oBikesTarget.GetById("5").Id);
            Assert.AreEqual(TypeOfBike.Cargo, l_oBikesTarget.GetById("5").TypeOfBike);
            Assert.AreEqual(WheelType.Two, l_oBikesTarget.GetById("5").WheelType);
            Assert.AreEqual(DateTime.Parse("2017-11-28 14:07:13.745568+01"), l_oBikesTarget.GetById("5").State.From); // Sommer/ Winterzeit!
            Assert.AreEqual("2360", l_oBikesTarget.GetById("5").State.Code);


            // Bike 5 is booked
            l_oBikesTarget = UpdaterJSON.GetBikesOccupied(
                GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 3),
                "a@B",
                () => DateTime.Now);

            Assert.AreEqual(3, l_oBikesTarget.Count, "One bike (nr. 5) got booked");

            Assert.IsNotNull(l_oBikesTarget.GetById("5"));
            Assert.AreEqual(InUseStateEnum.Booked, l_oBikesTarget.GetById("5").State.Value);
            Assert.AreEqual("5", l_oBikesTarget.GetById("5").Id);
            Assert.AreEqual(TypeOfBike.Cargo, l_oBikesTarget.GetById("5").TypeOfBike);
            Assert.AreEqual(WheelType.Two, l_oBikesTarget.GetById("5").WheelType);
            Assert.AreEqual(DateTime.Parse("2017 -11-28 14:08:32.756368+01"), l_oBikesTarget.GetById("5").State.From); // Sommer/ Winterzeit!
            Assert.AreEqual("2360", l_oBikesTarget.GetById("5").State.Code);
        }

        public void TestGetBikesAvailable_BikeNr5GetBooked()
        {
            // Bike 5 is availalbe.
            var l_oBikesTarget = UpdaterJSON.GetBikesAvailable(GetBikesAvailable(TinkApp.MerchantId, p_eSampleSet: SampleSets.Set2, p_lStageIndex: 1));

            Assert.AreEqual(11, l_oBikesTarget.Count, "Bike 5 is available an must be part of available bikes collection");

            // Verify state of bike 5.
            Assert.NotNull(l_oBikesTarget.GetById("5"));
            Assert.AreEqual(5, l_oBikesTarget.GetById("5").Id);
            Assert.AreEqual(TypeOfBike.Cargo, l_oBikesTarget.GetById("5").TypeOfBike);
            Assert.AreEqual(WheelType.Two, l_oBikesTarget.GetById("5").WheelType);
            Assert.AreEqual(InUseStateEnum.Disposable, l_oBikesTarget.GetById("5").State.Value);
            Assert.IsNull(l_oBikesTarget.GetById("5").State.From); // Sommer/ Winterzeit!
            Assert.IsNull(l_oBikesTarget.GetById("5").State.Code);

            // Bike 5 is reserved.
            // Count of bikes must decrease and bike #5 no more in list of bikes.
            l_oBikesTarget = UpdaterJSON.GetBikesAvailable(GetBikesAvailable(TinkApp.MerchantId, p_eSampleSet: SampleSets.Set2, p_lStageIndex: 2));

            Assert.AreEqual(10, l_oBikesTarget.Count, "One bike (nr. 5) got reserved");
            Assert.Null(l_oBikesTarget.GetById("5"), "Bike 5 got requested and must not be part of available bikes collection");

            // Bike 5 is booked.  
            // Count of bikes must decrease and bike #5 no more in list of bikes.
            l_oBikesTarget = UpdaterJSON.GetBikesAvailable(GetBikesAvailable(TinkApp.MerchantId, p_eSampleSet: SampleSets.Set2, p_lStageIndex: 3));

            Assert.Null(l_oBikesTarget.GetById("5"), "Bike 5 got booked and must not be part of available bikes collection");
            Assert.IsNull(l_oBikesTarget.GetById("5"));
        }

        [Test]
        public void TestGetBikesOccupied_BC_BikeNr5GetBooked()
        {
            var bikesTarget = UpdaterJSON.GetBikesOccupied(
                GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 1),
                "a@B",
                () => new DateTime(2017, 11, 28, 14, 8, 14)); // Date time now for bikes which are reserved

            // Check initial count of bikes.
            Assert.AreEqual(2, bikesTarget.Count);

            // Bike 5 is reserved
            bikesTarget = UpdaterJSON.GetBikesOccupied(
                GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 2),
                "a@B",
                () => new DateTime(2017, 11, 28, 14, 08, 36).Add(new TimeSpan(0, 2, 0))); // Date time now for bikes which are reserved

            Assert.AreEqual(3, bikesTarget.Count, "One bike (nr. 5) got reserved");

            Assert.NotNull(bikesTarget.GetById("5"));
            Assert.AreEqual(InUseStateEnum.Reserved, bikesTarget.GetById("5").State.Value);
            Assert.AreEqual("5", bikesTarget.GetById("5").Id);
            Assert.AreEqual("Cargo Long", bikesTarget.GetById("5").Description);
            Assert.AreEqual(TypeOfBike.Cargo, bikesTarget.GetById("5").TypeOfBike);
            Assert.AreEqual(WheelType.Two, bikesTarget.GetById("5").WheelType);
            Assert.AreEqual(DateTime.Parse("2017-11-28 14:07:13.745568+01"), bikesTarget.GetById("5").State.From); // Sommer/ Winterzeit!
            Assert.AreEqual("2360", bikesTarget.GetById("5").State.Code);

            // Bike 5 is booked
            bikesTarget = UpdaterJSON.GetBikesOccupied(
                CopriCallsMemory.GetBikesOccupied("4da3044c8657a04ba60e2eaa753bc51a", SampleSets.Set2, 3),
                "a@B",
                () => DateTime.Now);

            Assert.AreEqual(3, bikesTarget.Count, "One bike (nr. 5) got booked");

            Assert.IsNotNull(bikesTarget.GetById("5"));
            Assert.AreEqual(InUseStateEnum.Booked, bikesTarget.GetById("5").State.Value);
            Assert.AreEqual("5", bikesTarget.GetById("5").Id);
            Assert.AreEqual("Cargo Long", bikesTarget.GetById("5").Description);
            Assert.AreEqual(TypeOfBike.Cargo, bikesTarget.GetById("5").TypeOfBike);
            Assert.AreEqual(WheelType.Two, bikesTarget.GetById("5").WheelType);
            Assert.AreEqual(DateTime.Parse("2017 -11-28 14:08:32.756368+01"), bikesTarget.GetById("5").State.From); // Sommer/ Winterzeit!
            Assert.AreEqual("2360", bikesTarget.GetById("5").State.Code);
        }

        [Test]
        public void TestGetBikesOccupied_Bt_BikeNr5GetBooked()
        {
            var bikesTarget = UpdaterJSON.GetBikesOccupied(
                GetBikesOccupied("5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH", SampleSets.ShareeFr01_Set1, 1),
                "a@B",
                () => new DateTime(2017, 11, 28, 14, 8, 14)); // Date time now for bikes which are reserved

            // Check initial count of bikes.
            Assert.AreEqual(2, bikesTarget.Count);

            // Bike 5 is reserved
            bikesTarget = UpdaterJSON.GetBikesOccupied(
                GetBikesOccupied("5781_d47fc786e740ef77d85a24bcb6f0ff97_oiF2kahH", SampleSets.ShareeFr01_Set1, 2),
                "a@B",
                () => new DateTime(2017, 11, 28, 14, 08, 36).Add(new TimeSpan(0, 2, 0))); // Date time now for bikes which are reserved

            Assert.AreEqual(3, bikesTarget.Count, "One bike (nr. 5) got reserved");

            var btBikeReserved = bikesTarget.GetById("FR_1004") as BikeInfo;
            Assert.NotNull(btBikeReserved);
            Assert.AreEqual(InUseStateEnum.Reserved, bikesTarget.GetById("FR_1004").State.Value);
            Assert.AreEqual("FR_1004", btBikeReserved.Id);
            Assert.AreEqual("Tester-bike Oliver 2", btBikeReserved.Description);
            Assert.That(btBikeReserved.TypeOfBike, Is.Null);
            Assert.That(btBikeReserved.WheelType, Is.Null);
            Assert.AreEqual(DateTime.Parse("2021-07-04 17:46:36.237404+02"), btBikeReserved.State.From); // Sommer/ Winterzeit!
            Assert.That(btBikeReserved.State.Code, Is.EqualTo(string.Empty), "Not needed for bt bikes.");
            Assert.That(btBikeReserved.TariffDescription.FeeEuroPerHour, Is.EqualTo(3));
            Assert.That(btBikeReserved.TariffDescription.MaxFeeEuroPerDay, Is.EqualTo(10));
            Assert.That(btBikeReserved.TariffDescription.Number, Is.EqualTo(5494));
            Assert.That(btBikeReserved.TariffDescription.Name, Is.EqualTo("Tester Basic"));
            Assert.That(btBikeReserved.CurrentStation, Is.EqualTo("FR_103"));
            Assert.That(btBikeReserved.LockInfo.Id, Is.EqualTo(2302373));
            Assert.That(btBikeReserved.OperatorUri.AbsoluteUri, Does.Contain("https://shareeapp-fr01.copri.eu"));
            Assert.That(btBikeReserved.Group.Count, Is.EqualTo(1));
            Assert.That(btBikeReserved.Group.ToArray()[0], Is.EqualTo("FR_300029"));

            // Bike 5 is booked
            var btBikeRented = bikesTarget.GetById("1537") as BikeInfo;

            Assert.IsNotNull(btBikeRented);
            Assert.AreEqual(InUseStateEnum.Booked, btBikeRented.State.Value);
            Assert.AreEqual("1537", btBikeRented.Id);
            Assert.AreEqual("Oliver (Ilockit)", btBikeRented.Description);
            Assert.That(btBikeRented.TypeOfBike, Is.Null);
            Assert.That(btBikeRented.WheelType, Is.Null);
            Assert.AreEqual(DateTime.Parse("2020-10-12 08:38:30.401679+02"), btBikeRented.State.From); // Sommer/ Winterzeit!
            Assert.AreEqual(string.Empty, btBikeRented.State.Code, "Not needed for bt bikes.");
            Assert.That(btBikeRented.TariffDescription.FeeEuroPerHour, Is.EqualTo(2.5));
            Assert.That(btBikeRented.TariffDescription.MaxFeeEuroPerDay, Is.EqualTo(10));
            Assert.That(btBikeRented.TariffDescription.Number, Is.EqualTo(5494));
            Assert.That(btBikeRented.TariffDescription.Name, Is.EqualTo("Tester Basic"));
            Assert.That(btBikeRented.CurrentStation, Is.EqualTo("103"));
            Assert.That(btBikeRented.LockInfo.Id, Is.EqualTo(2200537));
            Assert.That(btBikeRented.OperatorUri.AbsoluteUri, Does.Contain("https://shareeapp-fr01.copri.eu"));
            Assert.That(btBikeRented.Group.Count, Is.EqualTo(1));
            Assert.That(btBikeRented.Group.ToArray()[0], Is.EqualTo("300029"));
        }


        [Test]
        public void TestGetBikesAvailable()
        {
            var l_oBikesTarget = UpdaterJSON.GetBikesAvailable(
                GetBikesAvailable(TinkApp.MerchantId, p_eSampleSet: SampleSets.Set2, p_lStageIndex: 1));

            // Verify count of bikes
            Assert.AreEqual(12, l_oBikesTarget.Count);

            // Verify properties of bike 5
            Assert.NotNull(l_oBikesTarget.GetById("5"));
            Assert.AreEqual("5", l_oBikesTarget.GetById("5").Id);
            Assert.AreEqual("TINK", l_oBikesTarget.GetById("5").Group.ToArray()[0]);
            Assert.AreEqual(TypeOfBike.Cargo, l_oBikesTarget.GetById("5").TypeOfBike);
            Assert.AreEqual(WheelType.Two, l_oBikesTarget.GetById("5").WheelType);
            Assert.AreEqual(InUseStateEnum.Disposable, l_oBikesTarget.GetById("5").State.Value);
            Assert.IsNull(l_oBikesTarget.GetById("5").State.From); // Sommer/ Winterzeit!
            Assert.IsNull(l_oBikesTarget.GetById("5").State.Code);

            // Verify properties of bike 52
            Assert.NotNull(l_oBikesTarget.GetById("52"));
            Assert.AreEqual("52", l_oBikesTarget.GetById("52").Id);
            Assert.AreEqual("Konrad", l_oBikesTarget.GetById("52").Group.ToArray()[0]);
        }

        [Test]
        public void TestGetBikesOccupied()
        {
            var l_oBikesTarget = UpdaterJSON.GetBikesOccupied(
                GetBikesOccupied(TinkApp.MerchantId, SampleSets.Set2, 1),
                "a@b",
                () => DateTime.Now);

            // Verify count of bikes
            Assert.AreEqual(0, l_oBikesTarget.Count);
        }

        [Test]
        public void TestGetBikesAll_BikesAvaialbleResponse()
        {
            var availableResponse = JsonConvert.DeserializeObject<BikesAvailableResponse>(
                @"{
                    ""bikes"" : {
                        ""2352"" : {
                        ""description"" : ""Cargo Long"",
                        ""state"" : ""available"",
                        ""bike"" : ""1"",
                        ""gps"" : { ""latitude"": ""47.669888"", ""longitude"": ""9.167749"" },
                        ""station"" : ""9"",
                        ""system"" : ""Ilockit""
                        },
                        ""2379"" : {
                        ""description"" : ""Cargo Long"",
                        ""state"" : ""available"",
                        ""bike"" : ""19"",
                        ""gps"" : { ""latitude"": ""47.6597846667"", ""longitude"": ""9.177439"" },
                        ""station"" : ""3""
                        }
                   }
                }");

            var bikes = UpdaterJSON.GetBikesAll(
                availableResponse,
                null,
                "Heinz.Mustermann@posteo.de",
                () => DateTime.Now);

            Assert.AreEqual(
                2,
                bikes.Count);

            Assert.AreEqual(
                1,
                bikes.Where(x => x is BikeInfo).Count(),
                "There must be one ILockitBike and one BC bike (BikeInfo class).");
        }
        [Test]
        public void TestGetBikesAll_BikesAvaialbleResponse_InvalidState()
        {
            var availableResponse = JsonConvert.DeserializeObject<BikesAvailableResponse>(
                @"{
                    ""bikes"" : {
                        ""2352"" : {
                        ""description"" : ""Cargo Long"",
                        ""state"" : ""reserved"",
                        ""bike"" : ""1"",
                        ""gps"" : { ""latitude"": ""47.669888"", ""longitude"": ""9.167749"" },
                        ""station"" : ""9""
                        }
                   }
                }");

            var bikes = UpdaterJSON.GetBikesAll(
                availableResponse,
                null,
                "Heinz.Mustermann@posteo.de",
                () => DateTime.Now);

            Assert.AreEqual(
                0, 
                bikes.Count,
                "State of a element of BikesAvailableResponse must never be reserved.");
        }

        [Test]
        public void TestGetBikesAll_BikesAvaialbleResponse_InvalidStation()
        {
            var availableResponse = JsonConvert.DeserializeObject<BikesAvailableResponse>(
                @"{
                    ""bikes"" : {
                        ""2352"" : {
                        ""description"" : ""Cargo Long"",
                        ""state"" : ""available"",
                        ""bike"" : ""1"",
                        ""gps"" : { ""latitude"": ""47.669888"", ""longitude"": ""9.167749"" },
                        ""station"" : """"
                        }
                   }
                }");

            var bikes = UpdaterJSON.GetBikesAll(
                availableResponse,
                null,
                "Heinz.Mustermann@posteo.de",
                () => DateTime.Now);

            Assert.AreEqual(
                0,
                bikes.Count,
                "Station of a element of BikesAvailableResponse must always be defined.");
        }

        [Test]
        public void TestGetBikesAll_BikesAvaialbleResponse_DuplicateId()
        {
            var availableResponse = JsonConvert.DeserializeObject<BikesAvailableResponse>(
                @"{
                    ""bikes"" : {
                        ""2352"" : {
                        ""description"" : ""Cargo Long"",
                        ""state"" : ""available"",
                        ""bike"" : ""1"",
                        ""gps"" : { ""latitude"": ""47.669888"", ""longitude"": ""9.167749"" },
                        ""station"" : ""9""
                        },
                        ""2379"" : {
                        ""description"" : ""Cargo Long"",
                        ""state"" : ""available"",
                        ""bike"" : ""1"",
                        ""gps"" : { ""latitude"": ""47.6597846667"", ""longitude"": ""9.177439"" },
                        ""station"" : ""3""
                        }
                   }
                }");

            var bikes = UpdaterJSON.GetBikesAll(
                availableResponse,
                null,
                "Heinz.Mustermann@posteo.de",
                () => DateTime.Now);

            Assert.AreEqual(
                0,
                bikes.Count,
                "Ids of a elements of BikesAvailableResponse must be unique.");
        }

        [Test]
        public void TestGetBikesAll_BikesReservedOccupiedResponse_InvalidState()
        {
            var reservedOccupiedResponse = JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(
                @"{
                      ""bikes_occupied"" : {
                         ""87785"" : {
                                ""station"" : ""2"",
                            ""state"" : ""available"",
                            ""bike"" : ""20"",
                            ""description"" : ""Cargo Long"",
                            ""start_time"" : ""2017-12-01 22:21:57.740069+01"",
                            ""timeCode"" : ""6603""
                         }
                    }
                 }");

            var bikes = UpdaterJSON.GetBikesAll(
                null,
                reservedOccupiedResponse,
                "Heinz.Mustermann@posteo.de",
                () => DateTime.Now);

            Assert.AreEqual(
                0,
                bikes.Count,
                "State of a element of BikesAvailableResponse must never be reserved.");
        }

        [Test]
        public void TestGetBikesAll_BikesReservedOccupiedResponse_DuplicateId()
        {
            var reservedOccupiedResponse = JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(
                @"{
                      ""bikes_occupied"" : {
                         ""87785"" : {
                                ""station"" : ""2"",
                            ""state"" : ""occupied"",
                            ""bike"" : ""20"",
                            ""description"" : ""Cargo Long"",
                            ""start_time"" : ""2017-12-01 22:21:57.740069+01"",
                            ""timeCode"" : ""6603""
                         },
                         ""87782"" : {
                                ""station"" : ""4"",
                            ""state"" : ""occupied"",
                            ""bike"" : ""20"",
                            ""description"" : ""Cargo Long"",
                            ""start_time"" : ""2017-11-28 13:06:55.147368+01"",
                            ""timeCode"" : ""2931""
                         }
                    }
                 }");

            var bikes = UpdaterJSON.GetBikesAll(
                null,
                reservedOccupiedResponse,
                "Heinz.Mustermann@posteo.de",
                () => DateTime.Now);

            Assert.AreEqual(
                0,
                bikes.Count,
                "Ids of a elements of BikesAvailableResponse must be unique.");
        }

        [Test]
        public void TestGetBikesAll_BikesReservedOccupiedResponse()
        {
            var reservedOccupiedResponse = JsonConvert.DeserializeObject<BikesReservedOccupiedResponse>(
                @"{
                      ""bikes_occupied"" : {
                         ""87785"" : {
                             ""station"" : ""2"",
                            ""state"" : ""occupied"",
                            ""bike"" : ""20"",
                            ""description"" : ""Cargo Long"",
                            ""start_time"" : ""2017-12-01 22:21:57.740069+01"",
                            ""timeCode"" : ""6603"",
                            ""system"" : ""Ilockit""
                         },
                         ""87782"" : {
                            ""station"" : ""4"",
                            ""state"" : ""occupied"",
                            ""bike"" : ""7"",
                            ""description"" : ""Cargo Long"",
                            ""start_time"" : ""2017-11-28 13:06:55.147368+01"",
                            ""timeCode"" : ""2931""
                         }
                    }
                 }");

            var bikes = UpdaterJSON.GetBikesAll(
                null,
                reservedOccupiedResponse,
                "Heinz.Mustermann@posteo.de",
                () => DateTime.Now);

            Assert.AreEqual(
                2,
                bikes.Count,
                "Ids of a elements of BikesAvailableResponse must be unique.");

            Assert.AreEqual(
                1,
                bikes.Where(x => x is BikeInfo).Count(),
                "There must be one ILockitBike and one BC bike (BikeInfo class).");
        }

        [Test]
        public void TestLoad_Reserved_CalculateAuthKeys()
        {
            // Construct requested bike.
            var bike = new TINK.Model.Bike.BluetoothLock.BikeInfoMutable(new BikeInfo(
                "17",
                22,
                new Guid("0000f00d-1212-efde-1523-785fef13d123"),
                new [] { (byte) 1, (byte)3, (byte)4 },
                new [] { (byte)11, (byte)3, (byte)1 },
                new [] { (byte)12, (byte)7, (byte)4 },
                DateTime.Now,
                "a@b",
                "1",
                null,
                null,
                () => DateTime.Now,
                false, /*isDemo*/
                null, /*group*/
                null, /*wheelType*/
                null, /*typeOfBike*/
                null /*description*/));

            var response = JsonConvert.DeserializeObject<BikeInfoReservedOrBooked>(@"
            {
                ""Ilockit_ID"": ""ISHAREIT+0815"",
                ""state"": ""requested"",
                ""start_time"":  ""2018-01-27 17:33:00.989464+01"",
                ""K_seed"": ""[-18, -80, 20, -90, 3, 69, 96, 4, -35, 75, -95, 102, 7, 121, -122, 15]"",
                ""K_u"": ""[99, 104, 120, 121, 63, 99, -10, -110, 94, 70, 15, -112, -6, 101, 117, -90, -113, -54, -90, -95, 0, 0, 0, 0]"",
            }");

            // Update from new auth keys.
            bike.Load(response, "a@b", () => DateTime.Now);

            // Verify that keys are correctly updated.
            Assert.IsTrue(new byte[] { 256 - 18, 256 - 80, 20, 256 - 90, 3, 69, 96, 4, 256 - 35, 75, 256 - 95, 102, 7, 121, 256 - 122, 15 }.SequenceEqual(bike.LockInfo.Seed));
            Assert.IsTrue(new byte[] { 99, 104, 120, 121, 63, 99, 256 - 10, 256 - 110, 94, 70, 15, 256 - 112, 256 - 6, 101, 117, 256-90, 256 - 113, 256 - 54, 256 - 90, 256 - 95, 0, 0, 0, 0 }.SequenceEqual(bike.LockInfo.UserKey));
        }

        [Test]
        public void TestLoad_Booked_CalculateAuthKeys()
        {
            // Construct occupied bike.
            var bike = new TINK.Model.Bike.BluetoothLock.BikeInfoMutable(new BikeInfo(
                "17",
                22,
                new Guid("0000f00d-1212-efde-1523-785fef13d123"),
                new[] { (byte)1, (byte)3, (byte)4 },
                new[] { (byte)11, (byte)3, (byte)1 },
                new[] { (byte)12, (byte)7, (byte)4 },
                DateTime.Now,
                "a@b",
                "1", 
                null /*operator uri*/));

            var response = JsonConvert.DeserializeObject<BikeInfoReservedOrBooked>(@"
            {
                ""Ilockit_ID"": ""ISHAREIT+0815"",
                ""state"": ""occupied"",
                ""start_time"":  ""2018-01-27 17:33:00.989464+01"",
                ""K_seed"": ""[-18, -80, 20, -90, 3, 69, 96, 4, -35, 75, -95, 102, 7, 121, -122, 15]"",
                ""K_u"": ""[99, 104, 120, 121, 63, 99, -10, -110, 94, 70, 15, -112, -6, 101, 117, -90, -113, -54, -90, -95, 0, 0, 0, 0]"",
            }");

            // Update from new auth keys.
            bike.Load(response, "a@b", () => DateTime.Now);

            // Verify that keys are correctly updated.
            Assert.IsTrue(new byte[] { 256 - 18, 256 - 80, 20, 256 - 90, 3, 69, 96, 4, 256 - 35, 75, 256 - 95, 102, 7, 121, 256 - 122, 15 }.SequenceEqual(bike.LockInfo.Seed));
            Assert.IsTrue(new byte[] { 99, 104, 120, 121, 63, 99, 256 - 10, 256 - 110, 94, 70, 15, 256 - 112, 256 - 6, 101, 117, 256 - 90, 256 - 113, 256 - 54, 256 - 90, 256 - 95, 0, 0, 0, 0 }.SequenceEqual(bike.LockInfo.UserKey));
        }

        [Test]
        public void TestLoad_Reserved_DoBook()
        {
            // Construct requested bike.
            var bike = new TINK.Model.Bike.BluetoothLock.BikeInfoMutable(new BikeInfo(
                "17",
                22,
                new Guid("0000f00d-1212-efde-1523-785fef13d123"),
                new[] { (byte)1, (byte)3, (byte)4 },
                new[] { (byte)11, (byte)3, (byte)1 },
                new[] { (byte)12, (byte)7, (byte)4 },
                DateTime.Now,
                "a@b",
                "1",
                null,
                null,
                () => DateTime.Now,
                false, /*isDemo*/
                null, /*group*/
                null, /*wheelType*/
                null, /*typeOfBike*/
                null /*description*/));

            Assert.AreEqual(InUseStateEnum.Reserved, bike.State.Value);

            var response = JsonConvert.DeserializeObject<BikeInfoReservedOrBooked>(@"
            {
                ""Ilockit_ID"": ""ISHAREIT+0815"",
                ""state"": ""occupied"",
                ""start_time"":  ""2018-01-27 17:33:00.989464+01"",
                ""K_seed"": ""[-18, -80, 20, -90, 3, 69, 96, 4, -35, 75, -95, 102, 7, 121, -122, 15]"",
                ""K_u"": ""[99, 104, 120, 121, 63, 99, -10, -110, 94, 70, 15, -112, -6, 101, 117, -90, -113, -54, -90, -95, 0, 0, 0, 0]"",
            }");

            // Update from new auth keys.
            bike.Load(response, "a@b", () => DateTime.Now);

            Assert.AreEqual(InUseStateEnum.Booked, bike.State.Value);
        }

        /// <summary> Verifies loading a default user without special permissions.</summary>
        [Test]
        public void TestGetAccount_DebugLevelNone()
        {
            var response = JsonConvert.DeserializeObject<AuthorizationResponse>(@"
            {
                  ""response_state"" : ""OK: nothing todo "",
                  ""user_group"" : [ ""300029"", ""300001"" ],
                  ""user_id"" : ""ohauff@posteo.de"",
                  ""authcookie"" : ""5781_f172cf59108fe53e7524c841847fee69_oiF2kahH"",
                  ""response"" : ""authorization"",
                  ""copri_version"" : ""4.1.0.0"",
                  ""response_text"" : ""Herzlich willkommen im Fahrradmietsystem"",
                  ""debuglevel"" : ""0"",
                  ""apiserver"" : ""https://shareeapp-fr01.copri.eu""
               }");

            var account = response.GetAccount("merch123", "hallo@welt", "0815");

            Assert.That(
                account.DebugLevel,
                Is.EqualTo(Permissions.None));
        }

        /// <summary> Verifies loading a admin user with all special permissions.</summary>
        [Test]
        public void TestGetAccount_DebugLevelAll()
        {
            var response = JsonConvert.DeserializeObject<AuthorizationResponse>(@"
            {
                  ""response_state"" : ""OK: nothing todo "",
                  ""user_group"" : [ ""300029"", ""300001"" ],
                  ""user_id"" : ""ohauff@posteo.de"",
                  ""authcookie"" : ""5781_f172cf59108fe53e7524c841847fee69_oiF2kahH"",
                  ""response"" : ""authorization"",
                  ""copri_version"" : ""4.1.0.0"",
                  ""response_text"" : ""Herzlich willkommen im Fahrradmietsystem"",
                  ""debuglevel"" : ""1"",
                  ""apiserver"" : ""https://shareeapp-fr01.copri.eu""
               }");

            var account = response.GetAccount("merch123", "hallo@welt", "0815");

            Assert.That(
                account.DebugLevel,
                Is.EqualTo(Permissions.All));
        }

        /// <summary> Verifies loading a admin user with all special permissions.</summary>
        [Test]
        public void TestGetAccount_DebugLevel_Logging()
        {
            var response = JsonConvert.DeserializeObject<AuthorizationResponse>(@"
            {
                  ""response_state"" : ""OK: nothing todo "",
                  ""user_group"" : [ ""300029"", ""300001"" ],
                  ""user_id"" : ""ohauff@posteo.de"",
                  ""authcookie"" : ""5781_f172cf59108fe53e7524c841847fee69_oiF2kahH"",
                  ""response"" : ""authorization"",
                  ""copri_version"" : ""4.1.0.0"",
                  ""response_text"" : ""Herzlich willkommen im Fahrradmietsystem"",
                  ""debuglevel"" : ""64"",
                  ""apiserver"" : ""https://shareeapp-fr01.copri.eu""
               }");

            var account = response.GetAccount("merch123", "hallo@welt", "0815");

            Assert.That(
                account.DebugLevel,
                Is.EqualTo(Permissions.PickLoggingLevel));
        }

        [Test]
        public void TestCreateTariffDescription()
        {
            var tariffDescription = JsonConvertRethrow.DeserializeObject<TariffDescription>(
            @"{
                ""eur_per_hour"" : ""10.50"",
               ""abo_eur_per_month"" : ""920.99"",
               ""free_hours"" : ""1.50"",
               ""number"" : ""5494"",
               ""name"" : ""Tester Basic""
            }");

            Assert.That(
                tariffDescription.Create().Name,
                Is.EqualTo("Tester Basic"));

            Assert.That(
                tariffDescription.Create().Number,
                Is.EqualTo(5494));

            Assert.That(
                tariffDescription.Create().FreeTimePerSession,
                Is.EqualTo(TimeSpan.FromMinutes(90)));

            Assert.That(
                tariffDescription.Create().FeeEuroPerHour,
                Is.EqualTo(10.5));

            Assert.That(
                tariffDescription.Create().AboEuroPerMonth,
                Is.EqualTo(920.99));
        }

        [Test]
        public void TestCreateTariffDescription_Name()
        {
            var tariffDescription = JsonConvertRethrow.DeserializeObject<TariffDescription>(
            @"{
                ""eur_per_hour"" : ""10.50"",
               ""abo_eur_per_month"" : ""920.99"",
               ""free_hours"" : ""1.50"",
               ""number"" : ""5494"",
               ""name"" : ""Tester Basic""
            }");

            Assert.That(
                tariffDescription.Create().Name,
                Is.EqualTo("Tester Basic"));
        }

        [Test]
        public void TestCreateTariffDescription_Number()
        {
            var tariffDescription = JsonConvertRethrow.DeserializeObject<TariffDescription>(
            @"{
                ""eur_per_hour"" : ""10.50"",
               ""abo_eur_per_month"" : ""920.99"",
               ""free_hours"" : ""1.50"",
               ""number"" : ""5494"",
               ""name"" : ""Tester Basic""
            }");

            Assert.That(
                tariffDescription.Create().Number,
                Is.EqualTo(5494));
        }

        [Test]
        public void TestCreateTariffDescription_FreeTimePerSession()
        {
            var tariffDescription = JsonConvertRethrow.DeserializeObject<TariffDescription>(
            @"{
                ""eur_per_hour"" : ""10.50"",
               ""abo_eur_per_month"" : ""920.99"",
               ""free_hours"" : ""1.50"",
               ""number"" : ""5494"",
               ""name"" : ""Tester Basic""
            }");

            Assert.That(
                tariffDescription.Create().FreeTimePerSession,
                Is.EqualTo(TimeSpan.FromMinutes(90)));
        }

        [Test]
        public void TestCreateTariffDescription_FeeEuroPerHour()
        {
            var tariffDescription = JsonConvertRethrow.DeserializeObject<TariffDescription>(
            @"{
                ""eur_per_hour"" : ""10.50"",
               ""abo_eur_per_month"" : ""920.99"",
               ""free_hours"" : ""1.50"",
               ""number"" : ""5494"",
               ""name"" : ""Tester Basic""
            }");

            Assert.That(
                tariffDescription.Create().FeeEuroPerHour,
                Is.EqualTo(10.5));
        }

        [Test]
        public void TestCreateTariffDescription_AboEuroPerMonth()
        {
            var tariffDescription = JsonConvertRethrow.DeserializeObject<TariffDescription>(
            @"{
                ""eur_per_hour"" : ""10.50"",
               ""abo_eur_per_month"" : ""920.99"",
               ""free_hours"" : ""1.50"",
               ""number"" : ""5494"",
               ""name"" : ""Tester Basic""
            }");

            Assert.That(
                tariffDescription.Create().AboEuroPerMonth,
                Is.EqualTo(920.99));
        }

        [Test]
        public void TestCreateTariffDescription_Name_Empty()
        {
            var tariffDescription = JsonConvertRethrow.DeserializeObject<TariffDescription>(
            @"{}");

            Assert.That(
                tariffDescription.Create().Name,
                Is.Null);
        }

        [Test]
        public void TestCreateTariffDescription_Number_Empty()
        {
            var tariffDescription = JsonConvertRethrow.DeserializeObject<TariffDescription>(
            @"{}");

            Assert.That(
                tariffDescription.Create().Number,
                Is.Null);
        }

        [Test]
        public void TestCreateTariffDescription_FreeTimePerSession_Empty()
        {
            var tariffDescription = JsonConvertRethrow.DeserializeObject<TariffDescription>(
            @"{}");

            Assert.That(
                tariffDescription.Create().FreeTimePerSession,
                Is.EqualTo(TimeSpan.Zero));
        }

        [Test]
        public void TestCreateTariffDescription_FeeEuroPerHour_Empty()
        {
            var tariffDescription = JsonConvertRethrow.DeserializeObject<TariffDescription>(
            @"{}");

            Assert.That(
                tariffDescription.Create().FeeEuroPerHour,
                Is.NaN);
        }

        [Test]
        public void TestCreateTariffDescription_AboEuroPerMonth_Empty()
        {
            var tariffDescription = JsonConvertRethrow.DeserializeObject<TariffDescription>(
            @"{}");

            Assert.That(
                tariffDescription.Create().AboEuroPerMonth,
                Is.NaN);
        }

        [Test]
        public void TestCreateTariffDescription_Name_Null()
        {
            Assert.That(
                BikeInfoFactory.Create((TariffDescription)null).Name,
                Is.Null);
        }

        [Test]
        public void TestCreateTariffDescription_Number_Null()
        {
            Assert.That(
                BikeInfoFactory.Create((TariffDescription)null).Number,
                Is.Null);
        }

        [Test]
        public void TestCreateTariffDescription_FreeTimePerSession_Null()
        {
             Assert.That(
                BikeInfoFactory.Create((TariffDescription)null).FreeTimePerSession,
                Is.EqualTo(TimeSpan.Zero));
        }

        [Test]
        public void TestCreateTariffDescription_FeeEuroPerHour_Null()
        {
            Assert.That(
                BikeInfoFactory.Create((TariffDescription)null).FeeEuroPerHour,
                Is.NaN);
        }

        [Test]
        public void TestCreateTariffDescription_AboEuroPerMonth_Null()
        {
             Assert.That(
                BikeInfoFactory.Create((TariffDescription)null).AboEuroPerMonth,
                Is.NaN);
        }

        /// <summary>
        /// COPRI response shortened, part not belonging to user_miniquery discarded.
        /// </summary>
        [Test]
        public void TestCreateMiniSurvey()
        {
            var response = JsonConvert.DeserializeObject<ResponseContainer<ReservationCancelReturnResponse>>(@"
            {
               ""shareejson"" : {
                  ""user_miniquery"" : {
                            ""title"" : ""Bitte unterstützen Sie unsere Begleitforschung"",
                     ""footer"" : ""Herzlichen Dank und viel Spaß bei der nächsten Fahrt!"",
                     ""questions"" : {
                                ""q3"" : {
                                    ""quest_text"" : ""3. Haben Sie Anmerkungen oder Anregungen?"",
                           ""type"" : ""text"",
                           ""query"" : {
                                        ""opt1"" : """"
                           }
                                },
                        ""q1"" : {
                                    ""type"" : ""check_one"",
                           ""quest_text"" : ""1. Was war der Hauptzweck dieser Ausleihe?"",
                           ""query"" : {
                                        ""opt2"" : ""b. Kinderbeförderung"",
                              ""opt5"" : ""e. Ausprobieren"",
                              ""opt4"" : ""d. Freizeit"",
                              ""opt1"" : ""a. Einkauf"",
                              ""opt3"" : ""c. Lastentransport"",
                              ""opt6"" : ""f. Sonstiges""
                           }
                                },
                        ""q2"" : {
                                    ""type"" : ""check_one"",
                           ""quest_text"" : ""2. Welches Verkehrsmittel hätten Sie ansonsten benutzt?"",
                           ""query"" : {
                                        ""opt6"" : ""f. Keines (ich hätte die Fahrt sonst nicht gemacht)"",
                              ""opt3"" : ""c. Bus oder Bahn"",
                              ""opt1"" : ""a. Auto"",
                              ""opt2"" : ""b. Motorrad oder Motorroller"",
                              ""opt7"" : ""g. Sonstige"",
                              ""opt4"" : ""d. Eigenes Fahrrad"",
                              ""opt5"" : ""e. Zu Fuß""
                           }
                                }
                            },
                     ""subtitle"" : ""Ihre drei Antworten werden anonym gespeichert.""
                  },
               }
            }

            ");

            var survey = response.shareejson.Create();
            
            Assert.That(
                survey,
                Is.Not.Null);

            Assert.That(
                survey.Title,
                Is.EqualTo("Bitte unterstützen Sie unsere Begleitforschung"));

            Assert.That(
                survey.Subtitle,
                Is.EqualTo("Ihre drei Antworten werden anonym gespeichert."));

            Assert.That(
                survey.Footer,
                Is.EqualTo("Herzlichen Dank und viel Spaß bei der nächsten Fahrt!"));

            Assert.That(
                survey.Questions.Count,
                Is.EqualTo(3));
        }

        /// <summary>
        /// COPRI response shortened, part not belonging to user_miniquery discarded.
        /// </summary>
        [Test]
        public void TestCreateMiniSurvey_Null()
        {
            var response = JsonConvert.DeserializeObject<ResponseContainer<ReservationCancelReturnResponse>>(@"
            {
               ""shareejson"" : {
               }
            }

            ");

            var survey = response.shareejson.Create();

            Assert.That(
                survey,
                Is.Not.Null);

            Assert.That(
                survey.Title,
                Is.Null);

            Assert.That(
                survey.Subtitle,
                Is.Null);

            Assert.That(
                survey.Footer,
                Is.Null);
        }

        /// <summary>
        /// COPRI response shortened, part not belonging to user_miniquery discarded.
        /// </summary>
        [Test]
        public void TestCreateMiniSurvey_EmptyQuery()
        {
            var response = JsonConvert.DeserializeObject<ResponseContainer<ReservationCancelReturnResponse>>(@"
            {
               ""shareejson"" : {
                  ""user_miniquery"" : {
                  },
               }
            }

            ");

            var survey = response.shareejson.Create();

            Assert.That(
                survey,
                Is.Not.Null);

            Assert.That(
                survey.Title,
                Is.Null);

            Assert.That(
                survey.Subtitle,
                Is.Null);

            Assert.That(
                survey.Footer,
                Is.Null);
        }

        /// <summary>
        /// COPRI response shortened, part not belonging to user_miniquery discarded.
        /// </summary>
        [Test]
        public void TestCreateMiniSurvey_InvalidQuestion_KeyNull()
        {
            var response = JsonConvert.DeserializeObject<ResponseContainer<ReservationCancelReturnResponse>>(@"
            {
               ""shareejson"" : {
                  ""user_miniquery"" : {
                            ""title"" : ""Bitte unterstützen Sie unsere Begleitforschung"",
                     ""footer"" : ""Herzlichen Dank und viel Spaß bei der nächsten Fahrt!"",
                     ""questions"" : {
                        """" : {
                                    ""type"" : ""check_one"",
                           ""quest_text"" : ""1. Was war der Hauptzweck dieser Ausleihe?"",
                           ""query"" : {
                                        ""opt2"" : ""b. Kinderbeförderung"",
                              ""opt5"" : ""e. Ausprobieren"",
                              ""opt4"" : ""d. Freizeit"",
                              ""opt1"" : ""a. Einkauf"",
                              ""opt3"" : ""c. Lastentransport"",
                              ""opt6"" : ""f. Sonstiges""
                           }
                                },
                            },
                     ""subtitle"" : ""Ihre drei Antworten werden anonym gespeichert.""
                  },
               }
            }

            ");

            var survey = response.shareejson.Create();

            Assert.That(
                survey,
                Is.Not.Null);

            Assert.That(
                survey.Questions.Count,
                Is.EqualTo(0));
        }

        /// <summary>
        /// COPRI response shortened, part not belonging to user_miniquery discarded.
        /// </summary>
        [Test]
        public void TestCreateMiniSurvey_InvalidQuestion_ValueNull()
        {
            var response = JsonConvert.DeserializeObject<ResponseContainer<ReservationCancelReturnResponse>>(@"
            {
               ""shareejson"" : {
                  ""user_miniquery"" : {
                            ""title"" : ""Bitte unterstützen Sie unsere Begleitforschung"",
                     ""footer"" : ""Herzlichen Dank und viel Spaß bei der nächsten Fahrt!"",
                     ""questions"" : {
                        ""q1"" : {
                                },
                            },
                     ""subtitle"" : ""Ihre drei Antworten werden anonym gespeichert.""
                  },
               }
            }

            ");

            var survey = response.shareejson.Create();

            Assert.That(
                survey,
                Is.Not.Null);

            Assert.That(
                survey.Questions.Count,
                Is.EqualTo(0));
        }
    }
}