Make most types serializable

This commit is contained in:
Jules 2025-05-13 20:35:22 +02:00
parent 9b1752c096
commit 7efc8170c5
Signed by: jdejaegh
GPG key ID: 99D6D184CA66933A
8 changed files with 68 additions and 12 deletions

View file

@ -1,6 +1,6 @@
"""Data classes for IRM KMI integration"""
from datetime import datetime
from enum import Enum
from enum import StrEnum
from typing import List, Required, TypedDict
@ -36,7 +36,7 @@ class Forecast(TypedDict, total=False):
is_daytime: bool | None # Mandatory to use with forecast_twice_daily
class ConditionEvol(Enum):
class ConditionEvol(StrEnum):
"""Possible state for evolution between weather conditions"""
ONE_WAY = 'one_way'
@ -44,7 +44,7 @@ class ConditionEvol(Enum):
STABLE = 'stable'
class RadarStyle(Enum):
class RadarStyle(StrEnum):
"""Possible style for the rain radar"""
OPTION_STYLE_STD = 'standard_style'
@ -53,7 +53,7 @@ class RadarStyle(Enum):
OPTION_STYLE_SATELLITE = 'satellite_style'
class PollenName(Enum):
class PollenName(StrEnum):
ALDER = 'alder'
ASH = 'ash'
BIRCH = 'birch'
@ -63,7 +63,7 @@ class PollenName(Enum):
OAK = 'oak'
class PollenLevel(Enum):
class PollenLevel(StrEnum):
"""Possible pollen levels"""
NONE = 'none'
@ -74,7 +74,7 @@ class PollenLevel(Enum):
RED = 'red'
PURPLE = 'purple'
class WarningType(Enum):
class WarningType(StrEnum):
"""Possible warning types"""
COLD = 'cold'

View file

@ -21,3 +21,15 @@ def get_api_with_data(fixture: str) -> IrmKmiApiClientHa:
api = IrmKmiApiClientHa(session=MagicMock(), user_agent='', cdt_map=IRM_KMI_TO_HA_CONDITION_MAP)
api._api_data = get_api_data(fixture)
return api
def is_serializable(x):
try:
json.dumps(x)
return True
except (TypeError, OverflowError):
return False
def assert_all_serializable(elements: list):
for element in elements:
for v in element.values():
assert is_serializable(v)

View file

@ -5,7 +5,7 @@ import pytest
from freezegun import freeze_time
from irm_kmi_api import CurrentWeatherData
from tests.conftest import get_api_data, get_api_with_data
from tests.conftest import get_api_data, get_api_with_data, is_serializable
from irm_kmi_api.const import ATTR_CONDITION_CLOUDY, ATTR_CONDITION_PARTLYCLOUDY
@ -140,3 +140,10 @@ def test_current_weather_attributes(
assert r == expected_
run(sensor, expected)
@freeze_time(datetime.fromisoformat('2023-12-26T17:30:00+00:00'))
def test_current_weather_is_serializable() -> None:
api = get_api_with_data("forecast.json")
tz = ZoneInfo("Europe/Brussels")
result = api.get_current_weather(tz)
assert is_serializable(result)

View file

@ -4,7 +4,7 @@ from zoneinfo import ZoneInfo
from freezegun import freeze_time
from irm_kmi_api import ConditionEvol, ExtendedForecast
from tests.conftest import get_api_with_data
from tests.conftest import get_api_with_data, assert_all_serializable
from irm_kmi_api.const import ATTR_CONDITION_PARTLYCLOUDY
@ -106,3 +106,11 @@ async def test_sunrise_sunset_be() -> None:
assert result[2]['sunrise'] == '2023-12-28T08:45:00+01:00'
assert result[2]['sunset'] == '2023-12-28T16:43:00+01:00'
def test_daily_serializable() -> None:
api = get_api_with_data("forecast.json")
tz = ZoneInfo("Europe/Brussels")
result = api.get_daily_forecast(tz, 'fr')
assert_all_serializable(result)

View file

@ -4,7 +4,7 @@ from zoneinfo import ZoneInfo
from freezegun import freeze_time
from irm_kmi_api import Forecast
from tests.conftest import get_api_with_data
from tests.conftest import get_api_with_data, assert_all_serializable
from irm_kmi_api.const import ATTR_CONDITION_CLOUDY, ATTR_CONDITION_RAINY
@ -88,4 +88,10 @@ def test_hourly_forecast_midnight_bug() -> None:
assert result[24]['datetime'] == '2024-06-01T00:00:00+02:00'
def test_hourly_serializable() -> None:
api = get_api_with_data("forecast.json")
tz = ZoneInfo("Europe/Brussels")
result = api.get_hourly_forecast(tz)
assert_all_serializable(result)

View file

@ -1,7 +1,7 @@
from unittest.mock import AsyncMock
from irm_kmi_api import PollenLevel, PollenName, PollenParser
from tests.conftest import get_api_with_data, load_fixture
from tests.conftest import get_api_with_data, load_fixture, is_serializable
def test_svg_pollen_parsing():
@ -76,3 +76,9 @@ async def test_pollen_data_from_api() -> None:
PollenName.HAZEL: PollenLevel.NONE}
assert result == expected
def test_pollen_is_serializable():
with open("tests/fixtures/pollens-2025.svg", "r") as file:
svg_data = file.read()
data = PollenParser(svg_data).get_pollen_data()
assert is_serializable(data)

View file

@ -1,7 +1,7 @@
import pytest
from irm_kmi_api import RadarForecast
from tests.conftest import get_api_with_data
from tests.conftest import get_api_with_data, assert_all_serializable
def test_radar_forecast() -> None:
@ -78,3 +78,10 @@ async def test_current_rainfall_unit(
for r in radar_forecast:
assert r.get('unit') == expected
def test_radar_serializable() -> None:
api = get_api_with_data("forecast.json")
result = api.get_radar_forecast()
assert_all_serializable(result)

View file

@ -3,7 +3,7 @@ from datetime import datetime
from freezegun import freeze_time
from irm_kmi_api import WarningType
from tests.conftest import get_api_with_data
from tests.conftest import get_api_with_data, is_serializable
@freeze_time(datetime.fromisoformat('2024-01-12T07:10:00+00:00'))
@ -23,3 +23,13 @@ async def test_warning_data() -> None:
assert first.get('friendly_name') == 'Fog'
assert first.get('id') == 7
assert first.get('level') == 1
async def test_warning_data_is_serializable() -> None:
api = get_api_with_data("be_forecast_warning.json")
result = api.get_warnings(lang='en')
for r in result:
del r["starts_at"]
del r["ends_at"]
assert is_serializable(r)