"""Test the DLNA DMS component setup, cleanup, and module-level functions.""" from typing import cast from unittest.mock import Mock from homeassistant.components.dlna_dms.const import ( CONF_SOURCE_ID, CONFIG_VERSION, DOMAIN, ) from homeassistant.components.dlna_dms.dms import DlnaDmsData from homeassistant.const import CONF_DEVICE_ID, CONF_URL from homeassistant.core import HomeAssistant from homeassistant.setup import async_setup_component from .conftest import ( MOCK_DEVICE_LOCATION, MOCK_DEVICE_NAME, MOCK_DEVICE_TYPE, MOCK_DEVICE_USN, MOCK_SOURCE_ID, ) from tests.common import MockConfigEntry async def test_resource_lifecycle( hass: HomeAssistant, aiohttp_session_requester_mock: Mock, config_entry_mock: MockConfigEntry, ssdp_scanner_mock: Mock, dms_device_mock: Mock, ) -> None: """Test that resources are acquired/released as the entity is setup/unloaded.""" # Set up the config entry config_entry_mock.add_to_hass(hass) assert await async_setup_component(hass, DOMAIN, {}) is True await hass.async_block_till_done() # Check the device source is created and working domain_data = cast(DlnaDmsData, hass.data[DOMAIN]) assert len(domain_data.devices) == 1 assert len(domain_data.sources) == 1 entity = next(iter(domain_data.devices.values())) assert entity.available is True # Check listener subscriptions assert len(config_entry_mock.update_listeners) == 0 assert ssdp_scanner_mock.async_register_callback.await_count == 2 assert ssdp_scanner_mock.async_register_callback.return_value.call_count == 0 # Check event notifiers are not subscribed - dlna_dms doesn't use them assert dms_device_mock.async_subscribe_services.await_count == 0 assert dms_device_mock.async_unsubscribe_services.await_count == 0 assert dms_device_mock.on_event is None # Unload the config entry assert await hass.config_entries.async_remove(config_entry_mock.entry_id) == { "require_restart": False } # Check update listeners are released assert not config_entry_mock.update_listeners assert ssdp_scanner_mock.async_register_callback.await_count == 2 assert ssdp_scanner_mock.async_register_callback.return_value.call_count == 2 # Check event notifiers are still not subscribed assert dms_device_mock.async_subscribe_services.await_count == 0 assert dms_device_mock.async_unsubscribe_services.await_count == 0 assert dms_device_mock.on_event is None # Check device source is gone assert not domain_data.devices assert not domain_data.sources async def test_migrate_entry(hass: HomeAssistant) -> None: """Test migrating a config entry from version 1 to version 2.""" # Create mock entry with version 1 mock_entry = MockConfigEntry( unique_id=MOCK_DEVICE_USN, domain=DOMAIN, version=1, data={ CONF_URL: MOCK_DEVICE_LOCATION, CONF_DEVICE_ID: MOCK_DEVICE_USN, }, title=MOCK_DEVICE_NAME, ) # Set it up mock_entry.add_to_hass(hass) assert await async_setup_component(hass, DOMAIN, {}) is True await hass.async_block_till_done() # Check that it has a source_id now updated_entry = hass.config_entries.async_get_entry(mock_entry.entry_id) assert updated_entry assert updated_entry.version == CONFIG_VERSION assert updated_entry.data.get(CONF_SOURCE_ID) == MOCK_SOURCE_ID async def test_migrate_entry_collision( hass: HomeAssistant, config_entry_mock: MockConfigEntry ) -> None: """Test migrating a config entry with a potentially colliding source ID.""" # Use existing mock entry config_entry_mock.add_to_hass(hass) # Create mock entry with same name, and old version, that needs migrating mock_entry = MockConfigEntry( unique_id=f"udn-migrating::{MOCK_DEVICE_TYPE}", domain=DOMAIN, version=1, data={ CONF_URL: "http://192.88.99.22/dms_description.xml", CONF_DEVICE_ID: f"different-udn::{MOCK_DEVICE_TYPE}", }, title=MOCK_DEVICE_NAME, ) mock_entry.add_to_hass(hass) # Set the integration up assert await async_setup_component(hass, DOMAIN, {}) is True await hass.async_block_till_done() # Check that it has a source_id now updated_entry = hass.config_entries.async_get_entry(mock_entry.entry_id) assert updated_entry assert updated_entry.version == CONFIG_VERSION assert updated_entry.data.get(CONF_SOURCE_ID) == f"{MOCK_SOURCE_ID}_1"