Add type hints to helper tests (#89784)

This commit is contained in:
epenet 2023-03-16 11:10:56 +01:00 committed by GitHub
parent 69e85b3216
commit 46a5aa71ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 97 additions and 39 deletions

View file

@ -1,4 +1,5 @@
"""Tests for the Config Entry Flow helper.""" """Tests for the Config Entry Flow helper."""
from collections.abc import Generator
from unittest.mock import Mock, PropertyMock, patch from unittest.mock import Mock, PropertyMock, patch
import pytest import pytest
@ -17,11 +18,11 @@ from tests.common import (
@pytest.fixture @pytest.fixture
def discovery_flow_conf(hass): def discovery_flow_conf(hass: HomeAssistant) -> Generator[dict[str, bool], None, None]:
"""Register a handler.""" """Register a handler."""
handler_conf = {"discovered": False} handler_conf = {"discovered": False}
async def has_discovered_devices(hass): async def has_discovered_devices(hass: HomeAssistant) -> bool:
"""Mock if we have discovered devices.""" """Mock if we have discovered devices."""
return handler_conf["discovered"] return handler_conf["discovered"]
@ -33,17 +34,19 @@ def discovery_flow_conf(hass):
@pytest.fixture @pytest.fixture
def webhook_flow_conf(hass): def webhook_flow_conf(hass: HomeAssistant) -> Generator[None, None, None]:
"""Register a handler.""" """Register a handler."""
with patch.dict(config_entries.HANDLERS): with patch.dict(config_entries.HANDLERS):
config_entry_flow.register_webhook_flow("test_single", "Test Single", {}, False) config_entry_flow.register_webhook_flow("test_single", "Test Single", {}, False)
config_entry_flow.register_webhook_flow( config_entry_flow.register_webhook_flow(
"test_multiple", "Test Multiple", {}, True "test_multiple", "Test Multiple", {}, True
) )
yield {} yield
async def test_single_entry_allowed(hass: HomeAssistant, discovery_flow_conf) -> None: async def test_single_entry_allowed(
hass: HomeAssistant, discovery_flow_conf: dict[str, bool]
) -> None:
"""Test only a single entry is allowed.""" """Test only a single entry is allowed."""
flow = config_entries.HANDLERS["test"]() flow = config_entries.HANDLERS["test"]()
flow.hass = hass flow.hass = hass
@ -56,7 +59,9 @@ async def test_single_entry_allowed(hass: HomeAssistant, discovery_flow_conf) ->
assert result["reason"] == "single_instance_allowed" assert result["reason"] == "single_instance_allowed"
async def test_user_no_devices_found(hass: HomeAssistant, discovery_flow_conf) -> None: async def test_user_no_devices_found(
hass: HomeAssistant, discovery_flow_conf: dict[str, bool]
) -> None:
"""Test if no devices found.""" """Test if no devices found."""
flow = config_entries.HANDLERS["test"]() flow = config_entries.HANDLERS["test"]()
flow.hass = hass flow.hass = hass
@ -67,7 +72,9 @@ async def test_user_no_devices_found(hass: HomeAssistant, discovery_flow_conf) -
assert result["reason"] == "no_devices_found" assert result["reason"] == "no_devices_found"
async def test_user_has_confirmation(hass: HomeAssistant, discovery_flow_conf) -> None: async def test_user_has_confirmation(
hass: HomeAssistant, discovery_flow_conf: dict[str, bool]
) -> None:
"""Test user requires confirmation to setup.""" """Test user requires confirmation to setup."""
discovery_flow_conf["discovered"] = True discovery_flow_conf["discovered"] = True
mock_entity_platform(hass, "config_flow.test", None) mock_entity_platform(hass, "config_flow.test", None)
@ -104,7 +111,7 @@ async def test_user_has_confirmation(hass: HomeAssistant, discovery_flow_conf) -
], ],
) )
async def test_discovery_single_instance( async def test_discovery_single_instance(
hass: HomeAssistant, discovery_flow_conf, source hass: HomeAssistant, discovery_flow_conf: dict[str, bool], source: str
) -> None: ) -> None:
"""Test we not allow duplicates.""" """Test we not allow duplicates."""
flow = config_entries.HANDLERS["test"]() flow = config_entries.HANDLERS["test"]()
@ -130,7 +137,7 @@ async def test_discovery_single_instance(
], ],
) )
async def test_discovery_confirmation( async def test_discovery_confirmation(
hass: HomeAssistant, discovery_flow_conf, source hass: HomeAssistant, discovery_flow_conf: dict[str, bool], source: str
) -> None: ) -> None:
"""Test we ask for confirmation via discovery.""" """Test we ask for confirmation via discovery."""
flow = config_entries.HANDLERS["test"]() flow = config_entries.HANDLERS["test"]()
@ -158,7 +165,7 @@ async def test_discovery_confirmation(
], ],
) )
async def test_discovery_during_onboarding( async def test_discovery_during_onboarding(
hass: HomeAssistant, discovery_flow_conf, source hass: HomeAssistant, discovery_flow_conf: dict[str, bool], source: str
) -> None: ) -> None:
"""Test we create config entry via discovery during onboarding.""" """Test we create config entry via discovery during onboarding."""
flow = config_entries.HANDLERS["test"]() flow = config_entries.HANDLERS["test"]()
@ -173,7 +180,9 @@ async def test_discovery_during_onboarding(
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
async def test_multiple_discoveries(hass: HomeAssistant, discovery_flow_conf) -> None: async def test_multiple_discoveries(
hass: HomeAssistant, discovery_flow_conf: dict[str, bool]
) -> None:
"""Test we only create one instance for multiple discoveries.""" """Test we only create one instance for multiple discoveries."""
mock_entity_platform(hass, "config_flow.test", None) mock_entity_platform(hass, "config_flow.test", None)
@ -189,7 +198,9 @@ async def test_multiple_discoveries(hass: HomeAssistant, discovery_flow_conf) ->
assert result["type"] == data_entry_flow.FlowResultType.ABORT assert result["type"] == data_entry_flow.FlowResultType.ABORT
async def test_only_one_in_progress(hass: HomeAssistant, discovery_flow_conf) -> None: async def test_only_one_in_progress(
hass: HomeAssistant, discovery_flow_conf: dict[str, bool]
) -> None:
"""Test a user initialized one will finish and cancel discovered one.""" """Test a user initialized one will finish and cancel discovered one."""
mock_entity_platform(hass, "config_flow.test", None) mock_entity_platform(hass, "config_flow.test", None)
@ -215,7 +226,9 @@ async def test_only_one_in_progress(hass: HomeAssistant, discovery_flow_conf) ->
assert len(hass.config_entries.flow.async_progress()) == 0 assert len(hass.config_entries.flow.async_progress()) == 0
async def test_import_abort_discovery(hass: HomeAssistant, discovery_flow_conf) -> None: async def test_import_abort_discovery(
hass: HomeAssistant, discovery_flow_conf: dict[str, bool]
) -> None:
"""Test import will finish and cancel discovered one.""" """Test import will finish and cancel discovered one."""
mock_entity_platform(hass, "config_flow.test", None) mock_entity_platform(hass, "config_flow.test", None)
@ -236,7 +249,9 @@ async def test_import_abort_discovery(hass: HomeAssistant, discovery_flow_conf)
assert len(hass.config_entries.flow.async_progress()) == 0 assert len(hass.config_entries.flow.async_progress()) == 0
async def test_import_no_confirmation(hass: HomeAssistant, discovery_flow_conf) -> None: async def test_import_no_confirmation(
hass: HomeAssistant, discovery_flow_conf: dict[str, bool]
) -> None:
"""Test import requires no confirmation to set up.""" """Test import requires no confirmation to set up."""
flow = config_entries.HANDLERS["test"]() flow = config_entries.HANDLERS["test"]()
flow.hass = hass flow.hass = hass
@ -247,7 +262,9 @@ async def test_import_no_confirmation(hass: HomeAssistant, discovery_flow_conf)
assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY assert result["type"] == data_entry_flow.FlowResultType.CREATE_ENTRY
async def test_import_single_instance(hass: HomeAssistant, discovery_flow_conf) -> None: async def test_import_single_instance(
hass: HomeAssistant, discovery_flow_conf: dict[str, bool]
) -> None:
"""Test import doesn't create second instance.""" """Test import doesn't create second instance."""
flow = config_entries.HANDLERS["test"]() flow = config_entries.HANDLERS["test"]()
flow.hass = hass flow.hass = hass
@ -259,7 +276,9 @@ async def test_import_single_instance(hass: HomeAssistant, discovery_flow_conf)
assert result["type"] == data_entry_flow.FlowResultType.ABORT assert result["type"] == data_entry_flow.FlowResultType.ABORT
async def test_ignored_discoveries(hass: HomeAssistant, discovery_flow_conf) -> None: async def test_ignored_discoveries(
hass: HomeAssistant, discovery_flow_conf: dict[str, bool]
) -> None:
"""Test we can ignore discovered entries.""" """Test we can ignore discovered entries."""
mock_entity_platform(hass, "config_flow.test", None) mock_entity_platform(hass, "config_flow.test", None)
@ -292,7 +311,7 @@ async def test_ignored_discoveries(hass: HomeAssistant, discovery_flow_conf) ->
async def test_webhook_single_entry_allowed( async def test_webhook_single_entry_allowed(
hass: HomeAssistant, webhook_flow_conf hass: HomeAssistant, webhook_flow_conf: None
) -> None: ) -> None:
"""Test only a single entry is allowed.""" """Test only a single entry is allowed."""
flow = config_entries.HANDLERS["test_single"]() flow = config_entries.HANDLERS["test_single"]()
@ -306,7 +325,7 @@ async def test_webhook_single_entry_allowed(
async def test_webhook_multiple_entries_allowed( async def test_webhook_multiple_entries_allowed(
hass: HomeAssistant, webhook_flow_conf hass: HomeAssistant, webhook_flow_conf: None
) -> None: ) -> None:
"""Test multiple entries are allowed when specified.""" """Test multiple entries are allowed when specified."""
flow = config_entries.HANDLERS["test_multiple"]() flow = config_entries.HANDLERS["test_multiple"]()
@ -320,7 +339,7 @@ async def test_webhook_multiple_entries_allowed(
async def test_webhook_config_flow_registers_webhook( async def test_webhook_config_flow_registers_webhook(
hass: HomeAssistant, webhook_flow_conf hass: HomeAssistant, webhook_flow_conf: None
) -> None: ) -> None:
"""Test setting up an entry creates a webhook.""" """Test setting up an entry creates a webhook."""
flow = config_entries.HANDLERS["test_single"]() flow = config_entries.HANDLERS["test_single"]()
@ -336,7 +355,9 @@ async def test_webhook_config_flow_registers_webhook(
assert result["data"]["webhook_id"] is not None assert result["data"]["webhook_id"] is not None
async def test_webhook_create_cloudhook(hass: HomeAssistant, webhook_flow_conf) -> None: async def test_webhook_create_cloudhook(
hass: HomeAssistant, webhook_flow_conf: None
) -> None:
"""Test cloudhook will be created if subscribed.""" """Test cloudhook will be created if subscribed."""
assert await setup.async_setup_component(hass, "cloud", {}) assert await setup.async_setup_component(hass, "cloud", {})
@ -390,7 +411,7 @@ async def test_webhook_create_cloudhook(hass: HomeAssistant, webhook_flow_conf)
async def test_webhook_create_cloudhook_aborts_not_connected( async def test_webhook_create_cloudhook_aborts_not_connected(
hass: HomeAssistant, webhook_flow_conf hass: HomeAssistant, webhook_flow_conf: None
) -> None: ) -> None:
"""Test cloudhook aborts if subscribed but not connected.""" """Test cloudhook aborts if subscribed but not connected."""
assert await setup.async_setup_component(hass, "cloud", {}) assert await setup.async_setup_component(hass, "cloud", {})

View file

@ -914,7 +914,10 @@ async def test_entity_description_fallback() -> None:
), ),
) )
async def test_friendly_name( async def test_friendly_name(
hass: HomeAssistant, has_entity_name, entity_name, expected_friendly_name hass: HomeAssistant,
has_entity_name: bool,
entity_name: str | None,
expected_friendly_name: str | None,
) -> None: ) -> None:
"""Test entity_id is influenced by entity name.""" """Test entity_id is influenced by entity name."""

