diff --git a/esphome/dashboard/web_server.py b/esphome/dashboard/web_server.py index e4c0b5b84a..ef6ec061cd 100644 --- a/esphome/dashboard/web_server.py +++ b/esphome/dashboard/web_server.py @@ -1038,12 +1038,11 @@ class ArchiveRequestHandler(BaseHandler): shutil.move(config_file, os.path.join(archive_path, configuration)) storage_json = StorageJSON.load(storage_path) - if storage_json is not None: - # Move build folder to archive (if exists) - name = storage_json.name - build_folder = os.path.join(settings.config_dir, name) + if storage_json is not None and storage_json.build_path: + # Delete build folder (if exists) + build_folder = storage_json.build_path if os.path.exists(build_folder): - shutil.move(build_folder, os.path.join(archive_path, name)) + shutil.rmtree(build_folder, ignore_errors=True) class UnArchiveRequestHandler(BaseHandler): diff --git a/tests/dashboard/test_web_server.py b/tests/dashboard/test_web_server.py index ea14309997..6bb9a04f6c 100644 --- a/tests/dashboard/test_web_server.py +++ b/tests/dashboard/test_web_server.py @@ -634,14 +634,16 @@ async def test_archive_handler_with_build_folder( config_dir.mkdir() archive_dir = tmp_path / "archive" archive_dir.mkdir() + build_dir = tmp_path / "build" + build_dir.mkdir() # Create a test configuration file configuration = "test_device.yaml" test_config = config_dir / configuration test_config.write_text("esphome:\n name: test_device\n") - # Create build folder with content - build_folder = config_dir / "test_device" + # Create build folder with content (in proper location) + build_folder = build_dir / "test_device" build_folder.mkdir() (build_folder / "firmware.bin").write_text("binary content") (build_folder / ".pioenvs").mkdir() @@ -651,10 +653,11 @@ async def test_archive_handler_with_build_folder( mock_dashboard_settings.rel_path.return_value = str(test_config) mock_archive_storage_path.return_value = str(archive_dir) - # Mock storage_json with device name + # Mock storage_json with device name and build_path with patch("esphome.dashboard.web_server.StorageJSON.load") as mock_load: mock_storage = MagicMock() mock_storage.name = "test_device" + mock_storage.build_path = str(build_folder) mock_load.return_value = mock_storage # Archive the configuration @@ -670,10 +673,10 @@ async def test_archive_handler_with_build_folder( assert not test_config.exists() assert (archive_dir / configuration).exists() - # Verify build folder was moved to archive + # Verify build folder was deleted (not archived) assert not build_folder.exists() - assert (archive_dir / "test_device").exists() - assert (archive_dir / "test_device" / "firmware.bin").exists() + # Build folder should NOT be in archive + assert not (archive_dir / "test_device").exists() @pytest.mark.asyncio @@ -703,10 +706,11 @@ async def test_archive_handler_no_build_folder( mock_dashboard_settings.rel_path.return_value = str(test_config) mock_archive_storage_path.return_value = str(archive_dir) - # Mock storage_json with device name + # Mock storage_json with device name but no build_path with patch("esphome.dashboard.web_server.StorageJSON.load") as mock_load: mock_storage = MagicMock() mock_storage.name = "test_device" + mock_storage.build_path = None mock_load.return_value = mock_storage # Archive the configuration (should not fail even without build folder)