mirror of
https://github.com/RichieCahill/dotfiles.git
synced 2026-04-17 04:58:19 -04:00
Added 35 test files with 502 tests covering all Python modules including API routes, ORM models, splendor game logic/TUI, heater controller, weather service, NixOS installer, ZFS dataset management, and utilities. Coverage improved from 11% to 99% (2540/2564 statements covered). https://claude.ai/code/session_01SVzgLDUS1Cdc4eh1ijETTh
249 lines
8.4 KiB
Python
249 lines
8.4 KiB
Python
"""Tests for python/heater modules."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from typing import TYPE_CHECKING
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from python.heater.models import ActionResult, DeviceConfig, HeaterStatus
|
|
|
|
if TYPE_CHECKING:
|
|
pass
|
|
|
|
|
|
# --- models tests ---
|
|
|
|
|
|
def test_device_config() -> None:
|
|
"""Test DeviceConfig creation."""
|
|
config = DeviceConfig(device_id="abc123", ip="192.168.1.1", local_key="key123")
|
|
assert config.device_id == "abc123"
|
|
assert config.ip == "192.168.1.1"
|
|
assert config.local_key == "key123"
|
|
assert config.version == 3.5
|
|
|
|
|
|
def test_device_config_custom_version() -> None:
|
|
"""Test DeviceConfig with custom version."""
|
|
config = DeviceConfig(device_id="abc", ip="10.0.0.1", local_key="key", version=3.3)
|
|
assert config.version == 3.3
|
|
|
|
|
|
def test_heater_status_defaults() -> None:
|
|
"""Test HeaterStatus default values."""
|
|
status = HeaterStatus(power=True)
|
|
assert status.power is True
|
|
assert status.setpoint is None
|
|
assert status.state is None
|
|
assert status.error_code is None
|
|
assert status.raw_dps == {}
|
|
|
|
|
|
def test_heater_status_full() -> None:
|
|
"""Test HeaterStatus with all fields."""
|
|
status = HeaterStatus(
|
|
power=True,
|
|
setpoint=72,
|
|
state="Heat",
|
|
error_code=0,
|
|
raw_dps={"1": True, "101": 72},
|
|
)
|
|
assert status.power is True
|
|
assert status.setpoint == 72
|
|
assert status.state == "Heat"
|
|
|
|
|
|
def test_action_result_success() -> None:
|
|
"""Test ActionResult success."""
|
|
result = ActionResult(success=True, action="on", power=True)
|
|
assert result.success is True
|
|
assert result.action == "on"
|
|
assert result.power is True
|
|
assert result.error is None
|
|
|
|
|
|
def test_action_result_failure() -> None:
|
|
"""Test ActionResult failure."""
|
|
result = ActionResult(success=False, action="on", error="Connection failed")
|
|
assert result.success is False
|
|
assert result.error == "Connection failed"
|
|
|
|
|
|
# --- controller tests (with mocked tinytuya) ---
|
|
|
|
|
|
def _get_controller_class() -> type:
|
|
"""Import HeaterController with mocked tinytuya."""
|
|
mock_tinytuya = MagicMock()
|
|
with patch.dict(sys.modules, {"tinytuya": mock_tinytuya}):
|
|
# Force reimport
|
|
if "python.heater.controller" in sys.modules:
|
|
del sys.modules["python.heater.controller"]
|
|
from python.heater.controller import HeaterController
|
|
|
|
return HeaterController
|
|
|
|
|
|
def test_heater_controller_status_success() -> None:
|
|
"""Test HeaterController.status returns correct status."""
|
|
mock_tinytuya = MagicMock()
|
|
mock_device = MagicMock()
|
|
mock_device.status.return_value = {"dps": {"1": True, "101": 72, "102": "Heat", "108": 0}}
|
|
mock_tinytuya.Device.return_value = mock_device
|
|
|
|
with patch.dict(sys.modules, {"tinytuya": mock_tinytuya}):
|
|
if "python.heater.controller" in sys.modules:
|
|
del sys.modules["python.heater.controller"]
|
|
from python.heater.controller import HeaterController
|
|
|
|
config = DeviceConfig(device_id="abc", ip="10.0.0.1", local_key="key")
|
|
controller = HeaterController(config)
|
|
status = controller.status()
|
|
|
|
assert status.power is True
|
|
assert status.setpoint == 72
|
|
assert status.state == "Heat"
|
|
|
|
|
|
def test_heater_controller_status_error() -> None:
|
|
"""Test HeaterController.status handles device error."""
|
|
mock_tinytuya = MagicMock()
|
|
mock_device = MagicMock()
|
|
mock_device.status.return_value = {"Error": "Connection timeout"}
|
|
mock_tinytuya.Device.return_value = mock_device
|
|
|
|
with patch.dict(sys.modules, {"tinytuya": mock_tinytuya}):
|
|
if "python.heater.controller" in sys.modules:
|
|
del sys.modules["python.heater.controller"]
|
|
from python.heater.controller import HeaterController
|
|
|
|
config = DeviceConfig(device_id="abc", ip="10.0.0.1", local_key="key")
|
|
controller = HeaterController(config)
|
|
status = controller.status()
|
|
|
|
assert status.power is False
|
|
|
|
|
|
def test_heater_controller_turn_on() -> None:
|
|
"""Test HeaterController.turn_on."""
|
|
mock_tinytuya = MagicMock()
|
|
mock_device = MagicMock()
|
|
mock_device.set_value.return_value = None
|
|
mock_tinytuya.Device.return_value = mock_device
|
|
|
|
with patch.dict(sys.modules, {"tinytuya": mock_tinytuya}):
|
|
if "python.heater.controller" in sys.modules:
|
|
del sys.modules["python.heater.controller"]
|
|
from python.heater.controller import HeaterController
|
|
|
|
config = DeviceConfig(device_id="abc", ip="10.0.0.1", local_key="key")
|
|
controller = HeaterController(config)
|
|
result = controller.turn_on()
|
|
|
|
assert result.success is True
|
|
assert result.action == "on"
|
|
assert result.power is True
|
|
|
|
|
|
def test_heater_controller_turn_on_error() -> None:
|
|
"""Test HeaterController.turn_on handles errors."""
|
|
mock_tinytuya = MagicMock()
|
|
mock_device = MagicMock()
|
|
mock_device.set_value.side_effect = ConnectionError("timeout")
|
|
mock_tinytuya.Device.return_value = mock_device
|
|
|
|
with patch.dict(sys.modules, {"tinytuya": mock_tinytuya}):
|
|
if "python.heater.controller" in sys.modules:
|
|
del sys.modules["python.heater.controller"]
|
|
from python.heater.controller import HeaterController
|
|
|
|
config = DeviceConfig(device_id="abc", ip="10.0.0.1", local_key="key")
|
|
controller = HeaterController(config)
|
|
result = controller.turn_on()
|
|
|
|
assert result.success is False
|
|
assert "timeout" in result.error
|
|
|
|
|
|
def test_heater_controller_turn_off() -> None:
|
|
"""Test HeaterController.turn_off."""
|
|
mock_tinytuya = MagicMock()
|
|
mock_device = MagicMock()
|
|
mock_device.set_value.return_value = None
|
|
mock_tinytuya.Device.return_value = mock_device
|
|
|
|
with patch.dict(sys.modules, {"tinytuya": mock_tinytuya}):
|
|
if "python.heater.controller" in sys.modules:
|
|
del sys.modules["python.heater.controller"]
|
|
from python.heater.controller import HeaterController
|
|
|
|
config = DeviceConfig(device_id="abc", ip="10.0.0.1", local_key="key")
|
|
controller = HeaterController(config)
|
|
result = controller.turn_off()
|
|
|
|
assert result.success is True
|
|
assert result.action == "off"
|
|
assert result.power is False
|
|
|
|
|
|
def test_heater_controller_turn_off_error() -> None:
|
|
"""Test HeaterController.turn_off handles errors."""
|
|
mock_tinytuya = MagicMock()
|
|
mock_device = MagicMock()
|
|
mock_device.set_value.side_effect = ConnectionError("timeout")
|
|
mock_tinytuya.Device.return_value = mock_device
|
|
|
|
with patch.dict(sys.modules, {"tinytuya": mock_tinytuya}):
|
|
if "python.heater.controller" in sys.modules:
|
|
del sys.modules["python.heater.controller"]
|
|
from python.heater.controller import HeaterController
|
|
|
|
config = DeviceConfig(device_id="abc", ip="10.0.0.1", local_key="key")
|
|
controller = HeaterController(config)
|
|
result = controller.turn_off()
|
|
|
|
assert result.success is False
|
|
|
|
|
|
def test_heater_controller_toggle_on_to_off() -> None:
|
|
"""Test HeaterController.toggle when heater is on."""
|
|
mock_tinytuya = MagicMock()
|
|
mock_device = MagicMock()
|
|
mock_device.status.return_value = {"dps": {"1": True}}
|
|
mock_device.set_value.return_value = None
|
|
mock_tinytuya.Device.return_value = mock_device
|
|
|
|
with patch.dict(sys.modules, {"tinytuya": mock_tinytuya}):
|
|
if "python.heater.controller" in sys.modules:
|
|
del sys.modules["python.heater.controller"]
|
|
from python.heater.controller import HeaterController
|
|
|
|
config = DeviceConfig(device_id="abc", ip="10.0.0.1", local_key="key")
|
|
controller = HeaterController(config)
|
|
result = controller.toggle()
|
|
|
|
assert result.success is True
|
|
assert result.action == "off"
|
|
|
|
|
|
def test_heater_controller_toggle_off_to_on() -> None:
|
|
"""Test HeaterController.toggle when heater is off."""
|
|
mock_tinytuya = MagicMock()
|
|
mock_device = MagicMock()
|
|
mock_device.status.return_value = {"dps": {"1": False}}
|
|
mock_device.set_value.return_value = None
|
|
mock_tinytuya.Device.return_value = mock_device
|
|
|
|
with patch.dict(sys.modules, {"tinytuya": mock_tinytuya}):
|
|
if "python.heater.controller" in sys.modules:
|
|
del sys.modules["python.heater.controller"]
|
|
from python.heater.controller import HeaterController
|
|
|
|
config = DeviceConfig(device_id="abc", ip="10.0.0.1", local_key="key")
|
|
controller = HeaterController(config)
|
|
result = controller.toggle()
|
|
|
|
assert result.success is True
|
|
assert result.action == "on"
|