View file

@ -18,6 +18,8 @@ from homeassistant.core import HomeAssistant, ServiceCall, callback
from homeassistant.exceptions import PlatformNotReady from homeassistant.exceptions import PlatformNotReady
from homeassistant.helpers import discovery from homeassistant.helpers import discovery
from homeassistant.helpers.entity_component import EntityComponent, async_update_entity from homeassistant.helpers.entity_component import EntityComponent, async_update_entity
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
@ -90,7 +92,7 @@ async def test_setup_recovers_when_setup_raises(hass: HomeAssistant) -> None:
) )
@patch("homeassistant.setup.async_setup_component", return_value=True) @patch("homeassistant.setup.async_setup_component", return_value=True)
async def test_setup_does_discovery( async def test_setup_does_discovery(
mock_setup_component, mock_setup, hass: HomeAssistant mock_setup_component: AsyncMock, mock_setup: AsyncMock, hass: HomeAssistant
) -> None: ) -> None:
"""Test setup for discovery.""" """Test setup for discovery."""
component = EntityComponent(_LOGGER, DOMAIN, hass) component = EntityComponent(_LOGGER, DOMAIN, hass)
@ -108,10 +110,17 @@ async def test_setup_does_discovery(
@patch("homeassistant.helpers.entity_platform.async_track_time_interval") @patch("homeassistant.helpers.entity_platform.async_track_time_interval")
async def test_set_scan_interval_via_config(mock_track, hass: HomeAssistant) -> None: async def test_set_scan_interval_via_config(
mock_track: Mock, hass: HomeAssistant
) -> None:
"""Test the setting of the scan interval via configuration.""" """Test the setting of the scan interval via configuration."""
def platform_setup(hass, config, add_entities, discovery_info=None): def platform_setup(
hass: HomeAssistant,
config: ConfigType,
add_entities: AddEntitiesCallback,
discovery_info: DiscoveryInfoType | None = None,
) -> None:
"""Test the platform setup.""" """Test the platform setup."""
add_entities([MockEntity(should_poll=True)]) add_entities([MockEntity(should_poll=True)])
@ -131,7 +140,12 @@ async def test_set_scan_interval_via_config(mock_track, hass: HomeAssistant) ->
async def test_set_entity_namespace_via_config(hass: HomeAssistant) -> None: async def test_set_entity_namespace_via_config(hass: HomeAssistant) -> None:
"""Test setting an entity namespace.""" """Test setting an entity namespace."""
def platform_setup(hass, config, add_entities, discovery_info=None): def platform_setup(
hass: HomeAssistant,
config: ConfigType,
add_entities: AddEntitiesCallback,
discovery_info: DiscoveryInfoType | None = None,
) -> None:
"""Test the platform setup.""" """Test the platform setup."""
add_entities([MockEntity(name="beer"), MockEntity(name=None)]) add_entities([MockEntity(name="beer"), MockEntity(name=None)])

View file

@ -23,6 +23,7 @@ from homeassistant.helpers.entity_component import (
DEFAULT_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL,
EntityComponent, EntityComponent,
) )
from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from tests.common import ( from tests.common import (
@ -81,11 +82,11 @@ async def test_polling_updates_entities_with_exception(hass: HomeAssistant) -> N
update_ok = [] update_ok = []
update_err = [] update_err = []
def update_mock(): def update_mock() -> None:
"""Mock normal update.""" """Mock normal update."""
update_ok.append(None) update_ok.append(None)
def update_mock_err(): def update_mock_err() -> None:
"""Mock error update.""" """Mock error update."""
update_err.append(None) update_err.append(None)
raise AssertionError("Fake error update") raise AssertionError("Fake error update")
@ -161,10 +162,17 @@ async def test_update_state_adds_entities_with_update_before_add_false(
@patch("homeassistant.helpers.entity_platform.async_track_time_interval") @patch("homeassistant.helpers.entity_platform.async_track_time_interval")
async def test_set_scan_interval_via_platform(mock_track, hass: HomeAssistant) -> None: async def test_set_scan_interval_via_platform(
mock_track: Mock, hass: HomeAssistant
) -> None:
"""Test the setting of the scan interval via platform.""" """Test the setting of the scan interval via platform."""
def platform_setup(hass, config, add_entities, discovery_info=None): def platform_setup(
hass: HomeAssistant,
config: ConfigType,
add_entities: entity_platform.AddEntitiesCallback,
discovery_info: DiscoveryInfoType | None = None,
) -> None:
"""Test the platform setup.""" """Test the platform setup."""
add_entities([MockEntity(should_poll=True)]) add_entities([MockEntity(should_poll=True)])
@ -192,7 +200,7 @@ async def test_adding_entities_with_generator_and_thread_callback(
""" """
component = EntityComponent(_LOGGER, DOMAIN, hass) component = EntityComponent(_LOGGER, DOMAIN, hass)
def create_entity(number): def create_entity(number: int) -> MockEntity:
"""Create entity helper.""" """Create entity helper."""
entity = MockEntity(unique_id=f"unique{number}") entity = MockEntity(unique_id=f"unique{number}")
entity.entity_id = async_generate_entity_id(DOMAIN + ".{}", "Number", hass=hass) entity.entity_id = async_generate_entity_id(DOMAIN + ".{}", "Number", hass=hass)
@ -402,7 +410,7 @@ async def test_raise_error_on_update(hass: HomeAssistant) -> None:
entity1 = MockEntity(name="test_1") entity1 = MockEntity(name="test_1")
entity2 = MockEntity(name="test_2") entity2 = MockEntity(name="test_2")
def _raise(): def _raise() -> None:
"""Raise an exception.""" """Raise an exception."""
raise AssertionError raise AssertionError
@ -1490,7 +1498,10 @@ class SlowEntity(MockEntity):
), ),
) )
async def test_entity_name_influences_entity_id( async def test_entity_name_influences_entity_id(
hass: HomeAssistant, has_entity_name, entity_name, expected_entity_id hass: HomeAssistant,
has_entity_name: bool,
entity_name: str | None,
expected_entity_id: str,
) -> None: ) -> None:
"""Test entity_id is influenced by entity name.""" """Test entity_id is influenced by entity name."""
registry = er.async_get(hass) registry = er.async_get(hass)

