|
|
@@ -47,13 +47,13 @@ def _mock_session_raises(exc):
|
|
|
return session
|
|
|
|
|
|
|
|
|
-def _reservation_slot(guest, checkin, checkout):
|
|
|
+def _reservation_slot(guest, checkin, checkout, checkin_time="14:00", checkout_time="11:00"):
|
|
|
return {
|
|
|
"guest_name": guest,
|
|
|
"checkin_date": str(checkin),
|
|
|
- "checkin_time": "14:00",
|
|
|
+ "checkin_time": checkin_time,
|
|
|
"checkout_date": str(checkout),
|
|
|
- "checkout_time": "11:00",
|
|
|
+ "checkout_time": checkout_time,
|
|
|
"wifi_ssid": "GuestNet",
|
|
|
"wifi_key": "wifikey",
|
|
|
"door_code": "1234",
|
|
|
@@ -105,9 +105,11 @@ def test_parse_reservation_missing_dates_gives_none_fields():
|
|
|
# ---------------------------------------------------------------------------
|
|
|
|
|
|
async def test_fetch_current_today_no_next(hass: HomeAssistant):
|
|
|
+ # checkin yesterday at 14:00, checkout tomorrow at 11:00 — window always active
|
|
|
today = date.today()
|
|
|
+ yesterday = today - timedelta(days=1)
|
|
|
tomorrow = today + timedelta(days=1)
|
|
|
- response = {str(today): _reservation_slot("Alice", today, tomorrow)}
|
|
|
+ response = {str(today): _reservation_slot("Alice", yesterday, tomorrow)}
|
|
|
|
|
|
session = _mock_session(200, response)
|
|
|
entry = _make_entry()
|
|
|
@@ -142,12 +144,15 @@ async def test_fetch_no_current_next_upcoming(hass: HomeAssistant):
|
|
|
|
|
|
|
|
|
async def test_fetch_both_current_and_next(hass: HomeAssistant):
|
|
|
+ # Alice: window always active (checked in yesterday, out tomorrow)
|
|
|
+ # Bob: future (5 days from now)
|
|
|
today = date.today()
|
|
|
+ yesterday = today - timedelta(days=1)
|
|
|
tomorrow = today + timedelta(days=1)
|
|
|
future = today + timedelta(days=5)
|
|
|
future_end = today + timedelta(days=8)
|
|
|
response = {
|
|
|
- str(today): _reservation_slot("Alice", today, tomorrow),
|
|
|
+ str(today): _reservation_slot("Alice", yesterday, tomorrow),
|
|
|
str(future): _reservation_slot("Bob", future, future_end),
|
|
|
}
|
|
|
|
|
|
@@ -162,10 +167,12 @@ async def test_fetch_both_current_and_next(hass: HomeAssistant):
|
|
|
|
|
|
|
|
|
async def test_fetch_multiday_current_not_duplicated_as_next(hass: HomeAssistant):
|
|
|
- """A reservation spanning multiple days should produce one current, not also be treated as next."""
|
|
|
+ """A multi-day stay appearing on multiple date keys should produce one current, not also next."""
|
|
|
+ # checkin yesterday, checkout in 3 days — window always active regardless of test time
|
|
|
today = date.today()
|
|
|
+ yesterday = today - timedelta(days=1)
|
|
|
checkout = today + timedelta(days=3)
|
|
|
- slot = _reservation_slot("Alice", today, checkout)
|
|
|
+ slot = _reservation_slot("Alice", yesterday, checkout)
|
|
|
# Same reservation appears on each day it spans
|
|
|
response = {
|
|
|
str(today): slot,
|
|
|
@@ -183,6 +190,40 @@ async def test_fetch_multiday_current_not_duplicated_as_next(hass: HomeAssistant
|
|
|
assert nxt is None
|
|
|
|
|
|
|
|
|
+async def test_fetch_current_not_promoted_before_checkin_time(hass: HomeAssistant):
|
|
|
+ """Next guest's slot should not become current just because their check-in DATE is today."""
|
|
|
+ # Guest A: checked in 2 days ago, checks out today at 23:59 — window active
|
|
|
+ # Guest B: checks in today at 14:00 — should be next, not current
|
|
|
+ # This covers the midnight-transition bug where a date-key lookup would wrongly
|
|
|
+ # promote Guest B to current at midnight of their check-in date.
|
|
|
+ from datetime import datetime as _dt, time as _time
|
|
|
+ today = date.today()
|
|
|
+ two_days_ago = today - timedelta(days=2)
|
|
|
+ tomorrow = today + timedelta(days=1)
|
|
|
+ response = {
|
|
|
+ str(today): _reservation_slot("Alice", two_days_ago, today, checkout_time="23:59"),
|
|
|
+ str(tomorrow): _reservation_slot("Bob", today, tomorrow, checkin_time="14:00"),
|
|
|
+ }
|
|
|
+
|
|
|
+ # Pin now to 09:00 — before Alice's checkout AND before Bob's check-in
|
|
|
+ fake_now = _dt.combine(today, _time(9, 0))
|
|
|
+ session = _mock_session(200, response)
|
|
|
+ backend = RoomCalApiBackend(hass, _make_entry())
|
|
|
+
|
|
|
+ with (
|
|
|
+ patch("custom_components.room_cal_ha.backends.api.async_get_clientsession", return_value=session),
|
|
|
+ patch("custom_components.room_cal_ha.backends.api.datetime") as mock_dt,
|
|
|
+ ):
|
|
|
+ mock_dt.now.return_value = fake_now
|
|
|
+ mock_dt.combine = _dt.combine
|
|
|
+ current, nxt = await backend.async_fetch()
|
|
|
+
|
|
|
+ assert current is not None
|
|
|
+ assert current.guest_name == "Alice"
|
|
|
+ assert nxt is not None
|
|
|
+ assert nxt.guest_name == "Bob"
|
|
|
+
|
|
|
+
|
|
|
async def test_fetch_empty_response(hass: HomeAssistant):
|
|
|
session = _mock_session(200, {})
|
|
|
backend = RoomCalApiBackend(hass, _make_entry())
|