93 lines
2.6 KiB
Python
93 lines
2.6 KiB
Python
from __future__ import annotations
|
|
|
|
from datetime import datetime, timezone
|
|
|
|
import pytest
|
|
|
|
from app.ha.exceptions import HaUnexpectedPayloadError
|
|
from app.ha.history import normalize_history_payload
|
|
|
|
|
|
def test_normalize_history_payload_groups_and_sorts_numeric_states() -> None:
|
|
payload = [
|
|
[
|
|
{
|
|
"entity_id": "sensor.temperature",
|
|
"state": "22.5",
|
|
"last_changed": "2026-06-01T12:15:00+00:00",
|
|
},
|
|
{
|
|
"state": "21.0",
|
|
"last_changed": "2026-06-01T12:00:00Z",
|
|
},
|
|
],
|
|
[
|
|
{
|
|
"entity_id": "sensor.humidity",
|
|
"state": 45,
|
|
"last_updated": "2026-06-01T12:00:00+00:00",
|
|
}
|
|
],
|
|
]
|
|
|
|
result = normalize_history_payload(payload)
|
|
|
|
assert [series.entity_id for series in result] == [
|
|
"sensor.humidity",
|
|
"sensor.temperature",
|
|
]
|
|
temperature = result[1]
|
|
assert [point.value for point in temperature.points] == [21.0, 22.5]
|
|
assert temperature.points[0].timestamp == datetime(
|
|
2026, 6, 1, 12, 0, tzinfo=timezone.utc
|
|
)
|
|
|
|
|
|
def test_normalize_history_payload_skips_non_numeric_and_non_finite_states() -> None:
|
|
payload = [
|
|
[
|
|
{
|
|
"entity_id": "sensor.temperature",
|
|
"state": state,
|
|
"last_changed": "2026-06-01T12:00:00+00:00",
|
|
}
|
|
for state in ("unknown", "unavailable", "nan", "inf", "-inf", True, None)
|
|
]
|
|
]
|
|
|
|
assert normalize_history_payload(payload) == []
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"payload",
|
|
[
|
|
{},
|
|
[{}],
|
|
[["invalid"]],
|
|
[[{"entity_id": "invalid", "state": "21", "last_changed": "2026-06-01"}]],
|
|
[[{"entity_id": "sensor.a", "state": "21", "last_changed": "invalid"}]],
|
|
[[{"state": "21", "last_changed": "2026-06-01T12:00:00+00:00"}]],
|
|
[
|
|
[
|
|
{
|
|
"entity_id": "sensor.a",
|
|
"state": "21",
|
|
"last_changed": "2026-06-01T12:00:00+00:00",
|
|
},
|
|
{
|
|
"entity_id": "sensor.b",
|
|
"state": "22",
|
|
"last_changed": "2026-06-01T12:01:00+00:00",
|
|
},
|
|
]
|
|
],
|
|
],
|
|
)
|
|
def test_normalize_history_payload_rejects_malformed_structure(payload: object) -> None:
|
|
with pytest.raises(HaUnexpectedPayloadError):
|
|
normalize_history_payload(payload)
|
|
|
|
|
|
def test_normalize_history_payload_accepts_empty_series() -> None:
|
|
assert normalize_history_payload([[]]) == []
|