|
| 1 | +from ..weather.constants import WEATHER_CODE_TO_CONDITION, key |
| 2 | +from ..weather.ingest import _parse_hourly |
| 3 | + |
| 4 | + |
| 5 | +HOURLY_FIXTURE = { |
| 6 | + "time": [ |
| 7 | + "2026-04-22T00:00", |
| 8 | + "2026-04-22T01:00", |
| 9 | + "2026-04-23T00:00", |
| 10 | + ], |
| 11 | + "temperature_2m": [45.23, 44.1, 50.0], |
| 12 | + "weather_code": [0, 61, 75], |
| 13 | + "precipitation": [0.0, 0.05, 0.0], |
| 14 | + "relative_humidity_2m": [78, 82, 60], |
| 15 | + "wind_speed_10m": [8.47, 9.2, 5.0], |
| 16 | +} |
| 17 | + |
| 18 | + |
| 19 | +def test_parse_hourly_groups_by_date(): |
| 20 | + by_date = _parse_hourly(HOURLY_FIXTURE) |
| 21 | + assert set(by_date.keys()) == {"2026-04-22", "2026-04-23"} |
| 22 | + assert set(by_date["2026-04-22"].keys()) == {"2026-04-22T00:00", "2026-04-22T01:00"} |
| 23 | + |
| 24 | + |
| 25 | +def test_parse_hourly_record_shape(): |
| 26 | + record = _parse_hourly(HOURLY_FIXTURE)["2026-04-22"]["2026-04-22T00:00"] |
| 27 | + assert record["temperature_f"] == 45.2 |
| 28 | + assert record["weather_code"] == 0 |
| 29 | + assert record["condition"] == "clear" |
| 30 | + assert record["precipitation_in"] == 0.0 |
| 31 | + assert record["humidity_pct"] == 78 |
| 32 | + assert record["wind_mph"] == 8.5 |
| 33 | + |
| 34 | + |
| 35 | +def test_weather_code_mapping(): |
| 36 | + assert WEATHER_CODE_TO_CONDITION[0] == "clear" |
| 37 | + assert WEATHER_CODE_TO_CONDITION[3] == "cloudy" |
| 38 | + assert WEATHER_CODE_TO_CONDITION[45] == "fog" |
| 39 | + assert WEATHER_CODE_TO_CONDITION[63] == "rain" |
| 40 | + assert WEATHER_CODE_TO_CONDITION[75] == "snow" |
| 41 | + assert WEATHER_CODE_TO_CONDITION[95] == "storm" |
| 42 | + |
| 43 | + |
| 44 | +def test_unknown_code_falls_back(): |
| 45 | + fixture = { |
| 46 | + "time": ["2026-04-22T00:00"], |
| 47 | + "temperature_2m": [40.0], |
| 48 | + "weather_code": [999], |
| 49 | + "precipitation": [0.0], |
| 50 | + "relative_humidity_2m": [50], |
| 51 | + "wind_speed_10m": [0.0], |
| 52 | + } |
| 53 | + record = _parse_hourly(fixture)["2026-04-22"]["2026-04-22T00:00"] |
| 54 | + assert record["condition"] == "unknown" |
| 55 | + |
| 56 | + |
| 57 | +def test_merge_preserves_other_hours_and_overwrites_same_hour(): |
| 58 | + existing = { |
| 59 | + "2026-04-22T00:00": {"temperature_f": 40.0, "condition": "clear"}, |
| 60 | + "2026-04-22T01:00": {"temperature_f": 39.0, "condition": "clear"}, |
| 61 | + } |
| 62 | + new = _parse_hourly( |
| 63 | + { |
| 64 | + "time": ["2026-04-22T01:00", "2026-04-22T02:00"], |
| 65 | + "temperature_2m": [41.0, 42.0], |
| 66 | + "weather_code": [61, 2], |
| 67 | + "precipitation": [0.1, 0.0], |
| 68 | + "relative_humidity_2m": [80, 75], |
| 69 | + "wind_speed_10m": [7.0, 6.0], |
| 70 | + } |
| 71 | + )["2026-04-22"] |
| 72 | + |
| 73 | + existing.update(new) |
| 74 | + |
| 75 | + assert existing["2026-04-22T00:00"]["temperature_f"] == 40.0 |
| 76 | + assert existing["2026-04-22T01:00"]["condition"] == "rain" |
| 77 | + assert existing["2026-04-22T01:00"]["temperature_f"] == 41.0 |
| 78 | + assert existing["2026-04-22T02:00"]["condition"] == "cloudy" |
| 79 | + |
| 80 | + |
| 81 | +def test_key_format(): |
| 82 | + assert key("2026-04-22") == "Weather/hourly/2026-04-22.json.gz" |
0 commit comments