mirror of
https://github.com/home-assistant/core.git
synced 2026-09-26 01:11:51 -04:00
Add shared test mocks for the Infrared integration (#170296)
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude
parent
d5f2cd8b17
commit
af41b704d5
@@ -95,6 +95,7 @@ if TYPE_CHECKING:
|
||||
|
||||
from .conversation import MockAgent
|
||||
from .device_tracker.common import MockScanner
|
||||
from .infrared.common import MockInfraredEntity
|
||||
from .light.common import MockLight
|
||||
from .radio_frequency.common import MockRadioFrequencyEntity
|
||||
from .sensor.common import MockSensor
|
||||
@@ -224,6 +225,25 @@ async def mock_rf_entity_fixture(
|
||||
return await mock_rf_entity_fixture_helper(hass)
|
||||
|
||||
|
||||
# Infrared test fixtures
|
||||
@pytest.fixture(name="init_infrared")
|
||||
async def init_infrared_fixture(hass: HomeAssistant) -> None:
|
||||
"""Set up the Infrared integration for testing."""
|
||||
from .infrared.common import init_infrared_fixture_helper # noqa: PLC0415
|
||||
|
||||
await init_infrared_fixture_helper(hass)
|
||||
|
||||
|
||||
@pytest.fixture(name="mock_infrared_entity")
|
||||
async def mock_infrared_entity_fixture(
|
||||
hass: HomeAssistant, init_infrared: None
|
||||
) -> MockInfraredEntity:
|
||||
"""Return a mock infrared entity."""
|
||||
from .infrared.common import mock_infrared_entity_fixture_helper # noqa: PLC0415
|
||||
|
||||
return await mock_infrared_entity_fixture_helper(hass)
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=find_spec("haffmpeg") is not None)
|
||||
def prevent_ffmpeg_subprocess() -> Generator[None]:
|
||||
"""If installed, prevent ffmpeg from creating a subprocess."""
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
"""Tests for the Infrared integration."""
|
||||
|
||||
ENTITY_ID = "infrared.test_ir_transmitter"
|
||||
|
||||
@@ -1,21 +1,13 @@
|
||||
"""Common fixtures for the Infrared tests."""
|
||||
"""Common test tools for the Infrared integration."""
|
||||
|
||||
from infrared_protocols.commands import Command as InfraredCommand
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.infrared import InfraredEntity
|
||||
from homeassistant.components.infrared import DATA_COMPONENT, InfraredEntity
|
||||
from homeassistant.components.infrared.const import DOMAIN
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def init_integration(hass: HomeAssistant) -> None:
|
||||
"""Set up the Infrared integration for testing."""
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
class MockInfraredEntity(InfraredEntity):
|
||||
"""Mock infrared entity for testing."""
|
||||
|
||||
@@ -32,7 +24,17 @@ class MockInfraredEntity(InfraredEntity):
|
||||
self.send_command_calls.append(command)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_infrared_entity() -> MockInfraredEntity:
|
||||
"""Return a mock infrared entity."""
|
||||
return MockInfraredEntity("test_ir_transmitter")
|
||||
async def init_infrared_fixture_helper(hass: HomeAssistant) -> None:
|
||||
"""Set up the Infrared integration for testing."""
|
||||
assert await async_setup_component(hass, DOMAIN, {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
||||
async def mock_infrared_entity_fixture_helper(
|
||||
hass: HomeAssistant,
|
||||
) -> MockInfraredEntity:
|
||||
"""Add a mock infrared entity to the running integration."""
|
||||
entity = MockInfraredEntity("test_ir_transmitter")
|
||||
component = hass.data[DATA_COMPONENT]
|
||||
await component.async_add_entities([entity])
|
||||
return entity
|
||||
@@ -18,7 +18,8 @@ from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util import dt as dt_util
|
||||
|
||||
from .conftest import MockInfraredEntity
|
||||
from . import ENTITY_ID
|
||||
from .common import MockInfraredEntity
|
||||
|
||||
from tests.common import mock_restore_cache
|
||||
|
||||
@@ -28,61 +29,46 @@ async def test_get_entities_integration_setup(hass: HomeAssistant) -> None:
|
||||
assert async_get_emitters(hass) == []
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_integration")
|
||||
@pytest.mark.usefixtures("init_infrared")
|
||||
async def test_get_entities_empty(hass: HomeAssistant) -> None:
|
||||
"""Test getting entities when none are registered."""
|
||||
assert async_get_emitters(hass) == []
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_integration")
|
||||
async def test_infrared_entity_initial_state(
|
||||
hass: HomeAssistant, mock_infrared_entity: MockInfraredEntity
|
||||
) -> None:
|
||||
@pytest.mark.usefixtures("mock_infrared_entity")
|
||||
async def test_infrared_entity_initial_state(hass: HomeAssistant) -> None:
|
||||
"""Test infrared entity has no state before any command is sent."""
|
||||
component = hass.data[DATA_COMPONENT]
|
||||
await component.async_add_entities([mock_infrared_entity])
|
||||
|
||||
state = hass.states.get("infrared.test_ir_transmitter")
|
||||
state = hass.states.get(ENTITY_ID)
|
||||
assert state is not None
|
||||
assert state.state == STATE_UNKNOWN
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_integration")
|
||||
async def test_async_send_command_success(
|
||||
hass: HomeAssistant,
|
||||
mock_infrared_entity: MockInfraredEntity,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test sending command via async_send_command helper."""
|
||||
# Add the mock entity to the component
|
||||
component = hass.data[DATA_COMPONENT]
|
||||
await component.async_add_entities([mock_infrared_entity])
|
||||
|
||||
# Freeze time so we can verify the state update
|
||||
now = dt_util.utcnow()
|
||||
freezer.move_to(now)
|
||||
|
||||
command = NECCommand(address=0x04FB, command=0x08F7, modulation=38000)
|
||||
await async_send_command(hass, mock_infrared_entity.entity_id, command)
|
||||
await async_send_command(hass, ENTITY_ID, command)
|
||||
|
||||
assert len(mock_infrared_entity.send_command_calls) == 1
|
||||
assert mock_infrared_entity.send_command_calls[0] is command
|
||||
|
||||
state = hass.states.get("infrared.test_ir_transmitter")
|
||||
state = hass.states.get(ENTITY_ID)
|
||||
assert state is not None
|
||||
assert state.state == now.isoformat(timespec="milliseconds")
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_integration")
|
||||
async def test_async_send_command_error_does_not_update_state(
|
||||
hass: HomeAssistant,
|
||||
mock_infrared_entity: MockInfraredEntity,
|
||||
) -> None:
|
||||
"""Test that state is not updated when async_send_command raises an error."""
|
||||
component = hass.data[DATA_COMPONENT]
|
||||
await component.async_add_entities([mock_infrared_entity])
|
||||
|
||||
state = hass.states.get("infrared.test_ir_transmitter")
|
||||
state = hass.states.get(ENTITY_ID)
|
||||
assert state is not None
|
||||
assert state.state == STATE_UNKNOWN
|
||||
|
||||
@@ -93,15 +79,14 @@ async def test_async_send_command_error_does_not_update_state(
|
||||
)
|
||||
|
||||
with pytest.raises(HomeAssistantError, match="Transmission failed"):
|
||||
await async_send_command(hass, mock_infrared_entity.entity_id, command)
|
||||
await async_send_command(hass, ENTITY_ID, command)
|
||||
|
||||
# Verify state was not updated after the error
|
||||
state = hass.states.get("infrared.test_ir_transmitter")
|
||||
state = hass.states.get(ENTITY_ID)
|
||||
assert state is not None
|
||||
assert state.state == STATE_UNKNOWN
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_integration")
|
||||
@pytest.mark.usefixtures("init_infrared")
|
||||
async def test_async_send_command_entity_not_found(hass: HomeAssistant) -> None:
|
||||
"""Test async_send_command raises error when entity not found."""
|
||||
command = NECCommand(
|
||||
@@ -134,19 +119,18 @@ async def test_async_send_command_component_not_loaded(hass: HomeAssistant) -> N
|
||||
)
|
||||
async def test_infrared_entity_state_restore(
|
||||
hass: HomeAssistant,
|
||||
mock_infrared_entity: MockInfraredEntity,
|
||||
restored_value: str,
|
||||
expected_state: str,
|
||||
) -> None:
|
||||
"""Test infrared entity state restore."""
|
||||
mock_restore_cache(hass, [State("infrared.test_ir_transmitter", restored_value)])
|
||||
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([mock_infrared_entity])
|
||||
await component.async_add_entities([MockInfraredEntity("test_ir_transmitter")])
|
||||
|
||||
state = hass.states.get("infrared.test_ir_transmitter")
|
||||
state = hass.states.get(ENTITY_ID)
|
||||
assert state is not None
|
||||
assert state.state == expected_state
|
||||
|
||||
@@ -3,14 +3,8 @@
|
||||
from collections.abc import Generator
|
||||
from unittest.mock import patch
|
||||
|
||||
from infrared_protocols.commands import Command as InfraredCommand
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.infrared import (
|
||||
DATA_COMPONENT as INFRARED_DATA_COMPONENT,
|
||||
DOMAIN as INFRARED_DOMAIN,
|
||||
InfraredEntity,
|
||||
)
|
||||
from homeassistant.components.lg_infrared import PLATFORMS
|
||||
from homeassistant.components.lg_infrared.const import (
|
||||
CONF_DEVICE_TYPE,
|
||||
@@ -20,27 +14,10 @@ from homeassistant.components.lg_infrared.const import (
|
||||
)
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
MOCK_INFRARED_ENTITY_ID = "infrared.test_ir_transmitter"
|
||||
|
||||
|
||||
class MockInfraredEntity(InfraredEntity):
|
||||
"""Mock infrared entity for testing."""
|
||||
|
||||
_attr_has_entity_name = True
|
||||
_attr_name = "Test IR transmitter"
|
||||
|
||||
def __init__(self, unique_id: str) -> None:
|
||||
"""Initialize mock entity."""
|
||||
self._attr_unique_id = unique_id
|
||||
self.send_command_calls: list[InfraredCommand] = []
|
||||
|
||||
async def async_send_command(self, command: InfraredCommand) -> None:
|
||||
"""Mock send command."""
|
||||
self.send_command_calls.append(command)
|
||||
from tests.components.infrared import ENTITY_ID as MOCK_INFRARED_ENTITY_ID
|
||||
from tests.components.infrared.common import MockInfraredEntity
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -58,12 +35,6 @@ def mock_config_entry() -> MockConfigEntry:
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_infrared_entity() -> MockInfraredEntity:
|
||||
"""Return a mock infrared entity."""
|
||||
return MockInfraredEntity("test_ir_transmitter")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def platforms() -> list[Platform]:
|
||||
"""Return platforms to set up."""
|
||||
@@ -94,12 +65,6 @@ async def init_integration(
|
||||
platforms: list[Platform],
|
||||
) -> MockConfigEntry:
|
||||
"""Set up the LG Infrared integration for testing."""
|
||||
assert await async_setup_component(hass, INFRARED_DOMAIN, {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
infrared_component = hass.data[INFRARED_DATA_COMPONENT]
|
||||
await infrared_component.async_add_entities([mock_infrared_entity])
|
||||
|
||||
mock_config_entry.add_to_hass(hass)
|
||||
|
||||
with patch("homeassistant.components.lg_infrared.PLATFORMS", platforms):
|
||||
|
||||
@@ -9,10 +9,10 @@ from homeassistant.const import ATTR_ENTITY_ID, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
|
||||
from .conftest import MockInfraredEntity
|
||||
from .utils import check_availability_follows_ir_entity
|
||||
|
||||
from tests.common import MockConfigEntry, snapshot_platform
|
||||
from tests.components.infrared.common import MockInfraredEntity
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.infrared import (
|
||||
DATA_COMPONENT as INFRARED_DATA_COMPONENT,
|
||||
DOMAIN as INFRARED_DOMAIN,
|
||||
)
|
||||
from homeassistant.components.lg_infrared.const import (
|
||||
CONF_DEVICE_TYPE,
|
||||
CONF_INFRARED_ENTITY_ID,
|
||||
@@ -16,26 +12,12 @@ from homeassistant.config_entries import SOURCE_USER
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.data_entry_flow import FlowResultType
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from .conftest import MOCK_INFRARED_ENTITY_ID, MockInfraredEntity
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.components.infrared import ENTITY_ID as MOCK_INFRARED_ENTITY_ID
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
async def setup_infrared(
|
||||
hass: HomeAssistant, mock_infrared_entity: MockInfraredEntity
|
||||
) -> None:
|
||||
"""Set up the infrared component with a mock entity."""
|
||||
assert await async_setup_component(hass, INFRARED_DOMAIN, {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
component = hass.data[INFRARED_DATA_COMPONENT]
|
||||
await component.async_add_entities([mock_infrared_entity])
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("setup_infrared")
|
||||
@pytest.mark.usefixtures("mock_infrared_entity")
|
||||
async def test_user_flow_success(
|
||||
hass: HomeAssistant,
|
||||
) -> None:
|
||||
@@ -64,7 +46,7 @@ async def test_user_flow_success(
|
||||
assert result["result"].unique_id == f"lg_ir_tv_{MOCK_INFRARED_ENTITY_ID}"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("setup_infrared")
|
||||
@pytest.mark.usefixtures("mock_infrared_entity")
|
||||
async def test_user_flow_already_configured(
|
||||
hass: HomeAssistant, mock_config_entry: MockConfigEntry
|
||||
) -> None:
|
||||
@@ -89,11 +71,9 @@ async def test_user_flow_already_configured(
|
||||
assert result["reason"] == "already_configured"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("init_infrared")
|
||||
async def test_user_flow_no_emitters(hass: HomeAssistant) -> None:
|
||||
"""Test user flow aborts when no infrared emitters exist."""
|
||||
assert await async_setup_component(hass, INFRARED_DOMAIN, {})
|
||||
await hass.async_block_till_done()
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
@@ -102,7 +82,7 @@ async def test_user_flow_no_emitters(hass: HomeAssistant) -> None:
|
||||
assert result["reason"] == "no_emitters"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures("setup_infrared")
|
||||
@pytest.mark.usefixtures("mock_infrared_entity")
|
||||
@pytest.mark.parametrize(
|
||||
("entity_name", "expected_title"),
|
||||
[
|
||||
|
||||
@@ -21,10 +21,10 @@ from homeassistant.const import ATTR_ENTITY_ID, Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr, entity_registry as er
|
||||
|
||||
from .conftest import MockInfraredEntity
|
||||
from .utils import check_availability_follows_ir_entity
|
||||
|
||||
from tests.common import MockConfigEntry, snapshot_platform
|
||||
from tests.components.infrared.common import MockInfraredEntity
|
||||
|
||||
MEDIA_PLAYER_ENTITY_ID = "media_player.lg_tv"
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
from homeassistant.const import STATE_UNAVAILABLE
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
from .conftest import MOCK_INFRARED_ENTITY_ID
|
||||
from tests.components.infrared import ENTITY_ID as MOCK_INFRARED_ENTITY_ID
|
||||
|
||||
|
||||
async def check_availability_follows_ir_entity(
|
||||
|
||||
Reference in New Issue
Block a user