import pytest from unittest.mock import AsyncMock, patch from pytest_homeassistant_custom_component.common import MockConfigEntry from custom_components.zlock_slots.const import DOMAIN, CONF_LOCK_ENTITY_IDS pytest_plugins = ["pytest_homeassistant_custom_component"] LOCK_ENTITY_ID = "lock.front_door" ALARM_TYPE_ENTITY = "sensor.front_door_alarm_type" ALARM_LEVEL_ENTITY = "sensor.front_door_alarm_level" DOOR_SENSOR_ENTITY = "binary_sensor.front_door_contact" class FakeUserData: def __init__(self, user_id: int, active: bool = True, user_type=0, credential_rule=None, expiring_timeout_minutes=None): self.user_id = user_id self.active = active self.user_type = user_type self.credential_rule = credential_rule self.expiring_timeout_minutes = expiring_timeout_minutes class FakeCredentialData: def __init__(self, user_id: int, slot: int, type=1, data=None): self.user_id = user_id self.slot = slot self.type = type self.data = data class FakeAccessControl: def __init__(self, users=None, credentials=None): self._users = list(users or []) # user_id -> PIN code string self._credentials: dict[int, str] = dict(credentials or {}) self.set_user = AsyncMock(side_effect=self._set_user) self.set_credential = AsyncMock(side_effect=self._set_credential) self.delete_user = AsyncMock(side_effect=self._delete_user) self.add_user = AsyncMock(side_effect=self._add_user) async def get_users_cached(self): return list(self._users) async def get_users(self): return list(self._users) async def get_credentials(self, user_id): if user_id in self._credentials: return [FakeCredentialData(user_id, user_id, data=self._credentials[user_id])] return [] async def get_credentials_cached(self, user_id): return await self.get_credentials(user_id) async def _set_user(self, user_id, options): self._users = [u for u in self._users if u.user_id != user_id] self._users.append(FakeUserData( user_id, active=options.active, user_type=options.user_type, credential_rule=options.credential_rule, expiring_timeout_minutes=options.expiring_timeout_minutes, )) async def _set_credential(self, user_id, credential_type, credential_slot, data): self._credentials[user_id] = data async def _delete_user(self, user_id): self._users = [u for u in self._users if u.user_id != user_id] self._credentials.pop(user_id, None) async def _add_user(self, user_id, options, credential=None): await self._set_user(user_id, options) if credential is not None: self._credentials[user_id] = credential.data else: self._credentials.pop(user_id, None) class FakeNode: def __init__(self, users=None, credentials=None): self.access_control = FakeAccessControl(users, credentials) @pytest.fixture(autouse=True) def auto_enable_custom_integrations(enable_custom_integrations): yield @pytest.fixture(autouse=True) def bypass_manifest_dependencies(): """zwave_js/frontend/lovelace can't be set up in the test harness.""" with patch( "homeassistant.setup._async_process_dependencies", return_value=[] ): yield @pytest.fixture def mock_node(): return FakeNode(users=[ FakeUserData(1, active=True), FakeUserData(2, active=False), ]) @pytest.fixture def config_entry(): return MockConfigEntry( domain=DOMAIN, data={CONF_LOCK_ENTITY_IDS: [LOCK_ENTITY_ID]}, options={}, entry_id="test_entry", )