View file

@ -10,6 +10,7 @@ from astral import LocationInfo
import astral.sun import astral.sun
import async_timeout import async_timeout
from freezegun import freeze_time from freezegun import freeze_time
from freezegun.api import FrozenDateTimeFactory
import jinja2 import jinja2
import pytest import pytest
@ -1406,7 +1407,7 @@ async def test_track_template_result_super_template_initially_false(
], ],
) )
async def test_track_template_result_super_template_2( async def test_track_template_result_super_template_2(
hass: HomeAssistant, availability_template hass: HomeAssistant, availability_template: str
) -> None: ) -> None:
"""Test tracking template with super template listening to different entities.""" """Test tracking template with super template listening to different entities."""
specific_runs = [] specific_runs = []
@ -1545,7 +1546,7 @@ async def test_track_template_result_super_template_2(
], ],
) )
async def test_track_template_result_super_template_2_initially_false( async def test_track_template_result_super_template_2_initially_false(
hass: HomeAssistant, availability_template hass: HomeAssistant, availability_template: str
) -> None: ) -> None:
"""Test tracking template with super template listening to different entities.""" """Test tracking template with super template listening to different entities."""
specific_runs = [] specific_runs = []
@ -3898,7 +3899,9 @@ async def test_periodic_task_duplicate_time(hass: HomeAssistant) -> None:
# DST starts early morning March 28th 2021 # DST starts early morning March 28th 2021
@pytest.mark.freeze_time("2021-03-28 01:28:00+01:00") @pytest.mark.freeze_time("2021-03-28 01:28:00+01:00")
async def test_periodic_task_entering_dst(hass: HomeAssistant, freezer) -> None: async def test_periodic_task_entering_dst(
hass: HomeAssistant, freezer: FrozenDateTimeFactory
) -> None:
"""Test periodic task behavior when entering dst.""" """Test periodic task behavior when entering dst."""
hass.config.set_time_zone("Europe/Vienna") hass.config.set_time_zone("Europe/Vienna")
specific_runs = [] specific_runs = []
@ -3944,7 +3947,9 @@ async def test_periodic_task_entering_dst(hass: HomeAssistant, freezer) -> None:
# DST starts early morning March 28th 2021 # DST starts early morning March 28th 2021
@pytest.mark.freeze_time("2021-03-28 01:59:59+01:00") @pytest.mark.freeze_time("2021-03-28 01:59:59+01:00")
async def test_periodic_task_entering_dst_2(hass: HomeAssistant, freezer) -> None: async def test_periodic_task_entering_dst_2(
hass: HomeAssistant, freezer: FrozenDateTimeFactory
) -> None:
"""Test periodic task behavior when entering dst. """Test periodic task behavior when entering dst.
This tests a task firing every second in the range 0..58 (not *:*:59) This tests a task firing every second in the range 0..58 (not *:*:59)
@ -3995,7 +4000,9 @@ async def test_periodic_task_entering_dst_2(hass: HomeAssistant, freezer) -> Non
# DST ends early morning October 31st 2021 # DST ends early morning October 31st 2021
@pytest.mark.freeze_time("2021-10-31 02:28:00+02:00") @pytest.mark.freeze_time("2021-10-31 02:28:00+02:00")
async def test_periodic_task_leaving_dst(hass: HomeAssistant, freezer) -> None: async def test_periodic_task_leaving_dst(
hass: HomeAssistant, freezer: FrozenDateTimeFactory
) -> None:
"""Test periodic task behavior when leaving dst.""" """Test periodic task behavior when leaving dst."""
hass.config.set_time_zone("Europe/Vienna") hass.config.set_time_zone("Europe/Vienna")
specific_runs = [] specific_runs = []
@ -4069,7 +4076,9 @@ async def test_periodic_task_leaving_dst(hass: HomeAssistant, freezer) -> None:
# DST ends early morning October 31st 2021 # DST ends early morning October 31st 2021
@pytest.mark.freeze_time("2021-10-31 02:28:00+02:00") @pytest.mark.freeze_time("2021-10-31 02:28:00+02:00")
async def test_periodic_task_leaving_dst_2(hass: HomeAssistant, freezer) -> None: async def test_periodic_task_leaving_dst_2(
hass: HomeAssistant, freezer: FrozenDateTimeFactory
) -> None:
"""Test periodic task behavior when leaving dst.""" """Test periodic task behavior when leaving dst."""
hass.config.set_time_zone("Europe/Vienna") hass.config.set_time_zone("Europe/Vienna")
specific_runs = [] specific_runs = []