From cdc2192bbaf5c1beb3532264e036bf2613813504 Mon Sep 17 00:00:00 2001 From: Joost Lekkerkerker Date: Thu, 11 Dec 2025 09:10:02 +0100 Subject: [PATCH] Clean up Homelink tests (#158685) Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../components/gentex_homelink/__init__.py | 8 +- .../components/gentex_homelink/coordinator.py | 16 +- .../components/gentex_homelink/event.py | 16 +- tests/components/gentex_homelink/__init__.py | 31 ++++ tests/components/gentex_homelink/conftest.py | 50 +++++ .../gentex_homelink/snapshots/test_event.ambr | 172 ++++++++++++++++++ .../gentex_homelink/snapshots/test_init.ambr | 32 ++++ .../gentex_homelink/test_coordinator.py | 160 ---------------- .../components/gentex_homelink/test_event.py | 102 ++++------- tests/components/gentex_homelink/test_init.py | 68 +++++-- 10 files changed, 389 insertions(+), 266 deletions(-) create mode 100644 tests/components/gentex_homelink/snapshots/test_event.ambr create mode 100644 tests/components/gentex_homelink/snapshots/test_init.ambr delete mode 100644 tests/components/gentex_homelink/test_coordinator.py diff --git a/homeassistant/components/gentex_homelink/__init__.py b/homeassistant/components/gentex_homelink/__init__.py index 71a3dc4a2cd..831a2e0ff3e 100644 --- a/homeassistant/components/gentex_homelink/__init__.py +++ b/homeassistant/components/gentex_homelink/__init__.py @@ -10,7 +10,7 @@ from homeassistant.helpers import aiohttp_client, config_entry_oauth2_flow from . import oauth2 from .const import DOMAIN -from .coordinator import HomeLinkConfigEntry, HomeLinkCoordinator, HomeLinkData +from .coordinator import HomeLinkConfigEntry, HomeLinkCoordinator PLATFORMS: list[Platform] = [Platform.EVENT] @@ -44,9 +44,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: HomeLinkConfigEntry) -> ) await coordinator.async_config_entry_first_refresh() - entry.runtime_data = HomeLinkData( - provider=provider, coordinator=coordinator, last_update_id=None - ) + entry.runtime_data = coordinator await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True @@ -54,5 +52,5 @@ async def async_setup_entry(hass: HomeAssistant, entry: HomeLinkConfigEntry) -> async def async_unload_entry(hass: HomeAssistant, entry: HomeLinkConfigEntry) -> bool: """Unload a config entry.""" - await entry.runtime_data.coordinator.async_on_unload(None) + await entry.runtime_data.async_on_unload(None) return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) diff --git a/homeassistant/components/gentex_homelink/coordinator.py b/homeassistant/components/gentex_homelink/coordinator.py index 8ef51228ead..61daf71ba0e 100644 --- a/homeassistant/components/gentex_homelink/coordinator.py +++ b/homeassistant/components/gentex_homelink/coordinator.py @@ -3,7 +3,6 @@ from __future__ import annotations from collections.abc import Callable -from dataclasses import dataclass from functools import partial import logging from typing import TypedDict @@ -17,19 +16,10 @@ from homeassistant.util.ssl import get_default_context _LOGGER = logging.getLogger(__name__) -type HomeLinkConfigEntry = ConfigEntry[HomeLinkData] +type HomeLinkConfigEntry = ConfigEntry[HomeLinkCoordinator] type EventCallback = Callable[[HomeLinkEventData], None] -@dataclass -class HomeLinkData: - """Class for HomeLink integration runtime data.""" - - provider: MQTTProvider - coordinator: HomeLinkCoordinator - last_update_id: str | None - - class HomeLinkEventData(TypedDict): """Data for a single event.""" @@ -68,7 +58,7 @@ class HomeLinkCoordinator: self._listeners[target_event_id] = update_callback return partial(self.__async_remove_listener_internal, target_event_id) - def __async_remove_listener_internal(self, listener_id: str): + def __async_remove_listener_internal(self, listener_id: str) -> None: del self._listeners[listener_id] @callback @@ -92,7 +82,7 @@ class HomeLinkCoordinator: await self.discover_devices() self.provider.listen(self.on_message) - async def discover_devices(self): + async def discover_devices(self) -> None: """Discover devices and build the Entities.""" self.device_data = await self.provider.discover() diff --git a/homeassistant/components/gentex_homelink/event.py b/homeassistant/components/gentex_homelink/event.py index fbc511e7c90..213502c9970 100644 --- a/homeassistant/components/gentex_homelink/event.py +++ b/homeassistant/components/gentex_homelink/event.py @@ -3,25 +3,24 @@ from __future__ import annotations from homeassistant.components.event import EventDeviceClass, EventEntity -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from .const import DOMAIN, EVENT_PRESSED -from .coordinator import HomeLinkCoordinator, HomeLinkEventData +from .coordinator import HomeLinkConfigEntry, HomeLinkCoordinator, HomeLinkEventData async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, + config_entry: HomeLinkConfigEntry, async_add_entities: AddConfigEntryEntitiesCallback, ) -> None: - """Add the entities for the binary sensor.""" - coordinator = config_entry.runtime_data.coordinator + """Add the entities for the event platform.""" + coordinator = config_entry.runtime_data async_add_entities( - HomeLinkEventEntity(button.id, button.name, device.id, device.name, coordinator) + HomeLinkEventEntity(coordinator, button.id, button.name, device.id, device.name) for device in coordinator.device_data for button in device.buttons ) @@ -40,11 +39,11 @@ class HomeLinkEventEntity(EventEntity): def __init__( self, + coordinator: HomeLinkCoordinator, button_id: str, param_name: str, device_id: str, device_name: str, - coordinator: HomeLinkCoordinator, ) -> None: """Initialize the event entity.""" @@ -74,5 +73,4 @@ class HomeLinkEventEntity(EventEntity): if update_data["requestId"] != self.last_request_id: self._trigger_event(EVENT_PRESSED) self.last_request_id = update_data["requestId"] - - self.async_write_ha_state() + self.async_write_ha_state() diff --git a/tests/components/gentex_homelink/__init__.py b/tests/components/gentex_homelink/__init__.py index 83a06ecb43a..fb5f94f953d 100644 --- a/tests/components/gentex_homelink/__init__.py +++ b/tests/components/gentex_homelink/__init__.py @@ -1 +1,32 @@ """Tests for the homelink integration.""" + +from typing import Any +from unittest.mock import AsyncMock + +from homeassistant.core import HomeAssistant + +from tests.common import MockConfigEntry + + +async def setup_integration(hass: HomeAssistant, entry: MockConfigEntry) -> None: + """Set up the homelink integration for testing.""" + entry.add_to_hass(hass) + await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + + +async def update_callback( + hass: HomeAssistant, mock: AsyncMock, update_type: str, data: dict[str, Any] +) -> None: + """Invoke the MQTT provider's message callback with the specified update type and data.""" + for call in mock.listen.call_args_list: + call[0][0]( + "topic", + { + "type": update_type, + "data": data, + }, + ) + + await hass.async_block_till_done() + await hass.async_block_till_done() diff --git a/tests/components/gentex_homelink/conftest.py b/tests/components/gentex_homelink/conftest.py index f1ef647ed9a..0fc9e9f0943 100644 --- a/tests/components/gentex_homelink/conftest.py +++ b/tests/components/gentex_homelink/conftest.py @@ -3,8 +3,14 @@ from collections.abc import Generator from unittest.mock import AsyncMock, patch +from homelink.model.button import Button +import homelink.model.device import pytest +from homeassistant.components.gentex_homelink import DOMAIN + +from tests.common import MockConfigEntry + @pytest.fixture def mock_srp_auth() -> Generator[AsyncMock]: @@ -24,6 +30,50 @@ def mock_srp_auth() -> Generator[AsyncMock]: yield instance +@pytest.fixture +def mock_mqtt_provider(mock_device: AsyncMock) -> Generator[AsyncMock]: + """Mock MQTT provider.""" + with patch( + "homeassistant.components.gentex_homelink.MQTTProvider", autospec=True + ) as mock_mqtt_provider: + instance = mock_mqtt_provider.return_value + instance.discover.return_value = [mock_device] + yield instance + + +@pytest.fixture +def mock_device() -> AsyncMock: + """Mock Device instance.""" + device = AsyncMock(spec=homelink.model.device.Device, autospec=True) + buttons = [ + Button(id="1", name="Button 1", device=device), + Button(id="2", name="Button 2", device=device), + Button(id="3", name="Button 3", device=device), + ] + device.id = "TestDevice" + device.name = "TestDevice" + device.buttons = buttons + return device + + +@pytest.fixture +def mock_config_entry() -> MockConfigEntry: + """Mock setup entry.""" + return MockConfigEntry( + domain=DOMAIN, + data={ + "auth_implementation": "gentex_homelink", + "token": { + "access_token": "access", + "refresh_token": "refresh", + "expires_in": 3600, + "token_type": "bearer", + "expires_at": 1234567890, + }, + }, + ) + + @pytest.fixture def mock_setup_entry() -> Generator[AsyncMock]: """Mock setup entry.""" diff --git a/tests/components/gentex_homelink/snapshots/test_event.ambr b/tests/components/gentex_homelink/snapshots/test_event.ambr new file mode 100644 index 00000000000..f0c6c3c8d16 --- /dev/null +++ b/tests/components/gentex_homelink/snapshots/test_event.ambr @@ -0,0 +1,172 @@ +# serializer version: 1 +# name: test_entities[event.testdevice_button_1-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'event_types': list([ + 'Pressed', + ]), + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'event', + 'entity_category': None, + 'entity_id': 'event.testdevice_button_1', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Button 1', + 'platform': 'gentex_homelink', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '1', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[event.testdevice_button_1-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'button', + 'event_type': None, + 'event_types': list([ + 'Pressed', + ]), + 'friendly_name': 'TestDevice Button 1', + }), + 'context': , + 'entity_id': 'event.testdevice_button_1', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_entities[event.testdevice_button_2-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'event_types': list([ + 'Pressed', + ]), + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'event', + 'entity_category': None, + 'entity_id': 'event.testdevice_button_2', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Button 2', + 'platform': 'gentex_homelink', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '2', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[event.testdevice_button_2-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'button', + 'event_type': None, + 'event_types': list([ + 'Pressed', + ]), + 'friendly_name': 'TestDevice Button 2', + }), + 'context': , + 'entity_id': 'event.testdevice_button_2', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- +# name: test_entities[event.testdevice_button_3-entry] + EntityRegistryEntrySnapshot({ + 'aliases': set({ + }), + 'area_id': None, + 'capabilities': dict({ + 'event_types': list([ + 'Pressed', + ]), + }), + 'config_entry_id': , + 'config_subentry_id': , + 'device_class': None, + 'device_id': , + 'disabled_by': None, + 'domain': 'event', + 'entity_category': None, + 'entity_id': 'event.testdevice_button_3', + 'has_entity_name': True, + 'hidden_by': None, + 'icon': None, + 'id': , + 'labels': set({ + }), + 'name': None, + 'options': dict({ + }), + 'original_device_class': , + 'original_icon': None, + 'original_name': 'Button 3', + 'platform': 'gentex_homelink', + 'previous_unique_id': None, + 'suggested_object_id': None, + 'supported_features': 0, + 'translation_key': None, + 'unique_id': '3', + 'unit_of_measurement': None, + }) +# --- +# name: test_entities[event.testdevice_button_3-state] + StateSnapshot({ + 'attributes': ReadOnlyDict({ + 'device_class': 'button', + 'event_type': None, + 'event_types': list([ + 'Pressed', + ]), + 'friendly_name': 'TestDevice Button 3', + }), + 'context': , + 'entity_id': 'event.testdevice_button_3', + 'last_changed': , + 'last_reported': , + 'last_updated': , + 'state': 'unknown', + }) +# --- diff --git a/tests/components/gentex_homelink/snapshots/test_init.ambr b/tests/components/gentex_homelink/snapshots/test_init.ambr new file mode 100644 index 00000000000..d9d52e290bc --- /dev/null +++ b/tests/components/gentex_homelink/snapshots/test_init.ambr @@ -0,0 +1,32 @@ +# serializer version: 1 +# name: test_device + DeviceRegistryEntrySnapshot({ + 'area_id': None, + 'config_entries': , + 'config_entries_subentries': , + 'configuration_url': None, + 'connections': set({ + }), + 'disabled_by': None, + 'entry_type': None, + 'hw_version': None, + 'id': , + 'identifiers': set({ + tuple( + 'gentex_homelink', + 'TestDevice', + ), + }), + 'labels': set({ + }), + 'manufacturer': None, + 'model': None, + 'model_id': None, + 'name': 'TestDevice', + 'name_by_user': None, + 'primary_config_entry': , + 'serial_number': None, + 'sw_version': None, + 'via_device_id': None, + }) +# --- diff --git a/tests/components/gentex_homelink/test_coordinator.py b/tests/components/gentex_homelink/test_coordinator.py deleted file mode 100644 index 2947e28839a..00000000000 --- a/tests/components/gentex_homelink/test_coordinator.py +++ /dev/null @@ -1,160 +0,0 @@ -"""Tests for the homelink coordinator.""" - -import asyncio -import time -from unittest.mock import patch - -from homelink.model.button import Button -from homelink.model.device import Device -import pytest - -from homeassistant.components.gentex_homelink import async_setup_entry -from homeassistant.components.gentex_homelink.const import EVENT_PRESSED -from homeassistant.config_entries import ConfigEntryState -from homeassistant.const import STATE_UNAVAILABLE -from homeassistant.core import HomeAssistant -import homeassistant.helpers.entity_registry as er - -from tests.common import MockConfigEntry -from tests.test_util.aiohttp import AiohttpClientMocker -from tests.typing import ClientSessionGenerator - -DOMAIN = "gentex_homelink" - -deviceInst = Device(id="TestDevice", name="TestDevice") -deviceInst.buttons = [ - Button(id="Button 1", name="Button 1", device=deviceInst), - Button(id="Button 2", name="Button 2", device=deviceInst), - Button(id="Button 3", name="Button 3", device=deviceInst), -] - - -async def test_get_state_updates( - hass: HomeAssistant, - hass_client_no_auth: ClientSessionGenerator, - aioclient_mock: AiohttpClientMocker, - caplog: pytest.LogCaptureFixture, -) -> None: - """Test state updates. - - Tests that get_state calls are called by home assistant, and the homeassistant components respond appropriately to the data returned. - """ - with patch( - "homeassistant.components.gentex_homelink.MQTTProvider", autospec=True - ) as MockProvider: - instance = MockProvider.return_value - instance.discover.return_value = [deviceInst] - config_entry = MockConfigEntry( - domain=DOMAIN, - unique_id=None, - version=1, - data={ - "auth_implementation": "gentex_homelink", - "token": {"expires_at": time.time() + 10000, "access_token": ""}, - "last_update_id": None, - }, - state=ConfigEntryState.LOADED, - ) - config_entry.add_to_hass(hass) - result = await async_setup_entry(hass, config_entry) - # Assert configuration worked without errors - assert result - - provider = config_entry.runtime_data.provider - state_data = { - "type": "state", - "data": { - "Button 1": {"requestId": "rid1", "timestamp": time.time()}, - "Button 2": {"requestId": "rid2", "timestamp": time.time()}, - "Button 3": {"requestId": "rid3", "timestamp": time.time()}, - }, - } - - # Test successful setup and first data fetch. The buttons should be unknown at the start - await hass.async_block_till_done(wait_background_tasks=True) - states = hass.states.async_all() - assert states, "No states were loaded" - assert all(state != STATE_UNAVAILABLE for state in states), ( - "At least one state was not initialized as STATE_UNAVAILABLE" - ) - buttons_unknown = [s.state == "unknown" for s in states] - assert buttons_unknown and all(buttons_unknown), ( - "At least one button state was not initialized to unknown" - ) - - provider.listen.mock_calls[0].args[0](None, state_data) - - await hass.async_block_till_done(wait_background_tasks=True) - await asyncio.gather(*asyncio.all_tasks() - {asyncio.current_task()}) - await asyncio.sleep(0.01) - states = hass.states.async_all() - - assert all(state != STATE_UNAVAILABLE for state in states), ( - "Some button became unavailable" - ) - buttons_pressed = [s.attributes["event_type"] == EVENT_PRESSED for s in states] - assert buttons_pressed and all(buttons_pressed), ( - "At least one button was not pressed" - ) - - -async def test_request_sync(hass: HomeAssistant) -> None: - """Test that the config entry is reloaded when a requestSync request is sent.""" - updatedDeviceInst = Device(id="TestDevice", name="TestDevice") - updatedDeviceInst.buttons = [ - Button(id="Button 1", name="New Button 1", device=deviceInst), - Button(id="Button 2", name="New Button 2", device=deviceInst), - Button(id="Button 3", name="New Button 3", device=deviceInst), - ] - - with patch( - "homeassistant.components.gentex_homelink.MQTTProvider", autospec=True - ) as MockProvider: - instance = MockProvider.return_value - instance.discover.side_effect = [[deviceInst], [updatedDeviceInst]] - config_entry = MockConfigEntry( - domain=DOMAIN, - unique_id=None, - version=1, - data={ - "auth_implementation": "gentex_homelink", - "token": {"expires_at": time.time() + 10000, "access_token": ""}, - "last_update_id": None, - }, - state=ConfigEntryState.LOADED, - ) - config_entry.add_to_hass(hass) - result = await async_setup_entry(hass, config_entry) - # Assert configuration worked without errors - assert result - - # Check to see if the correct buttons names were loaded - comp = er.async_get(hass) - button_names = {"Button 1", "Button 2", "Button 3"} - registered_button_names = {b.original_name for b in comp.entities.values()} - - assert button_names == registered_button_names, ( - "Expect button names to be correct for the initial config" - ) - - provider = config_entry.runtime_data.provider - coordinator = config_entry.runtime_data.coordinator - - with patch.object( - coordinator.hass.config_entries, "async_reload" - ) as async_reload_mock: - # Mimic request sync event - state_data = { - "type": "requestSync", - } - # async reload should not be called yet - async_reload_mock.assert_not_called() - # Send the request sync - provider.listen.mock_calls[0].args[0](None, state_data) - # Wait for the request to be processed - await hass.async_block_till_done(wait_background_tasks=True) - await asyncio.gather(*asyncio.all_tasks() - {asyncio.current_task()}) - await asyncio.sleep(0.01) - - # Now async reload should have been called - async_reload_mock.assert_called() diff --git a/tests/components/gentex_homelink/test_event.py b/tests/components/gentex_homelink/test_event.py index d3661f94492..9b07180a157 100644 --- a/tests/components/gentex_homelink/test_event.py +++ b/tests/components/gentex_homelink/test_event.py @@ -1,77 +1,55 @@ """Test that the devices and entities are correctly configured.""" -from unittest.mock import patch +import time +from unittest.mock import AsyncMock -from homelink.model.button import Button -from homelink.model.device import Device import pytest +from syrupy.assertion import SnapshotAssertion -from homeassistant.components.gentex_homelink import async_setup_entry -from homeassistant.components.gentex_homelink.const import DOMAIN -from homeassistant.config_entries import ConfigEntryState +from homeassistant.const import STATE_UNKNOWN from homeassistant.core import HomeAssistant -import homeassistant.helpers.device_registry as dr import homeassistant.helpers.entity_registry as er -from tests.common import MockConfigEntry -from tests.test_util.aiohttp import AiohttpClientMocker -from tests.typing import ClientSessionGenerator +from . import setup_integration, update_callback -CLIENT_ID = "1234" -CLIENT_SECRET = "5678" -TEST_CONFIG_ENTRY_ID = "ABC123" - -"""Mock classes for testing.""" +from tests.common import MockConfigEntry, snapshot_platform -deviceInst = Device(id="TestDevice", name="TestDevice") -deviceInst.buttons = [ - Button(id="1", name="Button 1", device=deviceInst), - Button(id="2", name="Button 2", device=deviceInst), - Button(id="3", name="Button 3", device=deviceInst), -] - - -@pytest.fixture -async def test_setup_config( +async def test_entities( hass: HomeAssistant, - hass_client_no_auth: ClientSessionGenerator, - aioclient_mock: AiohttpClientMocker, - caplog: pytest.LogCaptureFixture, + mock_config_entry: MockConfigEntry, + mock_mqtt_provider: AsyncMock, + entity_registry: er.EntityRegistry, + snapshot: SnapshotAssertion, ) -> None: - """Setup config entry.""" - with patch( - "homeassistant.components.gentex_homelink.MQTTProvider", autospec=True - ) as MockProvider: - instance = MockProvider.return_value - instance.discover.return_value = [deviceInst] - config_entry = MockConfigEntry( - domain=DOMAIN, - unique_id=None, - version=1, - data={"auth_implementation": "gentex_homelink"}, - state=ConfigEntryState.LOADED, - ) - config_entry.add_to_hass(hass) - result = await async_setup_entry(hass, config_entry) - - # Assert configuration worked without errors - assert result - - -async def test_device_registered(hass: HomeAssistant, test_setup_config) -> None: - """Check if a device is registered.""" - # Assert we got a device with the test ID - device_registry = dr.async_get(hass) - device = device_registry.async_get_device([(DOMAIN, "TestDevice")]) - assert device - assert device.name == "TestDevice" - - -def test_entities_registered(hass: HomeAssistant, test_setup_config) -> None: """Check if the entities are registered.""" - comp = er.async_get(hass) - button_names = {"Button 1", "Button 2", "Button 3"} - registered_button_names = {b.original_name for b in comp.entities.values()} + await setup_integration(hass, mock_config_entry) - assert button_names == registered_button_names + await snapshot_platform(hass, entity_registry, snapshot, mock_config_entry.entry_id) + + +@pytest.mark.freeze_time("2021-07-30") +async def test_entities_update( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_mqtt_provider: AsyncMock, +) -> None: + """Check if the entities are updated.""" + await setup_integration(hass, mock_config_entry) + + assert hass.states.get("event.testdevice_button_1").state == STATE_UNKNOWN + + await update_callback( + hass, + mock_mqtt_provider, + "state", + { + "1": {"requestId": "rid1", "timestamp": time.time()}, + "2": {"requestId": "rid2", "timestamp": time.time()}, + "3": {"requestId": "rid3", "timestamp": time.time()}, + }, + ) + assert ( + hass.states.get("event.testdevice_button_1").state + == "2021-07-30T00:00:00.000+00:00" + ) diff --git a/tests/components/gentex_homelink/test_init.py b/tests/components/gentex_homelink/test_init.py index a8a7b3e7675..d5e226c2ae0 100644 --- a/tests/components/gentex_homelink/test_init.py +++ b/tests/components/gentex_homelink/test_init.py @@ -1,32 +1,66 @@ """Test that the integration is initialized correctly.""" -from unittest.mock import patch +from unittest.mock import AsyncMock, patch + +from syrupy.assertion import SnapshotAssertion -from homeassistant.components import gentex_homelink from homeassistant.components.gentex_homelink.const import DOMAIN +from homeassistant.config_entries import ConfigEntryState from homeassistant.core import HomeAssistant -from homeassistant.setup import async_setup_component +import homeassistant.helpers.device_registry as dr + +from . import setup_integration, update_callback from tests.common import MockConfigEntry +async def test_device( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_mqtt_provider: AsyncMock, + device_registry: dr.DeviceRegistry, + snapshot: SnapshotAssertion, +) -> None: + """Test device is registered correctly.""" + await setup_integration(hass, mock_config_entry) + + device = device_registry.async_get_device( + identifiers={(DOMAIN, "TestDevice")}, + ) + assert device + assert device == snapshot + + +async def test_reload_sync( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_mqtt_provider: AsyncMock, +) -> None: + """Test that the config entry is reloaded when a requestSync request is sent.""" + await setup_integration(hass, mock_config_entry) + + with patch.object(hass.config_entries, "async_reload") as async_reload_mock: + await update_callback( + hass, + mock_mqtt_provider, + "requestSync", + {}, + ) + + async_reload_mock.assert_called_once_with(mock_config_entry.entry_id) + + async def test_load_unload_entry( hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_mqtt_provider: AsyncMock, ) -> None: """Test the entry can be loaded and unloaded.""" - with patch("homeassistant.components.gentex_homelink.MQTTProvider", autospec=True): - entry = MockConfigEntry( - domain=DOMAIN, - unique_id=None, - version=1, - data={"auth_implementation": "gentex_homelink"}, - ) - entry.add_to_hass(hass) + await setup_integration(hass, mock_config_entry) - assert await async_setup_component(hass, DOMAIN, {}) is True, ( - "Component is not set up" - ) + assert mock_config_entry.state is ConfigEntryState.LOADED - assert await gentex_homelink.async_unload_entry(hass, entry), ( - "Component not unloaded" - ) + await hass.config_entries.async_unload(mock_config_entry.entry_id) + await hass.async_block_till_done() + + assert mock_config_entry.state is ConfigEntryState.NOT_LOADED