Files
core/tests/components/smlight/test_infrared.py
T

190 lines
5.6 KiB
Python

"""Tests for SLZB-Ultima infrared entity."""
from unittest.mock import MagicMock
from infrared_protocols.commands import Command
from pysmlight.const import Events as SmEvents
from pysmlight.exceptions import SmlightError
from pysmlight.models import IRPayload
import pytest
from homeassistant.components.infrared import (
async_send_command,
async_subscribe_receiver,
)
from homeassistant.const import STATE_UNKNOWN, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from . import get_mock_event_function
from .conftest import setup_integration
from tests.common import MockConfigEntry
class MockCommand(Command):
"""Mock InfraredCommand."""
def __init__(self) -> None:
"""Initialize with fixed 38kHz modulation."""
super().__init__(modulation=38000)
def get_raw_timings(self) -> list[int]:
"""Return some fake timings."""
return [9000, -4500, 560, -1690]
@pytest.fixture
def platforms() -> list[Platform]:
"""Platforms, which should be loaded during the test."""
return [Platform.INFRARED]
async def test_infrared_setup_ultima(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_ultima_client: MagicMock,
) -> None:
"""Test infrared entities are created for Ultima devices."""
await setup_integration(hass, mock_config_entry)
state = hass.states.get("infrared.mock_title_infrared_emitter")
assert state is not None
state = hass.states.get("infrared.mock_title_infrared_receiver")
assert state is not None
async def test_infrared_not_created_non_ultima(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_smlight_client: MagicMock,
) -> None:
"""Test infrared entities are not created for non-Ultima devices."""
await setup_integration(hass, mock_config_entry)
state = hass.states.get("infrared.mock_title_infrared_emitter")
assert state is None
state = hass.states.get("infrared.mock_title_infrared_receiver")
assert state is None
async def test_infrared_send_command(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_ultima_client: MagicMock,
) -> None:
"""Test sending IR command."""
await setup_integration(hass, mock_config_entry)
entity_id = "infrared.mock_title_infrared_emitter"
state = hass.states.get(entity_id)
assert state is not None
await async_send_command(
hass,
entity_id,
MockCommand(),
)
mock_ultima_client.actions.send_ir_code.assert_called_once_with(
IRPayload.from_raw_timings([9000, 4500, 560, 1690], freq=38000)
)
async def test_infrared_send_command_error(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_ultima_client: MagicMock,
) -> None:
"""Test connection error handling."""
await setup_integration(hass, mock_config_entry)
entity_id = "infrared.mock_title_infrared_emitter"
state = hass.states.get(entity_id)
assert state is not None
mock_ultima_client.actions.send_ir_code.side_effect = SmlightError("Failed")
with pytest.raises(HomeAssistantError) as exc_info:
await async_send_command(
hass,
entity_id,
MockCommand(),
)
assert exc_info.value.translation_key == "send_ir_code_failed"
async def test_infrared_send_empty_command_error(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_ultima_client: MagicMock,
) -> None:
"""Test ValueError from pysmlight is surfaced as HomeAssistantError."""
await setup_integration(hass, mock_config_entry)
entity_id = "infrared.mock_title_infrared_emitter"
state = hass.states.get(entity_id)
assert state is not None
mock_ultima_client.actions.send_ir_code.side_effect = ValueError("empty payload")
with pytest.raises(HomeAssistantError) as exc_info:
await async_send_command(
hass,
entity_id,
MockCommand(),
)
assert exc_info.value.translation_key == "send_ir_code_failed"
@pytest.mark.freeze_time("2025-09-03T22:00:00+00:00")
async def test_infrared_state_updated_after_send(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_ultima_client: MagicMock,
) -> None:
"""Test that entity state is updated with a timestamp after a successful send."""
await setup_integration(hass, mock_config_entry)
entity_id = "infrared.mock_title_infrared_emitter"
state = hass.states.get(entity_id)
assert state is not None
assert state.state == STATE_UNKNOWN
await async_send_command(hass, entity_id, MockCommand())
state = hass.states.get(entity_id)
assert state.state == "2025-09-03T22:00:00.000+00:00"
@pytest.mark.freeze_time("2025-09-03T22:00:00+00:00")
async def test_infrared_receiver_event(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_ultima_client: MagicMock,
) -> None:
"""Test infrared receiver receives event and updates state."""
await setup_integration(hass, mock_config_entry)
entity_id = "infrared.mock_title_infrared_receiver"
state = hass.states.get(entity_id)
assert state is not None
assert state.state == STATE_UNKNOWN
signals = []
async_subscribe_receiver(hass, entity_id, signals.append)
event_function = get_mock_event_function(mock_ultima_client, SmEvents.IR_CODE)
assert event_function is not None
event_function([9000, 4500, 560, 1690])
await hass.async_block_till_done()
state = hass.states.get(entity_id)
assert state.state == "2025-09-03T22:00:00.000+00:00"
assert len(signals) == 1
assert signals[0].timings == [9000, 4500, 560, 1690]