Use non-autospec mock for Reolink's button tests (#146969)

This commit is contained in:
Abílio Costa 2025-06-16 20:14:02 +01:00 committed by GitHub
parent 589577a04c
commit 6f3ceb83c2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 116 additions and 105 deletions

View File

@ -62,21 +62,14 @@ def mock_setup_entry() -> Generator[AsyncMock]:
yield mock_setup_entry yield mock_setup_entry
@pytest.fixture(scope="module") def _init_host_mock(host_mock: MagicMock) -> None:
def reolink_connect_class() -> Generator[MagicMock]: host_mock.get_host_data = AsyncMock(return_value=None)
"""Mock reolink connection and return both the host_mock and host_mock_class.""" host_mock.get_states = AsyncMock(return_value=None)
with ( host_mock.check_new_firmware = AsyncMock(return_value=False)
patch( host_mock.unsubscribe = AsyncMock(return_value=True)
"homeassistant.components.reolink.host.Host", autospec=True host_mock.logout = AsyncMock(return_value=True)
) as host_mock_class, host_mock.reboot = AsyncMock()
): host_mock.set_ptz_command = AsyncMock()
host_mock = host_mock_class.return_value
host_mock.get_host_data.return_value = None
host_mock.get_states.return_value = None
host_mock.supported.return_value = True
host_mock.check_new_firmware.return_value = False
host_mock.unsubscribe.return_value = True
host_mock.logout.return_value = True
host_mock.is_nvr = True host_mock.is_nvr = True
host_mock.is_hub = False host_mock.is_hub = False
host_mock.mac_address = TEST_MAC host_mock.mac_address = TEST_MAC
@ -99,6 +92,7 @@ def reolink_connect_class() -> Generator[MagicMock]:
host_mock.sw_upload_progress.return_value = 100 host_mock.sw_upload_progress.return_value = 100
host_mock.manufacturer = "Reolink" host_mock.manufacturer = "Reolink"
host_mock.model = TEST_HOST_MODEL host_mock.model = TEST_HOST_MODEL
host_mock.supported.return_value = True
host_mock.item_number.return_value = TEST_ITEM_NUMBER host_mock.item_number.return_value = TEST_ITEM_NUMBER
host_mock.camera_model.return_value = TEST_CAM_MODEL host_mock.camera_model.return_value = TEST_CAM_MODEL
host_mock.camera_name.return_value = TEST_NVR_NAME host_mock.camera_name.return_value = TEST_NVR_NAME
@ -127,8 +121,6 @@ def reolink_connect_class() -> Generator[MagicMock]:
"{'host':'TEST_RESPONSE','channel':'TEST_RESPONSE'}" "{'host':'TEST_RESPONSE','channel':'TEST_RESPONSE'}"
) )
reolink_connect.chime_list = []
# enums # enums
host_mock.whiteled_mode.return_value = 1 host_mock.whiteled_mode.return_value = 1
host_mock.whiteled_mode_list.return_value = ["off", "auto"] host_mock.whiteled_mode_list.return_value = ["off", "auto"]
@ -142,11 +134,12 @@ def reolink_connect_class() -> Generator[MagicMock]:
host_mock.recording_packing_time = "60 Minutes" host_mock.recording_packing_time = "60 Minutes"
# Baichuan # Baichuan
host_mock.baichuan = create_autospec(Baichuan)
host_mock.baichuan_only = False host_mock.baichuan_only = False
# Disable tcp push by default for tests # Disable tcp push by default for tests
host_mock.baichuan.port = TEST_BC_PORT host_mock.baichuan.port = TEST_BC_PORT
host_mock.baichuan.events_active = False host_mock.baichuan.events_active = False
host_mock.baichuan.unsubscribe_events = AsyncMock()
host_mock.baichuan.check_subscribe_events = AsyncMock()
host_mock.baichuan.mac_address.return_value = TEST_MAC_CAM host_mock.baichuan.mac_address.return_value = TEST_MAC_CAM
host_mock.baichuan.privacy_mode.return_value = False host_mock.baichuan.privacy_mode.return_value = False
host_mock.baichuan.day_night_state.return_value = "day" host_mock.baichuan.day_night_state.return_value = "day"
@ -162,6 +155,18 @@ def reolink_connect_class() -> Generator[MagicMock]:
host_mock.baichuan.smart_ai_index.return_value = 1 host_mock.baichuan.smart_ai_index.return_value = 1
host_mock.baichuan.smart_ai_name.return_value = "zone1" host_mock.baichuan.smart_ai_name.return_value = "zone1"
@pytest.fixture(scope="module")
def reolink_connect_class() -> Generator[MagicMock]:
"""Mock reolink connection and return both the host_mock and host_mock_class."""
with (
patch(
"homeassistant.components.reolink.host.Host", autospec=True
) as host_mock_class,
):
host_mock = host_mock_class.return_value
host_mock.baichuan = create_autospec(Baichuan)
_init_host_mock(host_mock)
yield host_mock_class yield host_mock_class
@ -173,6 +178,18 @@ def reolink_connect(
return reolink_connect_class.return_value return reolink_connect_class.return_value
@pytest.fixture
def reolink_host() -> Generator[MagicMock]:
"""Mock reolink Host class."""
with patch(
"homeassistant.components.reolink.host.Host", autospec=False
) as host_mock_class:
host_mock = host_mock_class.return_value
host_mock.baichuan = MagicMock()
_init_host_mock(host_mock)
yield host_mock
@pytest.fixture @pytest.fixture
def reolink_platforms() -> Generator[None]: def reolink_platforms() -> Generator[None]:
"""Mock reolink entry setup.""" """Mock reolink entry setup."""

View File

@ -21,7 +21,7 @@ from tests.common import MockConfigEntry
async def test_button( async def test_button(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: MockConfigEntry, config_entry: MockConfigEntry,
reolink_connect: MagicMock, reolink_host: MagicMock,
) -> None: ) -> None:
"""Test button entity with ptz up.""" """Test button entity with ptz up."""
with patch("homeassistant.components.reolink.PLATFORMS", [Platform.BUTTON]): with patch("homeassistant.components.reolink.PLATFORMS", [Platform.BUTTON]):
@ -37,9 +37,9 @@ async def test_button(
{ATTR_ENTITY_ID: entity_id}, {ATTR_ENTITY_ID: entity_id},
blocking=True, blocking=True,
) )
reolink_connect.set_ptz_command.assert_called_once() reolink_host.set_ptz_command.assert_called_once()
reolink_connect.set_ptz_command.side_effect = ReolinkError("Test error") reolink_host.set_ptz_command.side_effect = ReolinkError("Test error")
with pytest.raises(HomeAssistantError): with pytest.raises(HomeAssistantError):
await hass.services.async_call( await hass.services.async_call(
BUTTON_DOMAIN, BUTTON_DOMAIN,
@ -48,13 +48,11 @@ async def test_button(
blocking=True, blocking=True,
) )
reolink_connect.set_ptz_command.reset_mock(side_effect=True)
async def test_ptz_move_service( async def test_ptz_move_service(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: MockConfigEntry, config_entry: MockConfigEntry,
reolink_connect: MagicMock, reolink_host: MagicMock,
) -> None: ) -> None:
"""Test ptz_move entity service using PTZ button entity.""" """Test ptz_move entity service using PTZ button entity."""
with patch("homeassistant.components.reolink.PLATFORMS", [Platform.BUTTON]): with patch("homeassistant.components.reolink.PLATFORMS", [Platform.BUTTON]):
@ -70,9 +68,9 @@ async def test_ptz_move_service(
{ATTR_ENTITY_ID: entity_id, ATTR_SPEED: 5}, {ATTR_ENTITY_ID: entity_id, ATTR_SPEED: 5},
blocking=True, blocking=True,
) )
reolink_connect.set_ptz_command.assert_called_with(0, command="Up", speed=5) reolink_host.set_ptz_command.assert_called_with(0, command="Up", speed=5)
reolink_connect.set_ptz_command.side_effect = ReolinkError("Test error") reolink_host.set_ptz_command.side_effect = ReolinkError("Test error")
with pytest.raises(HomeAssistantError): with pytest.raises(HomeAssistantError):
await hass.services.async_call( await hass.services.async_call(
DOMAIN, DOMAIN,
@ -81,14 +79,12 @@ async def test_ptz_move_service(
blocking=True, blocking=True,
) )
reolink_connect.set_ptz_command.reset_mock(side_effect=True)
@pytest.mark.usefixtures("entity_registry_enabled_by_default") @pytest.mark.usefixtures("entity_registry_enabled_by_default")
async def test_host_button( async def test_host_button(
hass: HomeAssistant, hass: HomeAssistant,
config_entry: MockConfigEntry, config_entry: MockConfigEntry,
reolink_connect: MagicMock, reolink_host: MagicMock,
) -> None: ) -> None:
"""Test host button entity with reboot.""" """Test host button entity with reboot."""
with patch("homeassistant.components.reolink.PLATFORMS", [Platform.BUTTON]): with patch("homeassistant.components.reolink.PLATFORMS", [Platform.BUTTON]):
@ -104,9 +100,9 @@ async def test_host_button(
{ATTR_ENTITY_ID: entity_id}, {ATTR_ENTITY_ID: entity_id},
blocking=True, blocking=True,
) )
reolink_connect.reboot.assert_called_once() reolink_host.reboot.assert_called_once()
reolink_connect.reboot.side_effect = ReolinkError("Test error") reolink_host.reboot.side_effect = ReolinkError("Test error")
with pytest.raises(HomeAssistantError): with pytest.raises(HomeAssistantError):
await hass.services.async_call( await hass.services.async_call(
BUTTON_DOMAIN, BUTTON_DOMAIN,
@ -114,5 +110,3 @@ async def test_host_button(
{ATTR_ENTITY_ID: entity_id}, {ATTR_ENTITY_ID: entity_id},
blocking=True, blocking=True,
) )
reolink_connect.reboot.reset_mock(side_effect=True)