hass.tibber_prices/tests/test_services_enrich.py
2025-11-03 00:32:27 +00:00

123 lines
4.2 KiB
Python

"""Test that min/max/average include enriched attributes."""
from datetime import UTC, datetime
import pytest
from custom_components.tibber_prices.services import _get_price_stat, _get_price_stats
# Constants for service enrichment tests
PRICE_MIN = 0.15
PRICE_MID = 0.25
PRICE_MAX = 0.35
PRICE_MINOR_MIN = 15
PRICE_MINOR_MID = 25
PRICE_MINOR_MAX = 35
DIFF_MIN = -10.5
DIFF_MID = 5.0
DIFF_MAX = 25.3
DIFF_MIN_LOW = -15.0
DIFF_MID_ZERO = 0.0
PRICE_LOW = 0.10
PRICE_HIGH = 0.20
def test_min_max_intervals_include_enriched_attributes() -> None:
"""Test that min/max intervals contain difference and rating_level."""
merged = [
{
"start_time": "2025-11-01T00:00:00+01:00",
"end_time": "2025-11-01T01:00:00+01:00",
"start_dt": datetime(2025, 11, 1, 0, 0, tzinfo=UTC),
"price": PRICE_MIN,
"price_minor": PRICE_MINOR_MIN,
"difference": DIFF_MIN,
"rating_level": "LOW",
"level": "VERY_CHEAP",
},
{
"start_time": "2025-11-01T01:00:00+01:00",
"end_time": "2025-11-01T02:00:00+01:00",
"start_dt": datetime(2025, 11, 1, 1, 0, tzinfo=UTC),
"price": PRICE_MID,
"price_minor": PRICE_MINOR_MID,
"difference": DIFF_MID,
"rating_level": "NORMAL",
"level": "NORMAL",
},
{
"start_time": "2025-11-01T02:00:00+01:00",
"end_time": "2025-11-01T03:00:00+01:00",
"start_dt": datetime(2025, 11, 1, 2, 0, tzinfo=UTC),
"price": PRICE_MAX,
"price_minor": PRICE_MINOR_MAX,
"difference": DIFF_MAX,
"rating_level": "HIGH",
"level": "EXPENSIVE",
},
]
stats = _get_price_stats(merged)
# Verify min interval has all attributes
assert stats.price_min == PRICE_MIN # noqa: S101
assert stats.price_min_interval is not None # noqa: S101
assert stats.price_min_interval["difference"] == DIFF_MIN # noqa: S101
assert stats.price_min_interval["rating_level"] == "LOW" # noqa: S101
assert stats.price_min_interval["level"] == "VERY_CHEAP" # noqa: S101
# Verify max interval has all attributes
assert stats.price_max == PRICE_MAX # noqa: S101
assert stats.price_max_interval is not None # noqa: S101
assert stats.price_max_interval["difference"] == DIFF_MAX # noqa: S101
assert stats.price_max_interval["rating_level"] == "HIGH" # noqa: S101
assert stats.price_max_interval["level"] == "EXPENSIVE" # noqa: S101
# Verify average price is calculated
assert stats.price_avg == pytest.approx( # noqa: S101
(PRICE_MIN + PRICE_MID + PRICE_MAX) / 3, rel=1e-4
)
def test_get_price_stat_returns_full_interval() -> None:
"""Test that _get_price_stat returns the complete interval dict."""
merged = [
{
"start_time": "2025-11-01T00:00:00+01:00",
"price": PRICE_LOW,
"difference": DIFF_MIN_LOW,
"rating_level": "LOW",
},
{
"start_time": "2025-11-01T01:00:00+01:00",
"price": PRICE_HIGH,
"difference": DIFF_MID_ZERO,
"rating_level": "NORMAL",
},
]
min_price, min_interval = _get_price_stat(merged, "min")
max_price, max_interval = _get_price_stat(merged, "max")
# Min should be first interval
assert min_price == PRICE_LOW # noqa: S101
assert min_interval is not None # noqa: S101
assert min_interval["difference"] == DIFF_MIN_LOW # noqa: S101
assert min_interval["rating_level"] == "LOW" # noqa: S101
# Max should be second interval
assert max_price == PRICE_HIGH # noqa: S101
assert max_interval is not None # noqa: S101
assert max_interval["difference"] == DIFF_MID_ZERO # noqa: S101
assert max_interval["rating_level"] == "NORMAL" # noqa: S101
def test_empty_merged_returns_none_intervals() -> None:
"""Test that empty merged list returns None for intervals."""
stats = _get_price_stats([])
assert stats.price_min == 0 # noqa: S101
assert stats.price_min_interval is None # noqa: S101
assert stats.price_max == 0 # noqa: S101
assert stats.price_max_interval is None # noqa: S101
assert stats.price_avg == 0 # noqa: S101