From b1848cd2f4a011d88421579e41048c119074039c Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Fri, 14 Jan 2022 17:16:59 +0100 Subject: [PATCH] Modernize Elgato tests (#64060) --- tests/components/elgato/__init__.py | 71 ----- tests/components/elgato/conftest.py | 76 +++++- ...ettings.json => settings-temperature.json} | 0 .../elgato/fixtures/state-color.json | 13 +- .../elgato/fixtures/state-temperature.json | 5 + tests/components/elgato/fixtures/state.json | 10 - tests/components/elgato/test_button.py | 58 ++-- tests/components/elgato/test_config_flow.py | 167 ++++++------ tests/components/elgato/test_init.py | 55 ++-- tests/components/elgato/test_light.py | 255 ++++++++---------- 10 files changed, 343 insertions(+), 367 deletions(-) rename tests/components/elgato/fixtures/{settings.json => settings-temperature.json} (100%) create mode 100644 tests/components/elgato/fixtures/state-temperature.json delete mode 100644 tests/components/elgato/fixtures/state.json diff --git a/tests/components/elgato/__init__.py b/tests/components/elgato/__init__.py index 9e6c9155f8a..7d69fa68f73 100644 --- a/tests/components/elgato/__init__.py +++ b/tests/components/elgato/__init__.py @@ -1,72 +1 @@ """Tests for the Elgato Key Light integration.""" - -from homeassistant.components.elgato.const import DOMAIN -from homeassistant.const import CONF_HOST, CONF_PORT, CONTENT_TYPE_JSON -from homeassistant.core import HomeAssistant - -from tests.common import MockConfigEntry, load_fixture -from tests.test_util.aiohttp import AiohttpClientMocker - - -async def init_integration( - hass: HomeAssistant, - aioclient_mock: AiohttpClientMocker, - skip_setup: bool = False, - color: bool = False, - mode_color: bool = False, -) -> MockConfigEntry: - """Set up the Elgato Key Light integration in Home Assistant.""" - aioclient_mock.get( - "http://127.0.0.1:9123/elgato/accessory-info", - text=load_fixture("elgato/info.json"), - headers={"Content-Type": CONTENT_TYPE_JSON}, - ) - - aioclient_mock.get( - "http://127.0.0.2:9123/elgato/accessory-info", - text=load_fixture("elgato/info.json"), - headers={"Content-Type": CONTENT_TYPE_JSON}, - ) - - settings = "elgato/settings.json" - if color: - settings = "elgato/settings-color.json" - - aioclient_mock.get( - "http://127.0.0.1:9123/elgato/lights/settings", - text=load_fixture(settings), - headers={"Content-Type": CONTENT_TYPE_JSON}, - ) - - state = "elgato/state.json" - if mode_color: - state = "elgato/state-color.json" - - aioclient_mock.get( - "http://127.0.0.1:9123/elgato/lights", - text=load_fixture(state), - headers={"Content-Type": CONTENT_TYPE_JSON}, - ) - - aioclient_mock.put( - "http://127.0.0.1:9123/elgato/lights", - text=load_fixture("elgato/state.json"), - headers={"Content-Type": CONTENT_TYPE_JSON}, - ) - - entry = MockConfigEntry( - domain=DOMAIN, - unique_id="CN11A1A00001", - data={ - CONF_HOST: "127.0.0.1", - CONF_PORT: 9123, - }, - ) - - entry.add_to_hass(hass) - - if not skip_setup: - await hass.config_entries.async_setup(entry.entry_id) - await hass.async_block_till_done() - - return entry diff --git a/tests/components/elgato/conftest.py b/tests/components/elgato/conftest.py index fe86f26b535..323d9cad7b7 100644 --- a/tests/components/elgato/conftest.py +++ b/tests/components/elgato/conftest.py @@ -1,2 +1,76 @@ -"""elgato conftest.""" +"""Fixtures for Elgato integration tests.""" +from collections.abc import Generator +from unittest.mock import AsyncMock, MagicMock, patch + +from elgato import Info, Settings, State +import pytest + +from homeassistant.components.elgato.const import DOMAIN +from homeassistant.const import CONF_HOST, CONF_PORT +from homeassistant.core import HomeAssistant + +from tests.common import MockConfigEntry, load_fixture from tests.components.light.conftest import mock_light_profiles # noqa: F401 + + +@pytest.fixture +def mock_config_entry() -> MockConfigEntry: + """Return the default mocked config entry.""" + return MockConfigEntry( + title="CN11A1A00001", + domain=DOMAIN, + data={CONF_HOST: "127.0.0.1", CONF_PORT: 9123}, + unique_id="CN11A1A00001", + ) + + +@pytest.fixture +def mock_setup_entry() -> Generator[AsyncMock, None, None]: + """Mock setting up a config entry.""" + with patch( + "homeassistant.components.elgato.async_setup_entry", return_value=True + ) as mock_setup: + yield mock_setup + + +@pytest.fixture +def mock_elgato_config_flow() -> Generator[None, MagicMock, None]: + """Return a mocked Elgato client.""" + with patch( + "homeassistant.components.elgato.config_flow.Elgato", autospec=True + ) as elgato_mock: + elgato = elgato_mock.return_value + elgato.info.return_value = Info.parse_raw(load_fixture("info.json", DOMAIN)) + yield elgato + + +@pytest.fixture +def mock_elgato(request: pytest.FixtureRequest) -> Generator[None, MagicMock, None]: + """Return a mocked Elgato client.""" + variant = {"state": "temperature", "settings": "temperature"} + if hasattr(request, "param") and request.param: + variant = request.param + + with patch("homeassistant.components.elgato.Elgato", autospec=True) as elgato_mock: + elgato = elgato_mock.return_value + elgato.info.return_value = Info.parse_raw(load_fixture("info.json", DOMAIN)) + elgato.state.return_value = State.parse_raw( + load_fixture(f"state-{variant['state']}.json", DOMAIN) + ) + elgato.settings.return_value = Settings.parse_raw( + load_fixture(f"settings-{variant['settings']}.json", DOMAIN) + ) + yield elgato + + +@pytest.fixture +async def init_integration( + hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_elgato: MagicMock +) -> MockConfigEntry: + """Set up the Elgato integration for testing.""" + mock_config_entry.add_to_hass(hass) + + await hass.config_entries.async_setup(mock_config_entry.entry_id) + await hass.async_block_till_done() + + return mock_config_entry diff --git a/tests/components/elgato/fixtures/settings.json b/tests/components/elgato/fixtures/settings-temperature.json similarity index 100% rename from tests/components/elgato/fixtures/settings.json rename to tests/components/elgato/fixtures/settings-temperature.json diff --git a/tests/components/elgato/fixtures/state-color.json b/tests/components/elgato/fixtures/state-color.json index b49a6f6dd80..d9b2567928d 100644 --- a/tests/components/elgato/fixtures/state-color.json +++ b/tests/components/elgato/fixtures/state-color.json @@ -1,11 +1,6 @@ { - "numberOfLights": 1, - "lights": [ - { - "on": 1, - "hue": 358.0, - "saturation": 6.0, - "brightness": 50 - } - ] + "on": 1, + "hue": 358.0, + "saturation": 6.0, + "brightness": 50 } diff --git a/tests/components/elgato/fixtures/state-temperature.json b/tests/components/elgato/fixtures/state-temperature.json new file mode 100644 index 00000000000..5b3d7690d85 --- /dev/null +++ b/tests/components/elgato/fixtures/state-temperature.json @@ -0,0 +1,5 @@ +{ + "on": 1, + "brightness": 21, + "temperature": 297 +} diff --git a/tests/components/elgato/fixtures/state.json b/tests/components/elgato/fixtures/state.json deleted file mode 100644 index f6180e14238..00000000000 --- a/tests/components/elgato/fixtures/state.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "numberOfLights": 1, - "lights": [ - { - "on": 1, - "brightness": 21, - "temperature": 297 - } - ] -} diff --git a/tests/components/elgato/test_button.py b/tests/components/elgato/test_button.py index 80a906e114f..4c29c49daec 100644 --- a/tests/components/elgato/test_button.py +++ b/tests/components/elgato/test_button.py @@ -1,5 +1,5 @@ """Tests for the Elgato Light button platform.""" -from unittest.mock import patch +from unittest.mock import MagicMock from elgato import ElgatoError import pytest @@ -10,17 +10,16 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er from homeassistant.helpers.entity import EntityCategory -from tests.components.elgato import init_integration -from tests.test_util.aiohttp import AiohttpClientMocker +from tests.common import MockConfigEntry @pytest.mark.freeze_time("2021-11-13 11:48:00") async def test_button_identify( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + init_integration: MockConfigEntry, + mock_elgato: MagicMock, ) -> None: """Test the Elgato identify button.""" - await init_integration(hass, aioclient_mock) - entity_registry = er.async_get(hass) state = hass.states.get("button.identify") @@ -33,18 +32,15 @@ async def test_button_identify( assert entry.unique_id == "CN11A1A00001_identify" assert entry.entity_category == EntityCategory.CONFIG - with patch( - "homeassistant.components.elgato.light.Elgato.identify" - ) as mock_identify: - await hass.services.async_call( - BUTTON_DOMAIN, - SERVICE_PRESS, - {ATTR_ENTITY_ID: "button.identify"}, - blocking=True, - ) + await hass.services.async_call( + BUTTON_DOMAIN, + SERVICE_PRESS, + {ATTR_ENTITY_ID: "button.identify"}, + blocking=True, + ) - assert len(mock_identify.mock_calls) == 1 - mock_identify.assert_called_with() + assert len(mock_elgato.identify.mock_calls) == 1 + mock_elgato.identify.assert_called_with() state = hass.states.get("button.identify") assert state @@ -52,22 +48,20 @@ async def test_button_identify( async def test_button_identify_error( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, caplog + hass: HomeAssistant, + init_integration: MockConfigEntry, + mock_elgato: MagicMock, + caplog: pytest.LogCaptureFixture, ) -> None: """Test an error occurs with the Elgato identify button.""" - await init_integration(hass, aioclient_mock) - - with patch( - "homeassistant.components.elgato.light.Elgato.identify", - side_effect=ElgatoError, - ) as mock_identify: - await hass.services.async_call( - BUTTON_DOMAIN, - SERVICE_PRESS, - {ATTR_ENTITY_ID: "button.identify"}, - blocking=True, - ) - + mock_elgato.identify.side_effect = ElgatoError + await hass.services.async_call( + BUTTON_DOMAIN, + SERVICE_PRESS, + {ATTR_ENTITY_ID: "button.identify"}, + blocking=True, + ) await hass.async_block_till_done() - assert len(mock_identify.mock_calls) == 1 + + assert len(mock_elgato.identify.mock_calls) == 1 assert "An error occurred while identifying the Elgato Light" in caplog.text diff --git a/tests/components/elgato/test_config_flow.py b/tests/components/elgato/test_config_flow.py index bd9a631b815..19d227134a0 100644 --- a/tests/components/elgato/test_config_flow.py +++ b/tests/components/elgato/test_config_flow.py @@ -1,77 +1,63 @@ """Tests for the Elgato Key Light config flow.""" -import aiohttp +from unittest.mock import AsyncMock, MagicMock + +from elgato import ElgatoConnectionError -from homeassistant import data_entry_flow from homeassistant.components import zeroconf from homeassistant.components.elgato.const import DOMAIN from homeassistant.config_entries import SOURCE_USER, SOURCE_ZEROCONF -from homeassistant.const import CONF_HOST, CONF_PORT, CONF_SOURCE, CONTENT_TYPE_JSON +from homeassistant.const import CONF_HOST, CONF_PORT, CONF_SOURCE from homeassistant.core import HomeAssistant +from homeassistant.data_entry_flow import ( + RESULT_TYPE_ABORT, + RESULT_TYPE_CREATE_ENTRY, + RESULT_TYPE_FORM, +) -from . import init_integration - -from tests.common import load_fixture -from tests.test_util.aiohttp import AiohttpClientMocker +from tests.common import MockConfigEntry async def test_full_user_flow_implementation( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + mock_elgato_config_flow: MagicMock, + mock_setup_entry: AsyncMock, ) -> None: """Test the full manual user flow from start to finish.""" - aioclient_mock.get( - "http://127.0.0.1:9123/elgato/accessory-info", - text=load_fixture("elgato/info.json"), - headers={"Content-Type": CONTENT_TYPE_JSON}, - ) - - # Start a discovered configuration flow, to guarantee a user flow doesn't abort - await hass.config_entries.flow.async_init( - DOMAIN, - context={CONF_SOURCE: SOURCE_ZEROCONF}, - data=zeroconf.ZeroconfServiceInfo( - host="127.0.0.1", - hostname="example.local.", - name="mock_name", - port=9123, - properties={}, - type="mock_type", - ), - ) - result = await hass.config_entries.flow.async_init( DOMAIN, - context={CONF_SOURCE: SOURCE_USER}, + context={"source": SOURCE_USER}, ) - assert result["step_id"] == "user" - assert result["type"] == data_entry_flow.RESULT_TYPE_FORM + assert result.get("type") == RESULT_TYPE_FORM + assert result.get("step_id") == SOURCE_USER + assert "flow_id" in result - result = await hass.config_entries.flow.async_configure( + result2 = await hass.config_entries.flow.async_configure( result["flow_id"], user_input={CONF_HOST: "127.0.0.1", CONF_PORT: 9123} ) - assert result["data"][CONF_HOST] == "127.0.0.1" - assert result["data"][CONF_PORT] == 9123 - assert result["title"] == "CN11A1A00001" - assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY + assert result2.get("type") == RESULT_TYPE_CREATE_ENTRY + assert result2.get("title") == "CN11A1A00001" + assert result2.get("data") == { + CONF_HOST: "127.0.0.1", + CONF_PORT: 9123, + } + assert "result" in result2 + assert result2["result"].unique_id == "CN11A1A00001" - entries = hass.config_entries.async_entries(DOMAIN) - assert entries[0].unique_id == "CN11A1A00001" + assert len(mock_setup_entry.mock_calls) == 1 + assert len(mock_elgato_config_flow.info.mock_calls) == 1 async def test_full_zeroconf_flow_implementation( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + mock_elgato_config_flow: MagicMock, + mock_setup_entry: AsyncMock, ) -> None: """Test the zeroconf flow from start to finish.""" - aioclient_mock.get( - "http://127.0.0.1:9123/elgato/accessory-info", - text=load_fixture("elgato/info.json"), - headers={"Content-Type": CONTENT_TYPE_JSON}, - ) - result = await hass.config_entries.flow.async_init( DOMAIN, - context={CONF_SOURCE: SOURCE_ZEROCONF}, + context={"source": SOURCE_ZEROCONF}, data=zeroconf.ZeroconfServiceInfo( host="127.0.0.1", hostname="example.local.", @@ -82,51 +68,57 @@ async def test_full_zeroconf_flow_implementation( ), ) - assert result["description_placeholders"] == {"serial_number": "CN11A1A00001"} - assert result["step_id"] == "zeroconf_confirm" - assert result["type"] == data_entry_flow.RESULT_TYPE_FORM + assert result.get("description_placeholders") == {"serial_number": "CN11A1A00001"} + assert result.get("step_id") == "zeroconf_confirm" + assert result.get("type") == RESULT_TYPE_FORM + assert "flow_id" in result progress = hass.config_entries.flow.async_progress() assert len(progress) == 1 - assert progress[0]["flow_id"] == result["flow_id"] - assert progress[0]["context"]["confirm_only"] is True + assert progress[0].get("flow_id") == result["flow_id"] + assert "context" in progress[0] + assert progress[0]["context"].get("confirm_only") is True - result = await hass.config_entries.flow.async_configure( + result2 = await hass.config_entries.flow.async_configure( result["flow_id"], user_input={} ) - assert result["data"][CONF_HOST] == "127.0.0.1" - assert result["data"][CONF_PORT] == 9123 - assert result["title"] == "CN11A1A00001" - assert result["type"] == data_entry_flow.RESULT_TYPE_CREATE_ENTRY + + assert result2.get("type") == RESULT_TYPE_CREATE_ENTRY + assert result2.get("title") == "CN11A1A00001" + assert result2.get("data") == { + CONF_HOST: "127.0.0.1", + CONF_PORT: 9123, + } + assert "result" in result2 + assert result2["result"].unique_id == "CN11A1A00001" + + assert len(mock_setup_entry.mock_calls) == 1 + assert len(mock_elgato_config_flow.info.mock_calls) == 1 async def test_connection_error( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + mock_elgato_config_flow: MagicMock, ) -> None: """Test we show user form on Elgato Key Light connection error.""" - aioclient_mock.get( - "http://127.0.0.1/elgato/accessory-info", exc=aiohttp.ClientError - ) - + mock_elgato_config_flow.info.side_effect = ElgatoConnectionError result = await hass.config_entries.flow.async_init( DOMAIN, - context={CONF_SOURCE: SOURCE_USER}, + context={"source": SOURCE_USER}, data={CONF_HOST: "127.0.0.1", CONF_PORT: 9123}, ) - assert result["errors"] == {"base": "cannot_connect"} - assert result["step_id"] == "user" - assert result["type"] == data_entry_flow.RESULT_TYPE_FORM + assert result.get("type") == RESULT_TYPE_FORM + assert result.get("errors") == {"base": "cannot_connect"} + assert result.get("step_id") == "user" async def test_zeroconf_connection_error( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + mock_elgato_config_flow: MagicMock, ) -> None: """Test we abort zeroconf flow on Elgato Key Light connection error.""" - aioclient_mock.get( - "http://127.0.0.1/elgato/accessory-info", exc=aiohttp.ClientError - ) - + mock_elgato_config_flow.info.side_effect = ElgatoConnectionError result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_ZEROCONF}, @@ -140,31 +132,34 @@ async def test_zeroconf_connection_error( ), ) - assert result["reason"] == "cannot_connect" - assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT + assert result.get("reason") == "cannot_connect" + assert result.get("type") == RESULT_TYPE_ABORT async def test_user_device_exists_abort( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + mock_elgato_config_flow: MagicMock, + mock_config_entry: MockConfigEntry, ) -> None: """Test we abort zeroconf flow if Elgato Key Light device already configured.""" - await init_integration(hass, aioclient_mock) - + mock_config_entry.add_to_hass(hass) result = await hass.config_entries.flow.async_init( DOMAIN, - context={CONF_SOURCE: SOURCE_USER}, + context={"source": SOURCE_USER}, data={CONF_HOST: "127.0.0.1", CONF_PORT: 9123}, ) - assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT + assert result.get("type") == RESULT_TYPE_ABORT + assert result.get("reason") == "already_configured" async def test_zeroconf_device_exists_abort( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + mock_elgato_config_flow: MagicMock, + mock_config_entry: MockConfigEntry, ) -> None: """Test we abort zeroconf flow if Elgato Key Light device already configured.""" - await init_integration(hass, aioclient_mock) - + mock_config_entry.add_to_hass(hass) result = await hass.config_entries.flow.async_init( DOMAIN, context={CONF_SOURCE: SOURCE_ZEROCONF}, @@ -178,9 +173,13 @@ async def test_zeroconf_device_exists_abort( ), ) - assert result["reason"] == "already_configured" - assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT + assert result.get("type") == RESULT_TYPE_ABORT + assert result.get("reason") == "already_configured" + entries = hass.config_entries.async_entries(DOMAIN) + assert entries[0].data[CONF_HOST] == "127.0.0.1" + + # Check the host updates on discovery result = await hass.config_entries.flow.async_init( DOMAIN, context={CONF_SOURCE: SOURCE_ZEROCONF}, @@ -194,8 +193,8 @@ async def test_zeroconf_device_exists_abort( ), ) - assert result["reason"] == "already_configured" - assert result["type"] == data_entry_flow.RESULT_TYPE_ABORT + assert result.get("type") == RESULT_TYPE_ABORT + assert result.get("reason") == "already_configured" entries = hass.config_entries.async_entries(DOMAIN) assert entries[0].data[CONF_HOST] == "127.0.0.2" diff --git a/tests/components/elgato/test_init.py b/tests/components/elgato/test_init.py index f764ecdba80..d2633ddf36c 100644 --- a/tests/components/elgato/test_init.py +++ b/tests/components/elgato/test_init.py @@ -1,33 +1,46 @@ """Tests for the Elgato Key Light integration.""" -import aiohttp +from unittest.mock import MagicMock + +from elgato import ElgatoConnectionError from homeassistant.components.elgato.const import DOMAIN from homeassistant.config_entries import ConfigEntryState from homeassistant.core import HomeAssistant -from tests.components.elgato import init_integration -from tests.test_util.aiohttp import AiohttpClientMocker +from tests.common import MockConfigEntry + + +async def test_load_unload_config_entry( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_elgato: MagicMock, +) -> None: + """Test the Elgato configuration entry loading/unloading.""" + mock_config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(mock_config_entry.entry_id) + await hass.async_block_till_done() + + assert mock_config_entry.state is ConfigEntryState.LOADED + assert len(mock_elgato.info.mock_calls) == 1 + + await hass.config_entries.async_unload(mock_config_entry.entry_id) + await hass.async_block_till_done() + + assert not hass.data.get(DOMAIN) + assert mock_config_entry.state is ConfigEntryState.NOT_LOADED async def test_config_entry_not_ready( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_elgato: MagicMock, ) -> None: - """Test the Elgato Key Light configuration entry not ready.""" - aioclient_mock.get( - "http://127.0.0.1:9123/elgato/accessory-info", exc=aiohttp.ClientError - ) + """Test the Elgato configuration entry not ready.""" + mock_elgato.info.side_effect = ElgatoConnectionError - entry = await init_integration(hass, aioclient_mock) - assert entry.state is ConfigEntryState.SETUP_RETRY - - -async def test_unload_config_entry( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker -) -> None: - """Test the Elgato Key Light configuration entry unloading.""" - entry = await init_integration(hass, aioclient_mock) - assert hass.data[DOMAIN] - - await hass.config_entries.async_unload(entry.entry_id) + mock_config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(mock_config_entry.entry_id) await hass.async_block_till_done() - assert not hass.data.get(DOMAIN) + + assert len(mock_elgato.info.mock_calls) == 1 + assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY diff --git a/tests/components/elgato/test_light.py b/tests/components/elgato/test_light.py index c85c71aa723..a037163d260 100644 --- a/tests/components/elgato/test_light.py +++ b/tests/components/elgato/test_light.py @@ -1,5 +1,5 @@ """Tests for the Elgato Key Light light platform.""" -from unittest.mock import patch +from unittest.mock import MagicMock from elgato import ElgatoError import pytest @@ -27,17 +27,15 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from tests.common import mock_coro -from tests.components.elgato import init_integration -from tests.test_util.aiohttp import AiohttpClientMocker +from tests.common import MockConfigEntry async def test_light_state_temperature( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + init_integration: MockConfigEntry, + mock_elgato: MagicMock, ) -> None: """Test the creation and values of the Elgato Lights in temperature mode.""" - await init_integration(hass, aioclient_mock) - entity_registry = er.async_get(hass) # First segment of the strip @@ -57,12 +55,15 @@ async def test_light_state_temperature( assert entry.unique_id == "CN11A1A00001" +@pytest.mark.parametrize( + "mock_elgato", [{"settings": "color", "state": "color"}], indirect=True +) async def test_light_state_color( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + init_integration: MockConfigEntry, + mock_elgato: MagicMock, ) -> None: """Test the creation and values of the Elgato Lights in temperature mode.""" - await init_integration(hass, aioclient_mock, color=True, mode_color=True) - entity_registry = er.async_get(hass) # First segment of the strip @@ -85,159 +86,135 @@ async def test_light_state_color( assert entry.unique_id == "CN11A1A00001" +@pytest.mark.parametrize( + "mock_elgato", [{"settings": "color", "state": "temperature"}], indirect=True +) async def test_light_change_state_temperature( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + init_integration: MockConfigEntry, + mock_elgato: MagicMock, ) -> None: """Test the change of state of a Elgato Key Light device.""" - await init_integration(hass, aioclient_mock, color=True, mode_color=False) - state = hass.states.get("light.frenck") assert state assert state.state == STATE_ON - with patch( - "homeassistant.components.elgato.light.Elgato.light", - return_value=mock_coro(), - ) as mock_light: - await hass.services.async_call( - LIGHT_DOMAIN, - SERVICE_TURN_ON, - { - ATTR_ENTITY_ID: "light.frenck", - ATTR_BRIGHTNESS: 255, - ATTR_COLOR_TEMP: 100, - }, - blocking=True, - ) - await hass.async_block_till_done() - assert len(mock_light.mock_calls) == 1 - mock_light.assert_called_with( - on=True, brightness=100, temperature=100, hue=None, saturation=None - ) + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_ON, + { + ATTR_ENTITY_ID: "light.frenck", + ATTR_BRIGHTNESS: 255, + ATTR_COLOR_TEMP: 100, + }, + blocking=True, + ) + await hass.async_block_till_done() + assert len(mock_elgato.light.mock_calls) == 1 + mock_elgato.light.assert_called_with( + on=True, brightness=100, temperature=100, hue=None, saturation=None + ) - await hass.services.async_call( - LIGHT_DOMAIN, - SERVICE_TURN_ON, - { - ATTR_ENTITY_ID: "light.frenck", - ATTR_BRIGHTNESS: 255, - }, - blocking=True, - ) - await hass.async_block_till_done() - assert len(mock_light.mock_calls) == 2 - mock_light.assert_called_with( - on=True, brightness=100, temperature=297, hue=None, saturation=None - ) + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_ON, + { + ATTR_ENTITY_ID: "light.frenck", + ATTR_BRIGHTNESS: 255, + }, + blocking=True, + ) + await hass.async_block_till_done() + assert len(mock_elgato.light.mock_calls) == 2 + mock_elgato.light.assert_called_with( + on=True, brightness=100, temperature=297, hue=None, saturation=None + ) - await hass.services.async_call( - LIGHT_DOMAIN, - SERVICE_TURN_OFF, - {ATTR_ENTITY_ID: "light.frenck"}, - blocking=True, - ) - await hass.async_block_till_done() - assert len(mock_light.mock_calls) == 3 - mock_light.assert_called_with(on=False) + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: "light.frenck"}, + blocking=True, + ) + await hass.async_block_till_done() + assert len(mock_elgato.light.mock_calls) == 3 + mock_elgato.light.assert_called_with(on=False) - -async def test_light_change_state_color( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker -) -> None: - """Test the color state state of a Elgato Light device.""" - await init_integration(hass, aioclient_mock, color=True) - - state = hass.states.get("light.frenck") - assert state - assert state.state == STATE_ON - - with patch( - "homeassistant.components.elgato.light.Elgato.light", - return_value=mock_coro(), - ) as mock_light: - await hass.services.async_call( - LIGHT_DOMAIN, - SERVICE_TURN_ON, - { - ATTR_ENTITY_ID: "light.frenck", - ATTR_BRIGHTNESS: 255, - ATTR_HS_COLOR: (10.1, 20.2), - }, - blocking=True, - ) - await hass.async_block_till_done() - assert len(mock_light.mock_calls) == 1 - mock_light.assert_called_with( - on=True, brightness=100, temperature=None, hue=10.1, saturation=20.2 - ) + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_ON, + { + ATTR_ENTITY_ID: "light.frenck", + ATTR_BRIGHTNESS: 255, + ATTR_HS_COLOR: (10.1, 20.2), + }, + blocking=True, + ) + await hass.async_block_till_done() + assert len(mock_elgato.light.mock_calls) == 4 + mock_elgato.light.assert_called_with( + on=True, brightness=100, temperature=None, hue=10.1, saturation=20.2 + ) @pytest.mark.parametrize("service", [SERVICE_TURN_ON, SERVICE_TURN_OFF]) async def test_light_unavailable( - service: str, hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + init_integration: MockConfigEntry, + mock_elgato: MagicMock, + service: str, ) -> None: """Test error/unavailable handling of an Elgato Light.""" - await init_integration(hass, aioclient_mock) - with patch( - "homeassistant.components.elgato.light.Elgato.light", - side_effect=ElgatoError, - ), patch( - "homeassistant.components.elgato.light.Elgato.state", - side_effect=ElgatoError, - ): - await hass.services.async_call( - LIGHT_DOMAIN, - service, - {ATTR_ENTITY_ID: "light.frenck"}, - blocking=True, - ) - await hass.async_block_till_done() - state = hass.states.get("light.frenck") - assert state.state == STATE_UNAVAILABLE + mock_elgato.state.side_effect = ElgatoError + mock_elgato.light.side_effect = ElgatoError + + await hass.services.async_call( + LIGHT_DOMAIN, + service, + {ATTR_ENTITY_ID: "light.frenck"}, + blocking=True, + ) + await hass.async_block_till_done() + state = hass.states.get("light.frenck") + assert state + assert state.state == STATE_UNAVAILABLE async def test_light_identify( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + init_integration: MockConfigEntry, + mock_elgato: MagicMock, ) -> None: """Test identifying an Elgato Light.""" - await init_integration(hass, aioclient_mock) - - with patch( - "homeassistant.components.elgato.light.Elgato.identify", - return_value=mock_coro(), - ) as mock_identify: - await hass.services.async_call( - DOMAIN, - SERVICE_IDENTIFY, - { - ATTR_ENTITY_ID: "light.frenck", - }, - blocking=True, - ) - await hass.async_block_till_done() - assert len(mock_identify.mock_calls) == 1 - mock_identify.assert_called_with() + await hass.services.async_call( + DOMAIN, + SERVICE_IDENTIFY, + { + ATTR_ENTITY_ID: "light.frenck", + }, + blocking=True, + ) + await hass.async_block_till_done() + assert len(mock_elgato.identify.mock_calls) == 1 + mock_elgato.identify.assert_called_with() async def test_light_identify_error( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, caplog + hass: HomeAssistant, + init_integration: MockConfigEntry, + mock_elgato: MagicMock, + caplog: pytest.LogCaptureFixture, ) -> None: """Test error occurred during identifying an Elgato Light.""" - await init_integration(hass, aioclient_mock) - - with patch( - "homeassistant.components.elgato.light.Elgato.identify", - side_effect=ElgatoError, - ) as mock_identify: - await hass.services.async_call( - DOMAIN, - SERVICE_IDENTIFY, - { - ATTR_ENTITY_ID: "light.frenck", - }, - blocking=True, - ) - await hass.async_block_till_done() - assert len(mock_identify.mock_calls) == 1 - + mock_elgato.identify.side_effect = ElgatoError + await hass.services.async_call( + DOMAIN, + SERVICE_IDENTIFY, + { + ATTR_ENTITY_ID: "light.frenck", + }, + blocking=True, + ) + await hass.async_block_till_done() + assert len(mock_elgato.identify.mock_calls) == 1 assert "An error occurred while identifying the Elgato Light" in caplog.text