Story 1.7 (TDD, phcc, Suite gruen 97/97): - logic/pipeline.py: reine End-to-End-Pipeline (normalize->rules->matcher->assemble) inkl. no-coverage-Fehlerpfad; logic/schedule.py: Zieldatum/Umschaltzeit (halboffen). - coordinator.py: DataUpdateCoordinator, asyncio.Lock, timeout(10), einheitlicher Fehler-Contract (UpdateFailed mit Vorgaenger / fehler_prognose sonst), changed via helpers.storage.Store, last_success_utc, defensiver Item-Aufbau aus Subentries. - luna-pro-Story-Review: 5/6 Findings uebernommen, 1 verworfen (.time()-naiv-Evidenz). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
42 lines
1.2 KiB
Python
42 lines
1.2 KiB
Python
"""Story 1.7 core — target-date / switchover (no HA harness, AD-3)."""
|
|
from __future__ import annotations
|
|
|
|
from datetime import date, datetime
|
|
from zoneinfo import ZoneInfo
|
|
|
|
from custom_components.what_to_wear.logic.schedule import parse_switchover, target_date_for
|
|
|
|
TZ = ZoneInfo("Europe/Berlin")
|
|
|
|
|
|
def _now(h, m=0):
|
|
return datetime(2026, 7, 14, h, m, tzinfo=TZ)
|
|
|
|
|
|
def test_before_switchover_is_today() -> None:
|
|
d, tomorrow = target_date_for(_now(9, 59), "10:00:00")
|
|
assert d == date(2026, 7, 14) and tomorrow is False
|
|
|
|
|
|
def test_at_switchover_is_tomorrow_half_open() -> None:
|
|
d, tomorrow = target_date_for(_now(10, 0), "10:00:00")
|
|
assert d == date(2026, 7, 15) and tomorrow is True
|
|
|
|
|
|
def test_after_switchover_is_tomorrow() -> None:
|
|
d, tomorrow = target_date_for(_now(20, 0), "10:00:00")
|
|
assert d == date(2026, 7, 15) and tomorrow is True
|
|
|
|
|
|
def test_configurable_switchover() -> None:
|
|
d, _ = target_date_for(_now(7, 0), "08:00:00")
|
|
assert d == date(2026, 7, 14)
|
|
d2, _ = target_date_for(_now(8, 0), "08:00:00")
|
|
assert d2 == date(2026, 7, 15)
|
|
|
|
|
|
def test_parse_switchover_fallback() -> None:
|
|
from datetime import time
|
|
|
|
assert parse_switchover("bad") == time(10, 0, 0)
|
|
assert parse_switchover("06:30:00") == time(6, 30, 0)
|