From 7393cba0a5808eaaa6503294cda861bc9b38223f Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Fri, 11 Jun 2021 11:36:54 +0200 Subject: [PATCH] Mock WLED in all WLED tests (#51724) * Mock WLED in all WLED tests * Update tests/components/wled/conftest.py Co-authored-by: Erik Montnemery * Remove useless AsyncMock * Add missing asserts Co-authored-by: Erik Montnemery --- tests/components/wled/__init__.py | 57 -- tests/components/wled/conftest.py | 79 ++- tests/components/wled/test_config_flow.py | 69 +- tests/components/wled/test_init.py | 57 +- tests/components/wled/test_light.py | 777 +++++++++++----------- tests/components/wled/test_sensor.py | 17 +- tests/components/wled/test_switch.py | 184 ++--- 7 files changed, 612 insertions(+), 628 deletions(-) diff --git a/tests/components/wled/__init__.py b/tests/components/wled/__init__.py index a39d1ef6453..40723f54294 100644 --- a/tests/components/wled/__init__.py +++ b/tests/components/wled/__init__.py @@ -1,58 +1 @@ """Tests for the WLED integration.""" - -import json - -from homeassistant.components.wled.const import DOMAIN -from homeassistant.const import CONF_HOST, CONF_MAC, 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, - rgbw: bool = False, - skip_setup: bool = False, -) -> MockConfigEntry: - """Set up the WLED integration in Home Assistant.""" - - fixture = "wled/rgb.json" if not rgbw else "wled/rgbw.json" - data = json.loads(load_fixture(fixture)) - - aioclient_mock.get( - "http://192.168.1.123:80/json/", - json=data, - headers={"Content-Type": CONTENT_TYPE_JSON}, - ) - - aioclient_mock.post( - "http://192.168.1.123:80/json/state", - json=data["state"], - headers={"Content-Type": CONTENT_TYPE_JSON}, - ) - - aioclient_mock.get( - "http://192.168.1.123:80/json/info", - json=data["info"], - headers={"Content-Type": CONTENT_TYPE_JSON}, - ) - - aioclient_mock.get( - "http://192.168.1.123:80/json/state", - json=data["state"], - headers={"Content-Type": CONTENT_TYPE_JSON}, - ) - - entry = MockConfigEntry( - domain=DOMAIN, data={CONF_HOST: "192.168.1.123", CONF_MAC: "aabbccddeeff"} - ) - - 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/wled/conftest.py b/tests/components/wled/conftest.py index 7b8eb9cd50c..f66171b6025 100644 --- a/tests/components/wled/conftest.py +++ b/tests/components/wled/conftest.py @@ -1,2 +1,79 @@ -"""wled conftest.""" +"""Fixtures for WLED integration tests.""" +import json +from typing import Generator +from unittest.mock import MagicMock, patch + +import pytest +from wled import Device as WLEDDevice + +from homeassistant.components.wled.const import DOMAIN +from homeassistant.const import CONF_HOST, CONF_MAC +from homeassistant.core import HomeAssistant +from homeassistant.setup import async_setup_component + +from tests.common import MockConfigEntry, load_fixture from tests.components.light.conftest import mock_light_profiles # noqa: F401 + + +@pytest.fixture(autouse=True) +async def mock_persistent_notification(hass: HomeAssistant) -> None: + """Set up component for persistent notifications.""" + await async_setup_component(hass, "persistent_notification", {}) + + +@pytest.fixture +def mock_config_entry() -> MockConfigEntry: + """Return the default mocked config entry.""" + return MockConfigEntry( + domain=DOMAIN, + data={CONF_HOST: "192.168.1.123", CONF_MAC: "aabbccddeeff"}, + ) + + +@pytest.fixture +def mock_setup_entry() -> Generator[None, None, None]: + """Mock setting up a config entry.""" + with patch("homeassistant.components.wled.async_setup_entry", return_value=True): + yield + + +@pytest.fixture +def mock_wled_config_flow( + request: pytest.FixtureRequest, +) -> Generator[None, MagicMock, None]: + """Return a mocked WLED client.""" + with patch( + "homeassistant.components.wled.config_flow.WLED", autospec=True + ) as wled_mock: + wled = wled_mock.return_value + wled.update.return_value = WLEDDevice(json.loads(load_fixture("wled/rgb.json"))) + yield wled + + +@pytest.fixture +def mock_wled(request: pytest.FixtureRequest) -> Generator[None, MagicMock, None]: + """Return a mocked WLED client.""" + fixture: str = "wled/rgb.json" + if hasattr(request, "param") and request.param: + fixture = request.param + + device = WLEDDevice(json.loads(load_fixture(fixture))) + with patch( + "homeassistant.components.wled.coordinator.WLED", autospec=True + ) as wled_mock: + wled = wled_mock.return_value + wled.update.return_value = device + yield wled + + +@pytest.fixture +async def init_integration( + hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_wled: MagicMock +) -> MockConfigEntry: + """Set up the WLED 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/wled/test_config_flow.py b/tests/components/wled/test_config_flow.py index 358902a8821..ea0167ed6d5 100644 --- a/tests/components/wled/test_config_flow.py +++ b/tests/components/wled/test_config_flow.py @@ -1,12 +1,11 @@ """Tests for the WLED config flow.""" -from unittest.mock import MagicMock, patch +from unittest.mock import MagicMock -import aiohttp from wled import WLEDConnectionError from homeassistant.components.wled.const import DOMAIN from homeassistant.config_entries import SOURCE_USER, SOURCE_ZEROCONF -from homeassistant.const import CONF_HOST, CONF_MAC, CONF_NAME, CONTENT_TYPE_JSON +from homeassistant.const import CONF_HOST, CONF_MAC, CONF_NAME from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import ( RESULT_TYPE_ABORT, @@ -14,22 +13,13 @@ from homeassistant.data_entry_flow import ( 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_wled_config_flow: MagicMock, mock_setup_entry: None ) -> None: """Test the full manual user flow from start to finish.""" - aioclient_mock.get( - "http://192.168.1.123:80/json/", - text=load_fixture("wled/rgb.json"), - headers={"Content-Type": CONTENT_TYPE_JSON}, - ) - result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER}, @@ -51,15 +41,9 @@ async def test_full_user_flow_implementation( async def test_full_zeroconf_flow_implementation( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, mock_wled_config_flow: MagicMock, mock_setup_entry: None ) -> None: """Test the full manual user flow from start to finish.""" - aioclient_mock.get( - "http://192.168.1.123:80/json/", - text=load_fixture("wled/rgb.json"), - headers={"Content-Type": CONTENT_TYPE_JSON}, - ) - result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_ZEROCONF}, @@ -91,16 +75,11 @@ async def test_full_zeroconf_flow_implementation( assert result2["data"][CONF_MAC] == "aabbccddeeff" -@patch( - "homeassistant.components.wled.coordinator.WLED.update", - side_effect=WLEDConnectionError, -) async def test_connection_error( - update_mock: MagicMock, hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, mock_wled_config_flow: MagicMock ) -> None: """Test we show user form on WLED connection error.""" - aioclient_mock.get("http://example.com/json/", exc=aiohttp.ClientError) - + mock_wled_config_flow.update.side_effect = WLEDConnectionError result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER}, @@ -112,15 +91,11 @@ async def test_connection_error( assert result.get("errors") == {"base": "cannot_connect"} -@patch( - "homeassistant.components.wled.coordinator.WLED.update", - side_effect=WLEDConnectionError, -) async def test_zeroconf_connection_error( - update_mock: MagicMock, hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, mock_wled_config_flow: MagicMock ) -> None: """Test we abort zeroconf flow on WLED connection error.""" - aioclient_mock.get("http://192.168.1.123/json/", exc=aiohttp.ClientError) + mock_wled_config_flow.update.side_effect = WLEDConnectionError result = await hass.config_entries.flow.async_init( DOMAIN, @@ -132,15 +107,11 @@ async def test_zeroconf_connection_error( assert result.get("reason") == "cannot_connect" -@patch( - "homeassistant.components.wled.coordinator.WLED.update", - side_effect=WLEDConnectionError, -) async def test_zeroconf_confirm_connection_error( - update_mock: MagicMock, hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, mock_wled_config_flow: MagicMock ) -> None: """Test we abort zeroconf flow on WLED connection error.""" - aioclient_mock.get("http://192.168.1.123:80/json/", exc=aiohttp.ClientError) + mock_wled_config_flow.update.side_effect = WLEDConnectionError result = await hass.config_entries.flow.async_init( DOMAIN, @@ -157,11 +128,11 @@ async def test_zeroconf_confirm_connection_error( async def test_user_device_exists_abort( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + init_integration: MagicMock, + mock_wled_config_flow: MagicMock, ) -> None: """Test we abort zeroconf flow if WLED device already configured.""" - await init_integration(hass, aioclient_mock) - result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER}, @@ -173,11 +144,11 @@ async def test_user_device_exists_abort( async def test_zeroconf_device_exists_abort( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + init_integration: MagicMock, + mock_wled_config_flow: MagicMock, ) -> None: """Test we abort zeroconf flow if WLED device already configured.""" - await init_integration(hass, aioclient_mock) - result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_ZEROCONF}, @@ -189,11 +160,11 @@ async def test_zeroconf_device_exists_abort( async def test_zeroconf_with_mac_device_exists_abort( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + init_integration: MockConfigEntry, + mock_wled_config_flow: MagicMock, ) -> None: """Test we abort zeroconf flow if WLED device already configured.""" - await init_integration(hass, aioclient_mock) - result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_ZEROCONF}, diff --git a/tests/components/wled/test_init.py b/tests/components/wled/test_init.py index 52b014760e5..50ee5520e5d 100644 --- a/tests/components/wled/test_init.py +++ b/tests/components/wled/test_init.py @@ -1,5 +1,5 @@ """Tests for the WLED integration.""" -from unittest.mock import MagicMock, patch +from unittest.mock import AsyncMock, MagicMock, patch from wled import WLEDConnectionError @@ -7,37 +7,44 @@ from homeassistant.components.wled.const import DOMAIN from homeassistant.config_entries import ConfigEntryState from homeassistant.core import HomeAssistant -from tests.components.wled import init_integration -from tests.test_util.aiohttp import AiohttpClientMocker +from tests.common import MockConfigEntry -@patch( - "homeassistant.components.wled.coordinator.WLED.update", - side_effect=WLEDConnectionError, -) -async def test_config_entry_not_ready( - mock_update: MagicMock, hass: HomeAssistant, aioclient_mock: AiohttpClientMocker -) -> None: - """Test the WLED configuration entry not ready.""" - 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 +async def test_load_unload_config_entry( + hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_wled: AsyncMock ) -> None: """Test the WLED 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 mock_config_entry.state is ConfigEntryState.LOADED + + await hass.config_entries.async_unload(mock_config_entry.entry_id) + await hass.async_block_till_done() + assert not hass.data.get(DOMAIN) -async def test_setting_unique_id(hass, aioclient_mock): - """Test we set unique ID if not set yet.""" - entry = await init_integration(hass, aioclient_mock) +@patch( + "homeassistant.components.wled.coordinator.WLED.request", + side_effect=WLEDConnectionError, +) +async def test_config_entry_not_ready( + mock_request: MagicMock, hass: HomeAssistant, mock_config_entry: MockConfigEntry +) -> None: + """Test the WLED configuration entry not ready.""" + 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_request.call_count == 1 + assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY + + +async def test_setting_unique_id( + hass: HomeAssistant, init_integration: MockConfigEntry +) -> None: + """Test we set unique ID if not set yet.""" assert hass.data[DOMAIN] - assert entry.unique_id == "aabbccddeeff" + assert init_integration.unique_id == "aabbccddeeff" diff --git a/tests/components/wled/test_light.py b/tests/components/wled/test_light.py index 721c0cc3880..666006b07b1 100644 --- a/tests/components/wled/test_light.py +++ b/tests/components/wled/test_light.py @@ -1,8 +1,9 @@ """Tests for the WLED light platform.""" import json -from unittest.mock import patch +from unittest.mock import MagicMock -from wled import Device as WLEDDevice, WLEDConnectionError +import pytest +from wled import Device as WLEDDevice, WLEDConnectionError, WLEDError from homeassistant.components.light import ( ATTR_BRIGHTNESS, @@ -38,17 +39,13 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er import homeassistant.util.dt as dt_util -from tests.common import async_fire_time_changed, load_fixture -from tests.components.wled import init_integration -from tests.test_util.aiohttp import AiohttpClientMocker +from tests.common import MockConfigEntry, async_fire_time_changed, load_fixture async def test_rgb_light_state( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, init_integration: MockConfigEntry ) -> None: """Test the creation and values of the WLED lights.""" - await init_integration(hass, aioclient_mock) - entity_registry = er.async_get(hass) # First segment of the strip @@ -101,143 +98,142 @@ async def test_rgb_light_state( async def test_segment_change_state( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, caplog + hass: HomeAssistant, + init_integration: MockConfigEntry, + mock_wled: MagicMock, ) -> None: """Test the change of state of the WLED segments.""" - await init_integration(hass, aioclient_mock) + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", ATTR_TRANSITION: 5}, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.segment.call_count == 1 + mock_wled.segment.assert_called_with( + on=False, + segment_id=0, + transition=50, + ) - with patch("wled.WLED.segment") as light_mock: - await hass.services.async_call( - LIGHT_DOMAIN, - SERVICE_TURN_OFF, - {ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", ATTR_TRANSITION: 5}, - blocking=True, - ) - await hass.async_block_till_done() - light_mock.assert_called_once_with( - on=False, - segment_id=0, - transition=50, - ) - - with patch("wled.WLED.segment") as light_mock: - await hass.services.async_call( - LIGHT_DOMAIN, - SERVICE_TURN_ON, - { - ATTR_BRIGHTNESS: 42, - ATTR_EFFECT: "Chase", - ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", - ATTR_RGB_COLOR: [255, 0, 0], - ATTR_TRANSITION: 5, - }, - blocking=True, - ) - await hass.async_block_till_done() - light_mock.assert_called_once_with( - brightness=42, - color_primary=(255, 0, 0), - effect="Chase", - on=True, - segment_id=0, - transition=50, - ) + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_ON, + { + ATTR_BRIGHTNESS: 42, + ATTR_EFFECT: "Chase", + ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", + ATTR_RGB_COLOR: [255, 0, 0], + ATTR_TRANSITION: 5, + }, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.segment.call_count == 2 + mock_wled.segment.assert_called_with( + brightness=42, + color_primary=(255, 0, 0), + effect="Chase", + on=True, + segment_id=0, + transition=50, + ) async def test_master_change_state( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, caplog + hass: HomeAssistant, + init_integration: MockConfigEntry, + mock_wled: MagicMock, ) -> None: """Test the change of state of the WLED master light control.""" - await init_integration(hass, aioclient_mock) + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: "light.wled_rgb_light_master", ATTR_TRANSITION: 5}, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.master.call_count == 1 + mock_wled.master.assert_called_with( + on=False, + transition=50, + ) - with patch("wled.WLED.master") as light_mock: - await hass.services.async_call( - LIGHT_DOMAIN, - SERVICE_TURN_OFF, - {ATTR_ENTITY_ID: "light.wled_rgb_light_master", ATTR_TRANSITION: 5}, - blocking=True, - ) - await hass.async_block_till_done() - light_mock.assert_called_once_with( - on=False, - transition=50, - ) + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_ON, + { + ATTR_BRIGHTNESS: 42, + ATTR_ENTITY_ID: "light.wled_rgb_light_master", + ATTR_TRANSITION: 5, + }, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.master.call_count == 2 + mock_wled.master.assert_called_with( + brightness=42, + on=True, + transition=50, + ) - with patch("wled.WLED.master") as light_mock: - await hass.services.async_call( - LIGHT_DOMAIN, - SERVICE_TURN_ON, - { - ATTR_BRIGHTNESS: 42, - ATTR_ENTITY_ID: "light.wled_rgb_light_master", - ATTR_TRANSITION: 5, - }, - blocking=True, - ) - await hass.async_block_till_done() - light_mock.assert_called_once_with( - brightness=42, - on=True, - transition=50, - ) + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: "light.wled_rgb_light_master", ATTR_TRANSITION: 5}, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.master.call_count == 3 + mock_wled.master.assert_called_with( + on=False, + transition=50, + ) - with patch("wled.WLED.master") as light_mock: - await hass.services.async_call( - LIGHT_DOMAIN, - SERVICE_TURN_OFF, - {ATTR_ENTITY_ID: "light.wled_rgb_light_master", ATTR_TRANSITION: 5}, - blocking=True, - ) - await hass.async_block_till_done() - light_mock.assert_called_once_with( - on=False, - transition=50, - ) - - with patch("wled.WLED.master") as light_mock: - await hass.services.async_call( - LIGHT_DOMAIN, - SERVICE_TURN_ON, - { - ATTR_BRIGHTNESS: 42, - ATTR_ENTITY_ID: "light.wled_rgb_light_master", - ATTR_TRANSITION: 5, - }, - blocking=True, - ) - await hass.async_block_till_done() - light_mock.assert_called_once_with( - brightness=42, - on=True, - transition=50, - ) + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_ON, + { + ATTR_BRIGHTNESS: 42, + ATTR_ENTITY_ID: "light.wled_rgb_light_master", + ATTR_TRANSITION: 5, + }, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.master.call_count == 4 + mock_wled.master.assert_called_with( + brightness=42, + on=True, + transition=50, + ) async def test_dynamically_handle_segments( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + init_integration: MockConfigEntry, + mock_wled: MagicMock, ) -> None: """Test if a new/deleted segment is dynamically added/removed.""" - await init_integration(hass, aioclient_mock) - assert hass.states.get("light.wled_rgb_light_master") assert hass.states.get("light.wled_rgb_light_segment_0") assert hass.states.get("light.wled_rgb_light_segment_1") - data = json.loads(load_fixture("wled/rgb_single_segment.json")) - device = WLEDDevice(data) + return_value = mock_wled.update.return_value + mock_wled.update.return_value = WLEDDevice( + json.loads(load_fixture("wled/rgb_single_segment.json")) + ) - # Test removal if segment went missing, including the master entity - with patch( - "homeassistant.components.wled.coordinator.WLED.update", - return_value=device, - ): - async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL) - await hass.async_block_till_done() - assert hass.states.get("light.wled_rgb_light_segment_0") - assert not hass.states.get("light.wled_rgb_light_segment_1") - assert not hass.states.get("light.wled_rgb_light_master") + async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL) + await hass.async_block_till_done() + + assert hass.states.get("light.wled_rgb_light_segment_0") + assert not hass.states.get("light.wled_rgb_light_segment_1") + assert not hass.states.get("light.wled_rgb_light_master") # Test adding if segment shows up again, including the master entity + mock_wled.update.return_value = return_value async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL) await hass.async_block_till_done() @@ -246,345 +242,336 @@ async def test_dynamically_handle_segments( assert hass.states.get("light.wled_rgb_light_segment_1") +@pytest.mark.parametrize("mock_wled", ["wled/rgb_single_segment.json"], indirect=True) async def test_single_segment_behavior( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, caplog + hass: HomeAssistant, + init_integration: MockConfigEntry, + mock_wled: MagicMock, ) -> None: """Test the behavior of the integration with a single segment.""" - await init_integration(hass, aioclient_mock) + device = mock_wled.update.return_value - data = json.loads(load_fixture("wled/rgb_single_segment.json")) - device = WLEDDevice(data) - - # Test absent master - with patch( - "homeassistant.components.wled.coordinator.WLED.update", - return_value=device, - ): - async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL) - await hass.async_block_till_done() - - assert not hass.states.get("light.wled_rgb_light_master") - - state = hass.states.get("light.wled_rgb_light_segment_0") - assert state - assert state.state == STATE_ON + assert not hass.states.get("light.wled_rgb_light_master") + state = hass.states.get("light.wled_rgb_light") + assert state + assert state.state == STATE_ON # Test segment brightness takes master into account device.state.brightness = 100 device.state.segments[0].brightness = 255 - with patch( - "homeassistant.components.wled.coordinator.WLED.update", - return_value=device, - ): - async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL) - await hass.async_block_till_done() + async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL) + await hass.async_block_till_done() - state = hass.states.get("light.wled_rgb_light_segment_0") - assert state - assert state.attributes.get(ATTR_BRIGHTNESS) == 100 + state = hass.states.get("light.wled_rgb_light") + assert state + assert state.attributes.get(ATTR_BRIGHTNESS) == 100 # Test segment is off when master is off device.state.on = False - with patch( - "homeassistant.components.wled.coordinator.WLED.update", - return_value=device, - ): - async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL) - await hass.async_block_till_done() - state = hass.states.get("light.wled_rgb_light_segment_0") - assert state - assert state.state == STATE_OFF + async_fire_time_changed(hass, dt_util.utcnow() + SCAN_INTERVAL) + await hass.async_block_till_done() + state = hass.states.get("light.wled_rgb_light") + assert state + assert state.state == STATE_OFF # Test master is turned off when turning off a single segment - with patch("wled.WLED.master") as master_mock: - await hass.services.async_call( - LIGHT_DOMAIN, - SERVICE_TURN_OFF, - {ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", ATTR_TRANSITION: 5}, - blocking=True, - ) - await hass.async_block_till_done() - master_mock.assert_called_once_with( - on=False, - transition=50, - ) + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: "light.wled_rgb_light", ATTR_TRANSITION: 5}, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.master.call_count == 1 + mock_wled.master.assert_called_with( + on=False, + transition=50, + ) # Test master is turned on when turning on a single segment, and segment # brightness is set to 255. - with patch("wled.WLED.master") as master_mock, patch( - "wled.WLED.segment" - ) as segment_mock: - await hass.services.async_call( - LIGHT_DOMAIN, - SERVICE_TURN_ON, - { - ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", - ATTR_TRANSITION: 5, - ATTR_BRIGHTNESS: 42, - }, - blocking=True, - ) - await hass.async_block_till_done() - master_mock.assert_called_once_with(on=True, transition=50, brightness=42) - segment_mock.assert_called_once_with(on=True, segment_id=0, brightness=255) + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_ON, + { + ATTR_ENTITY_ID: "light.wled_rgb_light", + ATTR_TRANSITION: 5, + ATTR_BRIGHTNESS: 42, + }, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.segment.call_count == 1 + assert mock_wled.master.call_count == 2 + mock_wled.segment.assert_called_with(on=True, segment_id=0, brightness=255) + mock_wled.master.assert_called_with(on=True, transition=50, brightness=42) async def test_light_error( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, caplog + hass: HomeAssistant, + init_integration: MockConfigEntry, + mock_wled: MagicMock, + caplog: pytest.LogCaptureFixture, ) -> None: """Test error handling of the WLED lights.""" - aioclient_mock.post("http://192.168.1.123:80/json/state", text="", status=400) - await init_integration(hass, aioclient_mock) + mock_wled.segment.side_effect = WLEDError - with patch("homeassistant.components.wled.coordinator.WLED.update"): - await hass.services.async_call( - LIGHT_DOMAIN, - SERVICE_TURN_OFF, - {ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0"}, - blocking=True, - ) - await hass.async_block_till_done() + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0"}, + blocking=True, + ) + await hass.async_block_till_done() - state = hass.states.get("light.wled_rgb_light_segment_0") - assert state.state == STATE_ON - assert "Invalid response from API" in caplog.text + state = hass.states.get("light.wled_rgb_light_segment_0") + assert state + assert state.state == STATE_ON + assert "Invalid response from API" in caplog.text + assert mock_wled.segment.call_count == 1 + mock_wled.segment.assert_called_with(on=False, segment_id=0) async def test_light_connection_error( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + init_integration: MockConfigEntry, + mock_wled: MagicMock, + caplog: pytest.LogCaptureFixture, ) -> None: """Test error handling of the WLED switches.""" - await init_integration(hass, aioclient_mock) + mock_wled.segment.side_effect = WLEDConnectionError - with patch("homeassistant.components.wled.coordinator.WLED.update"), patch( - "homeassistant.components.wled.coordinator.WLED.segment", - side_effect=WLEDConnectionError, - ): - await hass.services.async_call( - LIGHT_DOMAIN, - SERVICE_TURN_OFF, - {ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0"}, - blocking=True, - ) - await hass.async_block_till_done() + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0"}, + blocking=True, + ) + await hass.async_block_till_done() - state = hass.states.get("light.wled_rgb_light_segment_0") - assert state.state == STATE_UNAVAILABLE + state = hass.states.get("light.wled_rgb_light_segment_0") + assert state + assert state.state == STATE_UNAVAILABLE + assert "Error communicating with API" in caplog.text + assert mock_wled.segment.call_count == 1 + mock_wled.segment.assert_called_with(on=False, segment_id=0) +@pytest.mark.parametrize("mock_wled", ["wled/rgbw.json"], indirect=True) async def test_rgbw_light( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, init_integration: MockConfigEntry, mock_wled: MagicMock ) -> None: """Test RGBW support for WLED.""" - await init_integration(hass, aioclient_mock, rgbw=True) - state = hass.states.get("light.wled_rgbw_light") + assert state assert state.state == STATE_ON assert state.attributes.get(ATTR_RGBW_COLOR) == (255, 0, 0, 139) - with patch("wled.WLED.segment") as light_mock: - await hass.services.async_call( - LIGHT_DOMAIN, - SERVICE_TURN_ON, - { - ATTR_ENTITY_ID: "light.wled_rgbw_light", - ATTR_RGBW_COLOR: (255, 255, 255, 255), - }, - blocking=True, - ) - await hass.async_block_till_done() - light_mock.assert_called_once_with( - color_primary=(255, 255, 255, 255), - on=True, - segment_id=0, - ) + await hass.services.async_call( + LIGHT_DOMAIN, + SERVICE_TURN_ON, + { + ATTR_ENTITY_ID: "light.wled_rgbw_light", + ATTR_RGBW_COLOR: (255, 255, 255, 255), + }, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.segment.call_count == 1 + mock_wled.segment.assert_called_with( + color_primary=(255, 255, 255, 255), + on=True, + segment_id=0, + ) async def test_effect_service( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, init_integration: MockConfigEntry, mock_wled: MagicMock ) -> None: """Test the effect service of a WLED light.""" - await init_integration(hass, aioclient_mock) + await hass.services.async_call( + DOMAIN, + SERVICE_EFFECT, + { + ATTR_EFFECT: "Rainbow", + ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", + ATTR_INTENSITY: 200, + ATTR_PALETTE: "Tiamat", + ATTR_REVERSE: True, + ATTR_SPEED: 100, + }, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.segment.call_count == 1 + mock_wled.segment.assert_called_with( + effect="Rainbow", + intensity=200, + palette="Tiamat", + reverse=True, + segment_id=0, + speed=100, + ) - with patch("wled.WLED.segment") as light_mock: - await hass.services.async_call( - DOMAIN, - SERVICE_EFFECT, - { - ATTR_EFFECT: "Rainbow", - ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", - ATTR_INTENSITY: 200, - ATTR_PALETTE: "Tiamat", - ATTR_REVERSE: True, - ATTR_SPEED: 100, - }, - blocking=True, - ) - await hass.async_block_till_done() - light_mock.assert_called_once_with( - effect="Rainbow", - intensity=200, - palette="Tiamat", - reverse=True, - segment_id=0, - speed=100, - ) + await hass.services.async_call( + DOMAIN, + SERVICE_EFFECT, + {ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", ATTR_EFFECT: 9}, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.segment.call_count == 2 + mock_wled.segment.assert_called_with( + segment_id=0, + effect=9, + ) - with patch("wled.WLED.segment") as light_mock: - await hass.services.async_call( - DOMAIN, - SERVICE_EFFECT, - {ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", ATTR_EFFECT: 9}, - blocking=True, - ) - await hass.async_block_till_done() - light_mock.assert_called_once_with( - segment_id=0, - effect=9, - ) + await hass.services.async_call( + DOMAIN, + SERVICE_EFFECT, + { + ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", + ATTR_INTENSITY: 200, + ATTR_REVERSE: True, + ATTR_SPEED: 100, + }, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.segment.call_count == 3 + mock_wled.segment.assert_called_with( + intensity=200, + reverse=True, + segment_id=0, + speed=100, + ) - with patch("wled.WLED.segment") as light_mock: - await hass.services.async_call( - DOMAIN, - SERVICE_EFFECT, - { - ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", - ATTR_INTENSITY: 200, - ATTR_REVERSE: True, - ATTR_SPEED: 100, - }, - blocking=True, - ) - await hass.async_block_till_done() - light_mock.assert_called_once_with( - intensity=200, - reverse=True, - segment_id=0, - speed=100, - ) + await hass.services.async_call( + DOMAIN, + SERVICE_EFFECT, + { + ATTR_EFFECT: "Rainbow", + ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", + ATTR_PALETTE: "Tiamat", + ATTR_REVERSE: True, + ATTR_SPEED: 100, + }, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.segment.call_count == 4 + mock_wled.segment.assert_called_with( + effect="Rainbow", + palette="Tiamat", + reverse=True, + segment_id=0, + speed=100, + ) - with patch("wled.WLED.segment") as light_mock: - await hass.services.async_call( - DOMAIN, - SERVICE_EFFECT, - { - ATTR_EFFECT: "Rainbow", - ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", - ATTR_PALETTE: "Tiamat", - ATTR_REVERSE: True, - ATTR_SPEED: 100, - }, - blocking=True, - ) - await hass.async_block_till_done() - light_mock.assert_called_once_with( - effect="Rainbow", - palette="Tiamat", - reverse=True, - segment_id=0, - speed=100, - ) + await hass.services.async_call( + DOMAIN, + SERVICE_EFFECT, + { + ATTR_EFFECT: "Rainbow", + ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", + ATTR_INTENSITY: 200, + ATTR_SPEED: 100, + }, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.segment.call_count == 5 + mock_wled.segment.assert_called_with( + effect="Rainbow", + intensity=200, + segment_id=0, + speed=100, + ) - with patch("wled.WLED.segment") as light_mock: - await hass.services.async_call( - DOMAIN, - SERVICE_EFFECT, - { - ATTR_EFFECT: "Rainbow", - ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", - ATTR_INTENSITY: 200, - ATTR_SPEED: 100, - }, - blocking=True, - ) - await hass.async_block_till_done() - light_mock.assert_called_once_with( - effect="Rainbow", - intensity=200, - segment_id=0, - speed=100, - ) - - with patch("wled.WLED.segment") as light_mock: - await hass.services.async_call( - DOMAIN, - SERVICE_EFFECT, - { - ATTR_EFFECT: "Rainbow", - ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", - ATTR_INTENSITY: 200, - ATTR_REVERSE: True, - }, - blocking=True, - ) - await hass.async_block_till_done() - light_mock.assert_called_once_with( - effect="Rainbow", - intensity=200, - reverse=True, - segment_id=0, - ) + await hass.services.async_call( + DOMAIN, + SERVICE_EFFECT, + { + ATTR_EFFECT: "Rainbow", + ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", + ATTR_INTENSITY: 200, + ATTR_REVERSE: True, + }, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.segment.call_count == 6 + mock_wled.segment.assert_called_with( + effect="Rainbow", + intensity=200, + reverse=True, + segment_id=0, + ) async def test_effect_service_error( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, caplog + hass: HomeAssistant, + init_integration: MockConfigEntry, + mock_wled: MagicMock, + caplog: pytest.LogCaptureFixture, ) -> None: """Test error handling of the WLED effect service.""" - aioclient_mock.post("http://192.168.1.123:80/json/state", text="", status=400) - await init_integration(hass, aioclient_mock) + mock_wled.segment.side_effect = WLEDError - with patch("homeassistant.components.wled.coordinator.WLED.update"): - await hass.services.async_call( - DOMAIN, - SERVICE_EFFECT, - {ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", ATTR_EFFECT: 9}, - blocking=True, - ) - await hass.async_block_till_done() + await hass.services.async_call( + DOMAIN, + SERVICE_EFFECT, + {ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", ATTR_EFFECT: 9}, + blocking=True, + ) + await hass.async_block_till_done() - state = hass.states.get("light.wled_rgb_light_segment_0") - assert state.state == STATE_ON - assert "Invalid response from API" in caplog.text + state = hass.states.get("light.wled_rgb_light_segment_0") + assert state + assert state.state == STATE_ON + assert "Invalid response from API" in caplog.text + assert mock_wled.segment.call_count == 1 + mock_wled.segment.assert_called_with(effect=9, segment_id=0) async def test_preset_service( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, init_integration: MockConfigEntry, mock_wled: MagicMock ) -> None: """Test the preset service of a WLED light.""" - await init_integration(hass, aioclient_mock) - - with patch("wled.WLED.preset") as light_mock: - await hass.services.async_call( - DOMAIN, - SERVICE_PRESET, - { - ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", - ATTR_PRESET: 1, - }, - blocking=True, - ) - await hass.async_block_till_done() - light_mock.assert_called_once_with( - preset=1, - ) + await hass.services.async_call( + DOMAIN, + SERVICE_PRESET, + { + ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", + ATTR_PRESET: 1, + }, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.preset.call_count == 1 + mock_wled.preset.assert_called_with(preset=1) async def test_preset_service_error( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, caplog + hass: HomeAssistant, + init_integration: MockConfigEntry, + mock_wled: MagicMock, + caplog: pytest.LogCaptureFixture, ) -> None: """Test error handling of the WLED preset service.""" - aioclient_mock.post("http://192.168.1.123:80/json/state", text="", status=400) - await init_integration(hass, aioclient_mock) + mock_wled.preset.side_effect = WLEDError - with patch("homeassistant.components.wled.coordinator.WLED.update"): - await hass.services.async_call( - DOMAIN, - SERVICE_PRESET, - {ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", ATTR_PRESET: 1}, - blocking=True, - ) - await hass.async_block_till_done() + await hass.services.async_call( + DOMAIN, + SERVICE_PRESET, + {ATTR_ENTITY_ID: "light.wled_rgb_light_segment_0", ATTR_PRESET: 1}, + blocking=True, + ) + await hass.async_block_till_done() - state = hass.states.get("light.wled_rgb_light_segment_0") - assert state.state == STATE_ON - assert "Invalid response from API" in caplog.text + state = hass.states.get("light.wled_rgb_light_segment_0") + assert state + assert state.state == STATE_ON + assert "Invalid response from API" in caplog.text + assert mock_wled.preset.call_count == 1 + mock_wled.preset.assert_called_with(preset=1) diff --git a/tests/components/wled/test_sensor.py b/tests/components/wled/test_sensor.py index fcd36dd70a9..635cf47c687 100644 --- a/tests/components/wled/test_sensor.py +++ b/tests/components/wled/test_sensor.py @@ -1,6 +1,6 @@ """Tests for the WLED sensor platform.""" from datetime import datetime -from unittest.mock import patch +from unittest.mock import MagicMock, patch import pytest @@ -28,16 +28,15 @@ from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er from homeassistant.util import dt as dt_util -from tests.components.wled import init_integration -from tests.test_util.aiohttp import AiohttpClientMocker +from tests.common import MockConfigEntry async def test_sensors( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_wled: MagicMock, ) -> None: """Test the creation and values of the WLED sensors.""" - - entry = await init_integration(hass, aioclient_mock, skip_setup=True) registry = er.async_get(hass) # Pre-create registry entries for disabled by default sensors @@ -90,9 +89,10 @@ async def test_sensors( ) # Setup + mock_config_entry.add_to_hass(hass) test_time = datetime(2019, 11, 11, 9, 10, 32, tzinfo=dt_util.UTC) with patch("homeassistant.components.wled.sensor.utcnow", return_value=test_time): - await hass.config_entries.async_setup(entry.entry_id) + await hass.config_entries.async_setup(mock_config_entry.entry_id) await hass.async_block_till_done() state = hass.states.get("sensor.wled_rgb_light_estimated_current") @@ -184,10 +184,9 @@ async def test_sensors( ), ) async def test_disabled_by_default_sensors( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, entity_id: str + hass: HomeAssistant, init_integration: MockConfigEntry, entity_id: str ) -> None: """Test the disabled by default WLED sensors.""" - await init_integration(hass, aioclient_mock) registry = er.async_get(hass) state = hass.states.get(entity_id) diff --git a/tests/components/wled/test_switch.py b/tests/components/wled/test_switch.py index 7a396092ff9..eb8b8b526e0 100644 --- a/tests/components/wled/test_switch.py +++ b/tests/components/wled/test_switch.py @@ -1,7 +1,8 @@ """Tests for the WLED switch platform.""" -from unittest.mock import patch +from unittest.mock import MagicMock -from wled import WLEDConnectionError +import pytest +from wled import WLEDConnectionError, WLEDError from homeassistant.components.switch import DOMAIN as SWITCH_DOMAIN from homeassistant.components.wled.const import ( @@ -22,16 +23,13 @@ from homeassistant.const import ( from homeassistant.core import HomeAssistant from homeassistant.helpers import entity_registry as er -from tests.components.wled import init_integration -from tests.test_util.aiohttp import AiohttpClientMocker +from tests.common import MockConfigEntry async def test_switch_state( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, init_integration: MockConfigEntry ) -> None: """Test the creation and values of the WLED switches.""" - await init_integration(hass, aioclient_mock) - entity_registry = er.async_get(hass) state = hass.states.get("switch.wled_rgb_light_nightlight") @@ -68,113 +66,115 @@ async def test_switch_state( async def test_switch_change_state( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, init_integration: MockConfigEntry, mock_wled: MagicMock ) -> None: """Test the change of state of the WLED switches.""" - await init_integration(hass, aioclient_mock) # Nightlight - with patch("wled.WLED.nightlight") as nightlight_mock: - await hass.services.async_call( - SWITCH_DOMAIN, - SERVICE_TURN_ON, - {ATTR_ENTITY_ID: "switch.wled_rgb_light_nightlight"}, - blocking=True, - ) - await hass.async_block_till_done() - nightlight_mock.assert_called_once_with(on=True) + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_ON, + {ATTR_ENTITY_ID: "switch.wled_rgb_light_nightlight"}, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.nightlight.call_count == 1 + mock_wled.nightlight.assert_called_with(on=True) - with patch("wled.WLED.nightlight") as nightlight_mock: - await hass.services.async_call( - SWITCH_DOMAIN, - SERVICE_TURN_OFF, - {ATTR_ENTITY_ID: "switch.wled_rgb_light_nightlight"}, - blocking=True, - ) - await hass.async_block_till_done() - nightlight_mock.assert_called_once_with(on=False) + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: "switch.wled_rgb_light_nightlight"}, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.nightlight.call_count == 2 + mock_wled.nightlight.assert_called_with(on=False) # Sync send - with patch("wled.WLED.sync") as sync_mock: - await hass.services.async_call( - SWITCH_DOMAIN, - SERVICE_TURN_ON, - {ATTR_ENTITY_ID: "switch.wled_rgb_light_sync_send"}, - blocking=True, - ) - await hass.async_block_till_done() - sync_mock.assert_called_once_with(send=True) + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_ON, + {ATTR_ENTITY_ID: "switch.wled_rgb_light_sync_send"}, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.sync.call_count == 1 + mock_wled.sync.assert_called_with(send=True) - with patch("wled.WLED.sync") as sync_mock: - await hass.services.async_call( - SWITCH_DOMAIN, - SERVICE_TURN_OFF, - {ATTR_ENTITY_ID: "switch.wled_rgb_light_sync_send"}, - blocking=True, - ) - await hass.async_block_till_done() - sync_mock.assert_called_once_with(send=False) + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: "switch.wled_rgb_light_sync_send"}, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.sync.call_count == 2 + mock_wled.sync.assert_called_with(send=False) # Sync receive - with patch("wled.WLED.sync") as sync_mock: - await hass.services.async_call( - SWITCH_DOMAIN, - SERVICE_TURN_OFF, - {ATTR_ENTITY_ID: "switch.wled_rgb_light_sync_receive"}, - blocking=True, - ) - await hass.async_block_till_done() - sync_mock.assert_called_once_with(receive=False) + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_OFF, + {ATTR_ENTITY_ID: "switch.wled_rgb_light_sync_receive"}, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.sync.call_count == 3 + mock_wled.sync.assert_called_with(receive=False) - with patch("wled.WLED.sync") as sync_mock: - await hass.services.async_call( - SWITCH_DOMAIN, - SERVICE_TURN_ON, - {ATTR_ENTITY_ID: "switch.wled_rgb_light_sync_receive"}, - blocking=True, - ) - await hass.async_block_till_done() - sync_mock.assert_called_once_with(receive=True) + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_ON, + {ATTR_ENTITY_ID: "switch.wled_rgb_light_sync_receive"}, + blocking=True, + ) + await hass.async_block_till_done() + assert mock_wled.sync.call_count == 4 + mock_wled.sync.assert_called_with(receive=True) async def test_switch_error( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker, caplog + hass: HomeAssistant, + init_integration: MockConfigEntry, + mock_wled: MagicMock, + caplog: pytest.LogCaptureFixture, ) -> None: """Test error handling of the WLED switches.""" - aioclient_mock.post("http://192.168.1.123:80/json/state", text="", status=400) - await init_integration(hass, aioclient_mock) + mock_wled.nightlight.side_effect = WLEDError - with patch("homeassistant.components.wled.coordinator.WLED.update"): - await hass.services.async_call( - SWITCH_DOMAIN, - SERVICE_TURN_ON, - {ATTR_ENTITY_ID: "switch.wled_rgb_light_nightlight"}, - blocking=True, - ) - await hass.async_block_till_done() + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_ON, + {ATTR_ENTITY_ID: "switch.wled_rgb_light_nightlight"}, + blocking=True, + ) + await hass.async_block_till_done() - state = hass.states.get("switch.wled_rgb_light_nightlight") - assert state.state == STATE_OFF - assert "Invalid response from API" in caplog.text + state = hass.states.get("switch.wled_rgb_light_nightlight") + assert state + assert state.state == STATE_OFF + assert "Invalid response from API" in caplog.text async def test_switch_connection_error( - hass: HomeAssistant, aioclient_mock: AiohttpClientMocker + hass: HomeAssistant, + init_integration: MockConfigEntry, + mock_wled: MagicMock, + caplog: pytest.LogCaptureFixture, ) -> None: """Test error handling of the WLED switches.""" - await init_integration(hass, aioclient_mock) + mock_wled.nightlight.side_effect = WLEDConnectionError - with patch("homeassistant.components.wled.coordinator.WLED.update"), patch( - "homeassistant.components.wled.coordinator.WLED.nightlight", - side_effect=WLEDConnectionError, - ): - await hass.services.async_call( - SWITCH_DOMAIN, - SERVICE_TURN_ON, - {ATTR_ENTITY_ID: "switch.wled_rgb_light_nightlight"}, - blocking=True, - ) - await hass.async_block_till_done() + await hass.services.async_call( + SWITCH_DOMAIN, + SERVICE_TURN_ON, + {ATTR_ENTITY_ID: "switch.wled_rgb_light_nightlight"}, + blocking=True, + ) + await hass.async_block_till_done() - state = hass.states.get("switch.wled_rgb_light_nightlight") - assert state.state == STATE_UNAVAILABLE + state = hass.states.get("switch.wled_rgb_light_nightlight") + assert state + assert state.state == STATE_UNAVAILABLE + assert "Error communicating with API" in caplog.text