diff --git a/.coveragerc b/.coveragerc index 9745a0708c8..ca7251cc2c0 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1304,7 +1304,6 @@ omit = homeassistant/components/waze_travel_time/__init__.py homeassistant/components/waze_travel_time/helpers.py homeassistant/components/waze_travel_time/sensor.py - homeassistant/components/whois/__init__.py homeassistant/components/whois/diagnostics.py homeassistant/components/whois/sensor.py homeassistant/components/wiffi/* diff --git a/homeassistant/components/whois/__init__.py b/homeassistant/components/whois/__init__.py index cd659874135..aa64ebecf83 100644 --- a/homeassistant/components/whois/__init__.py +++ b/homeassistant/components/whois/__init__.py @@ -48,4 +48,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" - return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) + unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) + if unload_ok: + del hass.data[DOMAIN][entry.entry_id] + return unload_ok diff --git a/homeassistant/components/whois/sensor.py b/homeassistant/components/whois/sensor.py index b28e607e9bc..e1199f35f2d 100644 --- a/homeassistant/components/whois/sensor.py +++ b/homeassistant/components/whois/sensor.py @@ -147,10 +147,10 @@ SENSORS: tuple[WhoisSensorEntityDescription, ...] = ( ) -def setup_platform( +async def async_setup_platform( hass: HomeAssistant, config: ConfigType, - add_entities: AddEntitiesCallback, + async_add_entities: AddEntitiesCallback, discovery_info: DiscoveryInfoType | None = None, ) -> None: """Set up the WHOIS sensor.""" diff --git a/tests/components/whois/conftest.py b/tests/components/whois/conftest.py index a9053b51c2a..9a96e343627 100644 --- a/tests/components/whois/conftest.py +++ b/tests/components/whois/conftest.py @@ -2,12 +2,14 @@ from __future__ import annotations from collections.abc import Generator +from datetime import datetime from unittest.mock import AsyncMock, MagicMock, patch import pytest from homeassistant.components.whois.const import DOMAIN from homeassistant.const import CONF_DOMAIN +from homeassistant.core import HomeAssistant from tests.common import MockConfigEntry @@ -39,3 +41,41 @@ def mock_setup_entry() -> Generator[AsyncMock, None, None]: "homeassistant.components.whois.async_setup_entry", return_value=True ) as mock_setup: yield mock_setup + + +@pytest.fixture +def mock_whois() -> Generator[MagicMock, None, None]: + """Return a mocked query.""" + + with patch( + "homeassistant.components.whois.whois_query", + ) as whois_mock: + domain = whois_mock.return_value + domain.abuse_contact = "abuse@example.com" + domain.admin = "admin@example.com" + domain.creation_date = datetime(2019, 1, 1, 0, 0, 0, 0) + domain.dnssec = True + domain.expiration_date = datetime(2023, 1, 1, 0, 0, 0, 0) + domain.last_updated = datetime(2022, 1, 1, 0, 0, 0, 0) + domain.name = "home-assistant.io" + domain.name_servers = ["ns1.example.com", "ns2.example.com"] + domain.owner = "owner@example.com" + domain.registrant = "registrant@example.com" + domain.registrar = "My Registrar" + domain.reseller = "Top Domains, Low Prices" + domain.status = "OK" + domain.statuses = ["OK"] + yield whois_mock + + +@pytest.fixture +async def init_integration( + hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_whois: MagicMock +) -> MockConfigEntry: + """Set up thewhois integration for testing.""" + mock_config_entry.add_to_hass(hass) + + await hass.config_entries.async_setup(mock_config_entry.entry_id) + await hass.async_block_till_done() + + return mock_config_entry diff --git a/tests/components/whois/test_init.py b/tests/components/whois/test_init.py new file mode 100644 index 00000000000..6701d8ed20c --- /dev/null +++ b/tests/components/whois/test_init.py @@ -0,0 +1,80 @@ +"""Tests for the Whois integration.""" +from unittest.mock import MagicMock + +import pytest +from whois.exceptions import ( + FailedParsingWhoisOutput, + UnknownDateFormat, + UnknownTld, + WhoisCommandFailed, +) + +from homeassistant.components.sensor import DOMAIN as SENSOR_DOMAIN +from homeassistant.components.whois.const import DOMAIN +from homeassistant.config_entries import ConfigEntryState +from homeassistant.const import CONF_DOMAIN +from homeassistant.core import HomeAssistant +from homeassistant.setup import async_setup_component + +from tests.common import MockConfigEntry + + +async def test_load_unload_config_entry( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_whois: MagicMock, +) -> None: + """Test the Whois configuration entry loading/unloading.""" + mock_config_entry.add_to_hass(hass) + await hass.config_entries.async_setup(mock_config_entry.entry_id) + await hass.async_block_till_done() + + assert mock_config_entry.state is ConfigEntryState.LOADED + assert len(mock_whois.mock_calls) == 2 + + await hass.config_entries.async_unload(mock_config_entry.entry_id) + await hass.async_block_till_done() + + assert not hass.data.get(DOMAIN) + assert mock_config_entry.state is ConfigEntryState.NOT_LOADED + + +@pytest.mark.parametrize( + "side_effect", + [FailedParsingWhoisOutput, UnknownDateFormat, UnknownTld, WhoisCommandFailed], +) +async def test_error_handling( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, + mock_whois: MagicMock, + caplog: pytest.LogCaptureFixture, + side_effect: Exception, +) -> None: + """Test the Whois threw an error.""" + mock_config_entry.add_to_hass(hass) + mock_whois.side_effect = side_effect + + await hass.config_entries.async_setup(mock_config_entry.entry_id) + await hass.async_block_till_done() + + assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY + assert len(mock_whois.mock_calls) == 1 + + +async def test_import_config( + hass: HomeAssistant, + mock_whois: MagicMock, + mock_whois_config_flow: MagicMock, + caplog: pytest.LogCaptureFixture, +) -> None: + """Test the Whois being set up from config via import.""" + assert await async_setup_component( + hass, + SENSOR_DOMAIN, + {SENSOR_DOMAIN: {"platform": DOMAIN, CONF_DOMAIN: "home-assistant.io"}}, + ) + await hass.async_block_till_done() + + assert len(hass.config_entries.async_entries(DOMAIN)) == 1 + assert len(mock_whois.mock_calls) == 2 + assert "the Whois platform in YAML is deprecated" in caplog.text