Files
core/tests/components/luci/test_config_flow.py
T

204 lines
7.0 KiB
Python

"""Tests for the luci config flow."""
from typing import Any
from unittest.mock import MagicMock
import pytest
from requests.exceptions import ConnectionError as RequestsConnectionError
from homeassistant.components.luci.const import DOMAIN
from homeassistant.config_entries import SOURCE_IMPORT, SOURCE_USER
from homeassistant.const import (
CONF_HOST,
CONF_PASSWORD,
CONF_SSL,
CONF_USERNAME,
CONF_VERIFY_SSL,
)
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
from tests.common import MockConfigEntry
REAUTH_INPUT = {
CONF_USERNAME: "root",
CONF_PASSWORD: "new-password",
}
USER_INPUT = {
CONF_HOST: "192.168.1.1",
CONF_USERNAME: "root",
CONF_PASSWORD: "password",
CONF_SSL: False,
CONF_VERIFY_SSL: True,
}
# Client configurations that make ``_try_connect`` fail, mapped to the error
# the flow should report. ``cannot_connect`` is a connection error raised by
# the client, ``invalid_auth`` is the client reporting it is not logged in.
CONNECT_ERRORS = [
({"side_effect": RequestsConnectionError}, "cannot_connect"),
({"return_value": False}, "invalid_auth"),
]
@pytest.mark.usefixtures("mock_setup_entry")
async def test_user_flow(hass: HomeAssistant, mock_luci_client: MagicMock) -> None:
"""Test the happy path of the user flow."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
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["title"] == "192.168.1.1"
assert result["data"] == USER_INPUT
@pytest.mark.usefixtures("mock_setup_entry", "mock_luci_client")
async def test_user_flow_already_configured(
hass: HomeAssistant, mock_config_entry: MockConfigEntry
) -> None:
"""Test the user flow aborts when the host is already configured."""
mock_config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
assert result["type"] is FlowResultType.FORM
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=USER_INPUT
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
@pytest.mark.parametrize(("client_config", "base_error"), CONNECT_ERRORS)
@pytest.mark.usefixtures("mock_setup_entry")
async def test_user_flow_errors(
hass: HomeAssistant,
mock_luci_client: MagicMock,
client_config: dict[str, Any],
base_error: str,
) -> None:
"""Test the user flow shows errors and recovers on retry."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}
)
assert result["type"] is FlowResultType.FORM
mock_luci_client.is_logged_in.configure_mock(**client_config)
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=USER_INPUT
)
assert result["type"] is FlowResultType.FORM
assert result["errors"] == {"base": base_error}
mock_luci_client.is_logged_in.configure_mock(side_effect=None, return_value=True)
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"] == USER_INPUT
@pytest.mark.usefixtures("mock_setup_entry")
async def test_import_flow(hass: HomeAssistant, mock_luci_client: MagicMock) -> None:
"""Test the happy path of the import flow."""
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_IMPORT}, data=USER_INPUT
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["title"] == "192.168.1.1"
assert result["data"] == USER_INPUT
@pytest.mark.usefixtures("mock_setup_entry", "mock_luci_client")
async def test_import_flow_already_configured(
hass: HomeAssistant, mock_config_entry: MockConfigEntry
) -> None:
"""Test the import flow aborts when the host is already configured."""
mock_config_entry.add_to_hass(hass)
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_IMPORT}, data=USER_INPUT
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
@pytest.mark.parametrize(("client_config", "reason"), CONNECT_ERRORS)
@pytest.mark.usefixtures("mock_setup_entry")
async def test_import_flow_errors(
hass: HomeAssistant,
mock_luci_client: MagicMock,
client_config: dict[str, Any],
reason: str,
) -> None:
"""Test the import flow aborts when connecting fails."""
mock_luci_client.is_logged_in.configure_mock(**client_config)
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_IMPORT}, data=USER_INPUT
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == reason
@pytest.mark.usefixtures("mock_setup_entry")
async def test_reauth_flow(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_luci_client: MagicMock,
) -> None:
"""Test the happy path of the reauth flow."""
mock_config_entry.add_to_hass(hass)
result = await mock_config_entry.start_reauth_flow(hass)
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=REAUTH_INPUT
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "reauth_successful"
assert mock_config_entry.data[CONF_PASSWORD] == "new-password"
@pytest.mark.parametrize(("client_config", "base_error"), CONNECT_ERRORS)
@pytest.mark.usefixtures("mock_setup_entry")
async def test_reauth_flow_errors(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_luci_client: MagicMock,
client_config: dict[str, Any],
base_error: str,
) -> None:
"""Test the reauth flow shows errors and recovers on retry."""
mock_config_entry.add_to_hass(hass)
result = await mock_config_entry.start_reauth_flow(hass)
assert result["type"] is FlowResultType.FORM
mock_luci_client.is_logged_in.configure_mock(**client_config)
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=REAUTH_INPUT
)
assert result["type"] is FlowResultType.FORM
assert result["step_id"] == "reauth_confirm"
assert result["errors"] == {"base": base_error}
mock_luci_client.is_logged_in.configure_mock(side_effect=None, return_value=True)
result = await hass.config_entries.flow.async_configure(
result["flow_id"], user_input=REAUTH_INPUT
)
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "reauth_successful"
assert mock_config_entry.data[CONF_PASSWORD] == "new-password"