diff --git a/.coveragerc b/.coveragerc index 1a8bfb462d8..e75460f742f 100644 --- a/.coveragerc +++ b/.coveragerc @@ -234,8 +234,6 @@ omit = homeassistant/components/dlib_face_detect/image_processing.py homeassistant/components/dlib_face_identify/image_processing.py homeassistant/components/dlink/switch.py - homeassistant/components/dnsip/__init__.py - homeassistant/components/dnsip/sensor.py homeassistant/components/dominos/* homeassistant/components/doods/* homeassistant/components/doorbird/__init__.py diff --git a/tests/components/dnsip/__init__.py b/tests/components/dnsip/__init__.py index 9fb6f529c5e..1a465b59ab6 100644 --- a/tests/components/dnsip/__init__.py +++ b/tests/components/dnsip/__init__.py @@ -1 +1,37 @@ """Tests for the dnsip integration.""" +from __future__ import annotations + + +class QueryResult: + """Return Query results.""" + + host = "1.2.3.4" + ttl = 60 + + +class RetrieveDNS: + """Return list of test information.""" + + def __init__( + self, nameservers: list[str] | None = None, error: Exception | None = None + ) -> None: + """Initialize DNS class.""" + if nameservers: + self.nameservers = nameservers + self._nameservers = ["1.2.3.4"] + self.error = error + + async def query(self, hostname, qtype) -> dict[str, str]: + """Return information.""" + if self.error: + raise self.error + return [QueryResult] + + @property + def nameservers(self) -> list[str]: + """Return nameserver.""" + return self._nameservers + + @nameservers.setter + def nameservers(self, value: list[str]) -> None: + self._nameservers = value diff --git a/tests/components/dnsip/test_config_flow.py b/tests/components/dnsip/test_config_flow.py index fdec45be7f5..990fd4df159 100644 --- a/tests/components/dnsip/test_config_flow.py +++ b/tests/components/dnsip/test_config_flow.py @@ -20,23 +20,11 @@ from homeassistant.const import CONF_NAME from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType +from . import RetrieveDNS + from tests.common import MockConfigEntry -class RetrieveDNS: - """Return list of test information.""" - - @staticmethod - async def query(hostname, qtype) -> dict[str, str]: - """Return information.""" - return {"hostname": "1.2.3.4"} - - @property - def nameservers(self) -> list[str]: - """Return nameserver.""" - return ["1.2.3.4"] - - async def test_form(hass: HomeAssistant) -> None: """Test we get the form.""" @@ -164,12 +152,13 @@ async def test_flow_already_exist(hass: HomeAssistant) -> None: DOMAIN, context={"source": config_entries.SOURCE_USER} ) + dns_mock = RetrieveDNS() with patch( "homeassistant.components.dnsip.async_setup_entry", return_value=True, ), patch( "homeassistant.components.dnsip.config_flow.aiodns.DNSResolver", - return_value=RetrieveDNS, + return_value=dns_mock, ): result2 = await hass.config_entries.flow.async_configure( result["flow_id"], @@ -204,9 +193,6 @@ async def test_options_flow(hass: HomeAssistant) -> None: with patch( "homeassistant.components.dnsip.config_flow.aiodns.DNSResolver", return_value=RetrieveDNS(), - ), patch( - "homeassistant.components.dnsip.async_setup_entry", - return_value=True, ): assert await hass.config_entries.async_setup(entry.entry_id) await hass.async_block_till_done() @@ -223,6 +209,7 @@ async def test_options_flow(hass: HomeAssistant) -> None: CONF_RESOLVER_IPV6: "2001:4860:4860::8888", }, ) + await hass.async_block_till_done() assert result["type"] == FlowResultType.CREATE_ENTRY assert result["data"] == { @@ -230,6 +217,8 @@ async def test_options_flow(hass: HomeAssistant) -> None: "resolver_ipv6": "2001:4860:4860::8888", } + assert entry.state == config_entries.ConfigEntryState.LOADED + @pytest.mark.parametrize( "p_input", diff --git a/tests/components/dnsip/test_init.py b/tests/components/dnsip/test_init.py new file mode 100644 index 00000000000..1c8cf04c783 --- /dev/null +++ b/tests/components/dnsip/test_init.py @@ -0,0 +1,54 @@ +"""Test for DNS IP component Init.""" +from __future__ import annotations + +from unittest.mock import patch + +from homeassistant import config_entries +from homeassistant.components.dnsip.const import ( + CONF_HOSTNAME, + CONF_IPV4, + CONF_IPV6, + CONF_RESOLVER, + CONF_RESOLVER_IPV6, + DOMAIN, +) +from homeassistant.config_entries import SOURCE_USER +from homeassistant.const import CONF_NAME +from homeassistant.core import HomeAssistant + +from . import RetrieveDNS + +from tests.common import MockConfigEntry + + +async def test_load_unload_entry(hass: HomeAssistant) -> None: + """Test load and unload an entry.""" + entry = MockConfigEntry( + domain=DOMAIN, + source=SOURCE_USER, + data={ + CONF_HOSTNAME: "home-assistant.io", + CONF_NAME: "home-assistant.io", + CONF_IPV4: True, + CONF_IPV6: False, + }, + options={ + CONF_RESOLVER: "208.67.222.222", + CONF_RESOLVER_IPV6: "2620:0:ccc::2", + }, + entry_id="1", + unique_id="home-assistant.io", + ) + entry.add_to_hass(hass) + + with patch( + "homeassistant.components.dnsip.config_flow.aiodns.DNSResolver", + return_value=RetrieveDNS(), + ): + await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + + assert entry.state == config_entries.ConfigEntryState.LOADED + assert await hass.config_entries.async_unload(entry.entry_id) + await hass.async_block_till_done() + assert entry.state is config_entries.ConfigEntryState.NOT_LOADED diff --git a/tests/components/dnsip/test_sensor.py b/tests/components/dnsip/test_sensor.py new file mode 100644 index 00000000000..f44d58d2125 --- /dev/null +++ b/tests/components/dnsip/test_sensor.py @@ -0,0 +1,105 @@ +"""The test for the DNS IP sensor platform.""" +from __future__ import annotations + +from datetime import timedelta +from unittest.mock import patch + +from aiodns.error import DNSError + +from homeassistant.components.dnsip.const import ( + CONF_HOSTNAME, + CONF_IPV4, + CONF_IPV6, + CONF_RESOLVER, + CONF_RESOLVER_IPV6, + DOMAIN, +) +from homeassistant.config_entries import SOURCE_USER +from homeassistant.const import CONF_NAME, STATE_UNAVAILABLE +from homeassistant.core import HomeAssistant +from homeassistant.util import dt + +from . import RetrieveDNS + +from tests.common import MockConfigEntry, async_fire_time_changed + + +async def test_sensor(hass: HomeAssistant) -> None: + """Test the DNS IP sensor.""" + entry = MockConfigEntry( + domain=DOMAIN, + source=SOURCE_USER, + data={ + CONF_HOSTNAME: "home-assistant.io", + CONF_NAME: "home-assistant.io", + CONF_IPV4: True, + CONF_IPV6: True, + }, + options={ + CONF_RESOLVER: "208.67.222.222", + CONF_RESOLVER_IPV6: "2620:0:ccc::2", + }, + entry_id="1", + unique_id="home-assistant.io", + ) + entry.add_to_hass(hass) + + with patch( + "homeassistant.components.dnsip.sensor.aiodns.DNSResolver", + return_value=RetrieveDNS(), + ): + await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + + state1 = hass.states.get("sensor.home_assistant_io") + state2 = hass.states.get("sensor.home_assistant_io_ipv6") + + assert state1.state == "1.2.3.4" + assert state2.state == "1.2.3.4" + + +async def test_sensor_no_response(hass: HomeAssistant) -> None: + """Test the DNS IP sensor with DNS error.""" + entry = MockConfigEntry( + domain=DOMAIN, + source=SOURCE_USER, + data={ + CONF_HOSTNAME: "home-assistant.io", + CONF_NAME: "home-assistant.io", + CONF_IPV4: True, + CONF_IPV6: False, + }, + options={ + CONF_RESOLVER: "208.67.222.222", + CONF_RESOLVER_IPV6: "2620:0:ccc::2", + }, + entry_id="1", + unique_id="home-assistant.io", + ) + entry.add_to_hass(hass) + + dns_mock = RetrieveDNS() + with patch( + "homeassistant.components.dnsip.sensor.aiodns.DNSResolver", + return_value=dns_mock, + ): + await hass.config_entries.async_setup(entry.entry_id) + await hass.async_block_till_done() + + state = hass.states.get("sensor.home_assistant_io") + + assert state.state == "1.2.3.4" + + dns_mock.error = DNSError() + with patch( + "homeassistant.components.dnsip.sensor.aiodns.DNSResolver", + return_value=dns_mock, + ): + async_fire_time_changed( + hass, + dt.utcnow() + timedelta(minutes=10), + ) + await hass.async_block_till_done() + + state = hass.states.get("sensor.home_assistant_io") + assert state.state == STATE_UNAVAILABLE