From a60d2b69e3d0fdbfd870a0086a34dd613faef70a Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Tue, 21 Jan 2025 13:40:54 +0100 Subject: [PATCH] Add service backup.create_automatic (#136152) --- homeassistant/components/backup/__init__.py | 18 ++++ homeassistant/components/backup/icons.json | 3 + homeassistant/components/backup/services.yaml | 1 + homeassistant/components/backup/strings.json | 4 + tests/components/backup/test_init.py | 92 ++++++++++++++++++- 5 files changed, 117 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/backup/__init__.py b/homeassistant/components/backup/__init__.py index 93cadcfb2f3b83..8d25a0c25cbcfa 100644 --- a/homeassistant/components/backup/__init__.py +++ b/homeassistant/components/backup/__init__.py @@ -88,8 +88,26 @@ async def async_handle_create_service(call: ServiceCall) -> None: password=None, ) + async def async_handle_create_automatic_service(call: ServiceCall) -> None: + """Service handler for creating automatic backups.""" + config_data = backup_manager.config.data + await backup_manager.async_create_backup( + agent_ids=config_data.create_backup.agent_ids, + include_addons=config_data.create_backup.include_addons, + include_all_addons=config_data.create_backup.include_all_addons, + include_database=config_data.create_backup.include_database, + include_folders=config_data.create_backup.include_folders, + include_homeassistant=True, # always include HA + name=config_data.create_backup.name, + password=config_data.create_backup.password, + with_automatic_settings=True, + ) + if not with_hassio: hass.services.async_register(DOMAIN, "create", async_handle_create_service) + hass.services.async_register( + DOMAIN, "create_automatic", async_handle_create_automatic_service + ) async_register_http_views(hass) diff --git a/homeassistant/components/backup/icons.json b/homeassistant/components/backup/icons.json index bd5ff4a81eedb0..8a412f66edcfb5 100644 --- a/homeassistant/components/backup/icons.json +++ b/homeassistant/components/backup/icons.json @@ -2,6 +2,9 @@ "services": { "create": { "service": "mdi:cloud-upload" + }, + "create_automatic": { + "service": "mdi:cloud-upload" } } } diff --git a/homeassistant/components/backup/services.yaml b/homeassistant/components/backup/services.yaml index 900aa39dd6e404..70900f93bffc3b 100644 --- a/homeassistant/components/backup/services.yaml +++ b/homeassistant/components/backup/services.yaml @@ -1 +1,2 @@ create: +create_automatic: diff --git a/homeassistant/components/backup/strings.json b/homeassistant/components/backup/strings.json index 43ae57cc781a27..32d76ded049bac 100644 --- a/homeassistant/components/backup/strings.json +++ b/homeassistant/components/backup/strings.json @@ -13,6 +13,10 @@ "create": { "name": "Create backup", "description": "Creates a new backup." + }, + "create_automatic": { + "name": "Create automatic backup", + "description": "Creates a new backup with automatic backup settings." } } } diff --git a/tests/components/backup/test_init.py b/tests/components/backup/test_init.py index 16a49af9647186..925e2cb9b7acb1 100644 --- a/tests/components/backup/test_init.py +++ b/tests/components/backup/test_init.py @@ -11,6 +11,8 @@ from .common import setup_backup_integration +from tests.typing import WebSocketGenerator + @pytest.mark.usefixtures("supervisor_client") async def test_setup_with_hassio( @@ -45,7 +47,16 @@ async def test_create_service( service_data=service_data, ) - assert generate_backup.called + generate_backup.assert_called_once_with( + agent_ids=["backup.local"], + include_addons=None, + include_all_addons=False, + include_database=True, + include_folders=None, + include_homeassistant=True, + name=None, + password=None, + ) async def test_create_service_with_hassio(hass: HomeAssistant) -> None: @@ -54,3 +65,82 @@ async def test_create_service_with_hassio(hass: HomeAssistant) -> None: with pytest.raises(ServiceNotFound): await hass.services.async_call(DOMAIN, "create", blocking=True) + + +@pytest.mark.parametrize( + ("commands", "expected_kwargs"), + [ + ( + [], + { + "agent_ids": [], + "include_addons": None, + "include_all_addons": False, + "include_database": True, + "include_folders": None, + "include_homeassistant": True, + "name": None, + "password": None, + "with_automatic_settings": True, + }, + ), + ( + [ + { + "type": "backup/config/update", + "create_backup": { + "agent_ids": ["test-agent"], + "include_addons": ["my-addon"], + "include_all_addons": True, + "include_database": False, + "include_folders": ["share"], + "name": "cool_backup", + "password": "hunter2", + }, + }, + ], + { + "agent_ids": ["test-agent"], + "include_addons": ["my-addon"], + "include_all_addons": True, + "include_database": False, + "include_folders": ["share"], + "include_homeassistant": True, + "name": "cool_backup", + "password": "hunter2", + "with_automatic_settings": True, + }, + ), + ], +) +@pytest.mark.parametrize("service_data", [None, {}]) +@pytest.mark.parametrize("with_hassio", [True, False]) +@pytest.mark.usefixtures("supervisor_client") +async def test_create_automatic_service( + hass: HomeAssistant, + hass_ws_client: WebSocketGenerator, + commands: list[dict[str, Any]], + expected_kwargs: dict[str, Any], + service_data: dict[str, Any] | None, + with_hassio: bool, +) -> None: + """Test generate backup.""" + await setup_backup_integration(hass, with_hassio=with_hassio) + + client = await hass_ws_client(hass) + for command in commands: + await client.send_json_auto_id(command) + result = await client.receive_json() + assert result["success"] + + with patch( + "homeassistant.components.backup.manager.BackupManager.async_create_backup", + ) as generate_backup: + await hass.services.async_call( + DOMAIN, + "create_automatic", + blocking=True, + service_data=service_data, + ) + + generate_backup.assert_called_once_with(**expected_kwargs)