public void Serialize_OpenW_onecall()
        {
            var filename = "./Resources/OpenW_onecall_SI.json";
            var client   = new WeatherServiceBase_Wrapper();

            ForecastDSL input = null;

            using (var jsonStream = File.OpenRead(filename)) {
                input = client.ParseJsonFromStream_Wrapper <ForecastDSL>(jsonStream, new MyAlertConverter());
            }

            string outputJson = null;

            using (var sw = new StringWriter())
                using (var jw = new JsonTextWriter(sw)) {
                    var serializer = new JsonSerializer();
                    serializer.NullValueHandling = NullValueHandling.Ignore;
                    serializer.ContractResolver  = new DefaultContractResolver {
                        NamingStrategy = new CamelCaseNamingStrategy()
                    };
                    //serializer.Formatting = Formatting.Indented;
                    serializer.Converters.Add(new MyAlertConverter());
                    serializer.Serialize(jw, input);
                    outputJson = sw.ToString();
                }
            outputJson.ShouldNotBeNullOrWhiteSpace();
            outputJson[0].ShouldBe('{');
            outputJson[outputJson.Length - 1].ShouldBe('}');
        }
        /// <summary>
        ///     if there is more info on the daily data, copy it on Currently
        /// </summary>
        private ForecastDSL PatchReturnedData(ForecastDSL forecast)
        {
            // check if there is more info on the daily data. If not return the input
            DataPointDSL sameDay = null;

            if ((forecast.Daily?.Count ?? 0) > 0)
            {
                sameDay = forecast.Daily.FirstOrDefault(d =>
                                                        (d.SunriseTime != null) &&
                                                        (d.SunriseTime.Value.Date.Equals(forecast.Currently.Time.Date)));
            }
            if (sameDay == null)
            {
                return(forecast);
            }

            // if there are more info on the daily data, copy it on output.Currently

            var currently = forecast.Currently;

            //if (string.IsNullOrEmpty(currently.Description)) currently.Description = sameDay.Description;
            //if (string.IsNullOrEmpty(currently.Summary)) currently.Summary = sameDay.Summary;
            //if (string.IsNullOrEmpty(currently.Icon)) currently.Icon = sameDay.Icon;

            if (!currently.Temperature.Daily.HasValue)
            {
                currently.Temperature.Daily = sameDay.Temperature.Daily;
            }
            if (!currently.Temperature.DewPoint.HasValue)
            {
                currently.Temperature.DewPoint = sameDay.Temperature.DewPoint;
            }
            if (!currently.Temperature.Evening.HasValue)
            {
                currently.Temperature.Evening = sameDay.Temperature.Evening;
            }
            if (!currently.Temperature.Max.HasValue)
            {
                currently.Temperature.Max = sameDay.Temperature.Max;
            }
            if (!currently.Temperature.Min.HasValue)
            {
                currently.Temperature.Min = sameDay.Temperature.Min;
            }
            if (!currently.Temperature.Morning.HasValue)
            {
                currently.Temperature.Morning = sameDay.Temperature.Morning;
            }
            if (!currently.Temperature.Night.HasValue)
            {
                currently.Temperature.Night = sameDay.Temperature.Night;
            }
            if (!currently.Temperature.Humidity.HasValue)
            {
                currently.Temperature.Humidity = sameDay.Temperature.Humidity;
            }
            if (!currently.Temperature.Pressure.HasValue)
            {
                currently.Temperature.Pressure = sameDay.Temperature.Pressure;
            }

            if (!currently.ApparentTemperature.Daily.HasValue)
            {
                currently.ApparentTemperature.Daily = sameDay.ApparentTemperature.Daily;
            }
            if (!currently.ApparentTemperature.DewPoint.HasValue)
            {
                currently.ApparentTemperature.DewPoint = sameDay.ApparentTemperature.DewPoint;
            }
            if (!currently.ApparentTemperature.Evening.HasValue)
            {
                currently.ApparentTemperature.Evening = sameDay.ApparentTemperature.Evening;
            }
            if (!currently.ApparentTemperature.Max.HasValue)
            {
                currently.ApparentTemperature.Max = sameDay.ApparentTemperature.Max;
            }
            if (!currently.ApparentTemperature.Min.HasValue)
            {
                currently.ApparentTemperature.Min = sameDay.ApparentTemperature.Min;
            }
            if (!currently.ApparentTemperature.Morning.HasValue)
            {
                currently.ApparentTemperature.Morning = sameDay.ApparentTemperature.Morning;
            }
            if (!currently.ApparentTemperature.Night.HasValue)
            {
                currently.ApparentTemperature.Night = sameDay.ApparentTemperature.Night;
            }
            if (!currently.ApparentTemperature.Humidity.HasValue)
            {
                currently.ApparentTemperature.Humidity = sameDay.ApparentTemperature.Humidity;
            }
            if (!currently.ApparentTemperature.Pressure.HasValue)
            {
                currently.ApparentTemperature.Pressure = sameDay.ApparentTemperature.Pressure;
            }

            return(forecast);
        }
        public async void GetForecastDSL_ByCoordinates_Test()
        {
            // prepare SI
            ForecastDSL output = null;

            using (var stream = new BufferedStream(File.OpenRead("./Resources/OpenW_onecall_SI.json"), 8192)) {
                var mockHttp = new MockHttpMessageHandler();
                mockHttp
                .When(OpenWeatherService.EndPointRoot + "*")
                .Respond("application/json", stream);
                IOpenWeatherService client = new OpenWeatherService("12345", mockHttp);

                output = await client.GetForecastDSL(BolognaLatitude, BolognaLongitude, OWUnit.Metric, Language.Italian);

                stream.Close();
            }
            // assert
            output.ShouldNotBeNull();
            output.Coordinates.Latitude.ShouldBe(44.47);
            output.Coordinates.Longitude.ShouldBe(11.43);
            output.TimeZone.ShouldBe("Europe/Rome");
            output.TimeZoneOffset.ShouldBe(3600);

            output.Currently.ShouldNotBeNull();
            output.Currently.Time.ToUnixTimeSeconds().ShouldBe(1609711216L);
            output.Currently.Wind.Speed.ShouldBe(1.5f);
            output.Currently.Wind.Bearing.ShouldBe(260);
            output.Currently.Visibility.ShouldBe(10000);
            output.Currently.Rain.ShouldBe(0.24f);
            output.Currently.Snow.ShouldBe(1.01f);
            output.Currently.ProbOfPrecipitation.ShouldBeNull();
            output.Currently.SunriseTime.Value.ToUnixTimeSeconds().ShouldBe(1609656638);
            output.Currently.SunsetTime.Value.ToUnixTimeSeconds().ShouldBe(1609688798);
            //output.Current.SunriseTime.ShouldBe(((int)1609656638).ToDateTimeOffset());
            output.Currently.SunriseTime.ShouldBe(new DateTime(2021, 01, 03, 6, 50, 38, DateTimeKind.Utc));;
            output.Currently.SunsetTime.Value.ShouldBeGreaterThan(output.Currently.SunriseTime.Value);
            output.Currently.Temperature.Daily.ShouldBe(4.14f);
            output.Currently.Temperature.DewPoint.ShouldBe(4.11f);
            output.Currently.ApparentTemperature.Daily.ShouldBe(1.8f);
            output.Currently.Temperature.Humidity.ShouldBe(100);
            output.Currently.Temperature.Pressure.ShouldBe(1010);

            output.Hourly.Count.ShouldBe(48);
            output.Hourly[0].Visibility.ShouldBe(10000);
            output.Hourly[0].Rain.ShouldBe(0.24f);
            output.Hourly[0].ProbOfPrecipitation.ShouldBe(0.3f);
            output.Hourly[0].Temperature.Daily.ShouldBe(4.14f);
            output.Hourly[0].Temperature.DewPoint.ShouldBe(4.11f);
            output.Hourly[0].Temperature.Min.ShouldBeNull();
            output.Hourly[0].Temperature.Max.ShouldBeNull();
            output.Hourly[0].Temperature.Night.ShouldBeNull();
            output.Hourly[0].Temperature.Morning.ShouldBeNull();
            output.Hourly[0].Temperature.Humidity.ShouldBe(100);
            output.Hourly[0].Temperature.Pressure.ShouldBe(1010);
            output.Hourly[0].ApparentTemperature.Daily.ShouldBe(1.7f);
            output.Hourly[0].ApparentTemperature.Min.ShouldBeNull();
            output.Hourly[0].ApparentTemperature.Max.ShouldBeNull();
            output.Hourly[0].ApparentTemperature.Night.ShouldBeNull();
            output.Hourly[0].ApparentTemperature.Morning.ShouldBeNull();
            output.Hourly[0].Temperature.Humidity.ShouldBe(100);

            output.Daily.Count.ShouldBe(8);
            output.Daily[0].Visibility.ShouldBeNull();
            output.Daily[0].Rain.ShouldBe(0.58f);
            output.Daily[0].Snow.ShouldBe(0.99f);
            output.Daily[0].ProbOfPrecipitation.ShouldBe(0.6f);
            output.Daily[0].UVIndex.ShouldBe(0.94f);
            output.Daily[0].Temperature.Daily.ShouldBe(9.5f);
            output.Daily[0].Temperature.Night.ShouldBe(4.16f);
            output.Daily[0].Temperature.Evening.ShouldBe(6.87f);
            output.Daily[0].Temperature.Morning.ShouldBe(5.93f);
            output.Daily[0].Temperature.Min.ShouldBe(4.14f);
            output.Daily[0].Temperature.Max.ShouldBe(9.5f);
            output.Daily[0].Temperature.Humidity.ShouldBe(74);
            output.Daily[0].Temperature.Pressure.ShouldBe(1009);
            output.Daily[0].Temperature.DewPoint.ShouldBe(4.83f);
            output.Daily[0].ApparentTemperature.Daily.ShouldBe(7.3f);
            output.Daily[0].ApparentTemperature.Night.ShouldBe(1.7f);
            output.Daily[0].ApparentTemperature.Evening.ShouldBe(5.18f);
            output.Daily[0].ApparentTemperature.Morning.ShouldBe(2.8f);
            output.Daily[0].ApparentTemperature.Min.ShouldBeNull();
            output.Daily[0].ApparentTemperature.Max.ShouldBeNull();

            output.Alerts.ShouldNotBeNull();
            output.Alerts.Count.ShouldBe(2);
            output.Alerts[0].Sender.ShouldBe("NWS Tulsa (Eastern Oklahoma)");
            output.Alerts[0].Title.ShouldBe("Heat Advisory");
            output.Alerts[0].StartTime.ToUnixTimeSeconds().ShouldBe(1597341600);
            output.Alerts[0].ExpiresTime.ToUnixTimeSeconds().ShouldBe(1597366800);
            output.Alerts[0].Description.ShouldStartWith("...HEAT ADVISORY REMAINS IN EFFECT");
            output.Alerts[0].Severity.ShouldBe(Severity.Unknown);

            output.Alerts[1].Sender.ShouldBe("Second sender name");
            output.Alerts[1].Title.ShouldBe("Cold Advisory");
            output.Alerts[1].Description.ShouldBe("...Test\nWeather\nCondition.");

            //// prepare imperial
            //var outputImperial = await client.GetForecastDSL(BolognaLatitude, BolognaLongitude, OWUnit.Imperial, Language.English);
            //// assert
            //outputImperial.Coordinates.Latitude.ShouldBe(output.Coordinates.Latitude);
            //outputImperial.Coordinates.Longitude.ShouldBe(output.Coordinates.Longitude);
            //outputImperial.Currently.Temperature.Daily.ShouldNotBeNull();
            //outputImperial.Currently.Temperature.Daily.Value.ShouldBeGreaterThan(output.Currently.Temperature.Daily.Value);
            //outputImperial.Currently.Wind.Speed.ShouldNotBe(output.Currently.Wind.Speed);
            //outputImperial.Currently.Wind.Bearing.ShouldBe(output.Currently.Wind.Bearing);
        }