mirror of
https://github.com/home-assistant/core.git
synced 2025-07-10 06:47:09 +00:00
Add tests to MotionMount integration (#137540)
* Add entity tests * Add __init__ tests * Cleanup * Rename mock_motionmount_config_flow to mock_motionmount * Remove unneeded PropertyMock * Set defaults on mock_motionmount * Test proper device is created * Check whether proper device is created from test_init.py, also without mac * Find callback and use that to update name
This commit is contained in:
parent
79b984d612
commit
cd2313d2ca
@ -46,6 +46,7 @@ class MotionMountPresets(MotionMountEntity, SelectEntity):
|
||||
super().__init__(mm, config_entry)
|
||||
self._attr_unique_id = f"{self._base_unique_id}-preset"
|
||||
self._presets: list[motionmount.Preset] = []
|
||||
self._attr_current_option = None
|
||||
|
||||
def _update_options(self, presets: list[motionmount.Preset]) -> None:
|
||||
"""Convert presets to select options."""
|
||||
|
@ -7,6 +7,7 @@ from homeassistant.helpers.service_info.zeroconf import ZeroconfServiceInfo
|
||||
|
||||
HOST = "192.168.1.31"
|
||||
PORT = 23
|
||||
MAC = bytes.fromhex("c4dd57f8a55f")
|
||||
|
||||
TVM_ZEROCONF_SERVICE_TYPE = "_tvm._tcp.local."
|
||||
|
||||
|
@ -6,9 +6,9 @@ from unittest.mock import AsyncMock, MagicMock, patch
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.motionmount.const import DOMAIN
|
||||
from homeassistant.const import CONF_HOST, CONF_PORT
|
||||
from homeassistant.const import CONF_HOST, CONF_PIN, CONF_PORT
|
||||
|
||||
from . import HOST, PORT, ZEROCONF_MAC, ZEROCONF_NAME
|
||||
from . import HOST, MAC, PORT, ZEROCONF_MAC, ZEROCONF_NAME
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
@ -24,6 +24,17 @@ def mock_config_entry() -> MockConfigEntry:
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_config_entry_with_pin() -> MockConfigEntry:
|
||||
"""Return the default mocked config entry."""
|
||||
return MockConfigEntry(
|
||||
title=ZEROCONF_NAME,
|
||||
domain=DOMAIN,
|
||||
data={CONF_HOST: HOST, CONF_PORT: PORT, CONF_PIN: 1234},
|
||||
unique_id=ZEROCONF_MAC,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_setup_entry() -> Generator[AsyncMock]:
|
||||
"""Mock setting up a config entry."""
|
||||
@ -34,12 +45,14 @@ def mock_setup_entry() -> Generator[AsyncMock]:
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_motionmount_config_flow() -> Generator[MagicMock]:
|
||||
def mock_motionmount() -> Generator[MagicMock]:
|
||||
"""Return a mocked MotionMount config flow."""
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.motionmount.config_flow.motionmount.MotionMount",
|
||||
"homeassistant.components.motionmount.motionmount.MotionMount",
|
||||
autospec=True,
|
||||
) as motionmount_mock:
|
||||
client = motionmount_mock.return_value
|
||||
client.name = ZEROCONF_NAME
|
||||
client.mac = MAC
|
||||
yield client
|
||||
|
@ -35,10 +35,10 @@ pytestmark = pytest.mark.usefixtures("mock_setup_entry")
|
||||
|
||||
async def test_user_connection_error(
|
||||
hass: HomeAssistant,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test that the flow is aborted when there is an connection error."""
|
||||
mock_motionmount_config_flow.connect.side_effect = ConnectionRefusedError()
|
||||
mock_motionmount.connect.side_effect = ConnectionRefusedError()
|
||||
|
||||
user_input = MOCK_USER_INPUT.copy()
|
||||
|
||||
@ -54,10 +54,10 @@ async def test_user_connection_error(
|
||||
|
||||
async def test_user_connection_error_invalid_hostname(
|
||||
hass: HomeAssistant,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test that the flow is aborted when an invalid hostname is provided."""
|
||||
mock_motionmount_config_flow.connect.side_effect = socket.gaierror()
|
||||
mock_motionmount.connect.side_effect = socket.gaierror()
|
||||
|
||||
user_input = MOCK_USER_INPUT.copy()
|
||||
|
||||
@ -73,10 +73,10 @@ async def test_user_connection_error_invalid_hostname(
|
||||
|
||||
async def test_user_timeout_error(
|
||||
hass: HomeAssistant,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test that the flow is aborted when there is a timeout error."""
|
||||
mock_motionmount_config_flow.connect.side_effect = TimeoutError()
|
||||
mock_motionmount.connect.side_effect = TimeoutError()
|
||||
|
||||
user_input = MOCK_USER_INPUT.copy()
|
||||
|
||||
@ -92,10 +92,10 @@ async def test_user_timeout_error(
|
||||
|
||||
async def test_user_not_connected_error(
|
||||
hass: HomeAssistant,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test that the flow is aborted when there is a not connected error."""
|
||||
mock_motionmount_config_flow.connect.side_effect = motionmount.NotConnectedError()
|
||||
mock_motionmount.connect.side_effect = motionmount.NotConnectedError()
|
||||
|
||||
user_input = MOCK_USER_INPUT.copy()
|
||||
|
||||
@ -111,13 +111,11 @@ async def test_user_not_connected_error(
|
||||
|
||||
async def test_user_response_error_single_device_new_ce_old_pro(
|
||||
hass: HomeAssistant,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test that the flow creates an entry when there is a response error."""
|
||||
type(mock_motionmount_config_flow).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount_config_flow).mac = PropertyMock(
|
||||
return_value=b"\x00\x00\x00\x00\x00\x00"
|
||||
)
|
||||
type(mock_motionmount).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount).mac = PropertyMock(return_value=b"\x00\x00\x00\x00\x00\x00")
|
||||
|
||||
user_input = MOCK_USER_INPUT.copy()
|
||||
|
||||
@ -139,11 +137,11 @@ async def test_user_response_error_single_device_new_ce_old_pro(
|
||||
|
||||
async def test_user_response_error_single_device_new_ce_new_pro(
|
||||
hass: HomeAssistant,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test that the flow creates an entry when there is a response error."""
|
||||
type(mock_motionmount_config_flow).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount_config_flow).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_motionmount).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount).mac = PropertyMock(return_value=MAC)
|
||||
|
||||
user_input = MOCK_USER_INPUT.copy()
|
||||
|
||||
@ -167,13 +165,13 @@ async def test_user_response_error_single_device_new_ce_new_pro(
|
||||
async def test_user_response_error_multi_device_new_ce_new_pro(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test that the flow is aborted when there are multiple devices."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
type(mock_motionmount_config_flow).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount_config_flow).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_motionmount).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount).mac = PropertyMock(return_value=MAC)
|
||||
|
||||
user_input = MOCK_USER_INPUT.copy()
|
||||
|
||||
@ -190,14 +188,12 @@ async def test_user_response_error_multi_device_new_ce_new_pro(
|
||||
async def test_user_response_authentication_needed(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test that authentication is requested when needed."""
|
||||
type(mock_motionmount_config_flow).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount_config_flow).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_motionmount_config_flow).is_authenticated = PropertyMock(
|
||||
return_value=False
|
||||
)
|
||||
type(mock_motionmount).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_motionmount).is_authenticated = PropertyMock(return_value=False)
|
||||
|
||||
user_input = MOCK_USER_INPUT.copy()
|
||||
|
||||
@ -211,12 +207,8 @@ async def test_user_response_authentication_needed(
|
||||
assert result["step_id"] == "auth"
|
||||
|
||||
# Now simulate the user entered the correct pin to finalize the test
|
||||
type(mock_motionmount_config_flow).is_authenticated = PropertyMock(
|
||||
return_value=True
|
||||
)
|
||||
type(mock_motionmount_config_flow).can_authenticate = PropertyMock(
|
||||
return_value=True
|
||||
)
|
||||
type(mock_motionmount).is_authenticated = PropertyMock(return_value=True)
|
||||
type(mock_motionmount).can_authenticate = PropertyMock(return_value=True)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
@ -236,10 +228,10 @@ async def test_user_response_authentication_needed(
|
||||
|
||||
async def test_zeroconf_connection_error(
|
||||
hass: HomeAssistant,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test that the flow is aborted when there is an connection error."""
|
||||
mock_motionmount_config_flow.connect.side_effect = ConnectionRefusedError()
|
||||
mock_motionmount.connect.side_effect = ConnectionRefusedError()
|
||||
|
||||
discovery_info = dataclasses.replace(MOCK_ZEROCONF_TVM_SERVICE_INFO_V1)
|
||||
|
||||
@ -255,10 +247,10 @@ async def test_zeroconf_connection_error(
|
||||
|
||||
async def test_zeroconf_connection_error_invalid_hostname(
|
||||
hass: HomeAssistant,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test that the flow is aborted when there is an connection error."""
|
||||
mock_motionmount_config_flow.connect.side_effect = socket.gaierror()
|
||||
mock_motionmount.connect.side_effect = socket.gaierror()
|
||||
|
||||
discovery_info = dataclasses.replace(MOCK_ZEROCONF_TVM_SERVICE_INFO_V1)
|
||||
|
||||
@ -274,10 +266,10 @@ async def test_zeroconf_connection_error_invalid_hostname(
|
||||
|
||||
async def test_zeroconf_timout_error(
|
||||
hass: HomeAssistant,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test that the flow is aborted when there is a timeout error."""
|
||||
mock_motionmount_config_flow.connect.side_effect = TimeoutError()
|
||||
mock_motionmount.connect.side_effect = TimeoutError()
|
||||
|
||||
discovery_info = dataclasses.replace(MOCK_ZEROCONF_TVM_SERVICE_INFO_V1)
|
||||
|
||||
@ -293,10 +285,10 @@ async def test_zeroconf_timout_error(
|
||||
|
||||
async def test_zeroconf_not_connected_error(
|
||||
hass: HomeAssistant,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test that the flow is aborted when there is a not connected error."""
|
||||
mock_motionmount_config_flow.connect.side_effect = motionmount.NotConnectedError()
|
||||
mock_motionmount.connect.side_effect = motionmount.NotConnectedError()
|
||||
|
||||
discovery_info = dataclasses.replace(MOCK_ZEROCONF_TVM_SERVICE_INFO_V1)
|
||||
|
||||
@ -312,12 +304,10 @@ async def test_zeroconf_not_connected_error(
|
||||
|
||||
async def test_show_zeroconf_form_new_ce_old_pro(
|
||||
hass: HomeAssistant,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test that the zeroconf confirmation form is served."""
|
||||
type(mock_motionmount_config_flow).mac = PropertyMock(
|
||||
return_value=b"\x00\x00\x00\x00\x00\x00"
|
||||
)
|
||||
type(mock_motionmount).mac = PropertyMock(return_value=b"\x00\x00\x00\x00\x00\x00")
|
||||
|
||||
discovery_info = dataclasses.replace(MOCK_ZEROCONF_TVM_SERVICE_INFO_V1)
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
@ -348,10 +338,10 @@ async def test_show_zeroconf_form_new_ce_old_pro(
|
||||
|
||||
async def test_show_zeroconf_form_new_ce_new_pro(
|
||||
hass: HomeAssistant,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test that the zeroconf confirmation form is served."""
|
||||
type(mock_motionmount_config_flow).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_motionmount).mac = PropertyMock(return_value=MAC)
|
||||
|
||||
discovery_info = dataclasses.replace(MOCK_ZEROCONF_TVM_SERVICE_INFO_V2)
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
@ -383,7 +373,7 @@ async def test_show_zeroconf_form_new_ce_new_pro(
|
||||
async def test_zeroconf_device_exists_abort(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test we abort zeroconf flow if device already configured."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
@ -402,13 +392,11 @@ async def test_zeroconf_device_exists_abort(
|
||||
async def test_zeroconf_authentication_needed(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test that authentication is requested when needed."""
|
||||
type(mock_motionmount_config_flow).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_motionmount_config_flow).is_authenticated = PropertyMock(
|
||||
return_value=False
|
||||
)
|
||||
type(mock_motionmount).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_motionmount).is_authenticated = PropertyMock(return_value=False)
|
||||
|
||||
discovery_info = dataclasses.replace(MOCK_ZEROCONF_TVM_SERVICE_INFO_V2)
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
@ -421,12 +409,8 @@ async def test_zeroconf_authentication_needed(
|
||||
assert result["step_id"] == "auth"
|
||||
|
||||
# Now simulate the user entered the correct pin to finalize the test
|
||||
type(mock_motionmount_config_flow).is_authenticated = PropertyMock(
|
||||
return_value=True
|
||||
)
|
||||
type(mock_motionmount_config_flow).can_authenticate = PropertyMock(
|
||||
return_value=True
|
||||
)
|
||||
type(mock_motionmount).is_authenticated = PropertyMock(return_value=True)
|
||||
type(mock_motionmount).can_authenticate = PropertyMock(return_value=True)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
@ -448,17 +432,13 @@ async def test_zeroconf_authentication_needed(
|
||||
async def test_authentication_incorrect_then_correct_pin(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test that authentication is requested when needed."""
|
||||
type(mock_motionmount_config_flow).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount_config_flow).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_motionmount_config_flow).is_authenticated = PropertyMock(
|
||||
return_value=False
|
||||
)
|
||||
type(mock_motionmount_config_flow).can_authenticate = PropertyMock(
|
||||
return_value=True
|
||||
)
|
||||
type(mock_motionmount).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_motionmount).is_authenticated = PropertyMock(return_value=False)
|
||||
type(mock_motionmount).can_authenticate = PropertyMock(return_value=True)
|
||||
|
||||
user_input = MOCK_USER_INPUT.copy()
|
||||
|
||||
@ -483,9 +463,7 @@ async def test_authentication_incorrect_then_correct_pin(
|
||||
assert result["errors"][CONF_PIN] == CONF_PIN
|
||||
|
||||
# Now simulate the user entered the correct pin to finalize the test
|
||||
type(mock_motionmount_config_flow).is_authenticated = PropertyMock(
|
||||
return_value=True
|
||||
)
|
||||
type(mock_motionmount).is_authenticated = PropertyMock(return_value=True)
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
user_input=MOCK_PIN_INPUT.copy(),
|
||||
@ -505,18 +483,14 @@ async def test_authentication_incorrect_then_correct_pin(
|
||||
async def test_authentication_first_incorrect_pin_to_backoff(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test that authentication is requested when needed."""
|
||||
type(mock_motionmount_config_flow).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount_config_flow).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_motionmount_config_flow).is_authenticated = PropertyMock(
|
||||
return_value=False
|
||||
)
|
||||
type(mock_motionmount_config_flow).can_authenticate = PropertyMock(
|
||||
side_effect=[True, 1]
|
||||
)
|
||||
type(mock_motionmount).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_motionmount).is_authenticated = PropertyMock(return_value=False)
|
||||
type(mock_motionmount).can_authenticate = PropertyMock(side_effect=[True, 1])
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
@ -532,7 +506,7 @@ async def test_authentication_first_incorrect_pin_to_backoff(
|
||||
user_input=MOCK_PIN_INPUT.copy(),
|
||||
)
|
||||
|
||||
assert mock_motionmount_config_flow.authenticate.called
|
||||
assert mock_motionmount.authenticate.called
|
||||
assert result["type"] is FlowResultType.SHOW_PROGRESS
|
||||
assert result["step_id"] == "backoff"
|
||||
|
||||
@ -541,12 +515,8 @@ async def test_authentication_first_incorrect_pin_to_backoff(
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Now simulate the user entered the correct pin to finalize the test
|
||||
type(mock_motionmount_config_flow).is_authenticated = PropertyMock(
|
||||
return_value=True
|
||||
)
|
||||
type(mock_motionmount_config_flow).can_authenticate = PropertyMock(
|
||||
return_value=True
|
||||
)
|
||||
type(mock_motionmount).is_authenticated = PropertyMock(return_value=True)
|
||||
type(mock_motionmount).can_authenticate = PropertyMock(return_value=True)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
@ -567,16 +537,14 @@ async def test_authentication_first_incorrect_pin_to_backoff(
|
||||
async def test_authentication_multiple_incorrect_pins(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test that authentication is requested when needed."""
|
||||
type(mock_motionmount_config_flow).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount_config_flow).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_motionmount_config_flow).is_authenticated = PropertyMock(
|
||||
return_value=False
|
||||
)
|
||||
type(mock_motionmount_config_flow).can_authenticate = PropertyMock(return_value=1)
|
||||
type(mock_motionmount).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_motionmount).is_authenticated = PropertyMock(return_value=False)
|
||||
type(mock_motionmount).can_authenticate = PropertyMock(return_value=1)
|
||||
|
||||
user_input = MOCK_USER_INPUT.copy()
|
||||
|
||||
@ -602,12 +570,8 @@ async def test_authentication_multiple_incorrect_pins(
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Now simulate the user entered the correct pin to finalize the test
|
||||
type(mock_motionmount_config_flow).is_authenticated = PropertyMock(
|
||||
return_value=True
|
||||
)
|
||||
type(mock_motionmount_config_flow).can_authenticate = PropertyMock(
|
||||
return_value=True
|
||||
)
|
||||
type(mock_motionmount).is_authenticated = PropertyMock(return_value=True)
|
||||
type(mock_motionmount).can_authenticate = PropertyMock(return_value=True)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
@ -628,16 +592,14 @@ async def test_authentication_multiple_incorrect_pins(
|
||||
async def test_authentication_show_backoff_when_still_running(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test that authentication is requested when needed."""
|
||||
type(mock_motionmount_config_flow).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount_config_flow).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_motionmount_config_flow).is_authenticated = PropertyMock(
|
||||
return_value=False
|
||||
)
|
||||
type(mock_motionmount_config_flow).can_authenticate = PropertyMock(return_value=1)
|
||||
type(mock_motionmount).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_motionmount).is_authenticated = PropertyMock(return_value=False)
|
||||
type(mock_motionmount).can_authenticate = PropertyMock(return_value=1)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
@ -671,12 +633,8 @@ async def test_authentication_show_backoff_when_still_running(
|
||||
await hass.async_block_till_done()
|
||||
|
||||
# Now simulate the user entered the correct pin to finalize the test
|
||||
type(mock_motionmount_config_flow).is_authenticated = PropertyMock(
|
||||
return_value=True
|
||||
)
|
||||
type(mock_motionmount_config_flow).can_authenticate = PropertyMock(
|
||||
return_value=True
|
||||
)
|
||||
type(mock_motionmount).is_authenticated = PropertyMock(return_value=True)
|
||||
type(mock_motionmount).can_authenticate = PropertyMock(return_value=True)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
@ -697,17 +655,13 @@ async def test_authentication_show_backoff_when_still_running(
|
||||
async def test_authentication_correct_pin(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test that authentication is requested when needed."""
|
||||
type(mock_motionmount_config_flow).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount_config_flow).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_motionmount_config_flow).is_authenticated = PropertyMock(
|
||||
return_value=False
|
||||
)
|
||||
type(mock_motionmount_config_flow).can_authenticate = PropertyMock(
|
||||
return_value=True
|
||||
)
|
||||
type(mock_motionmount).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_motionmount).is_authenticated = PropertyMock(return_value=False)
|
||||
type(mock_motionmount).can_authenticate = PropertyMock(return_value=True)
|
||||
|
||||
user_input = MOCK_USER_INPUT.copy()
|
||||
|
||||
@ -720,9 +674,7 @@ async def test_authentication_correct_pin(
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "auth"
|
||||
|
||||
type(mock_motionmount_config_flow).is_authenticated = PropertyMock(
|
||||
return_value=True
|
||||
)
|
||||
type(mock_motionmount).is_authenticated = PropertyMock(return_value=True)
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
user_input=MOCK_PIN_INPUT.copy(),
|
||||
@ -741,11 +693,11 @@ async def test_authentication_correct_pin(
|
||||
|
||||
async def test_full_user_flow_implementation(
|
||||
hass: HomeAssistant,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test the full manual user flow from start to finish."""
|
||||
type(mock_motionmount_config_flow).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount_config_flow).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_motionmount).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount).mac = PropertyMock(return_value=MAC)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
@ -773,11 +725,11 @@ async def test_full_user_flow_implementation(
|
||||
|
||||
async def test_full_zeroconf_flow_implementation(
|
||||
hass: HomeAssistant,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test the full zeroconf flow from start to finish."""
|
||||
type(mock_motionmount_config_flow).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount_config_flow).mac = PropertyMock(return_value=MAC)
|
||||
type(mock_motionmount).name = PropertyMock(return_value=ZEROCONF_NAME)
|
||||
type(mock_motionmount).mac = PropertyMock(return_value=MAC)
|
||||
|
||||
discovery_info = dataclasses.replace(MOCK_ZEROCONF_TVM_SERVICE_INFO_V2)
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
@ -808,7 +760,7 @@ async def test_full_zeroconf_flow_implementation(
|
||||
async def test_full_reauth_flow_implementation(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_motionmount_config_flow: MagicMock,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test reauthentication."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
@ -824,12 +776,8 @@ async def test_full_reauth_flow_implementation(
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "auth"
|
||||
|
||||
type(mock_motionmount_config_flow).can_authenticate = PropertyMock(
|
||||
return_value=True
|
||||
)
|
||||
type(mock_motionmount_config_flow).is_authenticated = PropertyMock(
|
||||
return_value=True
|
||||
)
|
||||
type(mock_motionmount).can_authenticate = PropertyMock(return_value=True)
|
||||
type(mock_motionmount).is_authenticated = PropertyMock(return_value=True)
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"],
|
||||
user_input=MOCK_PIN_INPUT.copy(),
|
||||
|
47
tests/components/motionmount/test_entity.py
Normal file
47
tests/components/motionmount/test_entity.py
Normal file
@ -0,0 +1,47 @@
|
||||
"""Tests for the MotionMount Entity base."""
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
from homeassistant.helpers.device_registry import format_mac
|
||||
|
||||
from . import ZEROCONF_NAME
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_entity_rename(
|
||||
hass: HomeAssistant,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
entity_registry: er.EntityRegistry,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Tests the state attributes."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
mock_motionmount.is_authenticated = True
|
||||
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
|
||||
await hass.async_block_till_done()
|
||||
|
||||
mac = format_mac(mock_motionmount.mac.hex())
|
||||
device = device_registry.async_get_device(
|
||||
connections={(dr.CONNECTION_NETWORK_MAC, mac)}
|
||||
)
|
||||
assert device
|
||||
assert device.name == ZEROCONF_NAME
|
||||
|
||||
# Simulate the user changed the name of the device
|
||||
mock_motionmount.name = "Blub"
|
||||
|
||||
for callback in mock_motionmount.add_listener.call_args_list:
|
||||
callback[0][0]()
|
||||
await hass.async_block_till_done()
|
||||
|
||||
device = device_registry.async_get_device(
|
||||
connections={(dr.CONNECTION_NETWORK_MAC, mac)}
|
||||
)
|
||||
assert device
|
||||
assert device.name == "Blub"
|
129
tests/components/motionmount/test_init.py
Normal file
129
tests/components/motionmount/test_init.py
Normal file
@ -0,0 +1,129 @@
|
||||
"""Tests for the MotionMount init."""
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from homeassistant.components.motionmount import DOMAIN
|
||||
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
from homeassistant.helpers.device_registry import format_mac
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_setup_entry_with_mac(
|
||||
hass: HomeAssistant,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Tests the state attributes."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
mac = format_mac(mock_motionmount.mac.hex())
|
||||
device = device_registry.async_get_device(
|
||||
connections={(dr.CONNECTION_NETWORK_MAC, mac)}
|
||||
)
|
||||
assert device
|
||||
assert device.name == mock_config_entry.title
|
||||
|
||||
|
||||
async def test_setup_entry_without_mac(
|
||||
hass: HomeAssistant,
|
||||
device_registry: dr.DeviceRegistry,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Tests the state attributes."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
mock_motionmount.mac = b"\x00\x00\x00\x00\x00\x00"
|
||||
|
||||
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
device = device_registry.async_get_device(
|
||||
identifiers={(DOMAIN, mock_config_entry.entry_id)}
|
||||
)
|
||||
assert device
|
||||
assert device.name == mock_config_entry.title
|
||||
|
||||
|
||||
async def test_setup_entry_failed_connect(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Tests the state attributes."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
mock_motionmount.connect.side_effect = TimeoutError()
|
||||
assert not await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||
|
||||
|
||||
async def test_setup_entry_wrong_device(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Tests the state attributes."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
mock_motionmount.mac = b"\x00\x00\x00\x00\x00\x01"
|
||||
assert not await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||
|
||||
|
||||
async def test_setup_entry_no_pin(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Tests the state attributes."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
mock_motionmount.is_authenticated = False
|
||||
assert not await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.SETUP_ERROR
|
||||
assert any(mock_config_entry.async_get_active_flows(hass, sources={SOURCE_REAUTH}))
|
||||
|
||||
|
||||
async def test_setup_entry_wrong_pin(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry_with_pin: MockConfigEntry,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Tests the state attributes."""
|
||||
mock_config_entry_with_pin.add_to_hass(hass)
|
||||
|
||||
mock_motionmount.is_authenticated = False
|
||||
assert not await hass.config_entries.async_setup(
|
||||
mock_config_entry_with_pin.entry_id
|
||||
)
|
||||
|
||||
assert mock_config_entry_with_pin.state is ConfigEntryState.SETUP_ERROR
|
||||
assert any(
|
||||
mock_config_entry_with_pin.async_get_active_flows(hass, sources={SOURCE_REAUTH})
|
||||
)
|
||||
|
||||
|
||||
async def test_unload_entry(
|
||||
hass: HomeAssistant,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
mock_motionmount: MagicMock,
|
||||
) -> None:
|
||||
"""Test entries are unloaded correctly."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
assert await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
assert await hass.config_entries.async_unload(mock_config_entry.entry_id)
|
||||
assert mock_motionmount.disconnect.call_count == 1
|
@ -7,12 +7,10 @@ import pytest
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from . import ZEROCONF_NAME
|
||||
from . import MAC, ZEROCONF_NAME
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
MAC = bytes.fromhex("c4dd57f8a55f")
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("entity_registry_enabled_by_default")
|
||||
@pytest.mark.parametrize(
|
||||
|
Loading…
x
Reference in New Issue
Block a user