"""Test Gardena Bluetooth sensor.""" from collections.abc import Awaitable, Callable from typing import Any from unittest.mock import Mock, call from gardena_bluetooth.const import Sensor, Valve from gardena_bluetooth.exceptions import ( CharacteristicNoAccess, GardenaBluetoothException, ) from gardena_bluetooth.parse import Characteristic import pytest from syrupy.assertion import SnapshotAssertion from homeassistant.components.number import ( ATTR_VALUE, DOMAIN as NUMBER_DOMAIN, SERVICE_SET_VALUE, ) from homeassistant.const import ATTR_ENTITY_ID, Platform from homeassistant.core import HomeAssistant from . import setup_entry from tests.common import MockConfigEntry @pytest.mark.parametrize( ("uuid", "raw", "entity_id"), [ ( Valve.manual_watering_time.uuid, [ Valve.manual_watering_time.encode(100), Valve.manual_watering_time.encode(10), ], "number.mock_title_manual_watering_time", ), ( Valve.remaining_open_time.uuid, [ Valve.remaining_open_time.encode(100), Valve.remaining_open_time.encode(10), CharacteristicNoAccess("Test for no access"), GardenaBluetoothException("Test for errors on bluetooth"), ], "number.mock_title_remaining_open_time", ), ( Valve.remaining_open_time.uuid, [Valve.remaining_open_time.encode(100)], "number.mock_title_open_for", ), ], ) async def test_setup( hass: HomeAssistant, snapshot: SnapshotAssertion, mock_entry: MockConfigEntry, mock_read_char_raw: dict[str, bytes], scan_step: Callable[[], Awaitable[None]], uuid: str, raw: list[bytes], entity_id: str, ) -> None: """Test setup creates expected entities.""" mock_read_char_raw[uuid] = raw[0] await setup_entry(hass, mock_entry, [Platform.NUMBER]) assert hass.states.get(entity_id) == snapshot for char_raw in raw[1:]: mock_read_char_raw[uuid] = char_raw await scan_step() assert hass.states.get(entity_id) == snapshot @pytest.mark.parametrize( ("char", "value", "expected", "entity_id"), [ ( Valve.manual_watering_time, 100, 100, "number.mock_title_manual_watering_time", ), ( Valve.remaining_open_time, 100, 100 * 60, "number.mock_title_open_for", ), ], ) async def test_config( hass: HomeAssistant, mock_entry: MockConfigEntry, mock_read_char_raw: dict[str, bytes], mock_client: Mock, char: Characteristic, value: Any, expected: Any, entity_id: str, ) -> None: """Test setup creates expected entities.""" mock_read_char_raw[char.uuid] = char.encode(value) await setup_entry(hass, mock_entry, [Platform.NUMBER]) assert hass.states.get(entity_id) await hass.services.async_call( NUMBER_DOMAIN, SERVICE_SET_VALUE, {ATTR_ENTITY_ID: entity_id, ATTR_VALUE: value}, blocking=True, ) assert mock_client.write_char.mock_calls == [ call(char, expected), ] async def test_bluetooth_error_unavailable( hass: HomeAssistant, snapshot: SnapshotAssertion, mock_entry: MockConfigEntry, mock_read_char_raw: dict[str, bytes], scan_step: Callable[[], Awaitable[None]], ) -> None: """Verify that a connectivity error makes all entities unavailable.""" mock_read_char_raw[ Valve.manual_watering_time.uuid ] = Valve.manual_watering_time.encode(0) mock_read_char_raw[ Valve.remaining_open_time.uuid ] = Valve.remaining_open_time.encode(0) await setup_entry(hass, mock_entry, [Platform.NUMBER]) assert hass.states.get("number.mock_title_remaining_open_time") == snapshot assert hass.states.get("number.mock_title_manual_watering_time") == snapshot mock_read_char_raw[Valve.manual_watering_time.uuid] = GardenaBluetoothException( "Test for errors on bluetooth" ) await scan_step() assert hass.states.get("number.mock_title_remaining_open_time") == snapshot assert hass.states.get("number.mock_title_manual_watering_time") == snapshot async def test_connected_state( hass: HomeAssistant, snapshot: SnapshotAssertion, mock_entry: MockConfigEntry, mock_read_char_raw: dict[str, bytes], scan_step: Callable[[], Awaitable[None]], ) -> None: """Verify that a connectivity error makes all entities unavailable.""" mock_read_char_raw[Sensor.connected_state.uuid] = Sensor.connected_state.encode( False ) mock_read_char_raw[Sensor.threshold.uuid] = Sensor.threshold.encode(45) await setup_entry(hass, mock_entry, [Platform.NUMBER]) assert hass.states.get("number.mock_title_sensor_threshold") == snapshot mock_read_char_raw[Sensor.connected_state.uuid] = Sensor.connected_state.encode( True ) await scan_step() assert hass.states.get("number.mock_title_sensor_threshold") == snapshot