core/tests/components/motionmount/test_config_flow.py

840 lines
26 KiB
Python

"""Tests for the Vogel's MotionMount config flow."""
import dataclasses
from datetime import timedelta
import socket
from unittest.mock import MagicMock, PropertyMock
from freezegun.api import FrozenDateTimeFactory
import motionmount
import pytest
from homeassistant.components.motionmount.const import DOMAIN
from homeassistant.config_entries import SOURCE_REAUTH, SOURCE_USER, SOURCE_ZEROCONF
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PIN, CONF_PORT
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
from . import (
HOST,
MOCK_PIN_INPUT,
MOCK_USER_INPUT,
MOCK_ZEROCONF_TVM_SERVICE_INFO_V1,
MOCK_ZEROCONF_TVM_SERVICE_INFO_V2,
PORT,
ZEROCONF_HOSTNAME,
ZEROCONF_MAC,
ZEROCONF_NAME,
)
from tests.common import MockConfigEntry, async_fire_time_changed
MAC = bytes.fromhex("c4dd57f8a55f")
pytestmark = pytest.mark.usefixtures("mock_setup_entry")
async def test_user_connection_error(
hass: HomeAssistant,
mock_motionmount_config_flow: MagicMock,
) -> None:
"""Test that the flow is aborted when there is an connection error."""
mock_motionmount_config_flow.connect.side_effect = ConnectionRefusedError()
user_input = MOCK_USER_INPUT.copy()
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
data=user_input,
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "cannot_connect"
async def test_user_connection_error_invalid_hostname(
hass: HomeAssistant,
mock_motionmount_config_flow: MagicMock,
) -> None:
"""Test that the flow is aborted when an invalid hostname is provided."""
mock_motionmount_config_flow.connect.side_effect = socket.gaierror()
user_input = MOCK_USER_INPUT.copy()
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
data=user_input,
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "cannot_connect"
async def test_user_timeout_error(
hass: HomeAssistant,
mock_motionmount_config_flow: MagicMock,
) -> None:
"""Test that the flow is aborted when there is a timeout error."""
mock_motionmount_config_flow.connect.side_effect = TimeoutError()
user_input = MOCK_USER_INPUT.copy()
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
data=user_input,
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "time_out"
async def test_user_not_connected_error(
hass: HomeAssistant,
mock_motionmount_config_flow: MagicMock,
) -> None:
"""Test that the flow is aborted when there is a not connected error."""
mock_motionmount_config_flow.connect.side_effect = motionmount.NotConnectedError()
user_input = MOCK_USER_INPUT.copy()
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
data=user_input,
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "not_connected"
async def test_user_response_error_single_device_new_ce_old_pro(
hass: HomeAssistant,
mock_motionmount_config_flow: 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"
)
user_input = MOCK_USER_INPUT.copy()
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
data=user_input,
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == ZEROCONF_NAME
assert result["data"]
assert result["data"][CONF_HOST] == HOST
assert result["data"][CONF_PORT] == PORT
assert result["result"]
async def test_user_response_error_single_device_new_ce_new_pro(
hass: HomeAssistant,
mock_motionmount_config_flow: 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)
user_input = MOCK_USER_INPUT.copy()
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
data=user_input,
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == ZEROCONF_NAME
assert result["data"]
assert result["data"][CONF_HOST] == HOST
assert result["data"][CONF_PORT] == PORT
assert result["result"]
assert result["result"].unique_id == ZEROCONF_MAC
async def test_user_response_error_multi_device_new_ce_new_pro(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_motionmount_config_flow: 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)
user_input = MOCK_USER_INPUT.copy()
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
data=user_input,
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
async def test_user_response_authentication_needed(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_motionmount_config_flow: 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
)
user_input = MOCK_USER_INPUT.copy()
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
data=user_input,
)
assert result["type"] is FlowResultType.FORM
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
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=MOCK_PIN_INPUT.copy(),
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == ZEROCONF_NAME
assert result["data"]
assert result["data"][CONF_HOST] == HOST
assert result["data"][CONF_PORT] == PORT
assert result["result"]
assert result["result"].unique_id == ZEROCONF_MAC
async def test_zeroconf_connection_error(
hass: HomeAssistant,
mock_motionmount_config_flow: MagicMock,
) -> None:
"""Test that the flow is aborted when there is an connection error."""
mock_motionmount_config_flow.connect.side_effect = ConnectionRefusedError()
discovery_info = dataclasses.replace(MOCK_ZEROCONF_TVM_SERVICE_INFO_V1)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_ZEROCONF},
data=discovery_info,
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "cannot_connect"
async def test_zeroconf_connection_error_invalid_hostname(
hass: HomeAssistant,
mock_motionmount_config_flow: MagicMock,
) -> None:
"""Test that the flow is aborted when there is an connection error."""
mock_motionmount_config_flow.connect.side_effect = socket.gaierror()
discovery_info = dataclasses.replace(MOCK_ZEROCONF_TVM_SERVICE_INFO_V1)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_ZEROCONF},
data=discovery_info,
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "cannot_connect"
async def test_zeroconf_timout_error(
hass: HomeAssistant,
mock_motionmount_config_flow: MagicMock,
) -> None:
"""Test that the flow is aborted when there is a timeout error."""
mock_motionmount_config_flow.connect.side_effect = TimeoutError()
discovery_info = dataclasses.replace(MOCK_ZEROCONF_TVM_SERVICE_INFO_V1)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_ZEROCONF},
data=discovery_info,
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "time_out"
async def test_zeroconf_not_connected_error(
hass: HomeAssistant,
mock_motionmount_config_flow: MagicMock,
) -> None:
"""Test that the flow is aborted when there is a not connected error."""
mock_motionmount_config_flow.connect.side_effect = motionmount.NotConnectedError()
discovery_info = dataclasses.replace(MOCK_ZEROCONF_TVM_SERVICE_INFO_V1)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_ZEROCONF},
data=discovery_info,
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "not_connected"
async def test_show_zeroconf_form_new_ce_old_pro(
hass: HomeAssistant,
mock_motionmount_config_flow: 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"
)
discovery_info = dataclasses.replace(MOCK_ZEROCONF_TVM_SERVICE_INFO_V1)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_ZEROCONF},
data=discovery_info,
)
assert result["step_id"] == "zeroconf_confirm"
assert result["type"] is FlowResultType.FORM
assert result["description_placeholders"] == {CONF_NAME: "My MotionMount"}
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={}
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == ZEROCONF_NAME
assert result["data"]
assert result["data"][CONF_HOST] == ZEROCONF_HOSTNAME
assert result["data"][CONF_PORT] == PORT
assert result["data"][CONF_NAME] == ZEROCONF_NAME
assert result["result"]
assert result["result"].unique_id is None
async def test_show_zeroconf_form_new_ce_new_pro(
hass: HomeAssistant,
mock_motionmount_config_flow: MagicMock,
) -> None:
"""Test that the zeroconf confirmation form is served."""
type(mock_motionmount_config_flow).mac = PropertyMock(return_value=MAC)
discovery_info = dataclasses.replace(MOCK_ZEROCONF_TVM_SERVICE_INFO_V2)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_ZEROCONF},
data=discovery_info,
)
assert result["step_id"] == "zeroconf_confirm"
assert result["type"] is FlowResultType.FORM
assert result["description_placeholders"] == {CONF_NAME: "My MotionMount"}
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={}
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == ZEROCONF_NAME
assert result["data"]
assert result["data"][CONF_HOST] == ZEROCONF_HOSTNAME
assert result["data"][CONF_PORT] == PORT
assert result["data"][CONF_NAME] == ZEROCONF_NAME
assert result["result"]
assert result["result"].unique_id == ZEROCONF_MAC
async def test_zeroconf_device_exists_abort(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_motionmount_config_flow: MagicMock,
) -> None:
"""Test we abort zeroconf flow if device already configured."""
mock_config_entry.add_to_hass(hass)
discovery_info = dataclasses.replace(MOCK_ZEROCONF_TVM_SERVICE_INFO_V2)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_ZEROCONF},
data=discovery_info,
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
async def test_zeroconf_authentication_needed(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_motionmount_config_flow: 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
)
discovery_info = dataclasses.replace(MOCK_ZEROCONF_TVM_SERVICE_INFO_V2)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_ZEROCONF},
data=discovery_info,
)
assert result["type"] is FlowResultType.FORM
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
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=MOCK_PIN_INPUT.copy(),
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == ZEROCONF_NAME
assert result["data"]
assert result["data"][CONF_HOST] == ZEROCONF_HOSTNAME
assert result["data"][CONF_PORT] == PORT
assert result["data"][CONF_NAME] == ZEROCONF_NAME
assert result["result"]
assert result["result"].unique_id == ZEROCONF_MAC
async def test_authentication_incorrect_then_correct_pin(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_motionmount_config_flow: 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
)
user_input = MOCK_USER_INPUT.copy()
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
data=user_input,
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "auth"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=MOCK_PIN_INPUT.copy(),
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "auth"
assert result["errors"]
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
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=MOCK_PIN_INPUT.copy(),
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == ZEROCONF_NAME
assert result["data"]
assert result["data"][CONF_HOST] == HOST
assert result["data"][CONF_PORT] == PORT
assert result["result"]
assert result["result"].unique_id == ZEROCONF_MAC
async def test_authentication_first_incorrect_pin_to_backoff(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_motionmount_config_flow: 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]
)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
data=MOCK_USER_INPUT.copy(),
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "auth"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=MOCK_PIN_INPUT.copy(),
)
assert mock_motionmount_config_flow.authenticate.called
assert result["type"] is FlowResultType.SHOW_PROGRESS
assert result["step_id"] == "backoff"
freezer.tick(timedelta(seconds=2))
async_fire_time_changed(hass)
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
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=MOCK_PIN_INPUT.copy(),
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == ZEROCONF_NAME
assert result["data"]
assert result["data"][CONF_HOST] == HOST
assert result["data"][CONF_PORT] == PORT
assert result["result"]
assert result["result"].unique_id == ZEROCONF_MAC
async def test_authentication_multiple_incorrect_pins(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_motionmount_config_flow: 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)
user_input = MOCK_USER_INPUT.copy()
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
data=user_input,
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "auth"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=MOCK_PIN_INPUT.copy(),
)
assert result["type"] is FlowResultType.SHOW_PROGRESS
assert result["step_id"] == "backoff"
freezer.tick(timedelta(seconds=2))
async_fire_time_changed(hass)
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
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=MOCK_PIN_INPUT.copy(),
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == ZEROCONF_NAME
assert result["data"]
assert result["data"][CONF_HOST] == HOST
assert result["data"][CONF_PORT] == PORT
assert result["result"]
assert result["result"].unique_id == ZEROCONF_MAC
async def test_authentication_show_backoff_when_still_running(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_motionmount_config_flow: 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)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
data=MOCK_USER_INPUT.copy(),
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "auth"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=MOCK_PIN_INPUT.copy(),
)
assert result["type"] is FlowResultType.SHOW_PROGRESS
assert result["step_id"] == "backoff"
# This situation happens when the user cancels the progress dialog and tries to
# configure the MotionMount again
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=None,
)
assert result["type"] is FlowResultType.SHOW_PROGRESS
assert result["step_id"] == "backoff"
freezer.tick(timedelta(seconds=2))
async_fire_time_changed(hass)
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
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=MOCK_PIN_INPUT.copy(),
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == ZEROCONF_NAME
assert result["data"]
assert result["data"][CONF_HOST] == HOST
assert result["data"][CONF_PORT] == PORT
assert result["result"]
assert result["result"].unique_id == ZEROCONF_MAC
async def test_authentication_correct_pin(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_motionmount_config_flow: 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
)
user_input = MOCK_USER_INPUT.copy()
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
data=user_input,
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "auth"
type(mock_motionmount_config_flow).is_authenticated = PropertyMock(
return_value=True
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=MOCK_PIN_INPUT.copy(),
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == ZEROCONF_NAME
assert result["data"]
assert result["data"][CONF_HOST] == HOST
assert result["data"][CONF_PORT] == PORT
assert result["result"]
assert result["result"].unique_id == ZEROCONF_MAC
async def test_full_user_flow_implementation(
hass: HomeAssistant,
mock_motionmount_config_flow: 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)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER},
)
assert result["step_id"] == "user"
assert result["type"] is FlowResultType.FORM
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=MOCK_USER_INPUT.copy(),
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == ZEROCONF_NAME
assert result["data"]
assert result["data"][CONF_HOST] == HOST
assert result["data"][CONF_PORT] == PORT
assert result["result"]
assert result["result"].unique_id == ZEROCONF_MAC
async def test_full_zeroconf_flow_implementation(
hass: HomeAssistant,
mock_motionmount_config_flow: 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)
discovery_info = dataclasses.replace(MOCK_ZEROCONF_TVM_SERVICE_INFO_V2)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_ZEROCONF},
data=discovery_info,
)
assert result["step_id"] == "zeroconf_confirm"
assert result["type"] is FlowResultType.FORM
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input={}
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == ZEROCONF_NAME
assert result["data"]
assert result["data"][CONF_HOST] == ZEROCONF_HOSTNAME
assert result["data"][CONF_PORT] == PORT
assert result["data"][CONF_NAME] == ZEROCONF_NAME
assert result["result"]
assert result["result"].unique_id == ZEROCONF_MAC
async def test_full_reauth_flow_implementation(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_motionmount_config_flow: MagicMock,
) -> None:
"""Test reauthentication."""
mock_config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={
"source": SOURCE_REAUTH,
"entry_id": mock_config_entry.entry_id,
},
)
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
)
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=MOCK_PIN_INPUT.copy(),
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "reauth_successful"