Refactor cloud backup agent to use updated file handling methods (#149231)

This commit is contained in:
Joakim Sørensen 2025-07-22 14:15:56 +01:00 committed by GitHub
parent dd399ef59f
commit e5f9788d24
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 53 additions and 69 deletions

View File

@ -10,14 +10,8 @@ import random
from typing import Any from typing import Any
from aiohttp import ClientError, ClientResponseError from aiohttp import ClientError, ClientResponseError
from hass_nabucasa import Cloud, CloudError from hass_nabucasa import Cloud, CloudApiError, CloudApiNonRetryableError, CloudError
from hass_nabucasa.api import CloudApiError, CloudApiNonRetryableError from hass_nabucasa.files import FilesError, StorageType, StoredFile, calculate_b64md5
from hass_nabucasa.cloud_api import (
FilesHandlerListEntry,
async_files_delete_file,
async_files_list,
)
from hass_nabucasa.files import FilesError, StorageType, calculate_b64md5
from homeassistant.components.backup import ( from homeassistant.components.backup import (
AgentBackup, AgentBackup,
@ -186,8 +180,7 @@ class CloudBackupAgent(BackupAgent):
""" """
backup = await self._async_get_backup(backup_id) backup = await self._async_get_backup(backup_id)
try: try:
await async_files_delete_file( await self._cloud.files.delete(
self._cloud,
storage_type=StorageType.BACKUP, storage_type=StorageType.BACKUP,
filename=backup["Key"], filename=backup["Key"],
) )
@ -199,12 +192,10 @@ class CloudBackupAgent(BackupAgent):
backups = await self._async_list_backups() backups = await self._async_list_backups()
return [AgentBackup.from_dict(backup["Metadata"]) for backup in backups] return [AgentBackup.from_dict(backup["Metadata"]) for backup in backups]
async def _async_list_backups(self) -> list[FilesHandlerListEntry]: async def _async_list_backups(self) -> list[StoredFile]:
"""List backups.""" """List backups."""
try: try:
backups = await async_files_list( backups = await self._cloud.files.list(storage_type=StorageType.BACKUP)
self._cloud, storage_type=StorageType.BACKUP
)
except (ClientError, CloudError) as err: except (ClientError, CloudError) as err:
raise BackupAgentError("Failed to list backups") from err raise BackupAgentError("Failed to list backups") from err
@ -220,7 +211,7 @@ class CloudBackupAgent(BackupAgent):
backup = await self._async_get_backup(backup_id) backup = await self._async_get_backup(backup_id)
return AgentBackup.from_dict(backup["Metadata"]) return AgentBackup.from_dict(backup["Metadata"])
async def _async_get_backup(self, backup_id: str) -> FilesHandlerListEntry: async def _async_get_backup(self, backup_id: str) -> StoredFile:
"""Return a backup.""" """Return a backup."""
backups = await self._async_list_backups() backups = await self._async_list_backups()

View File

@ -3,7 +3,7 @@
from collections.abc import AsyncGenerator, Generator from collections.abc import AsyncGenerator, Generator
from io import StringIO from io import StringIO
from typing import Any from typing import Any
from unittest.mock import ANY, Mock, PropertyMock, patch from unittest.mock import ANY, AsyncMock, Mock, PropertyMock, patch
from aiohttp import ClientError, ClientResponseError from aiohttp import ClientError, ClientResponseError
from hass_nabucasa import CloudError from hass_nabucasa import CloudError
@ -48,22 +48,16 @@ async def setup_integration(
@pytest.fixture @pytest.fixture
def mock_delete_file() -> Generator[MagicMock]: def mock_delete_file(cloud: MagicMock) -> Generator[AsyncMock]:
"""Mock list files.""" """Mock delete files."""
with patch( cloud.files.delete = AsyncMock()
"homeassistant.components.cloud.backup.async_files_delete_file", return cloud.files.delete
spec_set=True,
) as delete_file:
yield delete_file
@pytest.fixture @pytest.fixture
def mock_list_files() -> Generator[MagicMock]: def mock_list_files(cloud: MagicMock) -> Generator[MagicMock]:
"""Mock list files.""" """Mock list files."""
with patch( cloud.files.list.return_value = [
"homeassistant.components.cloud.backup.async_files_list", spec_set=True
) as list_files:
list_files.return_value = [
{ {
"Key": "462e16810d6841228828d9dd2f9e341e.tar", "Key": "462e16810d6841228828d9dd2f9e341e.tar",
"LastModified": "2024-11-22T10:49:01.182Z", "LastModified": "2024-11-22T10:49:01.182Z",
@ -103,7 +97,7 @@ def mock_list_files() -> Generator[MagicMock]:
}, },
}, },
] ]
yield list_files return cloud.files.list
@pytest.fixture @pytest.fixture
@ -141,7 +135,7 @@ async def test_agents_list_backups(
client = await hass_ws_client(hass) client = await hass_ws_client(hass)
await client.send_json_auto_id({"type": "backup/info"}) await client.send_json_auto_id({"type": "backup/info"})
response = await client.receive_json() response = await client.receive_json()
mock_list_files.assert_called_once_with(cloud, storage_type="backup") mock_list_files.assert_called_once_with(storage_type="backup")
assert response["success"] assert response["success"]
assert response["result"]["agent_errors"] == {} assert response["result"]["agent_errors"] == {}
@ -250,7 +244,7 @@ async def test_agents_get_backup(
client = await hass_ws_client(hass) client = await hass_ws_client(hass)
await client.send_json_auto_id({"type": "backup/details", "backup_id": backup_id}) await client.send_json_auto_id({"type": "backup/details", "backup_id": backup_id})
response = await client.receive_json() response = await client.receive_json()
mock_list_files.assert_called_once_with(cloud, storage_type="backup") mock_list_files.assert_called_once_with(storage_type="backup")
assert response["success"] assert response["success"]
assert response["result"]["agent_errors"] == {} assert response["result"]["agent_errors"] == {}
@ -726,7 +720,6 @@ async def test_agents_delete(
assert response["success"] assert response["success"]
assert response["result"] == {"agent_errors": {}} assert response["result"] == {"agent_errors": {}}
mock_delete_file.assert_called_once_with( mock_delete_file.assert_called_once_with(
cloud,
filename="462e16810d6841228828d9dd2f9e341e.tar", filename="462e16810d6841228828d9dd2f9e341e.tar",
storage_type=StorageType.BACKUP, storage_type=StorageType.BACKUP,
) )