"""Mass apply respects :attr:`DeviceFilter.only_device_ids`.""" from __future__ import annotations from datetime import UTC, datetime from unittest.mock import AsyncMock, MagicMock, patch import pytest from shelly_manager.api.mass_config_apply import _HANDLERS # noqa: SLF001 from shelly_manager.core.device_manager import DeviceManager from shelly_manager.core.mass_config import MASS_CONFIG_OPERATIONS from shelly_manager.core.models import DeviceFilter, ShellyDevice def _dev(i: str, gen: int = 2) -> ShellyDevice: return ShellyDevice( id=i, name=None, mac=f"AA:BB:CC:DD:EE:{i[:2]}", ip=f"192.168.1.{i}", generation=gen, # type: ignore[arg-type] model="Plus1", firmware="1", online=True, last_seen=datetime.now(UTC), capabilities=[], status={}, settings={}, ) @pytest.mark.asyncio async def test_mass_apply_operation_only_device_ids_filters_list(app_config_sqlite) -> None: dm = DeviceManager(app_config_sqlite) a, b = _dev("AABBCCDDEE01"), _dev("AABBCCDDEE02") await dm.storage.save_device(a) await dm.storage.save_device(b) fake_rt = MagicMock() fake_rt.__aenter__ = AsyncMock(return_value=fake_rt) fake_rt.__aexit__ = AsyncMock(return_value=None) calls: list[str] = [] async def fake_apply(runtime, device, operation_id): from shelly_manager.api.mass_config_apply import MassApplyResult calls.append(device.id) return MassApplyResult( device_id=device.id, display_name=device.display_name, status="skipped", detail="mock", ) with ( patch("shelly_manager.core.device_manager.ShellyRuntime", return_value=fake_rt), patch( "shelly_manager.core.device_manager.apply_mass_operation", side_effect=fake_apply, ), ): await dm.mass_apply_operation( DeviceFilter(only_device_ids=["AABBCCDDEE01"]), "ble_disable", snapshot_before=False, ) assert calls == ["AABBCCDDEE01"] def test_all_rpc_mass_config_operations_have_handlers() -> None: rpc_ids = {o.id for o in MASS_CONFIG_OPERATIONS if o.kind == "rpc_config"} assert rpc_ids == set(_HANDLERS.keys())