mirror of
https://github.com/home-assistant/core.git
synced 2026-08-08 14:25:42 +01:00
204 lines
7.0 KiB
Python
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"
|