25#include <gtest/gtest.h>
26#include <gmock/gmock.h>
30#ifdef _USE_SYSTEM_JSONLIB
31#include <nlohmann/json.hpp>
57 std::string validResponse = R
"({
60 "status_message": "SUCCESS"
65 "name": "Test Station",
80 json stationData = json::parse(validResponse);
82 EXPECT_EQ(stationData[
"status"][
"status_code"], 0);
83 EXPECT_EQ(stationData[
"stations"][0][
"station_id"], 12345);
84 EXPECT_EQ(stationData[
"stations"][0][
"devices"][0][
"device_id"], 67890);
90 std::string validResponse = R
"({
93 "status_message": "SUCCESS"
97 "air_temperature": 22.5,
98 "relative_humidity": 65.2,
99 "barometric_pressure": 1013.25,
102 "wind_direction": 180.0,
103 "precip_accum_local_day": 0.0,
105 "solar_radiation": 450.0,
111 json obsData = json::parse(validResponse);
113 EXPECT_EQ(obsData["status"][
"status_code"], 0);
114 EXPECT_EQ(obsData[
"obs"][0][
"air_temperature"], 22.5);
115 EXPECT_EQ(obsData[
"obs"][0][
"relative_humidity"], 65.2);
116 EXPECT_EQ(obsData[
"obs"][0][
"wind_avg"], 5.2);
122 std::string errorResponse = R
"({
125 "status_message": "Invalid API key"
129 json errorData = json::parse(errorResponse);
131 EXPECT_EQ(errorData["status"][
"status_code"], 401);
132 EXPECT_EQ(errorData[
"status"][
"status_message"],
"Invalid API key");
138 std::string malformedResponse = R
"({
141 "status_message": "SUCCESS"
145 "air_temperature": "invalid_value",
146 "relative_humidity": 65.2
151 json obsData = json::parse(malformedResponse);
154 auto extractDouble = [&obsData](
const std::string & key,
double defaultValue = 0.0) ->
double
156 if (obsData[
"obs"][0].contains(key) && !obsData[
"obs"][0][key].
is_null())
160 return obsData[
"obs"][0][key].
get<
double>();
170 EXPECT_EQ(extractDouble(
"air_temperature"), 0.0);
171 EXPECT_EQ(extractDouble(
"relative_humidity"), 65.2);
172 EXPECT_EQ(extractDouble(
"nonexistent_field"), 0.0);
181 double windSpeed = 15.0;
182 double pressure = 1013.0;
193 EXPECT_GE(windSpeed, 0.0);
194 EXPECT_LE(windSpeed, 30.0);
197 EXPECT_GE(pressure, 800.0);
198 EXPECT_LE(pressure, 1200.0);
204 const int RATE_LIMIT_REQUESTS = 1000;
205 const int RATE_LIMIT_PERIOD = 3600;
207 int requestCount = 0;
208 auto lastRequestTime = std::chrono::system_clock::now();
209 auto now = std::chrono::system_clock::now();
212 auto timeSinceLastRequest = std::chrono::duration_cast<std::chrono::seconds>(now - lastRequestTime).count();
214 if (timeSinceLastRequest >= RATE_LIMIT_PERIOD)
217 lastRequestTime = now;
220 EXPECT_LT(requestCount, RATE_LIMIT_REQUESTS);
226 std::vector<int> expectedDelays = {1, 2, 4, 8, 16};
228 for (
int attempt = 0; attempt < 5; ++attempt)
230 int delaySeconds = (1 << attempt);
231 EXPECT_EQ(delaySeconds, expectedDelays[attempt]);
263 std::map<std::string, std::string> fieldMapping =
265 {
"air_temperature",
"WEATHER_TEMPERATURE"},
266 {
"relative_humidity",
"WEATHER_HUMIDITY"},
267 {
"barometric_pressure",
"WEATHER_PRESSURE"},
268 {
"wind_avg",
"WEATHER_WIND_SPEED"},
269 {
"wind_gust",
"WEATHER_WIND_GUST"},
270 {
"wind_direction",
"WEATHER_WIND_DIRECTION"},
271 {
"precip_accum_local_day",
"WEATHER_RAIN_HOUR"},
272 {
"precip_rate",
"WEATHER_RAIN_RATE"},
273 {
"solar_radiation",
"WEATHER_SOLAR_RADIATION"},
277 for (
const auto &mapping : fieldMapping)
279 EXPECT_FALSE(mapping.first.empty());
280 EXPECT_FALSE(mapping.second.empty());
287 std::vector<std::string> criticalParams =
289 "WEATHER_TEMPERATURE",
292 "WEATHER_WIND_SPEED",
298 for (
const auto ¶m : criticalParams)
300 EXPECT_FALSE(param.empty());
306 ::testing::InitGoogleTest(&argc, argv);
307 return RUN_ALL_TESTS();
std::unique_ptr< WeatherFlow > weatherFlow
a class to store JSON values
constexpr bool is_null() const noexcept
return whether value is null
auto get() const noexcept(noexcept(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))) -> decltype(std::declval< const basic_json_t & >().template get_impl< ValueType >(detail::priority_tag< 4 > {}))
get a (pointer) value (explicit)
general exception of the basic_json class
basic_json<> json
default specialization
TEST_F(WeatherFlowTest, ParseValidStationResponse)
std::unique_ptr< WeatherFlow > weatherFlow(new WeatherFlow())