Remove yaml import from feedreader integration (#132278)

* Remove yaml import from feedreader integration

* Update homeassistant/components/feedreader/config_flow.py

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>

* Drop _max_entries class attribute

---------

Co-authored-by: epenet <6771947+epenet@users.noreply.github.com>
pull/132419/head
Jan Bouwhuis 2024-12-05 20:57:43 +01:00 committed by GitHub
parent e5851c20e9
commit 3a2460f9f9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 6 additions and 153 deletions

View File

@ -2,17 +2,12 @@
from __future__ import annotations
import voluptuous as vol
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.const import CONF_SCAN_INTERVAL, CONF_URL, Platform
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.helpers.typing import ConfigType
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_URL, Platform
from homeassistant.core import HomeAssistant
from homeassistant.util.hass_dict import HassKey
from .const import CONF_MAX_ENTRIES, DEFAULT_MAX_ENTRIES, DEFAULT_SCAN_INTERVAL, DOMAIN
from .const import CONF_MAX_ENTRIES, DOMAIN
from .coordinator import FeedReaderCoordinator, StoredData
type FeedReaderConfigEntry = ConfigEntry[FeedReaderCoordinator]
@ -21,60 +16,6 @@ CONF_URLS = "urls"
MY_KEY: HassKey[StoredData] = HassKey(DOMAIN)
CONFIG_SCHEMA = vol.Schema(
vol.All(
cv.deprecated(DOMAIN),
{
DOMAIN: vol.Schema(
{
vol.Required(CONF_URLS): vol.All(cv.ensure_list, [cv.url]),
vol.Optional(
CONF_SCAN_INTERVAL, default=DEFAULT_SCAN_INTERVAL
): cv.time_period,
vol.Optional(
CONF_MAX_ENTRIES, default=DEFAULT_MAX_ENTRIES
): cv.positive_int,
}
)
},
),
extra=vol.ALLOW_EXTRA,
)
async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
"""Set up the Feedreader component."""
if DOMAIN in config:
for url in config[DOMAIN][CONF_URLS]:
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data={
CONF_URL: url,
CONF_MAX_ENTRIES: config[DOMAIN][CONF_MAX_ENTRIES],
},
)
)
async_create_issue(
hass,
HOMEASSISTANT_DOMAIN,
f"deprecated_yaml_{DOMAIN}",
breaks_in_ha_version="2025.1.0",
is_fixable=False,
is_persistent=False,
issue_domain=DOMAIN,
severity=IssueSeverity.WARNING,
translation_key="deprecated_yaml",
translation_placeholders={
"domain": DOMAIN,
"integration_title": "Feedreader",
},
)
return True
async def async_setup_entry(hass: HomeAssistant, entry: FeedReaderConfigEntry) -> bool:
"""Set up Feedreader from a config entry."""

View File

