| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- """Unit tests for GuestModeSwitch, ModeSyncSwitch, and OverrideReservationSwitch.
- Uses object.__new__ to bypass HA entity setup. async_write_ha_state is
- replaced with a MagicMock to avoid needing a real HA instance.
- """
- from unittest.mock import AsyncMock, MagicMock, patch
- import pytest
- from custom_components.room_cal_ha.switch import GuestModeSwitch, ModeSyncSwitch, OverrideReservationSwitch, UseUnifiSwitch
- def _guest_mode():
- s = object.__new__(GuestModeSwitch)
- s._state = False
- s._deferred = True
- s._coordinator = MagicMock()
- s.async_write_ha_state = MagicMock()
- return s
- def _mode_sync():
- s = object.__new__(ModeSyncSwitch)
- s._state = False
- s._coordinator = MagicMock()
- s._coordinator.cancel_mode_sync = MagicMock()
- s.async_write_ha_state = MagicMock()
- return s
- # ---------------------------------------------------------------------------
- # GuestModeSwitch — basic state
- # ---------------------------------------------------------------------------
- async def test_guest_mode_initial_state_is_false():
- s = _guest_mode()
- assert s.is_on is False
- async def test_guest_mode_turn_on_sets_state():
- s = _guest_mode()
- s._deferred = False
- await s.async_turn_on()
- assert s.is_on is True
- async def test_guest_mode_turn_off_sets_state():
- s = _guest_mode()
- s._state = True
- s._deferred = False
- await s.async_turn_off()
- assert s.is_on is False
- # ---------------------------------------------------------------------------
- # GuestModeSwitch — deferred write behavior
- # ---------------------------------------------------------------------------
- async def test_guest_mode_deferred_suppresses_write():
- s = _guest_mode()
- assert s._deferred is True
- s.async_write_ha_state() # should be a no-op when deferred
- # The real async_write_ha_state is replaced; calling it when deferred returns early.
- # We verify by re-implementing the check:
- with patch.object(type(s).__bases__[0], "async_write_ha_state") as mock_parent:
- s.async_write_ha_state = GuestModeSwitch.async_write_ha_state.__get__(s, type(s))
- s.async_write_ha_state()
- mock_parent.assert_not_called()
- def test_guest_mode_commit_state_unblocks_and_writes():
- s = _guest_mode()
- s._state = True
- real_write = MagicMock()
- with patch(
- "homeassistant.helpers.entity.Entity.async_write_ha_state",
- real_write,
- ):
- s.commit_state()
- assert s._deferred is False
- real_write.assert_called_once()
- # ---------------------------------------------------------------------------
- # ModeSyncSwitch — turn off cancels mode sync
- # ---------------------------------------------------------------------------
- async def test_mode_sync_turn_off_cancels_sync():
- s = _mode_sync()
- s._state = True
- await s.async_turn_off()
- assert s.is_on is False
- s._coordinator.cancel_mode_sync.assert_called_once()
- async def test_mode_sync_turn_on_does_not_cancel_sync():
- s = _mode_sync()
- await s.async_turn_on()
- s._coordinator.cancel_mode_sync.assert_not_called()
- async def test_mode_sync_initial_state_is_false():
- s = _mode_sync()
- assert s.is_on is False
- # ---------------------------------------------------------------------------
- # OverrideReservationSwitch
- # ---------------------------------------------------------------------------
- def _override_switch(override_active: bool = False):
- s = object.__new__(OverrideReservationSwitch)
- s.coordinator = MagicMock()
- s.coordinator.async_end_override = AsyncMock()
- data = MagicMock()
- data.override_active = override_active
- s.coordinator.data = data
- return s
- def test_override_switch_is_off_when_not_active():
- assert _override_switch(override_active=False).is_on is False
- def test_override_switch_is_on_when_active():
- assert _override_switch(override_active=True).is_on is True
- def test_override_switch_none_data_is_off():
- s = _override_switch()
- s.coordinator.data = None
- assert s.is_on is False
- async def test_override_switch_turn_off_ends_override():
- s = _override_switch(override_active=True)
- await s.async_turn_off()
- s.coordinator.async_end_override.assert_awaited_once()
- async def test_override_switch_turn_on_is_noop():
- s = _override_switch()
- await s.async_turn_on()
- s.coordinator.async_end_override.assert_not_awaited()
- # ---------------------------------------------------------------------------
- # UseUnifiSwitch
- # ---------------------------------------------------------------------------
- def _use_unifi():
- s = object.__new__(UseUnifiSwitch)
- s._coordinator = MagicMock()
- s.async_write_ha_state = MagicMock()
- return s
- def test_use_unifi_default_state_is_true():
- s = _use_unifi()
- assert s.is_on is True
- async def test_use_unifi_turn_off_sets_false():
- s = _use_unifi()
- await s.async_turn_off()
- assert s.is_on is False
- async def test_use_unifi_turn_on_restores_true():
- s = _use_unifi()
- s._state = False
- await s.async_turn_on()
- assert s.is_on is True
|