mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Fix double space quoting in WebDAV (#140364)
This commit is contained in:
parent
bc6d342919
commit
d2124db3ec
@ -13,7 +13,11 @@ from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryError, ConfigEntryNotReady
|
||||
|
||||
from .const import CONF_BACKUP_PATH, DATA_BACKUP_AGENT_LISTENERS, DOMAIN
|
||||
from .helpers import async_create_client, async_ensure_path_exists
|
||||
from .helpers import (
|
||||
async_create_client,
|
||||
async_ensure_path_exists,
|
||||
async_migrate_wrong_folder_path,
|
||||
)
|
||||
|
||||
type WebDavConfigEntry = ConfigEntry[Client]
|
||||
|
||||
@ -46,10 +50,11 @@ async def async_setup_entry(hass: HomeAssistant, entry: WebDavConfigEntry) -> bo
|
||||
translation_key="cannot_connect",
|
||||
)
|
||||
|
||||
path = entry.data.get(CONF_BACKUP_PATH, "/")
|
||||
await async_migrate_wrong_folder_path(client, path)
|
||||
|
||||
# Ensure the backup directory exists
|
||||
if not await async_ensure_path_exists(
|
||||
client, entry.data.get(CONF_BACKUP_PATH, "/")
|
||||
):
|
||||
if not await async_ensure_path_exists(client, path):
|
||||
raise ConfigEntryNotReady(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="cannot_access_or_create_backup_path",
|
||||
|
@ -1,10 +1,18 @@
|
||||
"""Helper functions for the WebDAV component."""
|
||||
|
||||
import logging
|
||||
|
||||
from aiowebdav2.client import Client, ClientOptions
|
||||
from aiowebdav2.exceptions import WebDavError
|
||||
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
|
||||
from .const import DOMAIN
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@callback
|
||||
def async_create_client(
|
||||
@ -36,3 +44,24 @@ async def async_ensure_path_exists(client: Client, path: str) -> bool:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def async_migrate_wrong_folder_path(client: Client, path: str) -> None:
|
||||
"""Migrate the wrong encoded folder path to the correct one."""
|
||||
wrong_path = path.replace(" ", "%20")
|
||||
if await client.check(wrong_path):
|
||||
try:
|
||||
await client.move(wrong_path, path)
|
||||
except WebDavError as err:
|
||||
raise ConfigEntryNotReady(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="failed_to_migrate_folder",
|
||||
translation_placeholders={
|
||||
"wrong_path": wrong_path,
|
||||
"correct_path": path,
|
||||
},
|
||||
) from err
|
||||
|
||||
_LOGGER.debug(
|
||||
"Migrated wrong encoded folder path from %s to %s", wrong_path, path
|
||||
)
|
||||
|
@ -8,5 +8,5 @@
|
||||
"iot_class": "cloud_polling",
|
||||
"loggers": ["aiowebdav2"],
|
||||
"quality_scale": "bronze",
|
||||
"requirements": ["aiowebdav2==0.4.1"]
|
||||
"requirements": ["aiowebdav2==0.4.2"]
|
||||
}
|
||||
|
@ -36,6 +36,9 @@
|
||||
},
|
||||
"cannot_access_or_create_backup_path": {
|
||||
"message": "Cannot access or create backup path. Please check the path and permissions."
|
||||
},
|
||||
"failed_to_migrate_folder": {
|
||||
"message": "Failed to migrate wrong encoded folder \"{wrong_path}\" to \"{correct_path}\"."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
2
requirements_all.txt
generated
2
requirements_all.txt
generated
@ -422,7 +422,7 @@ aiowaqi==3.1.0
|
||||
aiowatttime==0.1.1
|
||||
|
||||
# homeassistant.components.webdav
|
||||
aiowebdav2==0.4.1
|
||||
aiowebdav2==0.4.2
|
||||
|
||||
# homeassistant.components.webostv
|
||||
aiowebostv==0.7.3
|
||||
|
2
requirements_test_all.txt
generated
2
requirements_test_all.txt
generated
@ -404,7 +404,7 @@ aiowaqi==3.1.0
|
||||
aiowatttime==0.1.1
|
||||
|
||||
# homeassistant.components.webdav
|
||||
aiowebdav2==0.4.1
|
||||
aiowebdav2==0.4.2
|
||||
|
||||
# homeassistant.components.webostv
|
||||
aiowebostv==0.7.3
|
||||
|
@ -1 +1,14 @@
|
||||
"""Tests for the WebDAV integration."""
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def setup_integration(
|
||||
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
||||
) -> None:
|
||||
"""Set up the WebDAV integration for testing."""
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(mock_config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
@ -62,4 +62,5 @@ def mock_webdav_client() -> Generator[AsyncMock]:
|
||||
mock.download_iter.side_effect = _download_mock
|
||||
mock.upload_iter.return_value = None
|
||||
mock.clean.return_value = None
|
||||
mock.move.return_value = None
|
||||
yield mock
|
||||
|
96
tests/components/webdav/test_init.py
Normal file
96
tests/components/webdav/test_init.py
Normal file
@ -0,0 +1,96 @@
|
||||
"""Test WebDAV component setup."""
|
||||
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from aiowebdav2.exceptions import WebDavError
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.webdav.const import CONF_BACKUP_PATH, DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_URL, CONF_USERNAME
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from . import setup_integration
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
|
||||
async def test_migrate_wrong_path(
|
||||
hass: HomeAssistant, webdav_client: AsyncMock
|
||||
) -> None:
|
||||
"""Test migration of wrong encoded folder path."""
|
||||
webdav_client.list_with_properties.return_value = [
|
||||
{"/wrong%20path": []},
|
||||
]
|
||||
|
||||
config_entry = MockConfigEntry(
|
||||
title="user@webdav.demo",
|
||||
domain=DOMAIN,
|
||||
data={
|
||||
CONF_URL: "https://webdav.demo",
|
||||
CONF_USERNAME: "user",
|
||||
CONF_PASSWORD: "supersecretpassword",
|
||||
CONF_BACKUP_PATH: "/wrong path",
|
||||
},
|
||||
entry_id="01JKXV07ASC62D620DGYNG2R8H",
|
||||
)
|
||||
await setup_integration(hass, config_entry)
|
||||
|
||||
webdav_client.move.assert_called_once_with("/wrong%20path", "/wrong path")
|
||||
|
||||
|
||||
async def test_migrate_non_wrong_path(
|
||||
hass: HomeAssistant, webdav_client: AsyncMock
|
||||
) -> None:
|
||||
"""Test no migration of correct folder path."""
|
||||
webdav_client.list_with_properties.return_value = [
|
||||
{"/correct path": []},
|
||||
]
|
||||
webdav_client.check.side_effect = lambda path: path == "/correct path"
|
||||
|
||||
config_entry = MockConfigEntry(
|
||||
title="user@webdav.demo",
|
||||
domain=DOMAIN,
|
||||
data={
|
||||
CONF_URL: "https://webdav.demo",
|
||||
CONF_USERNAME: "user",
|
||||
CONF_PASSWORD: "supersecretpassword",
|
||||
CONF_BACKUP_PATH: "/correct path",
|
||||
},
|
||||
entry_id="01JKXV07ASC62D620DGYNG2R8H",
|
||||
)
|
||||
|
||||
await setup_integration(hass, config_entry)
|
||||
|
||||
webdav_client.move.assert_not_called()
|
||||
|
||||
|
||||
async def test_migrate_error(
|
||||
hass: HomeAssistant,
|
||||
webdav_client: AsyncMock,
|
||||
caplog: pytest.LogCaptureFixture,
|
||||
) -> None:
|
||||
"""Test migration of wrong encoded folder path with error."""
|
||||
webdav_client.list_with_properties.return_value = [
|
||||
{"/wrong%20path": []},
|
||||
]
|
||||
webdav_client.move.side_effect = WebDavError("Failed to move")
|
||||
|
||||
config_entry = MockConfigEntry(
|
||||
title="user@webdav.demo",
|
||||
domain=DOMAIN,
|
||||
data={
|
||||
CONF_URL: "https://webdav.demo",
|
||||
CONF_USERNAME: "user",
|
||||
CONF_PASSWORD: "supersecretpassword",
|
||||
CONF_BACKUP_PATH: "/wrong path",
|
||||
},
|
||||
entry_id="01JKXV07ASC62D620DGYNG2R8H",
|
||||
)
|
||||
await setup_integration(hass, config_entry)
|
||||
|
||||
assert config_entry.state is ConfigEntryState.SETUP_RETRY
|
||||
assert (
|
||||
'Failed to migrate wrong encoded folder "/wrong%20path" to "/wrong path"'
|
||||
in caplog.text
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user