diff --git a/.coveragerc b/.coveragerc index 8c67762250e..6566b4caad6 100644 --- a/.coveragerc +++ b/.coveragerc @@ -814,7 +814,8 @@ omit = homeassistant/components/streamlabswater/* homeassistant/components/suez_water/* homeassistant/components/supervisord/sensor.py - homeassistant/components/surepetcare/*.py + homeassistant/components/surepetcare/__init__.py + homeassistant/components/surepetcare/sensor.py homeassistant/components/swiss_hydrological_data/sensor.py homeassistant/components/swiss_public_transport/sensor.py homeassistant/components/swisscom/device_tracker.py diff --git a/homeassistant/components/surepetcare/__init__.py b/homeassistant/components/surepetcare/__init__.py index 90e754118ab..9aac8f11941 100644 --- a/homeassistant/components/surepetcare/__init__.py +++ b/homeassistant/components/surepetcare/__init__.py @@ -104,12 +104,13 @@ async def async_setup(hass, config) -> bool: ) # discover hubs the flaps/feeders are connected to + hub_ids = set() for device in things.copy(): device_data = await surepy.device(device[CONF_ID]) if ( CONF_PARENT in device_data and device_data[CONF_PARENT][CONF_PRODUCT_ID] == SureProductID.HUB - and device_data[CONF_PARENT][CONF_ID] not in things + and device_data[CONF_PARENT][CONF_ID] not in hub_ids ): things.append( { @@ -117,6 +118,7 @@ async def async_setup(hass, config) -> bool: CONF_TYPE: SureProductID.HUB, } ) + hub_ids.add(device_data[CONF_PARENT][CONF_ID]) # add pets things.extend( diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 758b78191e8..28739d751da 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -960,6 +960,9 @@ stringcase==1.2.0 # homeassistant.components.solarlog sunwatcher==0.2.1 +# homeassistant.components.surepetcare +surepy==0.2.5 + # homeassistant.components.tellduslive tellduslive==0.10.11 diff --git a/tests/components/surepetcare/__init__.py b/tests/components/surepetcare/__init__.py new file mode 100644 index 00000000000..a7ce6d3b6a6 --- /dev/null +++ b/tests/components/surepetcare/__init__.py @@ -0,0 +1,88 @@ +"""Tests for Sure Petcare integration.""" +from homeassistant.components.surepetcare.const import DOMAIN +from homeassistant.const import CONF_PASSWORD, CONF_USERNAME + +from tests.async_mock import patch + +HOUSEHOLD_ID = "household-id" +HUB_ID = "hub-id" + +MOCK_HUB = { + "id": HUB_ID, + "product_id": 1, + "household_id": HOUSEHOLD_ID, + "name": "Hub", + "status": {"online": True, "led_mode": 0, "pairing_mode": 0}, +} + +MOCK_FEEDER = { + "id": 12345, + "product_id": 4, + "household_id": HOUSEHOLD_ID, + "name": "Feeder", + "parent": {"product_id": 1, "id": HUB_ID}, + "status": { + "battery": 6.4, + "locking": {"mode": 0}, + "learn_mode": 0, + "signal": {"device_rssi": 60, "hub_rssi": 65}, + }, +} + +MOCK_CAT_FLAP = { + "id": 13579, + "product_id": 6, + "household_id": HOUSEHOLD_ID, + "name": "Cat Flap", + "parent": {"product_id": 1, "id": HUB_ID}, + "status": { + "battery": 6.4, + "locking": {"mode": 0}, + "learn_mode": 0, + "signal": {"device_rssi": 65, "hub_rssi": 64}, + }, +} + +MOCK_PET_FLAP = { + "id": 13576, + "product_id": 3, + "household_id": HOUSEHOLD_ID, + "name": "Pet Flap", + "parent": {"product_id": 1, "id": HUB_ID}, + "status": { + "battery": 6.4, + "locking": {"mode": 0}, + "learn_mode": 0, + "signal": {"device_rssi": 70, "hub_rssi": 65}, + }, +} + +MOCK_PET = { + "id": 24680, + "household_id": HOUSEHOLD_ID, + "name": "Pet", + "position": {"since": "2020-08-23T23:10:50", "where": 1}, + "status": {}, +} + +MOCK_API_DATA = { + "devices": [MOCK_HUB, MOCK_CAT_FLAP, MOCK_PET_FLAP, MOCK_FEEDER], + "pets": [MOCK_PET], +} + +MOCK_CONFIG = { + DOMAIN: { + CONF_USERNAME: "test-username", + CONF_PASSWORD: "test-password", + "feeders": [12345], + "flaps": [13579, 13576], + "pets": [24680], + }, +} + + +def _patch_sensor_setup(): + return patch( + "homeassistant.components.surepetcare.sensor.async_setup_platform", + return_value=True, + ) diff --git a/tests/components/surepetcare/conftest.py b/tests/components/surepetcare/conftest.py new file mode 100644 index 00000000000..6d85a2b0189 --- /dev/null +++ b/tests/components/surepetcare/conftest.py @@ -0,0 +1,23 @@ +"""Define fixtures available for all tests.""" +from pytest import fixture +from surepy import SurePetcare + +from homeassistant.helpers.aiohttp_client import async_get_clientsession + +from tests.async_mock import AsyncMock, patch + + +@fixture() +def surepetcare(hass): + """Mock the SurePetcare for easier testing.""" + with patch("homeassistant.components.surepetcare.SurePetcare") as mock_surepetcare: + instance = mock_surepetcare.return_value = SurePetcare( + "test-username", + "test-password", + hass.loop, + async_get_clientsession(hass), + api_timeout=1, + ) + instance.get_data = AsyncMock(return_value=None) + + yield mock_surepetcare diff --git a/tests/components/surepetcare/test_binary_sensor.py b/tests/components/surepetcare/test_binary_sensor.py new file mode 100644 index 00000000000..9478ca7a1d4 --- /dev/null +++ b/tests/components/surepetcare/test_binary_sensor.py @@ -0,0 +1,32 @@ +"""The tests for the Sure Petcare binary sensor platform.""" +from homeassistant.components.surepetcare.const import DOMAIN +from homeassistant.setup import async_setup_component + +from . import MOCK_API_DATA, MOCK_CONFIG, _patch_sensor_setup + +EXPECTED_ENTITY_IDS = { + "binary_sensor.pet_flap_pet_flap_connectivity": "household-id-13576-connectivity", + "binary_sensor.pet_flap_cat_flap_connectivity": "household-id-13579-connectivity", + "binary_sensor.feeder_feeder_connectivity": "household-id-12345-connectivity", + "binary_sensor.pet_pet": "household-id-24680", + "binary_sensor.hub_hub": "household-id-hub-id", +} + + +async def test_binary_sensors(hass, surepetcare) -> None: + """Test the generation of unique ids.""" + instance = surepetcare.return_value + instance.data = MOCK_API_DATA + instance.get_data.return_value = MOCK_API_DATA + + with _patch_sensor_setup(): + assert await async_setup_component(hass, DOMAIN, MOCK_CONFIG) + await hass.async_block_till_done() + + entity_registry = await hass.helpers.entity_registry.async_get_registry() + state_entity_ids = hass.states.async_entity_ids() + + for entity_id, unique_id in EXPECTED_ENTITY_IDS.items(): + assert entity_id in state_entity_ids + entity = entity_registry.async_get(entity_id) + assert entity.unique_id == unique_id