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 typing import Any
from unittest.mock import MagicMock
import pytest
from homeassistant.components.lock import (
ATTR_CODE,
CONF_DEFAULT_CODE,
DOMAIN,
SERVICE_LOCK,
SERVICE_OPEN,
SERVICE_UNLOCK,
STATE_JAMMED,
STATE_LOCKED,
STATE_LOCKING,
STATE_UNLOCKED,
STATE_UNLOCKING,
LockEntity,
LockEntityFeature,
)
from homeassistant.core import HomeAssistant
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):
"""Mock lock to use in tests."""
async def help_test_async_lock_service(
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__(
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)
await hass.services.async_call(DOMAIN, service, data, blocking=True)
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."""
lock = MockLockEntity()
lock.hass = hass
assert lock.code_format is None
assert lock.state is None
assert mock_lock_entity.code_format 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."""
lock = MockLockEntity()
lock.hass = hass
assert mock_lock_entity.state is None
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
assert lock.is_locking
assert lock.state == STATE_LOCKING
mock_lock_entity._attr_is_locked = True
mock_lock_entity._attr_is_locking = False
assert mock_lock_entity.is_locked
assert mock_lock_entity.state == STATE_LOCKED
await lock.async_handle_lock_service()
assert lock.is_locked
assert lock.state == STATE_LOCKED
mock_lock_entity._attr_is_unlocking = True
assert mock_lock_entity.is_unlocking
assert mock_lock_entity.state == STATE_UNLOCKING
lock._attr_is_unlocking = True
assert lock.is_unlocking
assert lock.state == STATE_UNLOCKING
mock_lock_entity._attr_is_locked = False
mock_lock_entity._attr_is_unlocking = False
assert not mock_lock_entity.is_locked
assert mock_lock_entity.state == STATE_UNLOCKED
await lock.async_handle_unlock_service()
assert not lock.is_locked
assert lock.state == STATE_UNLOCKED
lock._attr_is_jammed = True
assert lock.is_jammed
assert lock.state == STATE_JAMMED
assert not lock.is_locked
mock_lock_entity._attr_is_jammed = True
assert mock_lock_entity.is_jammed
assert mock_lock_entity.state == STATE_JAMMED
assert not mock_lock_entity.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,
entity_registry: er.EntityRegistry,
enable_custom_integrations: None,
mock_lock_entity: MockLock,
) -> None:
"""Test 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"]
"""Test mock attributes and default code stored in the registry."""
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()
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(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
enable_custom_integrations: None,
mock_lock_entity: MockLock,
) -> None:
"""Test default code stored in the registry is updated."""
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)
# 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"
assert mock_lock_entity._lock_option_default_code == ""
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()
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."""
lock = MockLockEntity(
code_format=r"^\d{4}$", supported_features=LockEntityFeature.OPEN
state = hass.states.get(mock_lock_entity.entity_id)
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 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
assert mock_lock_entity.calls_open.call_count == 1
mock_lock_entity.calls_open.assert_called_with(code="1234")
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."""
lock = MockLockEntity(code_format=r"^\d{4}$")
lock.hass = hass
state = hass.states.get(mock_lock_entity.entity_id)
assert state.attributes["code_format"] == r"^\d{4}$"
await lock.async_handle_unlock_service(code="1234")
assert not lock.is_locked
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 mock_lock_entity.calls_lock.call_count == 0
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):
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):
await lock.async_handle_lock_service(code="HELLO")
await lock.async_handle_lock_service(code="1234")
assert lock.is_locked
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_LOCK, code="HELLO"
)
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."""
lock = MockLockEntity(code_format=r"^\d{4}$")
lock.hass = hass
state = hass.states.get(mock_lock_entity.entity_id)
assert state.attributes["code_format"] == r"^\d{4}$"
await lock.async_handle_lock_service(code="1234")
assert lock.is_locked
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,
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_LOCK, code="1234"
)
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):
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):
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):
await lock.async_handle_unlock_service(code="123456")
async def test_lock_with_no_code(hass: HomeAssistant) -> None:
"""Test lock entity with default code that does not match the code format."""
lock = MockLockEntity(
supported_features=LockEntityFeature.OPEN,
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_UNLOCK, code="HELLO"
)
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_UNLOCK, code="1234"
)
lock.hass = hass
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({})
assert mock_lock_entity.calls_unlock.call_count == 1
mock_lock_entity.calls_unlock.assert_called_with(code="1234")
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."""
lock = MockLockEntity(
code_format=r"^\d{4}$",
supported_features=LockEntityFeature.OPEN,
lock_option_default_code="1234",
entity_registry.async_update_entity_options(
"lock.test_lock", "lock", {CONF_DEFAULT_CODE: "1234"}
)
lock.hass = hass
await hass.async_block_till_done()
assert lock.state_attributes == {"code_format": r"^\d{4}$"}
assert lock._lock_option_default_code == "1234"
assert mock_lock_entity.state_attributes == {"code_format": r"^\d{4}$"}
assert mock_lock_entity._lock_option_default_code == "1234"
await lock.async_handle_open_service()
lock.calls_open.assert_called_with({ATTR_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",
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_OPEN, code="1234"
)
lock.hass = hass
await lock.async_handle_open_service(code="4321")
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",
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="1234"
)
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}$"}
assert lock._lock_option_default_code == "123456"
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(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):
await lock.async_handle_open_service()
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_OPEN
)
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):
await lock.async_handle_unlock_service()
await help_test_async_lock_service(
hass, mock_lock_entity.entity_id, SERVICE_UNLOCK
)