"""Tests for presence detection.""" import time from unittest.mock import patch from vigilar.config import PresenceConfig, PresenceMember from vigilar.constants import HouseholdState from vigilar.presence.models import MemberPresence, derive_household_state class TestDeriveHouseholdState: def test_empty_when_no_members_home(self): members = [ MemberPresence(name="Dad", role="adult", is_home=False, last_seen=0), MemberPresence(name="Mom", role="adult", is_home=False, last_seen=0), ] assert derive_household_state(members) == HouseholdState.EMPTY def test_all_home(self): members = [ MemberPresence(name="Dad", role="adult", is_home=True, last_seen=0), MemberPresence(name="Mom", role="adult", is_home=True, last_seen=0), MemberPresence(name="Kid", role="child", is_home=True, last_seen=0), ] assert derive_household_state(members) == HouseholdState.ALL_HOME def test_kids_home_only(self): members = [ MemberPresence(name="Dad", role="adult", is_home=False, last_seen=0), MemberPresence(name="Kid", role="child", is_home=True, last_seen=0), ] assert derive_household_state(members) == HouseholdState.KIDS_HOME def test_adults_home_not_all(self): members = [ MemberPresence(name="Dad", role="adult", is_home=True, last_seen=0), MemberPresence(name="Kid", role="child", is_home=False, last_seen=0), ] assert derive_household_state(members) == HouseholdState.ADULTS_HOME def test_adults_home_no_children_configured(self): members = [ MemberPresence(name="Dad", role="adult", is_home=True, last_seen=0), ] assert derive_household_state(members) == HouseholdState.ALL_HOME def test_empty_list(self): assert derive_household_state([]) == HouseholdState.EMPTY class TestPingHost: @patch("vigilar.presence.monitor.subprocess.run") def test_ping_success(self, mock_run): from vigilar.presence.monitor import ping_host mock_run.return_value = type("R", (), {"returncode": 0})() assert ping_host("192.168.1.50") is True @patch("vigilar.presence.monitor.subprocess.run") def test_ping_failure(self, mock_run): from vigilar.presence.monitor import ping_host mock_run.return_value = type("R", (), {"returncode": 1})() assert ping_host("192.168.1.50") is False @patch("vigilar.presence.monitor.subprocess.run") def test_ping_timeout(self, mock_run): import subprocess as sp from vigilar.presence.monitor import ping_host mock_run.side_effect = sp.TimeoutExpired(cmd="ping", timeout=2) assert ping_host("192.168.1.50") is False class TestDepartureDelay: def test_not_departed_within_delay(self): from vigilar.presence.monitor import should_mark_away last_seen = time.monotonic() - 300 # 5 min ago assert should_mark_away(last_seen, departure_delay_m=10) is False def test_departed_after_delay(self): from vigilar.presence.monitor import should_mark_away last_seen = time.monotonic() - 700 # 11+ min ago assert should_mark_away(last_seen, departure_delay_m=10) is True