Files
dotfiles/tests/test_heater_main_extended.py
Claude b3199dfc31 Add comprehensive test suite achieving 99% code coverage
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
2026-03-09 03:55:38 +00:00

166 lines
6.1 KiB
Python

"""Extended tests for python/heater/main.py - FastAPI routes."""
from __future__ import annotations
import sys
from unittest.mock import MagicMock, patch
from python.heater.models import ActionResult, DeviceConfig, HeaterStatus
def test_heater_app_routes() -> None:
"""Test heater app has expected routes."""
mock_tinytuya = MagicMock()
with patch.dict(sys.modules, {"tinytuya": mock_tinytuya}):
if "python.heater.controller" in sys.modules:
del sys.modules["python.heater.controller"]
if "python.heater.main" in sys.modules:
del sys.modules["python.heater.main"]
from python.heater.main import create_app
config = DeviceConfig(device_id="abc", ip="10.0.0.1", local_key="key")
app = create_app(config)
route_paths = [r.path for r in app.routes]
assert "/status" in route_paths
assert "/on" in route_paths
assert "/off" in route_paths
assert "/toggle" in route_paths
def test_heater_get_status_route() -> None:
"""Test /status route handler."""
mock_tinytuya = MagicMock()
mock_device = MagicMock()
mock_device.status.return_value = {"dps": {"1": True, "101": 72}}
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"]
if "python.heater.main" in sys.modules:
del sys.modules["python.heater.main"]
from python.heater.main import create_app
from python.heater.controller import HeaterController
config = DeviceConfig(device_id="abc", ip="10.0.0.1", local_key="key")
app = create_app(config)
# Simulate lifespan by setting controller
app.state.controller = HeaterController(config)
# Find and call the status handler
for route in app.routes:
if hasattr(route, "path") and route.path == "/status":
result = route.endpoint()
assert result.power is True
break
def test_heater_on_route() -> None:
"""Test /on route handler."""
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"]
if "python.heater.main" in sys.modules:
del sys.modules["python.heater.main"]
from python.heater.main import create_app
from python.heater.controller import HeaterController
config = DeviceConfig(device_id="abc", ip="10.0.0.1", local_key="key")
app = create_app(config)
app.state.controller = HeaterController(config)
for route in app.routes:
if hasattr(route, "path") and route.path == "/on":
result = route.endpoint()
assert result.success is True
break
def test_heater_off_route() -> None:
"""Test /off route handler."""
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"]
if "python.heater.main" in sys.modules:
del sys.modules["python.heater.main"]
from python.heater.main import create_app
from python.heater.controller import HeaterController
config = DeviceConfig(device_id="abc", ip="10.0.0.1", local_key="key")
app = create_app(config)
app.state.controller = HeaterController(config)
for route in app.routes:
if hasattr(route, "path") and route.path == "/off":
result = route.endpoint()
assert result.success is True
break
def test_heater_toggle_route() -> None:
"""Test /toggle route handler."""
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"]
if "python.heater.main" in sys.modules:
del sys.modules["python.heater.main"]
from python.heater.main import create_app
from python.heater.controller import HeaterController
config = DeviceConfig(device_id="abc", ip="10.0.0.1", local_key="key")
app = create_app(config)
app.state.controller = HeaterController(config)
for route in app.routes:
if hasattr(route, "path") and route.path == "/toggle":
result = route.endpoint()
assert result.success is True
break
def test_heater_on_route_failure() -> None:
"""Test /on route raises HTTPException on failure."""
mock_tinytuya = MagicMock()
mock_device = MagicMock()
mock_device.set_value.side_effect = ConnectionError("fail")
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"]
if "python.heater.main" in sys.modules:
del sys.modules["python.heater.main"]
from python.heater.main import create_app
from python.heater.controller import HeaterController
from fastapi import HTTPException
config = DeviceConfig(device_id="abc", ip="10.0.0.1", local_key="key")
app = create_app(config)
app.state.controller = HeaterController(config)
import pytest
for route in app.routes:
if hasattr(route, "path") and route.path == "/on":
with pytest.raises(HTTPException):
route.endpoint()
break