Remove Nextbus YAML import (#115277)
This commit is contained in:
parent
e7c247f1f0
commit
763df83cdb
4 changed files with 7 additions and 217 deletions
|
@ -7,7 +7,7 @@ from py_nextbus import NextBusClient
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
|
from homeassistant.config_entries import ConfigFlow, ConfigFlowResult
|
||||||
from homeassistant.const import CONF_NAME, CONF_STOP
|
from homeassistant.const import CONF_STOP
|
||||||
from homeassistant.helpers.selector import (
|
from homeassistant.helpers.selector import (
|
||||||
SelectOptionDict,
|
SelectOptionDict,
|
||||||
SelectSelector,
|
SelectSelector,
|
||||||
|
@ -102,41 +102,6 @@ class NextBusFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||||
"""Initialize NextBus config flow."""
|
"""Initialize NextBus config flow."""
|
||||||
self.data: dict[str, str] = {}
|
self.data: dict[str, str] = {}
|
||||||
self._client = NextBusClient(output_format="json")
|
self._client = NextBusClient(output_format="json")
|
||||||
_LOGGER.info("Init new config flow")
|
|
||||||
|
|
||||||
async def async_step_import(self, config_input: dict[str, str]) -> ConfigFlowResult:
|
|
||||||
"""Handle import of config."""
|
|
||||||
agency_tag = config_input[CONF_AGENCY]
|
|
||||||
route_tag = config_input[CONF_ROUTE]
|
|
||||||
stop_tag = config_input[CONF_STOP]
|
|
||||||
|
|
||||||
validation_result = await self.hass.async_add_executor_job(
|
|
||||||
_validate_import,
|
|
||||||
self._client,
|
|
||||||
agency_tag,
|
|
||||||
route_tag,
|
|
||||||
stop_tag,
|
|
||||||
)
|
|
||||||
if isinstance(validation_result, str):
|
|
||||||
return self.async_abort(reason=validation_result)
|
|
||||||
|
|
||||||
data = {
|
|
||||||
CONF_AGENCY: agency_tag,
|
|
||||||
CONF_ROUTE: route_tag,
|
|
||||||
CONF_STOP: stop_tag,
|
|
||||||
CONF_NAME: config_input.get(
|
|
||||||
CONF_NAME,
|
|
||||||
f"{config_input[CONF_AGENCY]} {config_input[CONF_ROUTE]}",
|
|
||||||
),
|
|
||||||
}
|
|
||||||
|
|
||||||
await self.async_set_unique_id(_unique_id_from_data(data))
|
|
||||||
self._abort_if_unique_id_configured()
|
|
||||||
|
|
||||||
return self.async_create_entry(
|
|
||||||
title=" ".join(validation_result),
|
|
||||||
data=data,
|
|
||||||
)
|
|
||||||
|
|
||||||
async def async_step_user(
|
async def async_step_user(
|
||||||
self,
|
self,
|
||||||
|
|
|
@ -6,20 +6,11 @@ from itertools import chain
|
||||||
import logging
|
import logging
|
||||||
from typing import cast
|
from typing import cast
|
||||||
|
|
||||||
import voluptuous as vol
|
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
|
||||||
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.components.sensor import (
|
|
||||||
PLATFORM_SCHEMA,
|
|
||||||
SensorDeviceClass,
|
|
||||||
SensorEntity,
|
|
||||||
)
|
|
||||||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
|
|
||||||
from homeassistant.const import CONF_NAME, CONF_STOP
|
from homeassistant.const import CONF_NAME, CONF_STOP
|
||||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
import homeassistant.helpers.config_validation as cv
|
|
||||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
|
|
||||||
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
|
|
||||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||||
from homeassistant.util.dt import utc_from_timestamp
|
from homeassistant.util.dt import utc_from_timestamp
|
||||||
|
|
||||||
|
@ -29,43 +20,6 @@ from .util import listify, maybe_first
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
|
||||||
{
|
|
||||||
vol.Required(CONF_AGENCY): cv.string,
|
|
||||||
vol.Required(CONF_ROUTE): cv.string,
|
|
||||||
vol.Required(CONF_STOP): cv.string,
|
|
||||||
vol.Optional(CONF_NAME): cv.string,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_platform(
|
|
||||||
hass: HomeAssistant,
|
|
||||||
config: ConfigType,
|
|
||||||
async_add_entities: AddEntitiesCallback,
|
|
||||||
discovery_info: DiscoveryInfoType | None = None,
|
|
||||||
) -> None:
|
|
||||||
"""Initialize nextbus import from config."""
|
|
||||||
async_create_issue(
|
|
||||||
hass,
|
|
||||||
HOMEASSISTANT_DOMAIN,
|
|
||||||
f"deprecated_yaml_{DOMAIN}",
|
|
||||||
is_fixable=False,
|
|
||||||
breaks_in_ha_version="2024.4.0",
|
|
||||||
severity=IssueSeverity.WARNING,
|
|
||||||
translation_key="deprecated_yaml",
|
|
||||||
translation_placeholders={
|
|
||||||
"domain": DOMAIN,
|
|
||||||
"integration_title": "NextBus",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
hass.async_create_task(
|
|
||||||
hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN, context={"source": SOURCE_IMPORT}, data=config
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def async_setup_entry(
|
async def async_setup_entry(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
|
|
@ -7,7 +7,7 @@ import pytest
|
||||||
|
|
||||||
from homeassistant import config_entries, setup
|
from homeassistant import config_entries, setup
|
||||||
from homeassistant.components.nextbus.const import CONF_AGENCY, CONF_ROUTE, DOMAIN
|
from homeassistant.components.nextbus.const import CONF_AGENCY, CONF_ROUTE, DOMAIN
|
||||||
from homeassistant.const import CONF_NAME, CONF_STOP
|
from homeassistant.const import CONF_STOP
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.data_entry_flow import FlowResultType
|
from homeassistant.data_entry_flow import FlowResultType
|
||||||
|
|
||||||
|
@ -29,81 +29,6 @@ def mock_nextbus() -> Generator[MagicMock, None, None]:
|
||||||
yield client
|
yield client
|
||||||
|
|
||||||
|
|
||||||
async def test_import_config(
|
|
||||||
hass: HomeAssistant, mock_setup_entry: MagicMock, mock_nextbus_lists: MagicMock
|
|
||||||
) -> None:
|
|
||||||
"""Test config is imported and component set up."""
|
|
||||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
|
||||||
data = {
|
|
||||||
CONF_AGENCY: "sf-muni",
|
|
||||||
CONF_ROUTE: "F",
|
|
||||||
CONF_STOP: "5650",
|
|
||||||
}
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN,
|
|
||||||
context={"source": config_entries.SOURCE_IMPORT},
|
|
||||||
data=data,
|
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
assert result.get("type") is FlowResultType.CREATE_ENTRY
|
|
||||||
assert (
|
|
||||||
result.get("title")
|
|
||||||
== "San Francisco Muni F - Market & Wharves Market St & 7th St (Outbound)"
|
|
||||||
)
|
|
||||||
assert result.get("data") == {CONF_NAME: "sf-muni F", **data}
|
|
||||||
|
|
||||||
assert len(mock_setup_entry.mock_calls) == 1
|
|
||||||
|
|
||||||
# Check duplicate entries are aborted
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN,
|
|
||||||
context={"source": config_entries.SOURCE_IMPORT},
|
|
||||||
data=data,
|
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
assert result.get("type") is FlowResultType.ABORT
|
|
||||||
assert result.get("reason") == "already_configured"
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
("override", "expected_reason"),
|
|
||||||
[
|
|
||||||
({CONF_AGENCY: "not muni"}, "invalid_agency"),
|
|
||||||
({CONF_ROUTE: "not F"}, "invalid_route"),
|
|
||||||
({CONF_STOP: "not 5650"}, "invalid_stop"),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
async def test_import_config_invalid(
|
|
||||||
hass: HomeAssistant,
|
|
||||||
mock_setup_entry: MagicMock,
|
|
||||||
mock_nextbus_lists: MagicMock,
|
|
||||||
override: dict[str, str],
|
|
||||||
expected_reason: str,
|
|
||||||
) -> None:
|
|
||||||
"""Test user is redirected to user setup flow because they have invalid config."""
|
|
||||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
|
||||||
|
|
||||||
data = {
|
|
||||||
CONF_AGENCY: "sf-muni",
|
|
||||||
CONF_ROUTE: "F",
|
|
||||||
CONF_STOP: "5650",
|
|
||||||
**override,
|
|
||||||
}
|
|
||||||
|
|
||||||
result = await hass.config_entries.flow.async_init(
|
|
||||||
DOMAIN,
|
|
||||||
context={"source": config_entries.SOURCE_IMPORT},
|
|
||||||
data=data,
|
|
||||||
)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
assert result.get("type") is FlowResultType.ABORT
|
|
||||||
assert result.get("reason") == expected_reason
|
|
||||||
|
|
||||||
|
|
||||||
async def test_user_config(
|
async def test_user_config(
|
||||||
hass: HomeAssistant, mock_setup_entry: MagicMock, mock_nextbus_lists: MagicMock
|
hass: HomeAssistant, mock_setup_entry: MagicMock, mock_nextbus_lists: MagicMock
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
|
@ -5,7 +5,7 @@ from copy import deepcopy
|
||||||
from unittest.mock import MagicMock, patch
|
from unittest.mock import MagicMock, patch
|
||||||
from urllib.error import HTTPError
|
from urllib.error import HTTPError
|
||||||
|
|
||||||
from py_nextbus.client import NextBusFormatError, NextBusHTTPError, RouteStop
|
from py_nextbus.client import NextBusFormatError, NextBusHTTPError
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components import sensor
|
from homeassistant.components import sensor
|
||||||
|
@ -13,10 +13,8 @@ from homeassistant.components.nextbus.const import CONF_AGENCY, CONF_ROUTE, DOMA
|
||||||
from homeassistant.components.nextbus.coordinator import NextBusDataUpdateCoordinator
|
from homeassistant.components.nextbus.coordinator import NextBusDataUpdateCoordinator
|
||||||
from homeassistant.config_entries import ConfigEntryState
|
from homeassistant.config_entries import ConfigEntryState
|
||||||
from homeassistant.const import CONF_NAME, CONF_STOP
|
from homeassistant.const import CONF_NAME, CONF_STOP
|
||||||
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import entity_registry as er, issue_registry as ir
|
|
||||||
from homeassistant.helpers.update_coordinator import UpdateFailed
|
from homeassistant.helpers.update_coordinator import UpdateFailed
|
||||||
from homeassistant.setup import async_setup_component
|
|
||||||
|
|
||||||
from tests.common import MockConfigEntry
|
from tests.common import MockConfigEntry
|
||||||
|
|
||||||
|
@ -107,58 +105,6 @@ async def assert_setup_sensor(
|
||||||
return config_entry
|
return config_entry
|
||||||
|
|
||||||
|
|
||||||
async def test_legacy_yaml_setup(
|
|
||||||
hass: HomeAssistant,
|
|
||||||
issue_registry: ir.IssueRegistry,
|
|
||||||
) -> None:
|
|
||||||
"""Test config setup and yaml deprecation."""
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.nextbus.config_flow.NextBusClient",
|
|
||||||
) as NextBusClient:
|
|
||||||
NextBusClient.return_value.get_predictions_for_multi_stops.return_value = (
|
|
||||||
BASIC_RESULTS
|
|
||||||
)
|
|
||||||
await async_setup_component(hass, sensor.DOMAIN, PLATFORM_CONFIG)
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
issue = issue_registry.async_get_issue(
|
|
||||||
HOMEASSISTANT_DOMAIN, f"deprecated_yaml_{DOMAIN}"
|
|
||||||
)
|
|
||||||
assert issue
|
|
||||||
|
|
||||||
|
|
||||||
async def test_valid_config(
|
|
||||||
hass: HomeAssistant, mock_nextbus: MagicMock, mock_nextbus_lists: MagicMock
|
|
||||||
) -> None:
|
|
||||||
"""Test that sensor is set up properly with valid config."""
|
|
||||||
await assert_setup_sensor(hass, CONFIG_BASIC)
|
|
||||||
|
|
||||||
|
|
||||||
async def test_verify_valid_state(
|
|
||||||
hass: HomeAssistant,
|
|
||||||
mock_nextbus: MagicMock,
|
|
||||||
mock_nextbus_lists: MagicMock,
|
|
||||||
mock_nextbus_predictions: MagicMock,
|
|
||||||
) -> None:
|
|
||||||
"""Verify all attributes are set from a valid response."""
|
|
||||||
await assert_setup_sensor(hass, CONFIG_BASIC)
|
|
||||||
entity = er.async_get(hass).async_get(SENSOR_ID)
|
|
||||||
assert entity
|
|
||||||
|
|
||||||
mock_nextbus_predictions.assert_called_once_with(
|
|
||||||
{RouteStop(VALID_ROUTE, VALID_STOP)}
|
|
||||||
)
|
|
||||||
|
|
||||||
state = hass.states.get(SENSOR_ID)
|
|
||||||
assert state is not None
|
|
||||||
assert state.state == "2019-03-28T21:09:31+00:00"
|
|
||||||
assert state.attributes["agency"] == VALID_AGENCY_TITLE
|
|
||||||
assert state.attributes["route"] == VALID_ROUTE_TITLE
|
|
||||||
assert state.attributes["stop"] == VALID_STOP_TITLE
|
|
||||||
assert state.attributes["direction"] == "Outbound"
|
|
||||||
assert state.attributes["upcoming"] == "1, 2, 3, 10"
|
|
||||||
|
|
||||||
|
|
||||||
async def test_message_dict(
|
async def test_message_dict(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
mock_nextbus: MagicMock,
|
mock_nextbus: MagicMock,
|
||||||
|
|
Loading…
Add table
Reference in a new issue