Remove deprecated yaml import from local file (#143405)

This commit is contained in:
Michael 2025-04-22 11:50:28 +02:00 committed by GitHub
parent 39807abc7d
commit e9269a1d33
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 10 additions and 226 deletions

View File

@ -7,38 +7,19 @@ import mimetypes
import voluptuous as vol
from homeassistant.components.camera import (
PLATFORM_SCHEMA as CAMERA_PLATFORM_SCHEMA,
Camera,
)
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry
from homeassistant.components.camera import Camera
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_FILE_PATH, CONF_NAME
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ServiceValidationError
from homeassistant.helpers import (
config_validation as cv,
entity_platform,
issue_registry as ir,
)
from homeassistant.helpers.entity_platform import (
AddConfigEntryEntitiesCallback,
AddEntitiesCallback,
)
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.util import slugify
from homeassistant.helpers import config_validation as cv, entity_platform
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .const import DEFAULT_NAME, DOMAIN, SERVICE_UPDATE_FILE_PATH
from .const import SERVICE_UPDATE_FILE_PATH
from .util import check_file_path_access
_LOGGER = logging.getLogger(__name__)
PLATFORM_SCHEMA = CAMERA_PLATFORM_SCHEMA.extend(
{
vol.Required(CONF_FILE_PATH): cv.string,
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
}
)
async def async_setup_entry(
hass: HomeAssistant,
@ -67,57 +48,6 @@ async def async_setup_entry(
)
async def async_setup_platform(
hass: HomeAssistant,
config: ConfigType,
async_add_entities: AddEntitiesCallback,
discovery_info: DiscoveryInfoType | None = None,
) -> None:
"""Set up the Camera that works with local files."""
file_path: str = config[CONF_FILE_PATH]
file_path_slug = slugify(file_path)
if not await hass.async_add_executor_job(check_file_path_access, file_path):
ir.async_create_issue(
hass,
DOMAIN,
f"no_access_path_{file_path_slug}",
breaks_in_ha_version="2025.5.0",
is_fixable=False,
learn_more_url="https://www.home-assistant.io/integrations/local_file/",
severity=ir.IssueSeverity.WARNING,
translation_key="no_access_path",
translation_placeholders={
"file_path": file_path_slug,
},
)
return
ir.async_create_issue(
hass,
HOMEASSISTANT_DOMAIN,
f"deprecated_yaml_{DOMAIN}",
breaks_in_ha_version="2025.5.0",
is_fixable=False,
issue_domain=DOMAIN,
learn_more_url="https://www.home-assistant.io/integrations/local_file/",
severity=ir.IssueSeverity.WARNING,
translation_key="deprecated_yaml",
translation_placeholders={
"domain": DOMAIN,
"integration_title": "Local file",
},
)
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN,
context={"source": SOURCE_IMPORT},
data=config,
)
)
class LocalFile(Camera):
"""Representation of a local file camera."""

View File

@ -50,18 +50,12 @@ DATA_SCHEMA_SETUP = vol.Schema(
CONFIG_FLOW = {
"user": SchemaFlowFormStep(
schema=DATA_SCHEMA_SETUP,
validate_user_input=validate_options,
),
"import": SchemaFlowFormStep(
schema=DATA_SCHEMA_SETUP,
validate_user_input=validate_options,
),
schema=DATA_SCHEMA_SETUP, validate_user_input=validate_options
)
}
OPTIONS_FLOW = {
"init": SchemaFlowFormStep(
DATA_SCHEMA_OPTIONS,
validate_user_input=validate_options,
DATA_SCHEMA_OPTIONS, validate_user_input=validate_options
)
}

View File

@ -53,11 +53,5 @@
"file_path_not_accessible": {
"message": "Path {file_path} is not accessible"
}
},
"issues": {
"no_access_path": {
"title": "Incorrect file path",
"description": "While trying to import your configuration the provided file path {file_path} could not be read.\nPlease update your configuration to a correct file path and restart to fix this issue."
}
}
}

View File

