diff --git a/tests/components/conftest.py b/tests/components/conftest.py index ecef69e18e815..bb8297ca9eaa5 100644 --- a/tests/components/conftest.py +++ b/tests/components/conftest.py @@ -95,6 +95,7 @@ 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.""" diff --git a/tests/components/infrared/__init__.py b/tests/components/infrared/__init__.py index f5712a639f4b2..14b40a4f73189 100644 --- a/tests/components/infrared/__init__.py +++ b/tests/components/infrared/__init__.py @@ -1 +1,3 @@ """Tests for the Infrared integration.""" + +ENTITY_ID = "infrared.test_ir_transmitter" diff --git a/tests/components/infrared/conftest.py b/tests/components/infrared/common.py similarity index 62% rename from tests/components/infrared/conftest.py rename to tests/components/infrared/common.py index 92e66aafb4c73..7d07763e013b4 100644 --- a/tests/components/infrared/conftest.py +++ b/tests/components/infrared/common.py @@ -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 @@ async def async_send_command(self, command: InfraredCommand) -> None: 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 diff --git a/tests/components/infrared/test_init.py b/tests/components/infrared/test_init.py index de8045c55f1ff..5a1e8f37e83ec 100644 --- a/tests/components/infrared/test_init.py +++ b/tests/components/infrared/test_init.py @@ -18,7 +18,8 @@ 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 diff --git a/tests/components/lg_infrared/conftest.py b/tests/components/lg_infrared/conftest.py index 24e6399d8a9e9..4fe112aecaa41 100644 --- a/tests/components/lg_infrared/conftest.py +++ b/tests/components/lg_infrared/conftest.py @@ -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.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): diff --git a/tests/components/lg_infrared/test_button.py b/tests/components/lg_infrared/test_button.py index c93273abfe903..b4ab5bcfca999 100644 --- a/tests/components/lg_infrared/test_button.py +++ b/tests/components/lg_infrared/test_button.py @@ -9,10 +9,10 @@ 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 diff --git a/tests/components/lg_infrared/test_config_flow.py b/tests/components/lg_infrared/test_config_flow.py index a75f7d14019ff..9b800a1081af3 100644 --- a/tests/components/lg_infrared/test_config_flow.py +++ b/tests/components/lg_infrared/test_config_flow.py @@ -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.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"), [ diff --git a/tests/components/lg_infrared/test_media_player.py b/tests/components/lg_infrared/test_media_player.py index 612d7eb22d53e..066534c604ba7 100644 --- a/tests/components/lg_infrared/test_media_player.py +++ b/tests/components/lg_infrared/test_media_player.py @@ -21,10 +21,10 @@ 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" diff --git a/tests/components/lg_infrared/utils.py b/tests/components/lg_infrared/utils.py index 6db180573eb29..eb6f5d0849182 100644 --- a/tests/components/lg_infrared/utils.py +++ b/tests/components/lg_infrared/utils.py @@ -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(