1
0
mirror of https://github.com/home-assistant/core.git synced 2026-05-17 14:01:34 +01:00
Files
core/tests/components/radio_frequency/test_init.py
T
2026-04-27 11:25:25 +02:00

201 lines
6.8 KiB
Python

"""Tests for the Radio Frequency integration setup."""
from unittest.mock import AsyncMock
from freezegun.api import FrozenDateTimeFactory
import pytest
from rf_protocols import ModulationType
from homeassistant.components.radio_frequency import (
DATA_COMPONENT,
DOMAIN,
async_get_transmitters,
async_send_command,
)
from homeassistant.const import STATE_UNAVAILABLE, STATE_UNKNOWN
from homeassistant.core import HomeAssistant, State
from homeassistant.exceptions import HomeAssistantError
from homeassistant.setup import async_setup_component
from homeassistant.util import dt as dt_util
from . import ENTITY_ID
from .common import MockRadioFrequencyCommand, MockRadioFrequencyEntity
from tests.common import mock_restore_cache
async def test_get_transmitters_component_not_loaded(hass: HomeAssistant) -> None:
"""Test getting transmitters raises when the component is not loaded."""
with pytest.raises(HomeAssistantError, match="component_not_loaded"):
async_get_transmitters(hass, 433_920_000, ModulationType.OOK)
@pytest.mark.usefixtures("init_radio_frequency")
async def test_get_transmitters_no_entities(hass: HomeAssistant) -> None:
"""Test getting transmitters raises when none are registered."""
with pytest.raises(
HomeAssistantError,
match="No Radio Frequency transmitters available",
):
async_get_transmitters(hass, 433_920_000, ModulationType.OOK)
@pytest.mark.usefixtures("mock_rf_entity")
async def test_get_transmitters_with_frequency_ranges(hass: HomeAssistant) -> None:
"""Test transmitter with frequency ranges filters correctly."""
# 433.92 MHz is within 433-434 MHz range
result = async_get_transmitters(hass, 433_920_000, ModulationType.OOK)
assert result == [ENTITY_ID]
# 868 MHz is outside the range
result = async_get_transmitters(hass, 868_000_000, ModulationType.OOK)
assert result == []
@pytest.mark.usefixtures("mock_rf_entity")
async def test_get_transmitters_filters_by_modulation(hass: HomeAssistant) -> None:
"""Test transmitters are filtered by supported modulation."""
result = async_get_transmitters(hass, 433_920_000, "no_matching_modulation") # type: ignore[arg-type]
assert result == []
@pytest.mark.usefixtures("mock_rf_entity")
async def test_rf_entity_initial_state(hass: HomeAssistant) -> None:
"""Test radio frequency entity has no state before any command is sent."""
state = hass.states.get(ENTITY_ID)
assert state is not None
assert state.state == STATE_UNKNOWN
async def test_async_send_command_success(
hass: HomeAssistant,
mock_rf_entity: MockRadioFrequencyEntity,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test sending command via async_send_command helper."""
now = dt_util.utcnow()
freezer.move_to(now)
command = MockRadioFrequencyCommand(frequency=433_920_000)
await async_send_command(hass, ENTITY_ID, command)
assert len(mock_rf_entity.send_command_calls) == 1
assert mock_rf_entity.send_command_calls[0].command is command
state = hass.states.get(ENTITY_ID)
assert state is not None
assert state.state == now.isoformat(timespec="milliseconds")
async def test_async_send_command_error_does_not_update_state(
hass: HomeAssistant,
mock_rf_entity: MockRadioFrequencyEntity,
) -> None:
"""Test that state is not updated when async_send_command raises an error."""
state = hass.states.get(ENTITY_ID)
assert state is not None
assert state.state == STATE_UNKNOWN
command = MockRadioFrequencyCommand(frequency=433_920_000)
mock_rf_entity.async_send_command = AsyncMock(
side_effect=HomeAssistantError("Transmission failed")
)
with pytest.raises(HomeAssistantError, match="Transmission failed"):
await async_send_command(hass, ENTITY_ID, command)
state = hass.states.get(ENTITY_ID)
assert state is not None
assert state.state == STATE_UNKNOWN
@pytest.mark.usefixtures("init_radio_frequency")
async def test_async_send_command_entity_not_found(hass: HomeAssistant) -> None:
"""Test async_send_command raises error when entity not found."""
command = MockRadioFrequencyCommand(frequency=433_920_000)
with pytest.raises(
HomeAssistantError,
match="Radio Frequency entity `radio_frequency.nonexistent_entity` not found",
):
await async_send_command(hass, "radio_frequency.nonexistent_entity", command)
async def test_async_send_command_unsupported_frequency(
hass: HomeAssistant,
mock_rf_entity: MockRadioFrequencyEntity,
) -> None:
"""Test async_send_command raises when the frequency is not supported."""
command = MockRadioFrequencyCommand(frequency=868_000_000)
with pytest.raises(
HomeAssistantError,
match=(
f"Radio Frequency entity `{ENTITY_ID}` "
"does not support frequency 868000000 Hz"
),
):
await async_send_command(hass, ENTITY_ID, command)
assert mock_rf_entity.send_command_calls == []
@pytest.mark.usefixtures("mock_rf_entity")
async def test_async_send_command_unsupported_modulation(
hass: HomeAssistant,
mock_rf_entity: MockRadioFrequencyEntity,
) -> None:
"""Test async_send_command raises when the modulation is not supported."""
command = MockRadioFrequencyCommand(
frequency=433_920_000,
modulation="incorrect_modulation", # type: ignore[arg-type]
)
with pytest.raises(
HomeAssistantError,
match=(
f"Radio Frequency entity `{ENTITY_ID}` "
"does not support modulation incorrect_modulation"
),
):
await async_send_command(hass, ENTITY_ID, command)
assert mock_rf_entity.send_command_calls == []
async def test_async_send_command_component_not_loaded(hass: HomeAssistant) -> None:
"""Test async_send_command raises error when component not loaded."""
command = MockRadioFrequencyCommand(frequency=433_920_000)
with pytest.raises(HomeAssistantError, match="component_not_loaded"):
await async_send_command(hass, "radio_frequency.some_entity", command)
@pytest.mark.parametrize(
("restored_value", "expected_state"),
[
("2026-01-01T12:00:00.000+00:00", "2026-01-01T12:00:00.000+00:00"),
(STATE_UNAVAILABLE, STATE_UNKNOWN),
],
)
async def test_rf_entity_state_restore(
hass: HomeAssistant,
restored_value: str,
expected_state: str,
) -> None:
"""Test radio frequency entity state restore."""
mock_restore_cache(hass, [State(ENTITY_ID, restored_value)])
assert await async_setup_component(hass, DOMAIN, {})
await hass.async_block_till_done()
component = hass.data[DATA_COMPONENT]
await component.async_add_entities(
[MockRadioFrequencyEntity("test_rf_transmitter")]
)
state = hass.states.get(ENTITY_ID)
assert state is not None
assert state.state == expected_state