@ -11,7 +11,6 @@ import feedparser
import voluptuous as vol
from homeassistant.config_entries import (
SOURCE_IMPORT,
ConfigEntry,
ConfigFlow,
ConfigFlowResult,
@ -20,13 +19,11 @@ from homeassistant.config_entries import (
from homeassistant.const import CONF_URL
from homeassistant.core import HomeAssistant, callback
import homeassistant.helpers.config_validation as cv
from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue
from homeassistant.helpers.selector import (
TextSelector,
TextSelectorConfig,
TextSelectorType,
)
from homeassistant.util import slugify
from .const import CONF_MAX_ENTRIES, DEFAULT_MAX_ENTRIES, DOMAIN
@ -42,7 +39,6 @@ class FeedReaderConfigFlow(ConfigFlow, domain=DOMAIN):
"""Handle a config flow."""
VERSION = 1
_max_entries: int | None = None
@staticmethod
@callback
@ -75,21 +71,6 @@ class FeedReaderConfigFlow(ConfigFlow, domain=DOMAIN):
errors=errors,
)
def abort_on_import_error(self, url: str, error: str) -> ConfigFlowResult:
"""Abort import flow on error."""
async_create_issue(
self.hass,
DOMAIN,
f"import_yaml_error_{DOMAIN}_{error}_{slugify(url)}",
breaks_in_ha_version="2025.1.0",
is_fixable=False,
issue_domain=DOMAIN,
severity=IssueSeverity.WARNING,
translation_key=f"import_yaml_error_{error}",
translation_placeholders={"url": url},
)
return self.async_abort(reason=error)
async def async_step_user(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:
@ -104,8 +85,6 @@ class FeedReaderConfigFlow(ConfigFlow, domain=DOMAIN):
if feed.bozo:
LOGGER.debug("feed bozo_exception: %s", feed.bozo_exception)
if isinstance(feed.bozo_exception, urllib.error.URLError):
if self.context["source"] == SOURCE_IMPORT:
return self.abort_on_import_error(user_input[CONF_URL], "url_error")
return self.show_user_form(user_input, {"base": "url_error"})
feed_title = html.unescape(feed["feed"]["title"])
@ -113,14 +92,9 @@ class FeedReaderConfigFlow(ConfigFlow, domain=DOMAIN):
return self.async_create_entry(
title=feed_title,
data=user_input,
options={CONF_MAX_ENTRIES: self._max_entries or DEFAULT_MAX_ENTRIES},
options={CONF_MAX_ENTRIES: DEFAULT_MAX_ENTRIES},
)
async def async_step_import(self, import_data: dict[str, Any]) -> ConfigFlowResult:
"""Handle an import flow."""
self._max_entries = import_data[CONF_MAX_ENTRIES]
return await self.async_step_user({CONF_URL: import_data[CONF_URL]})
async def async_step_reconfigure(
self, user_input: dict[str, Any] | None = None
) -> ConfigFlowResult:

View File

@ -5,7 +5,6 @@ import urllib
import pytest
from homeassistant.components.feedreader import CONF_URLS
from homeassistant.components.feedreader.const import (
CONF_MAX_ENTRIES,
DEFAULT_MAX_ENTRIES,
@ -13,10 +12,8 @@ from homeassistant.components.feedreader.const import (
)
from homeassistant.config_entries import SOURCE_USER
from homeassistant.const import CONF_URL
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType
from homeassistant.helpers import issue_registry as ir
from homeassistant.setup import async_setup_component
from . import create_mock_entry
from .const import FEED_TITLE, URL, VALID_CONFIG_DEFAULT
@ -95,65 +92,6 @@ async def test_user_errors(
assert result["options"][CONF_MAX_ENTRIES] == DEFAULT_MAX_ENTRIES
@pytest.mark.parametrize(
("data", "expected_data", "expected_options"),
[
({CONF_URLS: [URL]}, {CONF_URL: URL}, {CONF_MAX_ENTRIES: DEFAULT_MAX_ENTRIES}),
(
{CONF_URLS: [URL], CONF_MAX_ENTRIES: 5},
{CONF_URL: URL},
{CONF_MAX_ENTRIES: 5},
),
],
)
async def test_import(
hass: HomeAssistant,
issue_registry: ir.IssueRegistry,
data,
expected_data,
expected_options,
feedparser,
setup_entry,
) -> None:
"""Test starting an import flow."""
config_entries = hass.config_entries.async_entries(DOMAIN)
assert not config_entries
assert await async_setup_component(hass, DOMAIN, {DOMAIN: data})
config_entries = hass.config_entries.async_entries(DOMAIN)
assert config_entries
assert len(config_entries) == 1
assert config_entries[0].title == FEED_TITLE
assert config_entries[0].data == expected_data
assert config_entries[0].options == expected_options
assert issue_registry.async_get_issue(
HOMEASSISTANT_DOMAIN, "deprecated_yaml_feedreader"
)
async def test_import_errors(
hass: HomeAssistant,
issue_registry: ir.IssueRegistry,
feedparser,
setup_entry,
feed_one_event,
) -> None:
"""Test starting an import flow which results in an URL error."""
config_entries = hass.config_entries.async_entries(DOMAIN)
assert not config_entries
# raise URLError
feedparser.side_effect = urllib.error.URLError("Test")
feedparser.return_value = None
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {CONF_URLS: [URL]}})
assert issue_registry.async_get_issue(
DOMAIN,
"import_yaml_error_feedreader_url_error_http_some_rss_local_rss_feed_xml",
)
async def test_reconfigure(hass: HomeAssistant, feedparser) -> None:
"""Test starting a reconfigure flow."""
entry = create_mock_entry(VALID_CONFIG_DEFAULT)