Use mocked entity platform for lock service tests (#105020)

* Use mocked entity platform for lock service tests

* Cleanup old mock class

* Follow up on code review

* Improve mock entity platform

* Use entity_id of passed entity instead of constant
This commit is contained in:
Jan Bouwhuis 2023-12-12 15:49:01 +01:00 committed by GitHub
parent 5c514b6b19
commit 280637822b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 403 additions and 236 deletions

View File

@ -0,0 +1,141 @@
"""Fixtures for the lock entity platform tests."""
from collections.abc import Generator
from typing import Any
from unittest.mock import MagicMock
import pytest
from homeassistant.components.lock import (
DOMAIN as LOCK_DOMAIN,
LockEntity,
LockEntityFeature,
)
from homeassistant.config_entries import ConfigEntry, ConfigFlow
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from tests.common import (
MockConfigEntry,
MockModule,
MockPlatform,
mock_config_flow,
mock_integration,
mock_platform,
)
TEST_DOMAIN = "test"
class MockLock(LockEntity):
"""Mocked lock entity."""
def __init__(
self,
supported_features: LockEntityFeature = LockEntityFeature(0),
code_format: str | None = None,
) -> None:
"""Initialize the lock."""
self.calls_open = MagicMock()
self.calls_lock = MagicMock()
self.calls_unlock = MagicMock()
self._attr_code_format = code_format
self._attr_supported_features = supported_features
self._attr_has_entity_name = True
self._attr_name = "test_lock"
self._attr_unique_id = "very_unique_lock_id"
super().__init__()
def lock(self, **kwargs: Any) -> None:
"""Mock lock lock calls."""
self.calls_lock(**kwargs)
def unlock(self, **kwargs: Any) -> None:
"""Mock lock unlock calls."""
self.calls_unlock(**kwargs)
def open(self, **kwargs: Any) -> None:
"""Mock lock open calls."""
self.calls_open(**kwargs)
class MockFlow(ConfigFlow):
"""Test flow."""
@pytest.fixture(autouse=True)
def config_flow_fixture(hass: HomeAssistant) -> Generator[None, None, None]:
"""Mock config flow."""
mock_platform(hass, f"{TEST_DOMAIN}.config_flow")
with mock_config_flow(TEST_DOMAIN, MockFlow):
yield
@pytest.fixture
async def code_format() -> str | None:
"""Return the code format for the test lock entity."""
return None
@pytest.fixture(name="supported_features")
async def lock_supported_features() -> LockEntityFeature:
"""Return the supported features for the test lock entity."""
return LockEntityFeature.OPEN
@pytest.fixture(name="mock_lock_entity")
async def setup_lock_platform_test_entity(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
code_format: str | None,
supported_features: LockEntityFeature,
) -> MagicMock:
"""Set up lock entity using an entity platform."""
async def async_setup_entry_init(
hass: HomeAssistant, config_entry: ConfigEntry
) -> bool:
"""Set up test config entry."""
await hass.config_entries.async_forward_entry_setup(config_entry, LOCK_DOMAIN)
return True
MockPlatform(hass, f"{TEST_DOMAIN}.config_flow")
mock_integration(
hass,
MockModule(
TEST_DOMAIN,
async_setup_entry=async_setup_entry_init,
),
)
# Unnamed sensor without device class -> no name
entity = MockLock(
supported_features=supported_features,
code_format=code_format,
)
async def async_setup_entry_platform(
hass: HomeAssistant,
config_entry: ConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up test lock platform via config entry."""
async_add_entities([entity])
mock_platform(
hass,
f"{TEST_DOMAIN}.{LOCK_DOMAIN}",
MockPlatform(async_setup_entry=async_setup_entry_platform),
)
config_entry = MockConfigEntry(domain=TEST_DOMAIN)
config_entry.add_to_hass(hass)
assert await hass.config_entries.async_setup(config_entry.entry_id)
await hass.async_block_till_done()
state = hass.states.get(entity.entity_id)
assert state is not None
return entity

View File

@ -2,328 +2,354 @@
from __future__ import annotations from __future__ import annotations
from typing import Any from typing import Any
from unittest.mock import MagicMock
import pytest import pytest
from homeassistant.components.lock import ( from homeassistant.components.lock import (
ATTR_CODE, ATTR_CODE,
CONF_DEFAULT_CODE, CONF_DEFAULT_CODE,
DOMAIN,
SERVICE_LOCK,
SERVICE_OPEN,
SERVICE_UNLOCK,
STATE_JAMMED, STATE_JAMMED,
STATE_LOCKED, STATE_LOCKED,
STATE_LOCKING, STATE_LOCKING,
STATE_UNLOCKED, STATE_UNLOCKED,
STATE_UNLOCKING, STATE_UNLOCKING,
LockEntity,
LockEntityFeature, LockEntityFeature,
) )
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
import homeassistant.helpers.entity_registry as er import homeassistant.helpers.entity_registry as er
from homeassistant.setup import async_setup_component from homeassistant.helpers.typing import UNDEFINED, UndefinedType
from tests.testing_config.custom_components.test.lock import MockLock from .conftest import MockLock
class MockLockEntity(LockEntity): async def help_test_async_lock_service(
"""Mock lock to use in tests.""" hass: HomeAssistant,
entity_id: str,
service: str,
code: str | None | UndefinedType = UNDEFINED,
) -> None:
"""Help to lock a test lock."""
data: dict[str, Any] = {"entity_id": entity_id}
if code is not UNDEFINED:
data[ATTR_CODE] = code
def __init__( await hass.services.async_call(DOMAIN, service, data, blocking=True)
self,
code_format: str | None = None,
lock_option_default_code: str = "",
supported_features: LockEntityFeature = LockEntityFeature(0),
) -> None:
"""Initialize mock lock entity."""
self._attr_supported_features = supported_features
self.calls_lock = MagicMock()
self.calls_unlock = MagicMock()
self.calls_open = MagicMock()
if code_format is not None:
self._attr_code_format = code_format
self._lock_option_default_code = lock_option_default_code
async def async_lock(self, **kwargs: Any) -> None:
"""Lock the lock."""
self.calls_lock(kwargs)
self._attr_is_locking = False
self._attr_is_locked = True
async def async_unlock(self, **kwargs: Any) -> None:
"""Unlock the lock."""
self.calls_unlock(kwargs)
self._attr_is_unlocking = False
self._attr_is_locked = False
async def async_open(self, **kwargs: Any) -> None:
"""Open the door latch."""
self.calls_open(kwargs)
async def test_lock_default(hass: HomeAssistant) -> None: async def test_lock_default(hass: HomeAssistant, mock_lock_entity: MockLock) -> None:
"""Test lock entity with defaults.""" """Test lock entity with defaults."""
lock = MockLockEntity()
lock.hass = hass
assert lock.code_format is None assert mock_lock_entity.code_format is None
assert lock.state is None assert mock_lock_entity.state is None
assert mock_lock_entity.is_jammed is None
assert mock_lock_entity.is_locked is None
assert mock_lock_entity.is_locking is None
assert mock_lock_entity.is_unlocking is None
async def test_lock_states(hass: HomeAssistant) -> None: async def test_lock_states(hass: HomeAssistant, mock_lock_entity: MockLock) -> None:
"""Test lock entity states.""" """Test lock entity states."""
lock = MockLockEntity() assert mock_lock_entity.state is None
lock.hass = hass
assert lock.state is None mock_lock_entity._attr_is_locking = True
assert mock_lock_entity.is_locking
assert mock_lock_entity.state == STATE_LOCKING
lock._attr_is_locking = True mock_lock_entity._attr_is_locked = True
assert lock.is_locking mock_lock_entity._attr_is_locking = False
assert lock.state == STATE_LOCKING assert mock_lock_entity.is_locked
assert mock_lock_entity.state == STATE_LOCKED
await lock.async_handle_lock_service() mock_lock_entity._attr_is_unlocking = True
assert lock.is_locked assert mock_lock_entity.is_unlocking
assert lock.state == STATE_LOCKED assert mock_lock_entity.state == STATE_UNLOCKING
lock._attr_is_unlocking = True mock_lock_entity._attr_is_locked = False
assert lock.is_unlocking mock_lock_entity._attr_is_unlocking = False
assert lock.state == STATE_UNLOCKING assert not mock_lock_entity.is_locked
assert mock_lock_entity.state == STATE_UNLOCKED
await lock.async_handle_unlock_service() mock_lock_entity._attr_is_jammed = True
assert not lock.is_locked assert mock_lock_entity.is_jammed
assert lock.state == STATE_UNLOCKED assert mock_lock_entity.state == STATE_JAMMED
assert not mock_lock_entity.is_locked
lock._attr_is_jammed = True
assert lock.is_jammed
assert lock.state == STATE_JAMMED
assert not lock.is_locked
async def test_set_default_code_option( @pytest.mark.parametrize(
("code_format", "supported_features"),
[(r"^\d{4}$", LockEntityFeature.OPEN)],
)
async def test_set_mock_lock_options(
hass: HomeAssistant, hass: HomeAssistant,
entity_registry: er.EntityRegistry, entity_registry: er.EntityRegistry,
enable_custom_integrations: None, mock_lock_entity: MockLock,
) -> None: ) -> None:
"""Test default code stored in the registry.""" """Test mock attributes and default code stored in the registry."""
entry = entity_registry.async_get_or_create("lock", "test", "very_unique")
await hass.async_block_till_done()
platform = getattr(hass.components, "test.lock")
platform.init(empty=True)
platform.ENTITIES["lock1"] = platform.MockLock(
name="Test",
code_format=r"^\d{4}$",
supported_features=LockEntityFeature.OPEN,
unique_id="very_unique",
)
assert await async_setup_component(hass, "lock", {"lock": {"platform": "test"}})
await hass.async_block_till_done()
entity0: MockLock = platform.ENTITIES["lock1"]
entity_registry.async_update_entity_options( entity_registry.async_update_entity_options(
entry.entity_id, "lock", {CONF_DEFAULT_CODE: "1234"} "lock.test_lock", "lock", {CONF_DEFAULT_CODE: "1234"}
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert entity0._lock_option_default_code == "1234" assert mock_lock_entity._lock_option_default_code == "1234"
state = hass.states.get(mock_lock_entity.entity_id)
assert state is not None
assert state.attributes["code_format"] == r"^\d{4}$"
assert state.attributes["supported_features"] == LockEntityFeature.OPEN
@pytest.mark.parametrize("code_format", [r"^\d{4}$"])
async def test_default_code_option_update( async def test_default_code_option_update(
hass: HomeAssistant, hass: HomeAssistant,
entity_registry: er.EntityRegistry, entity_registry: er.EntityRegistry,
enable_custom_integrations: None, mock_lock_entity: MockLock,
) -> None: ) -> None:
"""Test default code stored in the registry is updated.""" """Test default code stored in the registry is updated."""
entry = entity_registry.async_get_or_create("lock", "test", "very_unique") assert mock_lock_entity._lock_option_default_code == ""
await hass.async_block_till_done()
platform = getattr(hass.components, "test.lock")
platform.init(empty=True)
# Pre-register entities
entry = entity_registry.async_get_or_create("lock", "test", "very_unique")
entity_registry.async_update_entity_options(
entry.entity_id,
"lock",
{
"default_code": "5432",
},
)
platform.ENTITIES["lock1"] = platform.MockLock(
name="Test",
code_format=r"^\d{4}$",
supported_features=LockEntityFeature.OPEN,
unique_id="very_unique",
)
assert await async_setup_component(hass, "lock", {"lock": {"platform": "test"}})
await hass.async_block_till_done()
entity0: MockLock = platform.ENTITIES["lock1"]
assert entity0._lock_option_default_code == "5432"
entity_registry.async_update_entity_options( entity_registry.async_update_entity_options(
entry.entity_id, "lock", {CONF_DEFAULT_CODE: "1234"} "lock.test_lock", "lock", {CONF_DEFAULT_CODE: "4321"}
) )
await hass.async_block_till_done() await hass.async_block_till_done()
assert entity0._lock_option_default_code == "1234" assert mock_lock_entity._lock_option_default_code == "4321"
async def test_lock_open_with_code(hass: HomeAssistant) -> None: @pytest.mark.parametrize(
("code_format", "supported_features"),
[(r"^\d{4}$", LockEntityFeature.OPEN)],
)
async def test_lock_open_with_code(
hass: HomeAssistant, mock_lock_entity: MockLock
) -> None:
"""Test lock entity with open service.""" """Test lock entity with open service."""
lock = MockLockEntity( state = hass.states.get(mock_lock_entity.entity_id)
code_format=r"^\d{4}$", supported_features=LockEntityFeature.OPEN assert state.attributes["code_format"] == r"^\d{4}$"
with pytest.raises(ValueError):
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_OPEN
)
with pytest.raises(ValueError):
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_OPEN, code=""
)
with pytest.raises(ValueError):
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_OPEN, code="HELLO"
)
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_OPEN, code="1234"
) )
lock.hass = hass assert mock_lock_entity.calls_open.call_count == 1
mock_lock_entity.calls_open.assert_called_with(code="1234")
assert lock.state_attributes == {"code_format": r"^\d{4}$"}
with pytest.raises(ValueError):
await lock.async_handle_open_service()
with pytest.raises(ValueError):
await lock.async_handle_open_service(code="")
with pytest.raises(ValueError):
await lock.async_handle_open_service(code="HELLO")
await lock.async_handle_open_service(code="1234")
assert lock.calls_open.call_count == 1
async def test_lock_lock_with_code(hass: HomeAssistant) -> None: @pytest.mark.parametrize(
("code_format", "supported_features"),
[(r"^\d{4}$", LockEntityFeature.OPEN)],
)
async def test_lock_lock_with_code(
hass: HomeAssistant, mock_lock_entity: MockLock
) -> None:
"""Test lock entity with open service.""" """Test lock entity with open service."""
lock = MockLockEntity(code_format=r"^\d{4}$") state = hass.states.get(mock_lock_entity.entity_id)
lock.hass = hass assert state.attributes["code_format"] == r"^\d{4}$"
await lock.async_handle_unlock_service(code="1234") await help_test_async_lock_service(
assert not lock.is_locked hass, mock_lock_entity.entity_id, SERVICE_UNLOCK, code="1234"
)
mock_lock_entity.calls_unlock.assert_called_with(code="1234")
assert mock_lock_entity.calls_lock.call_count == 0
with pytest.raises(ValueError): with pytest.raises(ValueError):
await lock.async_handle_lock_service() await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_LOCK
)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await lock.async_handle_lock_service(code="") await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_LOCK, code=""
)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await lock.async_handle_lock_service(code="HELLO") await help_test_async_lock_service(
await lock.async_handle_lock_service(code="1234") hass, mock_lock_entity.entity_id, SERVICE_LOCK, code="HELLO"
assert lock.is_locked )
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_LOCK, code="1234"
)
assert mock_lock_entity.calls_lock.call_count == 1
mock_lock_entity.calls_lock.assert_called_with(code="1234")
async def test_lock_unlock_with_code(hass: HomeAssistant) -> None: @pytest.mark.parametrize(
("code_format", "supported_features"),
[(r"^\d{4}$", LockEntityFeature.OPEN)],
)
async def test_lock_unlock_with_code(
hass: HomeAssistant, mock_lock_entity: MockLock
) -> None:
"""Test unlock entity with open service.""" """Test unlock entity with open service."""
lock = MockLockEntity(code_format=r"^\d{4}$") state = hass.states.get(mock_lock_entity.entity_id)
lock.hass = hass assert state.attributes["code_format"] == r"^\d{4}$"
await lock.async_handle_lock_service(code="1234") await help_test_async_lock_service(
assert lock.is_locked hass, mock_lock_entity.entity_id, SERVICE_LOCK, code="1234"
with pytest.raises(ValueError):
await lock.async_handle_unlock_service()
with pytest.raises(ValueError):
await lock.async_handle_unlock_service(code="")
with pytest.raises(ValueError):
await lock.async_handle_unlock_service(code="HELLO")
await lock.async_handle_unlock_service(code="1234")
assert not lock.is_locked
async def test_lock_with_illegal_code(hass: HomeAssistant) -> None:
"""Test lock entity with default code that does not match the code format."""
lock = MockLockEntity(
code_format=r"^\d{4}$",
supported_features=LockEntityFeature.OPEN,
) )
lock.hass = hass mock_lock_entity.calls_lock.assert_called_with(code="1234")
assert mock_lock_entity.calls_unlock.call_count == 0
with pytest.raises(ValueError): with pytest.raises(ValueError):
await lock.async_handle_open_service(code="123456") await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_UNLOCK
)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await lock.async_handle_lock_service(code="123456") await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_UNLOCK, code=""
)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await lock.async_handle_unlock_service(code="123456") await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_UNLOCK, code="HELLO"
)
async def test_lock_with_no_code(hass: HomeAssistant) -> None: await help_test_async_lock_service(
"""Test lock entity with default code that does not match the code format.""" hass, mock_lock_entity.entity_id, SERVICE_UNLOCK, code="1234"
lock = MockLockEntity(
supported_features=LockEntityFeature.OPEN,
) )
lock.hass = hass assert mock_lock_entity.calls_unlock.call_count == 1
mock_lock_entity.calls_unlock.assert_called_with(code="1234")
await lock.async_handle_open_service()
lock.calls_open.assert_called_with({})
await lock.async_handle_lock_service()
lock.calls_lock.assert_called_with({})
await lock.async_handle_unlock_service()
lock.calls_unlock.assert_called_with({})
await lock.async_handle_open_service(code="")
lock.calls_open.assert_called_with({})
await lock.async_handle_lock_service(code="")
lock.calls_lock.assert_called_with({})
await lock.async_handle_unlock_service(code="")
lock.calls_unlock.assert_called_with({})
async def test_lock_with_default_code(hass: HomeAssistant) -> None: @pytest.mark.parametrize(
("code_format", "supported_features"),
[(r"^\d{4}$", LockEntityFeature.OPEN)],
)
async def test_lock_with_illegal_code(
hass: HomeAssistant, mock_lock_entity: MockLock
) -> None:
"""Test lock entity with default code that does not match the code format."""
with pytest.raises(ValueError):
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_OPEN, code="123456"
)
with pytest.raises(ValueError):
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_LOCK, code="123456"
)
with pytest.raises(ValueError):
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_UNLOCK, code="123456"
)
@pytest.mark.parametrize(
("code_format", "supported_features"),
[(None, LockEntityFeature.OPEN)],
)
async def test_lock_with_no_code(
hass: HomeAssistant, mock_lock_entity: MockLock
) -> None:
"""Test lock entity without code."""
await help_test_async_lock_service(hass, mock_lock_entity.entity_id, SERVICE_OPEN)
mock_lock_entity.calls_open.assert_called_with()
await help_test_async_lock_service(hass, mock_lock_entity.entity_id, SERVICE_LOCK)
mock_lock_entity.calls_lock.assert_called_with()
await help_test_async_lock_service(hass, mock_lock_entity.entity_id, SERVICE_UNLOCK)
mock_lock_entity.calls_unlock.assert_called_with()
mock_lock_entity.calls_open.reset_mock()
mock_lock_entity.calls_lock.reset_mock()
mock_lock_entity.calls_unlock.reset_mock()
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_OPEN, code=""
)
mock_lock_entity.calls_open.assert_called_with()
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_LOCK, code=""
)
mock_lock_entity.calls_lock.assert_called_with()
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_UNLOCK, code=""
)
mock_lock_entity.calls_unlock.assert_called_with()
@pytest.mark.parametrize(
("code_format", "supported_features"),
[(r"^\d{4}$", LockEntityFeature.OPEN)],
)
async def test_lock_with_default_code(
hass: HomeAssistant, entity_registry: er.EntityRegistry, mock_lock_entity: MockLock
) -> None:
"""Test lock entity with default code.""" """Test lock entity with default code."""
lock = MockLockEntity( entity_registry.async_update_entity_options(
code_format=r"^\d{4}$", "lock.test_lock", "lock", {CONF_DEFAULT_CODE: "1234"}
supported_features=LockEntityFeature.OPEN,
lock_option_default_code="1234",
) )
lock.hass = hass await hass.async_block_till_done()
assert lock.state_attributes == {"code_format": r"^\d{4}$"} assert mock_lock_entity.state_attributes == {"code_format": r"^\d{4}$"}
assert lock._lock_option_default_code == "1234" assert mock_lock_entity._lock_option_default_code == "1234"
await lock.async_handle_open_service() await help_test_async_lock_service(
lock.calls_open.assert_called_with({ATTR_CODE: "1234"}) hass, mock_lock_entity.entity_id, SERVICE_OPEN, code="1234"
await lock.async_handle_lock_service()
lock.calls_lock.assert_called_with({ATTR_CODE: "1234"})
await lock.async_handle_unlock_service()
lock.calls_unlock.assert_called_with({ATTR_CODE: "1234"})
await lock.async_handle_open_service(code="")
lock.calls_open.assert_called_with({ATTR_CODE: "1234"})
await lock.async_handle_lock_service(code="")
lock.calls_lock.assert_called_with({ATTR_CODE: "1234"})
await lock.async_handle_unlock_service(code="")
lock.calls_unlock.assert_called_with({ATTR_CODE: "1234"})
async def test_lock_with_provided_and_default_code(hass: HomeAssistant) -> None:
"""Test lock entity with provided code when default code is set."""
lock = MockLockEntity(
code_format=r"^\d{4}$",
supported_features=LockEntityFeature.OPEN,
lock_option_default_code="1234",
) )
lock.hass = hass mock_lock_entity.calls_open.assert_called_with(code="1234")
await help_test_async_lock_service(
await lock.async_handle_open_service(code="4321") hass, mock_lock_entity.entity_id, SERVICE_LOCK, code="1234"
lock.calls_open.assert_called_with({ATTR_CODE: "4321"})
await lock.async_handle_lock_service(code="4321")
lock.calls_lock.assert_called_with({ATTR_CODE: "4321"})
await lock.async_handle_unlock_service(code="4321")
lock.calls_unlock.assert_called_with({ATTR_CODE: "4321"})
async def test_lock_with_illegal_default_code(hass: HomeAssistant) -> None:
"""Test lock entity with default code that does not match the code format."""
lock = MockLockEntity(
code_format=r"^\d{4}$",
supported_features=LockEntityFeature.OPEN,
lock_option_default_code="123456",
) )
lock.hass = hass mock_lock_entity.calls_lock.assert_called_with(code="1234")
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_UNLOCK, code="1234"
)
mock_lock_entity.calls_unlock.assert_called_with(code="1234")
assert lock.state_attributes == {"code_format": r"^\d{4}$"} mock_lock_entity.calls_open.reset_mock()
assert lock._lock_option_default_code == "123456" mock_lock_entity.calls_lock.reset_mock()
mock_lock_entity.calls_unlock.reset_mock()
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_OPEN, code=""
)
mock_lock_entity.calls_open.assert_called_with(code="1234")
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_LOCK, code=""
)
mock_lock_entity.calls_lock.assert_called_with(code="1234")
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_UNLOCK, code=""
)
mock_lock_entity.calls_unlock.assert_called_with(code="1234")
@pytest.mark.parametrize(
("code_format", "supported_features"),
[(r"^\d{4}$", LockEntityFeature.OPEN)],
)
async def test_lock_with_illegal_default_code(
hass: HomeAssistant, entity_registry: er.EntityRegistry, mock_lock_entity: MockLock
) -> None:
"""Test lock entity with illegal default code."""
entity_registry.async_update_entity_options(
"lock.test_lock", "lock", {CONF_DEFAULT_CODE: "123456"}
)
await hass.async_block_till_done()
assert mock_lock_entity.state_attributes == {"code_format": r"^\d{4}$"}
assert mock_lock_entity._lock_option_default_code == ""
with pytest.raises(ValueError): with pytest.raises(ValueError):
await lock.async_handle_open_service() await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_OPEN
)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await lock.async_handle_lock_service() await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_LOCK
)
with pytest.raises(ValueError): with pytest.raises(ValueError):
await lock.async_handle_unlock_service() await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_UNLOCK
)