Files
shelly-ui/tests/test_mass_apply_subset.py
jonas 71803418e5 Initial commit: Shelly Manager with Textual CLI, Streamlit UI, and comprehensive .gitignore
Shelly device management app with mDNS/subnet discovery, inventory,
configuration, and mass operations for Gen1/Gen2+ devices.

Includes .gitignore excluding runtime data (device DB, user config),
AI conversation history, build artifacts, and common Python/OS patterns.
2026-03-23 21:51:59 +01:00

76 lines
2.3 KiB
Python

"""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())