diff --git a/homeassistant/components/folder_watcher/__init__.py b/homeassistant/components/folder_watcher/__init__.py index 800a95509c2..3aeaa6f7ef2 100644 --- a/homeassistant/components/folder_watcher/__init__.py +++ b/homeassistant/components/folder_watcher/__init__.py @@ -4,9 +4,8 @@ from __future__ import annotations import logging import os -from typing import Any, cast +from typing import cast -import voluptuous as vol from watchdog.events import ( FileClosedEvent, FileCreatedEvent, @@ -19,69 +18,17 @@ from watchdog.events import ( ) from watchdog.observers import Observer -from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry +from homeassistant.config_entries import ConfigEntry from homeassistant.const import EVENT_HOMEASSISTANT_START, EVENT_HOMEASSISTANT_STOP from homeassistant.core import Event, HomeAssistant -import homeassistant.helpers.config_validation as cv from homeassistant.helpers.dispatcher import dispatcher_send from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue -from homeassistant.helpers.typing import ConfigType -from .const import CONF_FOLDER, CONF_PATTERNS, DEFAULT_PATTERN, DOMAIN, PLATFORMS +from .const import CONF_FOLDER, CONF_PATTERNS, DOMAIN, PLATFORMS _LOGGER = logging.getLogger(__name__) -CONFIG_SCHEMA = vol.Schema( - { - DOMAIN: vol.All( - cv.ensure_list, - [ - vol.Schema( - { - vol.Required(CONF_FOLDER): cv.isdir, - vol.Optional(CONF_PATTERNS, default=[DEFAULT_PATTERN]): vol.All( - cv.ensure_list, [cv.string] - ), - } - ) - ], - ) - }, - extra=vol.ALLOW_EXTRA, -) - - -async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: - """Set up the folder watcher.""" - if DOMAIN in config: - conf: list[dict[str, Any]] = config[DOMAIN] - for watcher in conf: - path: str = watcher[CONF_FOLDER] - if not hass.config.is_allowed_path(path): - async_create_issue( - hass, - DOMAIN, - f"import_failed_not_allowed_path_{path}", - is_fixable=False, - is_persistent=False, - severity=IssueSeverity.ERROR, - translation_key="import_failed_not_allowed_path", - translation_placeholders={ - "path": path, - "config_variable": "allowlist_external_dirs", - }, - ) - continue - hass.async_create_task( - hass.config_entries.flow.async_init( - DOMAIN, context={"source": SOURCE_IMPORT}, data=watcher - ) - ) - - return True - - async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Folder watcher from a config entry.""" diff --git a/homeassistant/components/folder_watcher/config_flow.py b/homeassistant/components/folder_watcher/config_flow.py index fe43cd1c725..eb176cfaf24 100644 --- a/homeassistant/components/folder_watcher/config_flow.py +++ b/homeassistant/components/folder_watcher/config_flow.py @@ -8,10 +8,8 @@ from typing import Any import voluptuous as vol -from homeassistant.components.homeassistant import DOMAIN as HOMEASSISTANT_DOMAIN from homeassistant.config_entries import ConfigFlowResult from homeassistant.core import callback -from homeassistant.helpers.issue_registry import IssueSeverity, async_create_issue from homeassistant.helpers.schema_config_entry_flow import ( SchemaCommonFlowHandler, SchemaConfigFlowHandler, @@ -46,28 +44,6 @@ async def validate_setup( return user_input -async def validate_import_setup( - handler: SchemaCommonFlowHandler, user_input: dict[str, Any] -) -> dict[str, Any]: - """Create issue on successful import.""" - async_create_issue( - handler.parent_handler.hass, - HOMEASSISTANT_DOMAIN, - f"deprecated_yaml_{DOMAIN}", - breaks_in_ha_version="2024.11.0", - is_fixable=False, - is_persistent=False, - issue_domain=DOMAIN, - severity=IssueSeverity.WARNING, - translation_key="deprecated_yaml", - translation_placeholders={ - "domain": DOMAIN, - "integration_title": "Folder Watcher", - }, - ) - return user_input - - OPTIONS_SCHEMA = vol.Schema( { vol.Optional(CONF_PATTERNS, default=[DEFAULT_PATTERN]): SelectSelector( @@ -88,9 +64,6 @@ DATA_SCHEMA = vol.Schema( CONFIG_FLOW = { "user": SchemaFlowFormStep(schema=DATA_SCHEMA, validate_user_input=validate_setup), - "import": SchemaFlowFormStep( - schema=DATA_SCHEMA, validate_user_input=validate_import_setup - ), } OPTIONS_FLOW = { "init": SchemaFlowFormStep(schema=OPTIONS_SCHEMA), diff --git a/tests/components/folder_watcher/test_config_flow.py b/tests/components/folder_watcher/test_config_flow.py index 745059717fb..3b41b5724fc 100644 --- a/tests/components/folder_watcher/test_config_flow.py +++ b/tests/components/folder_watcher/test_config_flow.py @@ -148,39 +148,3 @@ async def test_form_already_configured(hass: HomeAssistant, tmp_path: Path) -> N assert result["type"] == FlowResultType.ABORT assert result["reason"] == "already_configured" - - -async def test_import(hass: HomeAssistant, tmp_path: Path) -> None: - """Test import flow.""" - path = tmp_path.as_posix() - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": config_entries.SOURCE_IMPORT}, - data={CONF_FOLDER: path, CONF_PATTERNS: ["*"]}, - ) - await hass.async_block_till_done() - - assert result["type"] == FlowResultType.CREATE_ENTRY - assert result["title"] == f"Folder Watcher {path}" - assert result["options"] == {CONF_FOLDER: path, CONF_PATTERNS: ["*"]} - - -async def test_import_already_configured(hass: HomeAssistant, tmp_path: Path) -> None: - """Test we abort import when entry is already configured.""" - path = tmp_path.as_posix() - - entry = MockConfigEntry( - domain=DOMAIN, - title=f"Folder Watcher {path}", - data={CONF_FOLDER: path}, - ) - entry.add_to_hass(hass) - - result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": config_entries.SOURCE_IMPORT}, - data={CONF_FOLDER: path}, - ) - - assert result["type"] == FlowResultType.ABORT - assert result["reason"] == "already_configured" diff --git a/tests/components/folder_watcher/test_init.py b/tests/components/folder_watcher/test_init.py index 965ae33c4f8..f4a3b7e3630 100644 --- a/tests/components/folder_watcher/test_init.py +++ b/tests/components/folder_watcher/test_init.py @@ -1,33 +1,68 @@ """The tests for the folder_watcher component.""" -import os +from pathlib import Path from types import SimpleNamespace from unittest.mock import Mock, patch +from freezegun.api import FrozenDateTimeFactory + from homeassistant.components import folder_watcher +from homeassistant.components.folder_watcher.const import DOMAIN +from homeassistant.config_entries import SOURCE_USER, ConfigEntryState from homeassistant.core import HomeAssistant -from homeassistant.setup import async_setup_component +from homeassistant.helpers import issue_registry as ir + +from tests.common import MockConfigEntry -async def test_invalid_path_setup(hass: HomeAssistant) -> None: +async def test_invalid_path_setup( + hass: HomeAssistant, + tmp_path: Path, + freezer: FrozenDateTimeFactory, + issue_registry: ir.IssueRegistry, +) -> None: """Test that an invalid path is not set up.""" - assert not await async_setup_component( - hass, - folder_watcher.DOMAIN, - {folder_watcher.DOMAIN: {folder_watcher.CONF_FOLDER: "invalid_path"}}, + freezer.move_to("2022-04-19 10:31:02+00:00") + path = tmp_path.as_posix() + config_entry = MockConfigEntry( + domain=DOMAIN, + source=SOURCE_USER, + title=f"Folder Watcher {path!s}", + data={}, + options={"folder": str(path), "patterns": ["*"]}, + entry_id="1", ) + config_entry.add_to_hass(hass) -async def test_valid_path_setup(hass: HomeAssistant) -> None: + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + assert config_entry.state is ConfigEntryState.SETUP_ERROR + assert len(issue_registry.issues) == 1 + + +async def test_valid_path_setup( + hass: HomeAssistant, tmp_path: Path, freezer: FrozenDateTimeFactory +) -> None: """Test that a valid path is setup.""" - cwd = os.path.join(os.path.dirname(__file__)) - hass.config.allowlist_external_dirs = {cwd} - with patch.object(folder_watcher, "Watcher"): - assert await async_setup_component( - hass, - folder_watcher.DOMAIN, - {folder_watcher.DOMAIN: {folder_watcher.CONF_FOLDER: cwd}}, - ) + freezer.move_to("2022-04-19 10:31:02+00:00") + path = tmp_path.as_posix() + hass.config.allowlist_external_dirs = {path} + config_entry = MockConfigEntry( + domain=DOMAIN, + source=SOURCE_USER, + title=f"Folder Watcher {path!s}", + data={}, + options={"folder": str(path), "patterns": ["*"]}, + entry_id="1", + ) + + config_entry.add_to_hass(hass) + + await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + + assert config_entry.state is ConfigEntryState.LOADED def test_event() -> None: