From ab064a7f3623fffb19b1347b7b5a38b756d31f58 Mon Sep 17 00:00:00 2001 From: starkillerOG Date: Fri, 23 Aug 2024 12:34:58 +0200 Subject: [PATCH] Reolink add 100% coverage of number platform (#124465) * Add 100% number test coverage * review comments * fix styling * re-add AsyncMock for chime --- tests/components/reolink/test_config_flow.py | 2 +- tests/components/reolink/test_host.py | 4 +- tests/components/reolink/test_init.py | 10 +- tests/components/reolink/test_media_source.py | 2 +- tests/components/reolink/test_number.py | 111 ++++++++++++++++++ tests/components/reolink/test_select.py | 12 +- 6 files changed, 121 insertions(+), 20 deletions(-) create mode 100644 tests/components/reolink/test_number.py diff --git a/tests/components/reolink/test_config_flow.py b/tests/components/reolink/test_config_flow.py index 55dd0d4fea9..716e66b8d6c 100644 --- a/tests/components/reolink/test_config_flow.py +++ b/tests/components/reolink/test_config_flow.py @@ -471,7 +471,7 @@ async def test_dhcp_ip_update( if not last_update_success: # ensure the last_update_succes is False for the device_coordinator. - reolink_connect.get_states = AsyncMock(side_effect=ReolinkError("Test error")) + reolink_connect.get_states.side_effect = ReolinkError("Test error") freezer.tick(DEVICE_UPDATE_INTERVAL) async_fire_time_changed(hass) await hass.async_block_till_done() diff --git a/tests/components/reolink/test_host.py b/tests/components/reolink/test_host.py index 690bfd035f8..c4096a4582f 100644 --- a/tests/components/reolink/test_host.py +++ b/tests/components/reolink/test_host.py @@ -59,9 +59,7 @@ async def test_webhook_callback( # test webhook callback single channel with error in event callback signal_ch.reset_mock() - reolink_connect.ONVIF_event_callback = AsyncMock( - side_effect=Exception("Test error") - ) + reolink_connect.ONVIF_event_callback.side_effect = Exception("Test error") await client.post(f"/api/webhook/{webhook_id}", data="test_data") signal_ch.assert_not_called() diff --git a/tests/components/reolink/test_init.py b/tests/components/reolink/test_init.py index f5cd56a05d2..fd54f298966 100644 --- a/tests/components/reolink/test_init.py +++ b/tests/components/reolink/test_init.py @@ -108,9 +108,7 @@ async def test_firmware_error_twice( config_entry: MockConfigEntry, ) -> None: """Test when the firmware update fails 2 times.""" - reolink_connect.check_new_firmware = AsyncMock( - side_effect=ReolinkError("Test error") - ) + reolink_connect.check_new_firmware.side_effect = ReolinkError("Test error") with patch("homeassistant.components.reolink.PLATFORMS", [Platform.UPDATE]): assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() @@ -140,9 +138,7 @@ async def test_credential_error_three( await hass.async_block_till_done() assert config_entry.state is ConfigEntryState.LOADED - reolink_connect.get_states = AsyncMock( - side_effect=CredentialsInvalidError("Test error") - ) + reolink_connect.get_states.side_effect = CredentialsInvalidError("Test error") issue_id = f"config_entry_reauth_{const.DOMAIN}_{config_entry.entry_id}" for _ in range(NUM_CRED_ERRORS): @@ -549,7 +545,7 @@ async def test_port_repair_issue( issue_registry: ir.IssueRegistry, ) -> None: """Test repairs issue is raised when auto enable of ports fails.""" - reolink_connect.set_net_port = AsyncMock(side_effect=ReolinkError("Test error")) + reolink_connect.set_net_port.side_effect = ReolinkError("Test error") reolink_connect.onvif_enabled = False reolink_connect.rtsp_enabled = False reolink_connect.rtmp_enabled = False diff --git a/tests/components/reolink/test_media_source.py b/tests/components/reolink/test_media_source.py index b09c267fcfd..cbc9bf51705 100644 --- a/tests/components/reolink/test_media_source.py +++ b/tests/components/reolink/test_media_source.py @@ -318,7 +318,7 @@ async def test_browsing_not_loaded( assert await hass.config_entries.async_setup(config_entry.entry_id) await hass.async_block_till_done() - reolink_connect.get_host_data = AsyncMock(side_effect=ReolinkError("Test error")) + reolink_connect.get_host_data.side_effect = ReolinkError("Test error") config_entry2 = MockConfigEntry( domain=const.DOMAIN, unique_id=format_mac(TEST_MAC2), diff --git a/tests/components/reolink/test_number.py b/tests/components/reolink/test_number.py new file mode 100644 index 00000000000..e9abcec946c --- /dev/null +++ b/tests/components/reolink/test_number.py @@ -0,0 +1,111 @@ +"""Test the Reolink number platform.""" + +from unittest.mock import AsyncMock, MagicMock, patch + +import pytest +from reolink_aio.api import Chime +from reolink_aio.exceptions import InvalidParameterError, ReolinkError + +from homeassistant.components.number import ( + ATTR_VALUE, + DOMAIN as NUMBER_DOMAIN, + SERVICE_SET_VALUE, +) +from homeassistant.config_entries import ConfigEntryState +from homeassistant.const import ATTR_ENTITY_ID, Platform +from homeassistant.core import HomeAssistant +from homeassistant.exceptions import HomeAssistantError + +from .conftest import TEST_NVR_NAME + +from tests.common import MockConfigEntry + + +async def test_number( + hass: HomeAssistant, + config_entry: MockConfigEntry, + reolink_connect: MagicMock, +) -> None: + """Test number entity with volume.""" + reolink_connect.volume.return_value = 80 + + with patch("homeassistant.components.reolink.PLATFORMS", [Platform.NUMBER]): + assert await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + assert config_entry.state is ConfigEntryState.LOADED + + entity_id = f"{Platform.NUMBER}.{TEST_NVR_NAME}_volume" + + assert hass.states.get(entity_id).state == "80" + + await hass.services.async_call( + NUMBER_DOMAIN, + SERVICE_SET_VALUE, + {ATTR_ENTITY_ID: entity_id, ATTR_VALUE: 50}, + blocking=True, + ) + reolink_connect.set_volume.assert_called_with(0, volume=50) + + reolink_connect.set_volume.side_effect = ReolinkError("Test error") + with pytest.raises(HomeAssistantError): + await hass.services.async_call( + NUMBER_DOMAIN, + SERVICE_SET_VALUE, + {ATTR_ENTITY_ID: entity_id, ATTR_VALUE: 50}, + blocking=True, + ) + + reolink_connect.set_volume.side_effect = InvalidParameterError("Test error") + with pytest.raises(HomeAssistantError): + await hass.services.async_call( + NUMBER_DOMAIN, + SERVICE_SET_VALUE, + {ATTR_ENTITY_ID: entity_id, ATTR_VALUE: 50}, + blocking=True, + ) + + +async def test_chime_number( + hass: HomeAssistant, + config_entry: MockConfigEntry, + reolink_connect: MagicMock, + test_chime: Chime, +) -> None: + """Test number entity of a chime with chime volume.""" + test_chime.volume = 3 + + with patch("homeassistant.components.reolink.PLATFORMS", [Platform.NUMBER]): + assert await hass.config_entries.async_setup(config_entry.entry_id) + await hass.async_block_till_done() + assert config_entry.state is ConfigEntryState.LOADED + + entity_id = f"{Platform.NUMBER}.test_chime_volume" + + assert hass.states.get(entity_id).state == "3" + + test_chime.set_option = AsyncMock() + await hass.services.async_call( + NUMBER_DOMAIN, + SERVICE_SET_VALUE, + {ATTR_ENTITY_ID: entity_id, ATTR_VALUE: 2}, + blocking=True, + ) + test_chime.set_option.assert_called_with(volume=2) + + test_chime.set_option.side_effect = ReolinkError("Test error") + with pytest.raises(HomeAssistantError): + await hass.services.async_call( + NUMBER_DOMAIN, + SERVICE_SET_VALUE, + {ATTR_ENTITY_ID: entity_id, ATTR_VALUE: 1}, + blocking=True, + ) + + test_chime.set_option.side_effect = InvalidParameterError("Test error") + with pytest.raises(HomeAssistantError): + await hass.services.async_call( + NUMBER_DOMAIN, + SERVICE_SET_VALUE, + {ATTR_ENTITY_ID: entity_id, ATTR_VALUE: 1}, + blocking=True, + ) diff --git a/tests/components/reolink/test_select.py b/tests/components/reolink/test_select.py index 5536e85afb9..082a543e392 100644 --- a/tests/components/reolink/test_select.py +++ b/tests/components/reolink/test_select.py @@ -41,7 +41,6 @@ async def test_floodlight_mode_select( entity_id = f"{Platform.SELECT}.{TEST_NVR_NAME}_floodlight_mode" assert hass.states.get(entity_id).state == "auto" - reolink_connect.set_whiteled = AsyncMock() await hass.services.async_call( SELECT_DOMAIN, SERVICE_SELECT_OPTION, @@ -50,7 +49,7 @@ async def test_floodlight_mode_select( ) reolink_connect.set_whiteled.assert_called_once() - reolink_connect.set_whiteled = AsyncMock(side_effect=ReolinkError("Test error")) + reolink_connect.set_whiteled.side_effect = ReolinkError("Test error") with pytest.raises(HomeAssistantError): await hass.services.async_call( SELECT_DOMAIN, @@ -59,9 +58,7 @@ async def test_floodlight_mode_select( blocking=True, ) - reolink_connect.set_whiteled = AsyncMock( - side_effect=InvalidParameterError("Test error") - ) + reolink_connect.set_whiteled.side_effect = InvalidParameterError("Test error") with pytest.raises(ServiceValidationError): await hass.services.async_call( SELECT_DOMAIN, @@ -94,7 +91,6 @@ async def test_play_quick_reply_message( entity_id = f"{Platform.SELECT}.{TEST_NVR_NAME}_play_quick_reply_message" assert hass.states.get(entity_id).state == STATE_UNKNOWN - reolink_connect.play_quick_reply = AsyncMock() await hass.services.async_call( SELECT_DOMAIN, SERVICE_SELECT_OPTION, @@ -131,7 +127,7 @@ async def test_chime_select( ) test_chime.set_tone.assert_called_once() - test_chime.set_tone = AsyncMock(side_effect=ReolinkError("Test error")) + test_chime.set_tone.side_effect = ReolinkError("Test error") with pytest.raises(HomeAssistantError): await hass.services.async_call( SELECT_DOMAIN, @@ -140,7 +136,7 @@ async def test_chime_select( blocking=True, ) - test_chime.set_tone = AsyncMock(side_effect=InvalidParameterError("Test error")) + test_chime.set_tone.side_effect = InvalidParameterError("Test error") with pytest.raises(ServiceValidationError): await hass.services.async_call( SELECT_DOMAIN,