hass-core/tests/components/fritz/test_config_flow.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

766 lines
24 KiB
Python
Raw Normal View History

"""Tests for Fritz!Tools config flow."""
import dataclasses
from unittest.mock import patch
from fritzconnection.core.exceptions import (
FritzAuthorizationError,
FritzConnectionException,
FritzSecurityError,
)
import pytest
from homeassistant.components.device_tracker import (
CONF_CONSIDER_HOME,
DEFAULT_CONSIDER_HOME,
)
from homeassistant.components.fritz.const import (
CONF_OLD_DISCOVERY,
DOMAIN,
ERROR_AUTH_INVALID,
ERROR_CANNOT_CONNECT,
ERROR_UNKNOWN,
FRITZ_AUTH_EXCEPTIONS,
)
2022-01-29 06:06:19 +01:00
from homeassistant.components.ssdp import ATTR_UPNP_UDN
from homeassistant.config_entries import (
SOURCE_REAUTH,
SOURCE_RECONFIGURE,
SOURCE_SSDP,
SOURCE_USER,
)
from homeassistant.const import (
CONF_HOST,
CONF_PASSWORD,
CONF_PORT,
CONF_SSL,
CONF_USERNAME,
)
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
2022-01-29 06:06:19 +01:00
from .const import (
MOCK_FIRMWARE_INFO,
MOCK_IPS,
2022-01-29 06:06:19 +01:00
MOCK_REQUEST,
MOCK_SSDP_DATA,
MOCK_USER_DATA,
MOCK_USER_INPUT_ADVANCED,
MOCK_USER_INPUT_SIMPLE,
)
2022-01-29 06:06:19 +01:00
from tests.common import MockConfigEntry
@pytest.mark.parametrize(
("show_advanced_options", "user_input", "expected_config"),
[
(
True,
MOCK_USER_INPUT_ADVANCED,
{
CONF_HOST: "fake_host",
CONF_PASSWORD: "fake_pass",
CONF_USERNAME: "fake_user",
CONF_PORT: 1234,
CONF_SSL: False,
},
),
(
False,
MOCK_USER_INPUT_SIMPLE,
{
CONF_HOST: "fake_host",
CONF_PASSWORD: "fake_pass",
CONF_USERNAME: "fake_user",
CONF_PORT: 49000,
CONF_SSL: False,
},
),
(
False,
{**MOCK_USER_INPUT_SIMPLE, CONF_SSL: True},
{
CONF_HOST: "fake_host",
CONF_PASSWORD: "fake_pass",
CONF_USERNAME: "fake_user",
CONF_PORT: 49443,
CONF_SSL: True,
},
),
],
)
async def test_user(
hass: HomeAssistant,
fc_class_mock,
show_advanced_options: bool,
user_input: dict,
expected_config: dict,
) -> None:
"""Test starting a flow by user."""
with (
patch(
"homeassistant.components.fritz.config_flow.FritzConnection",
side_effect=fc_class_mock,
),
patch(
"homeassistant.components.fritz.coordinator.FritzBoxTools._update_device_info",
return_value=MOCK_FIRMWARE_INFO,
),
patch("homeassistant.components.fritz.async_setup_entry") as mock_setup_entry,
Add switch platform to Fritz (#51610) * Add switch platform to Fritz * Fix tests * Pylint * Small fix * Bump fritzprofiles to fix log level and identifier * Fix different WiFi networks with same name * Changed exposed attributes * Moved to extra_state * Remove redundant lambda * Add missing wait * Removed identifiers * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Add mapping dict * Device Profile disabled by default * Heavy cleanup * Tweak * Bug fix * Update homeassistant/components/fritz/switch.py Co-authored-by: Aaron David Schneider <aaron.schneider@nbi.ku.dk> * Fix port forward switching + small log improvement * Cleanup from old approach * Handle port mapping hot removal (from device) * Minor fixes * Typying * Removed lambda call * Last missing strict typing * Split get entities * Func rename * Move FritzBoxBaseSwitch to switch.py * Removed lambda * Update homeassistant/components/fritz/common.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/common.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Fixes after applying comments * Remvoed redundant try block * Removed broad-except * Optimized async/sync switch * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Address remaining comments * Optimize return list * More optimization for return lists * Some missing strict typing * Redundant typing * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Wrong if * Introduce const for profile status * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Fix mypy * Switch back to get_local_ip() * Address latest comments Co-authored-by: J. Nick Koston <nick@koston.org> Co-authored-by: Aaron David Schneider <aaron.schneider@nbi.ku.dk>
2021-06-29 17:57:34 +02:00
patch(
"requests.get",
) as mock_request_get,
patch(
"requests.post",
) as mock_request_post,
patch(
"homeassistant.components.fritz.config_flow.socket.gethostbyname",
return_value=MOCK_IPS["fritz.box"],
),
):
Add switch platform to Fritz (#51610) * Add switch platform to Fritz * Fix tests * Pylint * Small fix * Bump fritzprofiles to fix log level and identifier * Fix different WiFi networks with same name * Changed exposed attributes * Moved to extra_state * Remove redundant lambda * Add missing wait * Removed identifiers * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Add mapping dict * Device Profile disabled by default * Heavy cleanup * Tweak * Bug fix * Update homeassistant/components/fritz/switch.py Co-authored-by: Aaron David Schneider <aaron.schneider@nbi.ku.dk> * Fix port forward switching + small log improvement * Cleanup from old approach * Handle port mapping hot removal (from device) * Minor fixes * Typying * Removed lambda call * Last missing strict typing * Split get entities * Func rename * Move FritzBoxBaseSwitch to switch.py * Removed lambda * Update homeassistant/components/fritz/common.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/common.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Fixes after applying comments * Remvoed redundant try block * Removed broad-except * Optimized async/sync switch * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Address remaining comments * Optimize return list * More optimization for return lists * Some missing strict typing * Redundant typing * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Wrong if * Introduce const for profile status * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Fix mypy * Switch back to get_local_ip() * Address latest comments Co-authored-by: J. Nick Koston <nick@koston.org> Co-authored-by: Aaron David Schneider <aaron.schneider@nbi.ku.dk>
2021-06-29 17:57:34 +02:00
mock_request_get.return_value.status_code = 200
mock_request_get.return_value.content = MOCK_REQUEST
mock_request_post.return_value.status_code = 200
mock_request_post.return_value.text = MOCK_REQUEST
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={
"source": SOURCE_USER,
"show_advanced_options": show_advanced_options,
},
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=user_input
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["data"] == expected_config
assert (
result["options"][CONF_CONSIDER_HOME]
== DEFAULT_CONSIDER_HOME.total_seconds()
)
assert not result["result"].unique_id
assert mock_setup_entry.called
@pytest.mark.parametrize(
("show_advanced_options", "user_input"),
[(True, MOCK_USER_INPUT_ADVANCED), (False, MOCK_USER_INPUT_SIMPLE)],
)
async def test_user_already_configured(
hass: HomeAssistant,
fc_class_mock,
show_advanced_options: bool,
user_input,
) -> None:
"""Test starting a flow by user with an already configured device."""
mock_config = MockConfigEntry(domain=DOMAIN, data=user_input)
mock_config.add_to_hass(hass)
with (
patch(
"homeassistant.components.fritz.config_flow.FritzConnection",
side_effect=fc_class_mock,
),
patch(
"homeassistant.components.fritz.coordinator.FritzBoxTools._update_device_info",
return_value=MOCK_FIRMWARE_INFO,
),
patch(
Add switch platform to Fritz (#51610) * Add switch platform to Fritz * Fix tests * Pylint * Small fix * Bump fritzprofiles to fix log level and identifier * Fix different WiFi networks with same name * Changed exposed attributes * Moved to extra_state * Remove redundant lambda * Add missing wait * Removed identifiers * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Add mapping dict * Device Profile disabled by default * Heavy cleanup * Tweak * Bug fix * Update homeassistant/components/fritz/switch.py Co-authored-by: Aaron David Schneider <aaron.schneider@nbi.ku.dk> * Fix port forward switching + small log improvement * Cleanup from old approach * Handle port mapping hot removal (from device) * Minor fixes * Typying * Removed lambda call * Last missing strict typing * Split get entities * Func rename * Move FritzBoxBaseSwitch to switch.py * Removed lambda * Update homeassistant/components/fritz/common.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/common.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Fixes after applying comments * Remvoed redundant try block * Removed broad-except * Optimized async/sync switch * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Address remaining comments * Optimize return list * More optimization for return lists * Some missing strict typing * Redundant typing * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Wrong if * Introduce const for profile status * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Fix mypy * Switch back to get_local_ip() * Address latest comments Co-authored-by: J. Nick Koston <nick@koston.org> Co-authored-by: Aaron David Schneider <aaron.schneider@nbi.ku.dk>
2021-06-29 17:57:34 +02:00
"requests.get",
) as mock_request_get,
patch(
"requests.post",
) as mock_request_post,
patch(
"homeassistant.components.fritz.config_flow.socket.gethostbyname",
return_value=MOCK_IPS["fritz.box"],
),
):
Add switch platform to Fritz (#51610) * Add switch platform to Fritz * Fix tests * Pylint * Small fix * Bump fritzprofiles to fix log level and identifier * Fix different WiFi networks with same name * Changed exposed attributes * Moved to extra_state * Remove redundant lambda * Add missing wait * Removed identifiers * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Add mapping dict * Device Profile disabled by default * Heavy cleanup * Tweak * Bug fix * Update homeassistant/components/fritz/switch.py Co-authored-by: Aaron David Schneider <aaron.schneider@nbi.ku.dk> * Fix port forward switching + small log improvement * Cleanup from old approach * Handle port mapping hot removal (from device) * Minor fixes * Typying * Removed lambda call * Last missing strict typing * Split get entities * Func rename * Move FritzBoxBaseSwitch to switch.py * Removed lambda * Update homeassistant/components/fritz/common.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/common.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Fixes after applying comments * Remvoed redundant try block * Removed broad-except * Optimized async/sync switch * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Address remaining comments * Optimize return list * More optimization for return lists * Some missing strict typing * Redundant typing * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Wrong if * Introduce const for profile status * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Fix mypy * Switch back to get_local_ip() * Address latest comments Co-authored-by: J. Nick Koston <nick@koston.org> Co-authored-by: Aaron David Schneider <aaron.schneider@nbi.ku.dk>
2021-06-29 17:57:34 +02:00
mock_request_get.return_value.status_code = 200
mock_request_get.return_value.content = MOCK_REQUEST
mock_request_post.return_value.status_code = 200
mock_request_post.return_value.text = MOCK_REQUEST
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={
"source": SOURCE_USER,
"show_advanced_options": show_advanced_options,
},
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=MOCK_USER_INPUT_SIMPLE
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"]["base"] == "already_configured"
@pytest.mark.parametrize(
"error",
FRITZ_AUTH_EXCEPTIONS,
)
@pytest.mark.parametrize(
("show_advanced_options", "user_input"),
[(True, MOCK_USER_INPUT_ADVANCED), (False, MOCK_USER_INPUT_SIMPLE)],
)
async def test_exception_security(
hass: HomeAssistant,
error,
show_advanced_options: bool,
user_input,
) -> None:
"""Test starting a flow by user with invalid credentials."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER, "show_advanced_options": show_advanced_options},
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
with patch(
"homeassistant.components.fritz.config_flow.FritzConnection",
side_effect=error,
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=user_input
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"]["base"] == ERROR_AUTH_INVALID
@pytest.mark.parametrize(
("show_advanced_options", "user_input"),
[(True, MOCK_USER_INPUT_ADVANCED), (False, MOCK_USER_INPUT_SIMPLE)],
)
async def test_exception_connection(
hass: HomeAssistant,
show_advanced_options: bool,
user_input,
) -> None:
"""Test starting a flow by user with a connection error."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER, "show_advanced_options": show_advanced_options},
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
with patch(
"homeassistant.components.fritz.config_flow.FritzConnection",
side_effect=FritzConnectionException,
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=user_input
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"]["base"] == ERROR_CANNOT_CONNECT
@pytest.mark.parametrize(
("show_advanced_options", "user_input"),
[(True, MOCK_USER_INPUT_ADVANCED), (False, MOCK_USER_INPUT_SIMPLE)],
)
async def test_exception_unknown(
hass: HomeAssistant, show_advanced_options: bool, user_input
) -> None:
"""Test starting a flow by user with an unknown exception."""
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_USER, "show_advanced_options": show_advanced_options},
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
with patch(
"homeassistant.components.fritz.config_flow.FritzConnection",
side_effect=OSError,
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=user_input
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"]["base"] == ERROR_UNKNOWN
async def test_reauth_successful(
hass: HomeAssistant,
fc_class_mock,
) -> None:
"""Test starting a reauthentication flow."""
mock_config = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
mock_config.add_to_hass(hass)
with (
patch(
"homeassistant.components.fritz.config_flow.FritzConnection",
side_effect=fc_class_mock,
),
patch(
"homeassistant.components.fritz.coordinator.FritzBoxTools._update_device_info",
return_value=MOCK_FIRMWARE_INFO,
),
patch(
"homeassistant.components.fritz.async_setup_entry",
Add switch platform to Fritz (#51610) * Add switch platform to Fritz * Fix tests * Pylint * Small fix * Bump fritzprofiles to fix log level and identifier * Fix different WiFi networks with same name * Changed exposed attributes * Moved to extra_state * Remove redundant lambda * Add missing wait * Removed identifiers * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Add mapping dict * Device Profile disabled by default * Heavy cleanup * Tweak * Bug fix * Update homeassistant/components/fritz/switch.py Co-authored-by: Aaron David Schneider <aaron.schneider@nbi.ku.dk> * Fix port forward switching + small log improvement * Cleanup from old approach * Handle port mapping hot removal (from device) * Minor fixes * Typying * Removed lambda call * Last missing strict typing * Split get entities * Func rename * Move FritzBoxBaseSwitch to switch.py * Removed lambda * Update homeassistant/components/fritz/common.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/common.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Fixes after applying comments * Remvoed redundant try block * Removed broad-except * Optimized async/sync switch * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Address remaining comments * Optimize return list * More optimization for return lists * Some missing strict typing * Redundant typing * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Wrong if * Introduce const for profile status * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Fix mypy * Switch back to get_local_ip() * Address latest comments Co-authored-by: J. Nick Koston <nick@koston.org> Co-authored-by: Aaron David Schneider <aaron.schneider@nbi.ku.dk>
2021-06-29 17:57:34 +02:00
) as mock_setup_entry,
patch(
"requests.get",
) as mock_request_get,
patch(
"requests.post",
) as mock_request_post,
):
mock_request_get.return_value.status_code = 200
mock_request_get.return_value.content = MOCK_REQUEST
mock_request_post.return_value.status_code = 200
mock_request_post.return_value.text = MOCK_REQUEST
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_REAUTH, "entry_id": mock_config.entry_id},
data=mock_config.data,
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "reauth_confirm"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_USERNAME: "other_fake_user",
CONF_PASSWORD: "other_fake_password",
},
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "reauth_successful"
assert mock_setup_entry.called
@pytest.mark.parametrize(
("side_effect", "error"),
[
(FritzAuthorizationError, ERROR_AUTH_INVALID),
(FritzConnectionException, ERROR_CANNOT_CONNECT),
(FritzSecurityError, ERROR_AUTH_INVALID),
],
)
async def test_reauth_not_successful(
hass: HomeAssistant,
fc_class_mock,
side_effect,
error,
) -> None:
"""Test starting a reauthentication flow but no connection found."""
mock_config = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
mock_config.add_to_hass(hass)
with patch(
"homeassistant.components.fritz.config_flow.FritzConnection",
side_effect=side_effect,
):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_REAUTH, "entry_id": mock_config.entry_id},
data=mock_config.data,
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "reauth_confirm"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_USERNAME: "other_fake_user",
CONF_PASSWORD: "other_fake_password",
},
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "reauth_confirm"
assert result["errors"]["base"] == error
@pytest.mark.parametrize(
("show_advanced_options", "user_input", "expected_config"),
[
(
True,
{CONF_HOST: "host_a", CONF_PORT: 49000, CONF_SSL: False},
{CONF_HOST: "host_a", CONF_PORT: 49000, CONF_SSL: False},
),
(
True,
{CONF_HOST: "host_a", CONF_PORT: 49443, CONF_SSL: True},
{CONF_HOST: "host_a", CONF_PORT: 49443, CONF_SSL: True},
),
(
True,
{CONF_HOST: "host_a", CONF_PORT: 12345, CONF_SSL: True},
{CONF_HOST: "host_a", CONF_PORT: 12345, CONF_SSL: True},
),
(
False,
{CONF_HOST: "host_b", CONF_SSL: False},
{CONF_HOST: "host_b", CONF_PORT: 49000, CONF_SSL: False},
),
(
False,
{CONF_HOST: "host_b", CONF_SSL: True},
{CONF_HOST: "host_b", CONF_PORT: 49443, CONF_SSL: True},
),
],
)
async def test_reconfigure_successful(
hass: HomeAssistant,
fc_class_mock,
show_advanced_options: bool,
user_input: dict,
expected_config: dict,
) -> None:
"""Test starting a reconfigure flow."""
mock_config = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
mock_config.add_to_hass(hass)
with (
patch(
"homeassistant.components.fritz.config_flow.FritzConnection",
side_effect=fc_class_mock,
),
patch(
"homeassistant.components.fritz.coordinator.FritzBoxTools._update_device_info",
return_value=MOCK_FIRMWARE_INFO,
),
patch(
"homeassistant.components.fritz.async_setup_entry",
) as mock_setup_entry,
patch(
"requests.get",
) as mock_request_get,
patch(
"requests.post",
) as mock_request_post,
):
mock_request_get.return_value.status_code = 200
mock_request_get.return_value.content = MOCK_REQUEST
mock_request_post.return_value.status_code = 200
mock_request_post.return_value.text = MOCK_REQUEST
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={
"source": SOURCE_RECONFIGURE,
"entry_id": mock_config.entry_id,
"show_advanced_options": show_advanced_options,
},
data=mock_config.data,
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "reconfigure_confirm"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input=user_input,
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "reconfigure_successful"
assert mock_config.data == {
**expected_config,
CONF_USERNAME: "fake_user",
CONF_PASSWORD: "fake_pass",
}
assert mock_setup_entry.called
async def test_reconfigure_not_successful(
hass: HomeAssistant,
fc_class_mock,
) -> None:
"""Test starting a reconfigure flow but no connection found."""
mock_config = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
mock_config.add_to_hass(hass)
with (
patch(
"homeassistant.components.fritz.config_flow.FritzConnection",
side_effect=[FritzConnectionException, fc_class_mock],
),
patch(
"homeassistant.components.fritz.coordinator.FritzBoxTools._update_device_info",
return_value=MOCK_FIRMWARE_INFO,
),
patch(
"homeassistant.components.fritz.async_setup_entry",
),
patch(
"requests.get",
) as mock_request_get,
patch(
"requests.post",
) as mock_request_post,
):
mock_request_get.return_value.status_code = 200
mock_request_get.return_value.content = MOCK_REQUEST
mock_request_post.return_value.status_code = 200
mock_request_post.return_value.text = MOCK_REQUEST
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_RECONFIGURE, "entry_id": mock_config.entry_id},
data=mock_config.data,
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "reconfigure_confirm"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_HOST: "fake_host",
CONF_SSL: False,
},
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "reconfigure_confirm"
assert result["errors"]["base"] == ERROR_CANNOT_CONNECT
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_HOST: "fake_host",
CONF_SSL: False,
},
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "reconfigure_successful"
assert mock_config.data == {
CONF_HOST: "fake_host",
CONF_PASSWORD: "fake_pass",
CONF_USERNAME: "fake_user",
CONF_PORT: 49000,
CONF_SSL: False,
}
async def test_ssdp_already_configured(hass: HomeAssistant, fc_class_mock) -> None:
"""Test starting a flow from discovery with an already configured device."""
mock_config = MockConfigEntry(
domain=DOMAIN,
data=MOCK_USER_DATA,
unique_id="only-a-test",
)
mock_config.add_to_hass(hass)
with (
patch(
"homeassistant.components.fritz.config_flow.FritzConnection",
side_effect=fc_class_mock,
),
patch(
"homeassistant.components.fritz.config_flow.socket.gethostbyname",
return_value=MOCK_IPS["fritz.box"],
),
):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_SSDP}, data=MOCK_SSDP_DATA
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
async def test_ssdp_already_configured_host(hass: HomeAssistant, fc_class_mock) -> None:
"""Test starting a flow from discovery with an already configured host."""
mock_config = MockConfigEntry(
domain=DOMAIN,
data=MOCK_USER_DATA,
unique_id="different-test",
)
mock_config.add_to_hass(hass)
with (
patch(
"homeassistant.components.fritz.config_flow.FritzConnection",
side_effect=fc_class_mock,
),
patch(
"homeassistant.components.fritz.config_flow.socket.gethostbyname",
return_value=MOCK_IPS["fritz.box"],
),
):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_SSDP}, data=MOCK_SSDP_DATA
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
async def test_ssdp_already_configured_host_uuid(
hass: HomeAssistant, fc_class_mock
) -> None:
2021-06-11 14:35:03 +03:00
"""Test starting a flow from discovery with an already configured uuid."""
mock_config = MockConfigEntry(
domain=DOMAIN,
data=MOCK_USER_DATA,
unique_id=None,
)
mock_config.add_to_hass(hass)
with (
patch(
"homeassistant.components.fritz.config_flow.FritzConnection",
side_effect=fc_class_mock,
),
patch(
"homeassistant.components.fritz.config_flow.socket.gethostbyname",
return_value=MOCK_IPS["fritz.box"],
),
):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_SSDP}, data=MOCK_SSDP_DATA
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
async def test_ssdp_already_in_progress_host(
hass: HomeAssistant, fc_class_mock
) -> None:
"""Test starting a flow from discovery twice."""
with patch(
"homeassistant.components.fritz.config_flow.FritzConnection",
side_effect=fc_class_mock,
):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_SSDP}, data=MOCK_SSDP_DATA
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "confirm"
MOCK_NO_UNIQUE_ID = dataclasses.replace(MOCK_SSDP_DATA)
MOCK_NO_UNIQUE_ID.upnp = MOCK_NO_UNIQUE_ID.upnp.copy()
del MOCK_NO_UNIQUE_ID.upnp[ATTR_UPNP_UDN]
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_SSDP}, data=MOCK_NO_UNIQUE_ID
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_in_progress"
async def test_ssdp(hass: HomeAssistant, fc_class_mock) -> None:
"""Test starting a flow from discovery."""
with (
patch(
"homeassistant.components.fritz.config_flow.FritzConnection",
side_effect=fc_class_mock,
),
patch(
"homeassistant.components.fritz.coordinator.FritzBoxTools._update_device_info",
return_value=MOCK_FIRMWARE_INFO,
),
patch("homeassistant.components.fritz.async_setup_entry") as mock_setup_entry,
Add switch platform to Fritz (#51610) * Add switch platform to Fritz * Fix tests * Pylint * Small fix * Bump fritzprofiles to fix log level and identifier * Fix different WiFi networks with same name * Changed exposed attributes * Moved to extra_state * Remove redundant lambda * Add missing wait * Removed identifiers * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Add mapping dict * Device Profile disabled by default * Heavy cleanup * Tweak * Bug fix * Update homeassistant/components/fritz/switch.py Co-authored-by: Aaron David Schneider <aaron.schneider@nbi.ku.dk> * Fix port forward switching + small log improvement * Cleanup from old approach * Handle port mapping hot removal (from device) * Minor fixes * Typying * Removed lambda call * Last missing strict typing * Split get entities * Func rename * Move FritzBoxBaseSwitch to switch.py * Removed lambda * Update homeassistant/components/fritz/common.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/common.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Fixes after applying comments * Remvoed redundant try block * Removed broad-except * Optimized async/sync switch * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Address remaining comments * Optimize return list * More optimization for return lists * Some missing strict typing * Redundant typing * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Wrong if * Introduce const for profile status * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Update homeassistant/components/fritz/switch.py Co-authored-by: J. Nick Koston <nick@koston.org> * Fix mypy * Switch back to get_local_ip() * Address latest comments Co-authored-by: J. Nick Koston <nick@koston.org> Co-authored-by: Aaron David Schneider <aaron.schneider@nbi.ku.dk>
2021-06-29 17:57:34 +02:00
patch("requests.get") as mock_request_get,
patch("requests.post") as mock_request_post,
):
mock_request_get.return_value.status_code = 200
mock_request_get.return_value.content = MOCK_REQUEST
mock_request_post.return_value.status_code = 200
mock_request_post.return_value.text = MOCK_REQUEST
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_SSDP}, data=MOCK_SSDP_DATA
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "confirm"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_USERNAME: "fake_user",
CONF_PASSWORD: "fake_pass",
},
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["data"][CONF_HOST] == MOCK_IPS["fritz.box"]
assert result["data"][CONF_PASSWORD] == "fake_pass"
assert result["data"][CONF_USERNAME] == "fake_user"
assert mock_setup_entry.called
async def test_ssdp_exception(hass: HomeAssistant) -> None:
"""Test starting a flow from discovery but no device found."""
with patch(
"homeassistant.components.fritz.config_flow.FritzConnection",
side_effect=FritzConnectionException,
):
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_SSDP}, data=MOCK_SSDP_DATA
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "confirm"
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_USERNAME: "fake_user",
CONF_PASSWORD: "fake_pass",
},
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "confirm"
async def test_options_flow(hass: HomeAssistant) -> None:
"""Test options flow."""
mock_config = MockConfigEntry(domain=DOMAIN, data=MOCK_USER_DATA)
mock_config.add_to_hass(hass)
result = await hass.config_entries.options.async_init(mock_config.entry_id)
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={
CONF_CONSIDER_HOME: 37,
},
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["data"] == {
CONF_OLD_DISCOVERY: False,
CONF_CONSIDER_HOME: 37,
}