mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Improve config flow for GIOS (#139935)
* Initial commit * Use TYPE_CHECKING * Update strings * Remove default value * Improve tests
This commit is contained in:
parent
d3a96ba688
commit
98cf936ff5
@ -3,7 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from typing import Any
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from aiohttp.client_exceptions import ClientConnectorError
|
||||
from gios import ApiError, Gios, InvalidSensorsDataError, NoStationError
|
||||
@ -12,6 +12,12 @@ import voluptuous as vol
|
||||
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
|
||||
from homeassistant.const import CONF_NAME
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.selector import (
|
||||
SelectOptionDict,
|
||||
SelectSelector,
|
||||
SelectSelectorConfig,
|
||||
SelectSelectorMode,
|
||||
)
|
||||
|
||||
from .const import API_TIMEOUT, CONF_STATION_ID, DOMAIN
|
||||
|
||||
@ -27,40 +33,59 @@ class GiosFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
"""Handle a flow initialized by the user."""
|
||||
errors = {}
|
||||
|
||||
if user_input is not None:
|
||||
try:
|
||||
await self.async_set_unique_id(
|
||||
str(user_input[CONF_STATION_ID]), raise_on_progress=False
|
||||
)
|
||||
self._abort_if_unique_id_configured()
|
||||
|
||||
websession = async_get_clientsession(self.hass)
|
||||
|
||||
if user_input is not None:
|
||||
station_id = user_input[CONF_STATION_ID]
|
||||
|
||||
try:
|
||||
await self.async_set_unique_id(station_id, raise_on_progress=False)
|
||||
self._abort_if_unique_id_configured()
|
||||
|
||||
async with asyncio.timeout(API_TIMEOUT):
|
||||
gios = await Gios.create(websession, user_input[CONF_STATION_ID])
|
||||
gios = await Gios.create(websession, int(station_id))
|
||||
await gios.async_update()
|
||||
|
||||
# GIOS treats station ID as int
|
||||
user_input[CONF_STATION_ID] = int(station_id)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
assert gios.station_name is not None
|
||||
|
||||
return self.async_create_entry(
|
||||
title=gios.station_name,
|
||||
data=user_input,
|
||||
)
|
||||
except (ApiError, ClientConnectorError, TimeoutError):
|
||||
errors["base"] = "cannot_connect"
|
||||
except NoStationError:
|
||||
errors[CONF_STATION_ID] = "wrong_station_id"
|
||||
except InvalidSensorsDataError:
|
||||
errors[CONF_STATION_ID] = "invalid_sensors_data"
|
||||
|
||||
try:
|
||||
gios = await Gios.create(websession)
|
||||
except (ApiError, ClientConnectorError, NoStationError):
|
||||
return self.async_abort(reason="cannot_connect")
|
||||
|
||||
options: list[SelectOptionDict] = [
|
||||
SelectOptionDict(value=str(station.id), label=station.name)
|
||||
for station in gios.measurement_stations.values()
|
||||
]
|
||||
|
||||
schema: vol.Schema = vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_STATION_ID): SelectSelector(
|
||||
SelectSelectorConfig(
|
||||
options=options,
|
||||
sort=True,
|
||||
mode=SelectSelectorMode.DROPDOWN,
|
||||
),
|
||||
),
|
||||
vol.Optional(CONF_NAME, default=self.hass.config.location_name): str,
|
||||
}
|
||||
)
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="user",
|
||||
data_schema=vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_STATION_ID): int,
|
||||
vol.Optional(
|
||||
CONF_NAME, default=self.hass.config.location_name
|
||||
): str,
|
||||
}
|
||||
),
|
||||
data_schema=schema,
|
||||
errors=errors,
|
||||
)
|
||||
|
@ -5,17 +5,17 @@
|
||||
"title": "GIO\u015a (Polish Chief Inspectorate Of Environmental Protection)",
|
||||
"data": {
|
||||
"name": "[%key:common::config_flow::data::name%]",
|
||||
"station_id": "ID of the measuring station"
|
||||
"station_id": "Measuring station"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"wrong_station_id": "ID of the measuring station is not correct.",
|
||||
"invalid_sensors_data": "Invalid sensors' data for this measuring station.",
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_location%]"
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_location%]",
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
|
||||
}
|
||||
},
|
||||
"system_health": {
|
||||
|
@ -6,7 +6,8 @@ from unittest.mock import patch
|
||||
from gios import ApiError
|
||||
|
||||
from homeassistant.components.gios import config_flow
|
||||
from homeassistant.components.gios.const import CONF_STATION_ID
|
||||
from homeassistant.components.gios.const import CONF_STATION_ID, DOMAIN
|
||||
from homeassistant.config_entries import SOURCE_USER
|
||||
from homeassistant.const import CONF_NAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
@ -17,36 +18,35 @@ from tests.common import load_fixture
|
||||
|
||||
CONFIG = {
|
||||
CONF_NAME: "Foo",
|
||||
CONF_STATION_ID: 123,
|
||||
CONF_STATION_ID: "123",
|
||||
}
|
||||
|
||||
|
||||
async def test_show_form(hass: HomeAssistant) -> None:
|
||||
"""Test that the form is served with no input."""
|
||||
flow = config_flow.GiosFlowHandler()
|
||||
flow.hass = hass
|
||||
|
||||
result = await flow.async_step_user(user_input=None)
|
||||
with patch(
|
||||
"homeassistant.components.gios.coordinator.Gios._get_stations",
|
||||
return_value=STATIONS,
|
||||
):
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
|
||||
assert result["type"] is FlowResultType.FORM
|
||||
assert result["step_id"] == "user"
|
||||
|
||||
|
||||
async def test_invalid_station_id(hass: HomeAssistant) -> None:
|
||||
"""Test that errors are shown when measuring station ID is invalid."""
|
||||
async def test_form_with_api_error(hass: HomeAssistant) -> None:
|
||||
"""Test the form is aborted because of API error."""
|
||||
with patch(
|
||||
"homeassistant.components.gios.coordinator.Gios._get_stations",
|
||||
return_value=STATIONS,
|
||||
side_effect=ApiError("error"),
|
||||
):
|
||||
flow = config_flow.GiosFlowHandler()
|
||||
flow.hass = hass
|
||||
flow.context = {}
|
||||
|
||||
result = await flow.async_step_user(
|
||||
user_input={CONF_NAME: "Foo", CONF_STATION_ID: 0}
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
|
||||
assert result["errors"] == {CONF_STATION_ID: "wrong_station_id"}
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
|
||||
|
||||
async def test_invalid_sensor_data(hass: HomeAssistant) -> None:
|
||||
@ -76,15 +76,23 @@ async def test_invalid_sensor_data(hass: HomeAssistant) -> None:
|
||||
|
||||
async def test_cannot_connect(hass: HomeAssistant) -> None:
|
||||
"""Test that errors are shown when cannot connect to GIOS server."""
|
||||
with patch(
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.gios.coordinator.Gios._get_stations",
|
||||
return_value=STATIONS,
|
||||
),
|
||||
patch(
|
||||
"homeassistant.components.gios.coordinator.Gios._async_get",
|
||||
side_effect=ApiError("error"),
|
||||
),
|
||||
):
|
||||
flow = config_flow.GiosFlowHandler()
|
||||
flow.hass = hass
|
||||
flow.context = {}
|
||||
|
||||
result = await flow.async_step_user(user_input=CONFIG)
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
result = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], CONFIG
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert result["errors"] == {"base": "cannot_connect"}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user