@ -13,11 +13,8 @@ from homeassistant.components.local_file.const import (
)
from homeassistant.config_entries import SOURCE_USER
from homeassistant.const import ATTR_ENTITY_ID, CONF_FILE_PATH
from homeassistant.core import DOMAIN as HOMEASSISTANT_DOMAIN, HomeAssistant
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ServiceValidationError
from homeassistant.helpers import issue_registry as ir
from homeassistant.setup import async_setup_component
from homeassistant.util import slugify
from tests.common import MockConfigEntry
from tests.typing import ClientSessionGenerator
@ -212,76 +209,3 @@ async def test_update_file_path(
service_data,
blocking=True,
)
async def test_import_from_yaml_success(
hass: HomeAssistant, issue_registry: ir.IssueRegistry
) -> None:
"""Test import."""
with (
patch("os.path.isfile", Mock(return_value=True)),
patch("os.access", Mock(return_value=True)),
patch(
"homeassistant.components.local_file.camera.mimetypes.guess_type",
Mock(return_value=(None, None)),
),
):
await async_setup_component(
hass,
"camera",
{
"camera": {
"name": "config_test",
"platform": "local_file",
"file_path": "mock.file",
}
},
)
await hass.async_block_till_done()
assert hass.config_entries.async_has_entries(DOMAIN)
state = hass.states.get("camera.config_test")
assert state.attributes.get("file_path") == "mock.file"
issue = issue_registry.async_get_issue(
HOMEASSISTANT_DOMAIN, f"deprecated_yaml_{DOMAIN}"
)
assert issue
assert issue.translation_key == "deprecated_yaml"
async def test_import_from_yaml_fails(
hass: HomeAssistant, issue_registry: ir.IssueRegistry
) -> None:
"""Test import fails due to not accessible file."""
with (
patch("os.path.isfile", Mock(return_value=True)),
patch("os.access", Mock(return_value=False)),
patch(
"homeassistant.components.local_file.camera.mimetypes.guess_type",
Mock(return_value=(None, None)),
),
):
await async_setup_component(
hass,
"camera",
{
"camera": {
"name": "config_test",
"platform": "local_file",
"file_path": "mock.file",
}
},
)
await hass.async_block_till_done()
assert not hass.config_entries.async_has_entries(DOMAIN)
assert not hass.states.get("camera.config_test")
issue = issue_registry.async_get_issue(
DOMAIN, f"no_access_path_{slugify('mock.file')}"
)
assert issue
assert issue.translation_key == "no_access_path"

View File

@ -175,61 +175,3 @@ async def test_entry_already_exist(
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"
@pytest.mark.usefixtures("mock_setup_entry")
async def test_import(hass: HomeAssistant) -> None:
"""Test import."""
with (
patch("os.path.isfile", Mock(return_value=True)),
patch("os.access", Mock(return_value=True)),
patch(
"homeassistant.components.local_file.camera.mimetypes.guess_type",
Mock(return_value=(None, None)),
),
):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data={
"name": DEFAULT_NAME,
"file_path": "mock/path.jpg",
},
)
await hass.async_block_till_done()
assert result["type"] is FlowResultType.CREATE_ENTRY
assert result["version"] == 1
assert result["options"] == {
CONF_NAME: DEFAULT_NAME,
CONF_FILE_PATH: "mock/path.jpg",
}
@pytest.mark.usefixtures("mock_setup_entry")
async def test_import_already_exist(
hass: HomeAssistant, loaded_entry: MockConfigEntry
) -> None:
"""Test import abort existing entry."""
with (
patch("os.path.isfile", Mock(return_value=True)),
patch("os.access", Mock(return_value=True)),
patch(
"homeassistant.components.local_file.camera.mimetypes.guess_type",
Mock(return_value=(None, None)),
),
):
result = await hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data={
CONF_NAME: DEFAULT_NAME,
CONF_FILE_PATH: "mock.file",
},
)
await hass.async_block_till_done()
assert result["type"] is FlowResultType.ABORT
assert result["reason"] == "already_configured"