150 lines
4.6 KiB
Python
150 lines
4.6 KiB
Python
"""Tests for the Rain Bird config flow."""
|
|
|
|
import asyncio
|
|
from collections.abc import Generator
|
|
from http import HTTPStatus
|
|
from unittest.mock import Mock, patch
|
|
|
|
import pytest
|
|
|
|
from homeassistant import config_entries
|
|
from homeassistant.components.rainbird import DOMAIN
|
|
from homeassistant.components.rainbird.const import ATTR_DURATION
|
|
from homeassistant.config_entries import ConfigEntryState
|
|
from homeassistant.const import CONF_HOST, CONF_PASSWORD
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.data_entry_flow import FlowResult, FlowResultType
|
|
|
|
from .conftest import (
|
|
CONFIG_ENTRY_DATA,
|
|
HOST,
|
|
PASSWORD,
|
|
SERIAL_RESPONSE,
|
|
URL,
|
|
mock_response,
|
|
)
|
|
|
|
from tests.test_util.aiohttp import AiohttpClientMocker, AiohttpClientMockResponse
|
|
|
|
|
|
@pytest.fixture(name="responses")
|
|
def mock_responses() -> list[AiohttpClientMockResponse]:
|
|
"""Set up fake serial number response when testing the connection."""
|
|
return [mock_response(SERIAL_RESPONSE)]
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
async def config_entry_data() -> None:
|
|
"""Fixture to disable config entry setup for exercising config flow."""
|
|
return None
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
async def mock_setup() -> Generator[Mock, None, None]:
|
|
"""Fixture for patching out integration setup."""
|
|
|
|
with patch(
|
|
"homeassistant.components.rainbird.async_setup_entry",
|
|
return_value=True,
|
|
) as mock_setup:
|
|
yield mock_setup
|
|
|
|
|
|
async def complete_flow(hass: HomeAssistant) -> FlowResult:
|
|
"""Start the config flow and enter the host and password."""
|
|
result = await hass.config_entries.flow.async_init(
|
|
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
|
)
|
|
assert result.get("type") == FlowResultType.FORM
|
|
assert result.get("step_id") == "user"
|
|
assert not result.get("errors")
|
|
assert "flow_id" in result
|
|
|
|
return await hass.config_entries.flow.async_configure(
|
|
result["flow_id"],
|
|
{CONF_HOST: HOST, CONF_PASSWORD: PASSWORD},
|
|
)
|
|
|
|
|
|
async def test_controller_flow(hass: HomeAssistant, mock_setup: Mock) -> None:
|
|
"""Test the controller is setup correctly."""
|
|
|
|
result = await complete_flow(hass)
|
|
assert result.get("type") == "create_entry"
|
|
assert result.get("title") == HOST
|
|
assert "result" in result
|
|
assert result["result"].data == CONFIG_ENTRY_DATA
|
|
assert result["result"].options == {ATTR_DURATION: 6}
|
|
|
|
assert len(mock_setup.mock_calls) == 1
|
|
|
|
|
|
async def test_controller_cannot_connect(
|
|
hass: HomeAssistant,
|
|
mock_setup: Mock,
|
|
responses: list[AiohttpClientMockResponse],
|
|
aioclient_mock: AiohttpClientMocker,
|
|
) -> None:
|
|
"""Test an error talking to the controller."""
|
|
|
|
# Controller response with a failure
|
|
responses.clear()
|
|
responses.append(
|
|
AiohttpClientMockResponse("POST", URL, status=HTTPStatus.SERVICE_UNAVAILABLE)
|
|
)
|
|
|
|
result = await complete_flow(hass)
|
|
assert result.get("type") == FlowResultType.FORM
|
|
assert result.get("step_id") == "user"
|
|
assert result.get("errors") == {"base": "cannot_connect"}
|
|
|
|
assert not mock_setup.mock_calls
|
|
|
|
|
|
async def test_controller_timeout(
|
|
hass: HomeAssistant,
|
|
mock_setup: Mock,
|
|
) -> None:
|
|
"""Test an error talking to the controller."""
|
|
|
|
with patch(
|
|
"homeassistant.components.rainbird.config_flow.async_timeout.timeout",
|
|
side_effect=asyncio.TimeoutError,
|
|
):
|
|
result = await complete_flow(hass)
|
|
assert result.get("type") == FlowResultType.FORM
|
|
assert result.get("step_id") == "user"
|
|
assert result.get("errors") == {"base": "timeout_connect"}
|
|
|
|
assert not mock_setup.mock_calls
|
|
|
|
|
|
async def test_options_flow(hass: HomeAssistant, mock_setup: Mock) -> None:
|
|
"""Test config flow options."""
|
|
|
|
# Setup config flow
|
|
result = await complete_flow(hass)
|
|
assert result.get("type") == "create_entry"
|
|
assert result.get("title") == HOST
|
|
assert "result" in result
|
|
assert result["result"].data == CONFIG_ENTRY_DATA
|
|
assert result["result"].options == {ATTR_DURATION: 6}
|
|
|
|
# Assert single config entry is loaded
|
|
config_entry = next(iter(hass.config_entries.async_entries(DOMAIN)))
|
|
assert config_entry.state == ConfigEntryState.LOADED
|
|
|
|
# Initiate the options flow
|
|
result = await hass.config_entries.options.async_init(config_entry.entry_id)
|
|
assert result.get("type") == FlowResultType.FORM
|
|
assert result.get("step_id") == "init"
|
|
|
|
# Change the default duration
|
|
result = await hass.config_entries.options.async_configure(
|
|
result["flow_id"], user_input={ATTR_DURATION: 5}
|
|
)
|
|
assert result.get("type") == FlowResultType.CREATE_ENTRY
|
|
assert config_entry.options == {
|
|
ATTR_DURATION: 5,
|
|
}
|