From 2f10f5971788687792b9d9753925ff1fa2225284 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20S=C3=B8rensen?= Date: Mon, 17 May 2021 15:48:41 +0200 Subject: [PATCH] Block custom integrations with missing or invalid version (#49916) --- homeassistant/loader.py | 114 ++++++------------ homeassistant/package_constraints.txt | 2 +- requirements.txt | 2 +- script/hassfest/manifest.py | 27 +++-- setup.py | 2 +- .../alarm_control_panel/test_device_action.py | 10 +- tests/components/analytics/test_analytics.py | 2 +- .../binary_sensor/test_device_condition.py | 6 +- .../binary_sensor/test_device_trigger.py | 8 +- .../components/config/test_config_entries.py | 4 +- tests/components/cover/test_device_action.py | 32 +++-- .../components/cover/test_device_condition.py | 26 ++-- tests/components/cover/test_device_trigger.py | 26 ++-- .../components/device_automation/test_init.py | 14 ++- .../device_sun_light_trigger/test_init.py | 4 +- .../device_tracker/test_entities.py | 2 +- tests/components/device_tracker/test_init.py | 38 ++++-- tests/components/flux/test_switch.py | 56 ++++++--- .../generic_thermostat/test_climate.py | 2 +- tests/components/group/test_light.py | 18 +-- .../components/image_processing/test_init.py | 2 + tests/components/light/test_device_action.py | 2 +- .../components/light/test_device_condition.py | 4 +- tests/components/light/test_device_trigger.py | 6 +- tests/components/light/test_init.py | 40 +++--- tests/components/lock/test_device_action.py | 8 +- tests/components/remote/test_device_action.py | 2 +- .../remote/test_device_condition.py | 4 +- .../components/remote/test_device_trigger.py | 6 +- tests/components/scene/test_init.py | 6 +- .../sensor/test_device_condition.py | 20 +-- .../components/sensor/test_device_trigger.py | 24 ++-- tests/components/switch/test_device_action.py | 2 +- .../switch/test_device_condition.py | 4 +- .../components/switch/test_device_trigger.py | 6 +- tests/components/switch/test_init.py | 6 +- tests/components/trace/test_websocket_api.py | 5 +- tests/components/webhook/test_init.py | 4 +- tests/hassfest/test_version.py | 7 +- tests/helpers/test_translation.py | 23 +--- tests/test_loader.py | 92 ++++---------- .../custom_components/test/manifest.json | 3 +- .../test_embedded/manifest.json | 9 ++ .../test_package/manifest.json | 3 +- 44 files changed, 369 insertions(+), 314 deletions(-) create mode 100644 tests/testing_config/custom_components/test_embedded/manifest.json diff --git a/homeassistant/loader.py b/homeassistant/loader.py index cdf9a831450..abc5e533df5 100644 --- a/homeassistant/loader.py +++ b/homeassistant/loader.py @@ -17,7 +17,11 @@ import sys from types import ModuleType from typing import TYPE_CHECKING, Any, Callable, Dict, TypedDict, TypeVar, cast -from awesomeversion import AwesomeVersion, AwesomeVersionStrategy +from awesomeversion import ( + AwesomeVersion, + AwesomeVersionException, + AwesomeVersionStrategy, +) from homeassistant.generated.dhcp import DHCP from homeassistant.generated.mqtt import MQTT @@ -48,17 +52,7 @@ CUSTOM_WARNING = ( "cause stability problems, be sure to disable it if you " "experience issues with Home Assistant" ) -CUSTOM_WARNING_VERSION_MISSING = ( - "No 'version' key in the manifest file for " - "custom integration '%s'. As of Home Assistant " - "2021.6, this integration will no longer be " - "loaded. Please report this to the maintainer of '%s'" -) -CUSTOM_WARNING_VERSION_TYPE = ( - "'%s' is not a valid version for " - "custom integration '%s'. " - "Please report this to the maintainer of '%s'" -) + _UNDEF = object() # Internal; not helpers.typing.UNDEFINED due to circular dependency MAX_LOAD_CONCURRENTLY = 4 @@ -297,29 +291,14 @@ class Integration: continue return cls( - hass, f"{root_module.__name__}.{domain}", manifest_path.parent, manifest + hass, + f"{root_module.__name__}.{domain}", + manifest_path.parent, + manifest, ) return None - @classmethod - def resolve_legacy(cls, hass: HomeAssistant, domain: str) -> Integration | None: - """Resolve legacy component. - - Will create a stub manifest. - """ - comp = _load_file(hass, domain, _lookup_path(hass)) - - if comp is None: - return None - - return cls( - hass, - comp.__name__, - pathlib.Path(comp.__file__).parent, - manifest_from_legacy_module(domain, comp), - ) - def __init__( self, hass: HomeAssistant, @@ -531,7 +510,8 @@ async def async_get_integration(hass: HomeAssistant, domain: str) -> Integration # components to find the integration. integration = (await async_get_custom_components(hass)).get(domain) if integration is not None: - custom_integration_warning(integration) + validate_custom_integration_version(integration) + _LOGGER.warning(CUSTOM_WARNING, integration.domain) cache[domain] = integration event.set() return integration @@ -541,25 +521,15 @@ async def async_get_integration(hass: HomeAssistant, domain: str) -> Integration integration = await hass.async_add_executor_job( Integration.resolve_from_root, hass, components, domain ) - - if integration is not None: - cache[domain] = integration - event.set() - return integration - - integration = Integration.resolve_legacy(hass, domain) - if integration is not None: - custom_integration_warning(integration) - cache[domain] = integration - else: - # Remove event from cache. - cache.pop(domain) - event.set() if not integration: + # Remove event from cache. + cache.pop(domain) raise IntegrationNotFound(domain) + cache[domain] = integration + return integration @@ -772,33 +742,29 @@ def _lookup_path(hass: HomeAssistant) -> list[str]: return [PACKAGE_CUSTOM_COMPONENTS, PACKAGE_BUILTIN] -def validate_custom_integration_version(version: str) -> bool: - """Validate the version of custom integrations.""" - return AwesomeVersion(version).strategy in ( - AwesomeVersionStrategy.CALVER, - AwesomeVersionStrategy.SEMVER, - AwesomeVersionStrategy.SIMPLEVER, - AwesomeVersionStrategy.BUILDVER, - AwesomeVersionStrategy.PEP440, - ) +def validate_custom_integration_version(integration: Integration) -> None: + """ + Validate the version of custom integrations. - -def custom_integration_warning(integration: Integration) -> None: - """Create logs for custom integrations.""" - if not integration.pkg_path.startswith(PACKAGE_CUSTOM_COMPONENTS): - return None - - _LOGGER.warning(CUSTOM_WARNING, integration.domain) - - if integration.manifest.get("version") is None: - _LOGGER.error( - CUSTOM_WARNING_VERSION_MISSING, integration.domain, integration.domain + Raises IntegrationNotFound when version is missing or not valid + """ + try: + AwesomeVersion( + integration.version, + [ + AwesomeVersionStrategy.CALVER, + AwesomeVersionStrategy.SEMVER, + AwesomeVersionStrategy.SIMPLEVER, + AwesomeVersionStrategy.BUILDVER, + AwesomeVersionStrategy.PEP440, + ], ) - else: - if not validate_custom_integration_version(integration.manifest["version"]): - _LOGGER.error( - CUSTOM_WARNING_VERSION_TYPE, - integration.manifest["version"], - integration.domain, - integration.domain, - ) + except AwesomeVersionException: + _LOGGER.error( + "The custom integration '%s' does not have a " + "valid version key (%s) in the manifest file and was blocked from loading. " + "See https://developers.home-assistant.io/blog/2021/01/29/custom-integration-changes#versions for more details", + integration.domain, + integration.version, + ) + raise IntegrationNotFound(integration.domain) from None diff --git a/homeassistant/package_constraints.txt b/homeassistant/package_constraints.txt index 18421821d2a..d957f9c7cd9 100644 --- a/homeassistant/package_constraints.txt +++ b/homeassistant/package_constraints.txt @@ -7,7 +7,7 @@ astral==2.2 async-upnp-client==0.17.0 async_timeout==3.0.1 attrs==21.2.0 -awesomeversion==21.2.3 +awesomeversion==21.4.0 backports.zoneinfo;python_version<"3.9" bcrypt==3.1.7 certifi>=2020.12.5 diff --git a/requirements.txt b/requirements.txt index 39a30934d4c..4661a23a70f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ aiohttp==3.7.4.post0 astral==2.2 async_timeout==3.0.1 attrs==21.2.0 -awesomeversion==21.2.3 +awesomeversion==21.4.0 backports.zoneinfo;python_version<"3.9" bcrypt==3.1.7 certifi>=2020.12.5 diff --git a/script/hassfest/manifest.py b/script/hassfest/manifest.py index 016e3a0a322..a8e1858cad3 100644 --- a/script/hassfest/manifest.py +++ b/script/hassfest/manifest.py @@ -4,11 +4,14 @@ from __future__ import annotations from pathlib import Path from urllib.parse import urlparse +from awesomeversion import ( + AwesomeVersion, + AwesomeVersionException, + AwesomeVersionStrategy, +) import voluptuous as vol from voluptuous.humanize import humanize_error -from homeassistant.loader import validate_custom_integration_version - from .model import Config, Integration DOCUMENTATION_URL_SCHEMA = "https" @@ -142,10 +145,19 @@ def verify_uppercase(value: str): def verify_version(value: str): """Verify the version.""" - if not validate_custom_integration_version(value): - raise vol.Invalid( - f"'{value}' is not a valid version. This will cause a future version of Home Assistant to block this integration.", + try: + AwesomeVersion( + value, + [ + AwesomeVersionStrategy.CALVER, + AwesomeVersionStrategy.SEMVER, + AwesomeVersionStrategy.SIMPLEVER, + AwesomeVersionStrategy.BUILDVER, + AwesomeVersionStrategy.PEP440, + ], ) + except AwesomeVersionException: + raise vol.Invalid(f"'{value}' is not a valid version.") return value @@ -221,10 +233,7 @@ def validate_version(integration: Integration): Will be removed when the version key is no longer optional for custom integrations. """ if not integration.manifest.get("version"): - integration.add_error( - "manifest", - "No 'version' key in the manifest file. This will cause a future version of Home Assistant to block this integration.", - ) + integration.add_error("manifest", "No 'version' key in the manifest file.") return diff --git a/setup.py b/setup.py index 43a8107743e..d987f4671b4 100755 --- a/setup.py +++ b/setup.py @@ -36,7 +36,7 @@ REQUIRES = [ "astral==2.2", "async_timeout==3.0.1", "attrs==21.2.0", - "awesomeversion==21.2.3", + "awesomeversion==21.4.0", 'backports.zoneinfo;python_version<"3.9"', "bcrypt==3.1.7", "certifi>=2020.12.5", diff --git a/tests/components/alarm_control_panel/test_device_action.py b/tests/components/alarm_control_panel/test_device_action.py index 2b50f83fd8d..a4ec802f3f5 100644 --- a/tests/components/alarm_control_panel/test_device_action.py +++ b/tests/components/alarm_control_panel/test_device_action.py @@ -116,7 +116,9 @@ async def test_get_actions_arm_night_only(hass, device_reg, entity_reg): assert_lists_same(actions, expected_actions) -async def test_get_action_capabilities(hass, device_reg, entity_reg): +async def test_get_action_capabilities( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected capabilities from a sensor trigger.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -154,7 +156,9 @@ async def test_get_action_capabilities(hass, device_reg, entity_reg): assert capabilities == expected_capabilities[action["type"]] -async def test_get_action_capabilities_arm_code(hass, device_reg, entity_reg): +async def test_get_action_capabilities_arm_code( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected capabilities from a sensor trigger.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -198,7 +202,7 @@ async def test_get_action_capabilities_arm_code(hass, device_reg, entity_reg): assert capabilities == expected_capabilities[action["type"]] -async def test_action(hass): +async def test_action(hass, enable_custom_integrations): """Test for turn_on and turn_off actions.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() diff --git a/tests/components/analytics/test_analytics.py b/tests/components/analytics/test_analytics.py index ea871081f02..09f82e37fba 100644 --- a/tests/components/analytics/test_analytics.py +++ b/tests/components/analytics/test_analytics.py @@ -354,7 +354,7 @@ async def test_reusing_uuid(hass, aioclient_mock): assert analytics.uuid == "NOT_MOCK_UUID" -async def test_custom_integrations(hass, aioclient_mock): +async def test_custom_integrations(hass, aioclient_mock, enable_custom_integrations): """Test sending custom integrations.""" aioclient_mock.post(ANALYTICS_ENDPOINT_URL, status=200) analytics = Analytics(hass) diff --git a/tests/components/binary_sensor/test_device_condition.py b/tests/components/binary_sensor/test_device_condition.py index d8c9e1ca894..5d8673825fc 100644 --- a/tests/components/binary_sensor/test_device_condition.py +++ b/tests/components/binary_sensor/test_device_condition.py @@ -41,7 +41,7 @@ def calls(hass): return async_mock_service(hass, "test", "automation") -async def test_get_conditions(hass, device_reg, entity_reg): +async def test_get_conditions(hass, device_reg, entity_reg, enable_custom_integrations): """Test we get the expected conditions from a binary_sensor.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -100,7 +100,7 @@ async def test_get_condition_capabilities(hass, device_reg, entity_reg): assert capabilities == expected_capabilities -async def test_if_state(hass, calls): +async def test_if_state(hass, calls, enable_custom_integrations): """Test for turn_on and turn_off conditions.""" platform = getattr(hass.components, f"test.{DOMAIN}") @@ -173,7 +173,7 @@ async def test_if_state(hass, calls): assert calls[1].data["some"] == "is_off event - test_event2" -async def test_if_fires_on_for_condition(hass, calls): +async def test_if_fires_on_for_condition(hass, calls, enable_custom_integrations): """Test for firing if condition is on with delay.""" point1 = dt_util.utcnow() point2 = point1 + timedelta(seconds=10) diff --git a/tests/components/binary_sensor/test_device_trigger.py b/tests/components/binary_sensor/test_device_trigger.py index 9b50d52b785..0e5cbcc1d70 100644 --- a/tests/components/binary_sensor/test_device_trigger.py +++ b/tests/components/binary_sensor/test_device_trigger.py @@ -41,7 +41,7 @@ def calls(hass): return async_mock_service(hass, "test", "automation") -async def test_get_triggers(hass, device_reg, entity_reg): +async def test_get_triggers(hass, device_reg, entity_reg, enable_custom_integrations): """Test we get the expected triggers from a binary_sensor.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -100,7 +100,7 @@ async def test_get_trigger_capabilities(hass, device_reg, entity_reg): assert capabilities == expected_capabilities -async def test_if_fires_on_state_change(hass, calls): +async def test_if_fires_on_state_change(hass, calls, enable_custom_integrations): """Test for on and off triggers firing.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -184,7 +184,9 @@ async def test_if_fires_on_state_change(hass, calls): ) -async def test_if_fires_on_state_change_with_for(hass, calls): +async def test_if_fires_on_state_change_with_for( + hass, calls, enable_custom_integrations +): """Test for triggers firing with delay.""" platform = getattr(hass.components, f"test.{DOMAIN}") diff --git a/tests/components/config/test_config_entries.py b/tests/components/config/test_config_entries.py index 2763e5912fa..1ad2bd978fc 100644 --- a/tests/components/config/test_config_entries.py +++ b/tests/components/config/test_config_entries.py @@ -287,7 +287,7 @@ async def test_abort(hass, client): } -async def test_create_account(hass, client): +async def test_create_account(hass, client, enable_custom_integrations): """Test a flow that creates an account.""" mock_entity_platform(hass, "config_flow.test", None) @@ -337,7 +337,7 @@ async def test_create_account(hass, client): } -async def test_two_step_flow(hass, client): +async def test_two_step_flow(hass, client, enable_custom_integrations): """Test we can finish a two step flow.""" mock_integration( hass, MockModule("test", async_setup_entry=AsyncMock(return_value=True)) diff --git a/tests/components/cover/test_device_action.py b/tests/components/cover/test_device_action.py index 5cec3d901e1..60bb4e5401b 100644 --- a/tests/components/cover/test_device_action.py +++ b/tests/components/cover/test_device_action.py @@ -31,7 +31,7 @@ def entity_reg(hass): return mock_registry(hass) -async def test_get_actions(hass, device_reg, entity_reg): +async def test_get_actions(hass, device_reg, entity_reg, enable_custom_integrations): """Test we get the expected actions from a cover.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -73,7 +73,9 @@ async def test_get_actions(hass, device_reg, entity_reg): assert_lists_same(actions, expected_actions) -async def test_get_actions_tilt(hass, device_reg, entity_reg): +async def test_get_actions_tilt( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected actions from a cover.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -127,7 +129,9 @@ async def test_get_actions_tilt(hass, device_reg, entity_reg): assert_lists_same(actions, expected_actions) -async def test_get_actions_set_pos(hass, device_reg, entity_reg): +async def test_get_actions_set_pos( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected actions from a cover.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -157,7 +161,9 @@ async def test_get_actions_set_pos(hass, device_reg, entity_reg): assert_lists_same(actions, expected_actions) -async def test_get_actions_set_tilt_pos(hass, device_reg, entity_reg): +async def test_get_actions_set_tilt_pos( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected actions from a cover.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -205,7 +211,9 @@ async def test_get_actions_set_tilt_pos(hass, device_reg, entity_reg): assert_lists_same(actions, expected_actions) -async def test_get_action_capabilities(hass, device_reg, entity_reg): +async def test_get_action_capabilities( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected capabilities from a cover action.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -233,7 +241,9 @@ async def test_get_action_capabilities(hass, device_reg, entity_reg): assert capabilities == {"extra_fields": []} -async def test_get_action_capabilities_set_pos(hass, device_reg, entity_reg): +async def test_get_action_capabilities_set_pos( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected capabilities from a cover action.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -276,7 +286,9 @@ async def test_get_action_capabilities_set_pos(hass, device_reg, entity_reg): assert capabilities == {"extra_fields": []} -async def test_get_action_capabilities_set_tilt_pos(hass, device_reg, entity_reg): +async def test_get_action_capabilities_set_tilt_pos( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected capabilities from a cover action.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -319,7 +331,7 @@ async def test_get_action_capabilities_set_tilt_pos(hass, device_reg, entity_reg assert capabilities == {"extra_fields": []} -async def test_action(hass): +async def test_action(hass, enable_custom_integrations): """Test for cover actions.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -385,7 +397,7 @@ async def test_action(hass): assert len(stop_calls) == 1 -async def test_action_tilt(hass): +async def test_action_tilt(hass, enable_custom_integrations): """Test for cover tilt actions.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -438,7 +450,7 @@ async def test_action_tilt(hass): assert len(close_calls) == 1 -async def test_action_set_position(hass): +async def test_action_set_position(hass, enable_custom_integrations): """Test for cover set position actions.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() diff --git a/tests/components/cover/test_device_condition.py b/tests/components/cover/test_device_condition.py index 04415661515..8e8d92e5a1c 100644 --- a/tests/components/cover/test_device_condition.py +++ b/tests/components/cover/test_device_condition.py @@ -43,7 +43,7 @@ def calls(hass): return async_mock_service(hass, "test", "automation") -async def test_get_conditions(hass, device_reg, entity_reg): +async def test_get_conditions(hass, device_reg, entity_reg, enable_custom_integrations): """Test we get the expected conditions from a cover.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -94,7 +94,9 @@ async def test_get_conditions(hass, device_reg, entity_reg): assert_lists_same(conditions, expected_conditions) -async def test_get_conditions_set_pos(hass, device_reg, entity_reg): +async def test_get_conditions_set_pos( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected conditions from a cover.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -152,7 +154,9 @@ async def test_get_conditions_set_pos(hass, device_reg, entity_reg): assert_lists_same(conditions, expected_conditions) -async def test_get_conditions_set_tilt_pos(hass, device_reg, entity_reg): +async def test_get_conditions_set_tilt_pos( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected conditions from a cover.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -210,7 +214,9 @@ async def test_get_conditions_set_tilt_pos(hass, device_reg, entity_reg): assert_lists_same(conditions, expected_conditions) -async def test_get_condition_capabilities(hass, device_reg, entity_reg): +async def test_get_condition_capabilities( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected capabilities from a cover condition.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -237,7 +243,9 @@ async def test_get_condition_capabilities(hass, device_reg, entity_reg): assert capabilities == {"extra_fields": []} -async def test_get_condition_capabilities_set_pos(hass, device_reg, entity_reg): +async def test_get_condition_capabilities_set_pos( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected capabilities from a cover condition.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -287,7 +295,9 @@ async def test_get_condition_capabilities_set_pos(hass, device_reg, entity_reg): assert capabilities == {"extra_fields": []} -async def test_get_condition_capabilities_set_tilt_pos(hass, device_reg, entity_reg): +async def test_get_condition_capabilities_set_tilt_pos( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected capabilities from a cover condition.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -449,7 +459,7 @@ async def test_if_state(hass, calls): assert calls[3].data["some"] == "is_closing - event - test_event4" -async def test_if_position(hass, calls): +async def test_if_position(hass, calls, enable_custom_integrations): """Test for position conditions.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -553,7 +563,7 @@ async def test_if_position(hass, calls): assert calls[4].data["some"] == "is_pos_gt_45 - event - test_event1" -async def test_if_tilt_position(hass, calls): +async def test_if_tilt_position(hass, calls, enable_custom_integrations): """Test for tilt position conditions.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() diff --git a/tests/components/cover/test_device_trigger.py b/tests/components/cover/test_device_trigger.py index 7ff5a434e5b..8732fcc8020 100644 --- a/tests/components/cover/test_device_trigger.py +++ b/tests/components/cover/test_device_trigger.py @@ -47,7 +47,7 @@ def calls(hass): return async_mock_service(hass, "test", "automation") -async def test_get_triggers(hass, device_reg, entity_reg): +async def test_get_triggers(hass, device_reg, entity_reg, enable_custom_integrations): """Test we get the expected triggers from a cover.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -98,7 +98,9 @@ async def test_get_triggers(hass, device_reg, entity_reg): assert_lists_same(triggers, expected_triggers) -async def test_get_triggers_set_pos(hass, device_reg, entity_reg): +async def test_get_triggers_set_pos( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected triggers from a cover.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -156,7 +158,9 @@ async def test_get_triggers_set_pos(hass, device_reg, entity_reg): assert_lists_same(triggers, expected_triggers) -async def test_get_triggers_set_tilt_pos(hass, device_reg, entity_reg): +async def test_get_triggers_set_tilt_pos( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected triggers from a cover.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -214,7 +218,9 @@ async def test_get_triggers_set_tilt_pos(hass, device_reg, entity_reg): assert_lists_same(triggers, expected_triggers) -async def test_get_trigger_capabilities(hass, device_reg, entity_reg): +async def test_get_trigger_capabilities( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected capabilities from a cover trigger.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -245,7 +251,9 @@ async def test_get_trigger_capabilities(hass, device_reg, entity_reg): } -async def test_get_trigger_capabilities_set_pos(hass, device_reg, entity_reg): +async def test_get_trigger_capabilities_set_pos( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected capabilities from a cover trigger.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -303,7 +311,9 @@ async def test_get_trigger_capabilities_set_pos(hass, device_reg, entity_reg): } -async def test_get_trigger_capabilities_set_tilt_pos(hass, device_reg, entity_reg): +async def test_get_trigger_capabilities_set_tilt_pos( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected capabilities from a cover trigger.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -538,7 +548,7 @@ async def test_if_fires_on_state_change_with_for(hass, calls): ) -async def test_if_fires_on_position(hass, calls): +async def test_if_fires_on_position(hass, calls, enable_custom_integrations): """Test for position triggers.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -665,7 +675,7 @@ async def test_if_fires_on_position(hass, calls): ) -async def test_if_fires_on_tilt_position(hass, calls): +async def test_if_fires_on_tilt_position(hass, calls, enable_custom_integrations): """Test for tilt position triggers.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() diff --git a/tests/components/device_automation/test_init.py b/tests/components/device_automation/test_init.py index a2f042bcd73..7c16d067eff 100644 --- a/tests/components/device_automation/test_init.py +++ b/tests/components/device_automation/test_init.py @@ -490,7 +490,9 @@ async def test_automation_with_non_existing_integration(hass, caplog): assert "Integration 'beer' not found" in caplog.text -async def test_automation_with_integration_without_device_action(hass, caplog): +async def test_automation_with_integration_without_device_action( + hass, caplog, enable_custom_integrations +): """Test automation with integration without device action support.""" assert await async_setup_component( hass, @@ -509,7 +511,9 @@ async def test_automation_with_integration_without_device_action(hass, caplog): ) -async def test_automation_with_integration_without_device_condition(hass, caplog): +async def test_automation_with_integration_without_device_condition( + hass, caplog, enable_custom_integrations +): """Test automation with integration without device condition support.""" assert await async_setup_component( hass, @@ -534,7 +538,9 @@ async def test_automation_with_integration_without_device_condition(hass, caplog ) -async def test_automation_with_integration_without_device_trigger(hass, caplog): +async def test_automation_with_integration_without_device_trigger( + hass, caplog, enable_custom_integrations +): """Test automation with integration without device trigger support.""" assert await async_setup_component( hass, @@ -615,7 +621,7 @@ def calls(hass): return async_mock_service(hass, "test", "automation") -async def test_automation_with_sub_condition(hass, calls): +async def test_automation_with_sub_condition(hass, calls, enable_custom_integrations): """Test automation with device condition under and/or conditions.""" DOMAIN = "light" platform = getattr(hass.components, f"test.{DOMAIN}") diff --git a/tests/components/device_sun_light_trigger/test_init.py b/tests/components/device_sun_light_trigger/test_init.py index 7d478e7d8d1..f7d835427a1 100644 --- a/tests/components/device_sun_light_trigger/test_init.py +++ b/tests/components/device_sun_light_trigger/test_init.py @@ -29,7 +29,7 @@ from tests.common import async_fire_time_changed @pytest.fixture -def scanner(hass): +def scanner(hass, enable_custom_integrations): """Initialize components.""" scanner = getattr(hass.components, "test.device_tracker").get_scanner(None, None) @@ -100,7 +100,7 @@ async def test_lights_on_when_sun_sets(hass, scanner): ) -async def test_lights_turn_off_when_everyone_leaves(hass): +async def test_lights_turn_off_when_everyone_leaves(hass, enable_custom_integrations): """Test lights turn off when everyone leaves the house.""" assert await async_setup_component( hass, "light", {light.DOMAIN: {CONF_PLATFORM: "test"}} diff --git a/tests/components/device_tracker/test_entities.py b/tests/components/device_tracker/test_entities.py index 1bc058a1449..88e1dccdb34 100644 --- a/tests/components/device_tracker/test_entities.py +++ b/tests/components/device_tracker/test_entities.py @@ -18,7 +18,7 @@ from homeassistant.const import ATTR_BATTERY_LEVEL, STATE_HOME, STATE_NOT_HOME from tests.common import MockConfigEntry -async def test_scanner_entity_device_tracker(hass): +async def test_scanner_entity_device_tracker(hass, enable_custom_integrations): """Test ScannerEntity based device tracker.""" config_entry = MockConfigEntry(domain="test") config_entry.add_to_hass(hass) diff --git a/tests/components/device_tracker/test_init.py b/tests/components/device_tracker/test_init.py index 6155ed7d1db..bf72cb34119 100644 --- a/tests/components/device_tracker/test_init.py +++ b/tests/components/device_tracker/test_init.py @@ -94,7 +94,7 @@ async def test_reading_broken_yaml_config(hass): assert res[0].dev_id == "my_device" -async def test_reading_yaml_config(hass, yaml_devices): +async def test_reading_yaml_config(hass, yaml_devices, enable_custom_integrations): """Test the rendering of the YAML configuration.""" dev_id = "test" device = legacy.Device( @@ -161,7 +161,7 @@ async def test_duplicate_mac_dev_id(mock_warning, hass): assert "Duplicate device IDs" in args[0], "Duplicate device IDs warning expected" -async def test_setup_without_yaml_file(hass): +async def test_setup_without_yaml_file(hass, enable_custom_integrations): """Test with no YAML file.""" with assert_setup_component(1, device_tracker.DOMAIN): assert await async_setup_component(hass, device_tracker.DOMAIN, TEST_PLATFORM) @@ -224,7 +224,7 @@ async def test_discover_platform(mock_demo_setup_scanner, mock_see, hass): ) -async def test_update_stale(hass, mock_device_tracker_conf): +async def test_update_stale(hass, mock_device_tracker_conf, enable_custom_integrations): """Test stalled update.""" scanner = getattr(hass.components, "test.device_tracker").SCANNER @@ -265,7 +265,9 @@ async def test_update_stale(hass, mock_device_tracker_conf): assert hass.states.get("device_tracker.dev1").state == STATE_NOT_HOME -async def test_entity_attributes(hass, mock_device_tracker_conf): +async def test_entity_attributes( + hass, mock_device_tracker_conf, enable_custom_integrations +): """Test the entity attributes.""" devices = mock_device_tracker_conf dev_id = "test_entity" @@ -297,7 +299,7 @@ async def test_entity_attributes(hass, mock_device_tracker_conf): @patch("homeassistant.components.device_tracker.legacy." "DeviceTracker.async_see") -async def test_see_service(mock_see, hass): +async def test_see_service(mock_see, hass, enable_custom_integrations): """Test the see service with a unicode dev_id and NO MAC.""" with assert_setup_component(1, device_tracker.DOMAIN): assert await async_setup_component(hass, device_tracker.DOMAIN, TEST_PLATFORM) @@ -324,7 +326,9 @@ async def test_see_service(mock_see, hass): assert mock_see.call_args == call(**params) -async def test_see_service_guard_config_entry(hass, mock_device_tracker_conf): +async def test_see_service_guard_config_entry( + hass, mock_device_tracker_conf, enable_custom_integrations +): """Test the guard if the device is registered in the entity registry.""" mock_entry = Mock() dev_id = "test" @@ -340,7 +344,9 @@ async def test_see_service_guard_config_entry(hass, mock_device_tracker_conf): assert not devices -async def test_new_device_event_fired(hass, mock_device_tracker_conf): +async def test_new_device_event_fired( + hass, mock_device_tracker_conf, enable_custom_integrations +): """Test that the device tracker will fire an event.""" with assert_setup_component(1, device_tracker.DOMAIN): assert await async_setup_component(hass, device_tracker.DOMAIN, TEST_PLATFORM) @@ -370,7 +376,9 @@ async def test_new_device_event_fired(hass, mock_device_tracker_conf): } -async def test_duplicate_yaml_keys(hass, mock_device_tracker_conf): +async def test_duplicate_yaml_keys( + hass, mock_device_tracker_conf, enable_custom_integrations +): """Test that the device tracker will not generate invalid YAML.""" devices = mock_device_tracker_conf with assert_setup_component(1, device_tracker.DOMAIN): @@ -385,7 +393,9 @@ async def test_duplicate_yaml_keys(hass, mock_device_tracker_conf): assert devices[0].dev_id != devices[1].dev_id -async def test_invalid_dev_id(hass, mock_device_tracker_conf): +async def test_invalid_dev_id( + hass, mock_device_tracker_conf, enable_custom_integrations +): """Test that the device tracker will not allow invalid dev ids.""" devices = mock_device_tracker_conf with assert_setup_component(1, device_tracker.DOMAIN): @@ -397,7 +407,7 @@ async def test_invalid_dev_id(hass, mock_device_tracker_conf): assert not devices -async def test_see_state(hass, yaml_devices): +async def test_see_state(hass, yaml_devices, enable_custom_integrations): """Test device tracker see records state correctly.""" assert await async_setup_component(hass, device_tracker.DOMAIN, TEST_PLATFORM) @@ -433,7 +443,9 @@ async def test_see_state(hass, yaml_devices): assert attrs["number"] == 1 -async def test_see_passive_zone_state(hass, mock_device_tracker_conf): +async def test_see_passive_zone_state( + hass, mock_device_tracker_conf, enable_custom_integrations +): """Test that the device tracker sets gps for passive trackers.""" now = dt_util.utcnow() @@ -562,7 +574,9 @@ async def test_bad_platform(hass): assert f"{device_tracker.DOMAIN}.bad_platform" not in hass.config.components -async def test_adding_unknown_device_to_config(mock_device_tracker_conf, hass): +async def test_adding_unknown_device_to_config( + mock_device_tracker_conf, hass, enable_custom_integrations +): """Test the adding of unknown devices to configuration file.""" scanner = getattr(hass.components, "test.device_tracker").SCANNER scanner.reset() diff --git a/tests/components/flux/test_switch.py b/tests/components/flux/test_switch.py index 7438b690ab5..e331a788e9c 100644 --- a/tests/components/flux/test_switch.py +++ b/tests/components/flux/test_switch.py @@ -127,7 +127,9 @@ async def test_invalid_config_no_lights(hass): await hass.async_block_till_done() -async def test_flux_when_switch_is_off(hass, legacy_patchable_time): +async def test_flux_when_switch_is_off( + hass, legacy_patchable_time, enable_custom_integrations +): """Test the flux switch when it is off.""" platform = getattr(hass.components, "test.light") platform.init() @@ -178,7 +180,9 @@ async def test_flux_when_switch_is_off(hass, legacy_patchable_time): assert not turn_on_calls -async def test_flux_before_sunrise(hass, legacy_patchable_time): +async def test_flux_before_sunrise( + hass, legacy_patchable_time, enable_custom_integrations +): """Test the flux switch before sunrise.""" platform = getattr(hass.components, "test.light") platform.init() @@ -237,7 +241,9 @@ async def test_flux_before_sunrise(hass, legacy_patchable_time): assert call.data[light.ATTR_XY_COLOR] == [0.606, 0.379] -async def test_flux_before_sunrise_known_location(hass, legacy_patchable_time): +async def test_flux_before_sunrise_known_location( + hass, legacy_patchable_time, enable_custom_integrations +): """Test the flux switch before sunrise.""" platform = getattr(hass.components, "test.light") platform.init() @@ -296,7 +302,9 @@ async def test_flux_before_sunrise_known_location(hass, legacy_patchable_time): # pylint: disable=invalid-name -async def test_flux_after_sunrise_before_sunset(hass, legacy_patchable_time): +async def test_flux_after_sunrise_before_sunset( + hass, legacy_patchable_time, enable_custom_integrations +): """Test the flux switch after sunrise and before sunset.""" platform = getattr(hass.components, "test.light") platform.init() @@ -355,7 +363,9 @@ async def test_flux_after_sunrise_before_sunset(hass, legacy_patchable_time): # pylint: disable=invalid-name -async def test_flux_after_sunset_before_stop(hass, legacy_patchable_time): +async def test_flux_after_sunset_before_stop( + hass, legacy_patchable_time, enable_custom_integrations +): """Test the flux switch after sunset and before stop.""" platform = getattr(hass.components, "test.light") platform.init() @@ -415,7 +425,9 @@ async def test_flux_after_sunset_before_stop(hass, legacy_patchable_time): # pylint: disable=invalid-name -async def test_flux_after_stop_before_sunrise(hass, legacy_patchable_time): +async def test_flux_after_stop_before_sunrise( + hass, legacy_patchable_time, enable_custom_integrations +): """Test the flux switch after stop and before sunrise.""" platform = getattr(hass.components, "test.light") platform.init() @@ -474,7 +486,9 @@ async def test_flux_after_stop_before_sunrise(hass, legacy_patchable_time): # pylint: disable=invalid-name -async def test_flux_with_custom_start_stop_times(hass, legacy_patchable_time): +async def test_flux_with_custom_start_stop_times( + hass, legacy_patchable_time, enable_custom_integrations +): """Test the flux with custom start and stop times.""" platform = getattr(hass.components, "test.light") platform.init() @@ -534,7 +548,9 @@ async def test_flux_with_custom_start_stop_times(hass, legacy_patchable_time): assert call.data[light.ATTR_XY_COLOR] == [0.504, 0.385] -async def test_flux_before_sunrise_stop_next_day(hass, legacy_patchable_time): +async def test_flux_before_sunrise_stop_next_day( + hass, legacy_patchable_time, enable_custom_integrations +): """Test the flux switch before sunrise. This test has the stop_time on the next day (after midnight). @@ -598,7 +614,7 @@ async def test_flux_before_sunrise_stop_next_day(hass, legacy_patchable_time): # pylint: disable=invalid-name async def test_flux_after_sunrise_before_sunset_stop_next_day( - hass, legacy_patchable_time + hass, legacy_patchable_time, enable_custom_integrations ): """ Test the flux switch after sunrise and before sunset. @@ -665,7 +681,7 @@ async def test_flux_after_sunrise_before_sunset_stop_next_day( # pylint: disable=invalid-name @pytest.mark.parametrize("x", [0, 1]) async def test_flux_after_sunset_before_midnight_stop_next_day( - hass, legacy_patchable_time, x + hass, legacy_patchable_time, x, enable_custom_integrations ): """Test the flux switch after sunset and before stop. @@ -730,7 +746,7 @@ async def test_flux_after_sunset_before_midnight_stop_next_day( # pylint: disable=invalid-name async def test_flux_after_sunset_after_midnight_stop_next_day( - hass, legacy_patchable_time + hass, legacy_patchable_time, enable_custom_integrations ): """Test the flux switch after sunset and before stop. @@ -795,7 +811,7 @@ async def test_flux_after_sunset_after_midnight_stop_next_day( # pylint: disable=invalid-name async def test_flux_after_stop_before_sunrise_stop_next_day( - hass, legacy_patchable_time + hass, legacy_patchable_time, enable_custom_integrations ): """Test the flux switch after stop and before sunrise. @@ -859,7 +875,9 @@ async def test_flux_after_stop_before_sunrise_stop_next_day( # pylint: disable=invalid-name -async def test_flux_with_custom_colortemps(hass, legacy_patchable_time): +async def test_flux_with_custom_colortemps( + hass, legacy_patchable_time, enable_custom_integrations +): """Test the flux with custom start and stop colortemps.""" platform = getattr(hass.components, "test.light") platform.init() @@ -921,7 +939,9 @@ async def test_flux_with_custom_colortemps(hass, legacy_patchable_time): # pylint: disable=invalid-name -async def test_flux_with_custom_brightness(hass, legacy_patchable_time): +async def test_flux_with_custom_brightness( + hass, legacy_patchable_time, enable_custom_integrations +): """Test the flux with custom start and stop colortemps.""" platform = getattr(hass.components, "test.light") platform.init() @@ -981,7 +1001,9 @@ async def test_flux_with_custom_brightness(hass, legacy_patchable_time): assert call.data[light.ATTR_XY_COLOR] == [0.506, 0.385] -async def test_flux_with_multiple_lights(hass, legacy_patchable_time): +async def test_flux_with_multiple_lights( + hass, legacy_patchable_time, enable_custom_integrations +): """Test the flux switch with multiple light entities.""" platform = getattr(hass.components, "test.light") platform.init() @@ -1064,7 +1086,7 @@ async def test_flux_with_multiple_lights(hass, legacy_patchable_time): assert call.data[light.ATTR_XY_COLOR] == [0.46, 0.376] -async def test_flux_with_mired(hass, legacy_patchable_time): +async def test_flux_with_mired(hass, legacy_patchable_time, enable_custom_integrations): """Test the flux switch´s mode mired.""" platform = getattr(hass.components, "test.light") platform.init() @@ -1121,7 +1143,7 @@ async def test_flux_with_mired(hass, legacy_patchable_time): assert call.data[light.ATTR_COLOR_TEMP] == 269 -async def test_flux_with_rgb(hass, legacy_patchable_time): +async def test_flux_with_rgb(hass, legacy_patchable_time, enable_custom_integrations): """Test the flux switch´s mode rgb.""" platform = getattr(hass.components, "test.light") platform.init() diff --git a/tests/components/generic_thermostat/test_climate.py b/tests/components/generic_thermostat/test_climate.py index a7f42fffbd8..4b9fbca41e2 100644 --- a/tests/components/generic_thermostat/test_climate.py +++ b/tests/components/generic_thermostat/test_climate.py @@ -125,7 +125,7 @@ async def test_heater_input_boolean(hass, setup_comp_1): assert hass.states.get(heater_switch).state == STATE_ON -async def test_heater_switch(hass, setup_comp_1): +async def test_heater_switch(hass, setup_comp_1, enable_custom_integrations): """Test heater switching test switch.""" platform = getattr(hass.components, "test.switch") platform.init() diff --git a/tests/components/group/test_light.py b/tests/components/group/test_light.py index b409786dc07..14489450610 100644 --- a/tests/components/group/test_light.py +++ b/tests/components/group/test_light.py @@ -114,7 +114,7 @@ async def test_state_reporting(hass): assert hass.states.get("light.light_group").state == STATE_UNAVAILABLE -async def test_brightness(hass): +async def test_brightness(hass, enable_custom_integrations): """Test brightness reporting.""" platform = getattr(hass.components, "test.light") platform.init(empty=True) @@ -183,7 +183,7 @@ async def test_brightness(hass): assert state.attributes[ATTR_SUPPORTED_COLOR_MODES] == ["brightness"] -async def test_color_hs(hass): +async def test_color_hs(hass, enable_custom_integrations): """Test hs color reporting.""" platform = getattr(hass.components, "test.light") platform.init(empty=True) @@ -251,7 +251,7 @@ async def test_color_hs(hass): assert state.attributes[ATTR_SUPPORTED_FEATURES] == 0 -async def test_color_rgbw(hass): +async def test_color_rgbw(hass, enable_custom_integrations): """Test rgbw color reporting.""" platform = getattr(hass.components, "test.light") platform.init(empty=True) @@ -322,7 +322,7 @@ async def test_color_rgbw(hass): assert state.attributes[ATTR_SUPPORTED_FEATURES] == 0 -async def test_color_rgbww(hass): +async def test_color_rgbww(hass, enable_custom_integrations): """Test rgbww color reporting.""" platform = getattr(hass.components, "test.light") platform.init(empty=True) @@ -434,7 +434,7 @@ async def test_white_value(hass): assert state.attributes[ATTR_WHITE_VALUE] == 100 -async def test_color_temp(hass): +async def test_color_temp(hass, enable_custom_integrations): """Test color temp reporting.""" platform = getattr(hass.components, "test.light") platform.init(empty=True) @@ -501,7 +501,7 @@ async def test_color_temp(hass): assert state.attributes[ATTR_SUPPORTED_COLOR_MODES] == ["color_temp"] -async def test_emulated_color_temp_group(hass): +async def test_emulated_color_temp_group(hass, enable_custom_integrations): """Test emulated color temperature in a group.""" platform = getattr(hass.components, "test.light") platform.init(empty=True) @@ -564,7 +564,7 @@ async def test_emulated_color_temp_group(hass): assert state.attributes[ATTR_HS_COLOR] == (27.001, 19.243) -async def test_min_max_mireds(hass): +async def test_min_max_mireds(hass, enable_custom_integrations): """Test min/max mireds reporting. min/max mireds is reported both when light is on and off @@ -739,7 +739,7 @@ async def test_effect(hass): assert state.attributes[ATTR_EFFECT] == "Random" -async def test_supported_color_modes(hass): +async def test_supported_color_modes(hass, enable_custom_integrations): """Test supported_color_modes reporting.""" platform = getattr(hass.components, "test.light") platform.init(empty=True) @@ -784,7 +784,7 @@ async def test_supported_color_modes(hass): } -async def test_color_mode(hass): +async def test_color_mode(hass, enable_custom_integrations): """Test color_mode reporting.""" platform = getattr(hass.components, "test.light") platform.init(empty=True) diff --git a/tests/components/image_processing/test_init.py b/tests/components/image_processing/test_init.py index 3e6a3cc960f..55c76273ad7 100644 --- a/tests/components/image_processing/test_init.py +++ b/tests/components/image_processing/test_init.py @@ -6,6 +6,7 @@ import homeassistant.components.image_processing as ip from homeassistant.const import ATTR_ENTITY_PICTURE from homeassistant.core import callback from homeassistant.exceptions import HomeAssistantError +from homeassistant.loader import DATA_CUSTOM_COMPONENTS from homeassistant.setup import setup_component from tests.common import ( @@ -50,6 +51,7 @@ class TestImageProcessing: def setup_method(self): """Set up things to be run when tests are started.""" self.hass = get_test_home_assistant() + self.hass.data.pop(DATA_CUSTOM_COMPONENTS) setup_component( self.hass, diff --git a/tests/components/light/test_device_action.py b/tests/components/light/test_device_action.py index 440cae8f0fc..5628861b72d 100644 --- a/tests/components/light/test_device_action.py +++ b/tests/components/light/test_device_action.py @@ -256,7 +256,7 @@ async def test_get_action_capabilities_features( assert capabilities == expected -async def test_action(hass, calls): +async def test_action(hass, calls, enable_custom_integrations): """Test for turn_on and turn_off actions.""" platform = getattr(hass.components, f"test.{DOMAIN}") diff --git a/tests/components/light/test_device_condition.py b/tests/components/light/test_device_condition.py index d529c82bfa5..b174a312cd9 100644 --- a/tests/components/light/test_device_condition.py +++ b/tests/components/light/test_device_condition.py @@ -91,7 +91,7 @@ async def test_get_condition_capabilities(hass, device_reg, entity_reg): assert capabilities == expected_capabilities -async def test_if_state(hass, calls): +async def test_if_state(hass, calls, enable_custom_integrations): """Test for turn_on and turn_off conditions.""" platform = getattr(hass.components, f"test.{DOMAIN}") @@ -165,7 +165,7 @@ async def test_if_state(hass, calls): assert calls[1].data["some"] == "is_off event - test_event2" -async def test_if_fires_on_for_condition(hass, calls): +async def test_if_fires_on_for_condition(hass, calls, enable_custom_integrations): """Test for firing if condition is on with delay.""" point1 = dt_util.utcnow() point2 = point1 + timedelta(seconds=10) diff --git a/tests/components/light/test_device_trigger.py b/tests/components/light/test_device_trigger.py index 1c9f6cf1454..3217eb461b0 100644 --- a/tests/components/light/test_device_trigger.py +++ b/tests/components/light/test_device_trigger.py @@ -91,7 +91,7 @@ async def test_get_trigger_capabilities(hass, device_reg, entity_reg): assert capabilities == expected_capabilities -async def test_if_fires_on_state_change(hass, calls): +async def test_if_fires_on_state_change(hass, calls, enable_custom_integrations): """Test for turn_on and turn_off triggers firing.""" platform = getattr(hass.components, f"test.{DOMAIN}") @@ -178,7 +178,9 @@ async def test_if_fires_on_state_change(hass, calls): ) -async def test_if_fires_on_state_change_with_for(hass, calls): +async def test_if_fires_on_state_change_with_for( + hass, calls, enable_custom_integrations +): """Test for triggers firing with delay.""" platform = getattr(hass.components, f"test.{DOMAIN}") diff --git a/tests/components/light/test_init.py b/tests/components/light/test_init.py index 432959b67e4..71764eec186 100644 --- a/tests/components/light/test_init.py +++ b/tests/components/light/test_init.py @@ -106,7 +106,7 @@ async def test_methods(hass): assert call.data[light.ATTR_TRANSITION] == "transition_val" -async def test_services(hass, mock_light_profiles): +async def test_services(hass, mock_light_profiles, enable_custom_integrations): """Test the provided services.""" platform = getattr(hass.components, "test.light") @@ -491,7 +491,12 @@ async def test_services(hass, mock_light_profiles): ), ) async def test_light_profiles( - hass, mock_light_profiles, profile_name, expected_data, last_call + hass, + mock_light_profiles, + profile_name, + expected_data, + last_call, + enable_custom_integrations, ): """Test light profiles.""" platform = getattr(hass.components, "test.light") @@ -535,7 +540,9 @@ async def test_light_profiles( assert data == expected_data -async def test_default_profiles_group(hass, mock_light_profiles): +async def test_default_profiles_group( + hass, mock_light_profiles, enable_custom_integrations +): """Test default turn-on light profile for all lights.""" platform = getattr(hass.components, "test.light") platform.init() @@ -635,6 +642,7 @@ async def test_default_profiles_light( hass, mock_light_profiles, extra_call_params, + enable_custom_integrations, expected_params_state_was_off, expected_params_state_was_on, ): @@ -694,7 +702,7 @@ async def test_default_profiles_light( } -async def test_light_context(hass, hass_admin_user): +async def test_light_context(hass, hass_admin_user, enable_custom_integrations): """Test that light context works.""" platform = getattr(hass.components, "test.light") platform.init() @@ -718,7 +726,7 @@ async def test_light_context(hass, hass_admin_user): assert state2.context.user_id == hass_admin_user.id -async def test_light_turn_on_auth(hass, hass_admin_user): +async def test_light_turn_on_auth(hass, hass_admin_user, enable_custom_integrations): """Test that light context works.""" platform = getattr(hass.components, "test.light") platform.init() @@ -740,7 +748,7 @@ async def test_light_turn_on_auth(hass, hass_admin_user): ) -async def test_light_brightness_step(hass): +async def test_light_brightness_step(hass, enable_custom_integrations): """Test that light context works.""" platform = getattr(hass.components, "test.light") platform.init(empty=True) @@ -802,7 +810,7 @@ async def test_light_brightness_step(hass): assert entity0.state == "off" # 126 - 126; brightness is 0, light should turn off -async def test_light_brightness_pct_conversion(hass): +async def test_light_brightness_pct_conversion(hass, enable_custom_integrations): """Test that light brightness percent conversion.""" platform = getattr(hass.components, "test.light") platform.init() @@ -967,7 +975,9 @@ invalid_no_brightness_no_color_no_transition,,, @pytest.mark.parametrize("light_state", (STATE_ON, STATE_OFF)) -async def test_light_backwards_compatibility_supported_color_modes(hass, light_state): +async def test_light_backwards_compatibility_supported_color_modes( + hass, light_state, enable_custom_integrations +): """Test supported_color_modes if not implemented by the entity.""" platform = getattr(hass.components, "test.light") platform.init(empty=True) @@ -1072,7 +1082,9 @@ async def test_light_backwards_compatibility_supported_color_modes(hass, light_s assert state.attributes["color_mode"] == light.COLOR_MODE_UNKNOWN -async def test_light_backwards_compatibility_color_mode(hass): +async def test_light_backwards_compatibility_color_mode( + hass, enable_custom_integrations +): """Test color_mode if not implemented by the entity.""" platform = getattr(hass.components, "test.light") platform.init(empty=True) @@ -1148,7 +1160,7 @@ async def test_light_backwards_compatibility_color_mode(hass): assert state.attributes["color_mode"] == light.COLOR_MODE_HS -async def test_light_service_call_rgbw(hass): +async def test_light_service_call_rgbw(hass, enable_custom_integrations): """Test backwards compatibility for rgbw functionality in service calls.""" platform = getattr(hass.components, "test.light") platform.init(empty=True) @@ -1193,7 +1205,7 @@ async def test_light_service_call_rgbw(hass): assert data == {"brightness": 255, "rgbw_color": (10, 20, 30, 40)} -async def test_light_state_rgbw(hass): +async def test_light_state_rgbw(hass, enable_custom_integrations): """Test rgbw color conversion in state updates.""" platform = getattr(hass.components, "test.light") platform.init(empty=True) @@ -1251,7 +1263,7 @@ async def test_light_state_rgbw(hass): } -async def test_light_state_rgbww(hass): +async def test_light_state_rgbww(hass, enable_custom_integrations): """Test rgbww color conversion in state updates.""" platform = getattr(hass.components, "test.light") platform.init(empty=True) @@ -1284,7 +1296,7 @@ async def test_light_state_rgbww(hass): } -async def test_light_service_call_color_conversion(hass): +async def test_light_service_call_color_conversion(hass, enable_custom_integrations): """Test color conversion in service calls.""" platform = getattr(hass.components, "test.light") platform.init(empty=True) @@ -1552,7 +1564,7 @@ async def test_light_service_call_color_conversion(hass): assert data == {"brightness": 128, "rgbww_color": (0, 75, 140, 255, 255)} -async def test_light_state_color_conversion(hass): +async def test_light_state_color_conversion(hass, enable_custom_integrations): """Test color conversion in state updates.""" platform = getattr(hass.components, "test.light") platform.init(empty=True) diff --git a/tests/components/lock/test_device_action.py b/tests/components/lock/test_device_action.py index 7d484ae96aa..a84555bdd42 100644 --- a/tests/components/lock/test_device_action.py +++ b/tests/components/lock/test_device_action.py @@ -30,7 +30,9 @@ def entity_reg(hass): return mock_registry(hass) -async def test_get_actions_support_open(hass, device_reg, entity_reg): +async def test_get_actions_support_open( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected actions from a lock which supports open.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -74,7 +76,9 @@ async def test_get_actions_support_open(hass, device_reg, entity_reg): assert_lists_same(actions, expected_actions) -async def test_get_actions_not_support_open(hass, device_reg, entity_reg): +async def test_get_actions_not_support_open( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected actions from a lock which doesn't support open.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() diff --git a/tests/components/remote/test_device_action.py b/tests/components/remote/test_device_action.py index 7cd5a632982..1193764da3a 100644 --- a/tests/components/remote/test_device_action.py +++ b/tests/components/remote/test_device_action.py @@ -70,7 +70,7 @@ async def test_get_actions(hass, device_reg, entity_reg): assert actions == expected_actions -async def test_action(hass, calls): +async def test_action(hass, calls, enable_custom_integrations): """Test for turn_on and turn_off actions.""" platform = getattr(hass.components, f"test.{DOMAIN}") diff --git a/tests/components/remote/test_device_condition.py b/tests/components/remote/test_device_condition.py index 12cf0e05493..6f3c0e1c0a2 100644 --- a/tests/components/remote/test_device_condition.py +++ b/tests/components/remote/test_device_condition.py @@ -91,7 +91,7 @@ async def test_get_condition_capabilities(hass, device_reg, entity_reg): assert capabilities == expected_capabilities -async def test_if_state(hass, calls): +async def test_if_state(hass, calls, enable_custom_integrations): """Test for turn_on and turn_off conditions.""" platform = getattr(hass.components, f"test.{DOMAIN}") @@ -165,7 +165,7 @@ async def test_if_state(hass, calls): assert calls[1].data["some"] == "is_off event - test_event2" -async def test_if_fires_on_for_condition(hass, calls): +async def test_if_fires_on_for_condition(hass, calls, enable_custom_integrations): """Test for firing if condition is on with delay.""" point1 = dt_util.utcnow() point2 = point1 + timedelta(seconds=10) diff --git a/tests/components/remote/test_device_trigger.py b/tests/components/remote/test_device_trigger.py index 616c356936c..3afa731cf59 100644 --- a/tests/components/remote/test_device_trigger.py +++ b/tests/components/remote/test_device_trigger.py @@ -91,7 +91,7 @@ async def test_get_trigger_capabilities(hass, device_reg, entity_reg): assert capabilities == expected_capabilities -async def test_if_fires_on_state_change(hass, calls): +async def test_if_fires_on_state_change(hass, calls, enable_custom_integrations): """Test for turn_on and turn_off triggers firing.""" platform = getattr(hass.components, f"test.{DOMAIN}") @@ -176,7 +176,9 @@ async def test_if_fires_on_state_change(hass, calls): ) -async def test_if_fires_on_state_change_with_for(hass, calls): +async def test_if_fires_on_state_change_with_for( + hass, calls, enable_custom_integrations +): """Test for triggers firing with delay.""" platform = getattr(hass.components, f"test.{DOMAIN}") diff --git a/tests/components/scene/test_init.py b/tests/components/scene/test_init.py index a3d50d0214f..8263b9c3006 100644 --- a/tests/components/scene/test_init.py +++ b/tests/components/scene/test_init.py @@ -19,7 +19,7 @@ def entities(hass): yield platform.ENTITIES[0:2] -async def test_config_yaml_alias_anchor(hass, entities): +async def test_config_yaml_alias_anchor(hass, entities, enable_custom_integrations): """Test the usage of YAML aliases and anchors. The following test scene configuration is equivalent to: @@ -64,7 +64,7 @@ async def test_config_yaml_alias_anchor(hass, entities): assert light_2.last_call("turn_on")[1].get("brightness") == 100 -async def test_config_yaml_bool(hass, entities): +async def test_config_yaml_bool(hass, entities, enable_custom_integrations): """Test parsing of booleans in yaml config.""" light_1, light_2 = await setup_lights(hass, entities) @@ -91,7 +91,7 @@ async def test_config_yaml_bool(hass, entities): assert light_2.last_call("turn_on")[1].get("brightness") == 100 -async def test_activate_scene(hass, entities): +async def test_activate_scene(hass, entities, enable_custom_integrations): """Test active scene.""" light_1, light_2 = await setup_lights(hass, entities) diff --git a/tests/components/sensor/test_device_condition.py b/tests/components/sensor/test_device_condition.py index 2de95d44eb1..6cad21c5bde 100644 --- a/tests/components/sensor/test_device_condition.py +++ b/tests/components/sensor/test_device_condition.py @@ -41,7 +41,7 @@ def calls(hass): return async_mock_service(hass, "test", "automation") -async def test_get_conditions(hass, device_reg, entity_reg): +async def test_get_conditions(hass, device_reg, entity_reg, enable_custom_integrations): """Test we get the expected conditions from a sensor.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -80,7 +80,9 @@ async def test_get_conditions(hass, device_reg, entity_reg): assert conditions == expected_conditions -async def test_get_condition_capabilities(hass, device_reg, entity_reg): +async def test_get_condition_capabilities( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected capabilities from a sensor condition.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -126,7 +128,9 @@ async def test_get_condition_capabilities(hass, device_reg, entity_reg): assert capabilities == expected_capabilities -async def test_get_condition_capabilities_none(hass, device_reg, entity_reg): +async def test_get_condition_capabilities_none( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected capabilities from a sensor condition.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -162,7 +166,9 @@ async def test_get_condition_capabilities_none(hass, device_reg, entity_reg): assert capabilities == expected_capabilities -async def test_if_state_not_above_below(hass, calls, caplog): +async def test_if_state_not_above_below( + hass, calls, caplog, enable_custom_integrations +): """Test for bad value conditions.""" platform = getattr(hass.components, f"test.{DOMAIN}") @@ -196,7 +202,7 @@ async def test_if_state_not_above_below(hass, calls, caplog): assert "must contain at least one of below, above" in caplog.text -async def test_if_state_above(hass, calls): +async def test_if_state_above(hass, calls, enable_custom_integrations): """Test for value conditions.""" platform = getattr(hass.components, f"test.{DOMAIN}") @@ -254,7 +260,7 @@ async def test_if_state_above(hass, calls): assert calls[0].data["some"] == "event - test_event1" -async def test_if_state_below(hass, calls): +async def test_if_state_below(hass, calls, enable_custom_integrations): """Test for value conditions.""" platform = getattr(hass.components, f"test.{DOMAIN}") @@ -312,7 +318,7 @@ async def test_if_state_below(hass, calls): assert calls[0].data["some"] == "event - test_event1" -async def test_if_state_between(hass, calls): +async def test_if_state_between(hass, calls, enable_custom_integrations): """Test for value conditions.""" platform = getattr(hass.components, f"test.{DOMAIN}") diff --git a/tests/components/sensor/test_device_trigger.py b/tests/components/sensor/test_device_trigger.py index 4c65eff34ab..9da93510523 100644 --- a/tests/components/sensor/test_device_trigger.py +++ b/tests/components/sensor/test_device_trigger.py @@ -45,7 +45,7 @@ def calls(hass): return async_mock_service(hass, "test", "automation") -async def test_get_triggers(hass, device_reg, entity_reg): +async def test_get_triggers(hass, device_reg, entity_reg, enable_custom_integrations): """Test we get the expected triggers from a sensor.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -85,7 +85,9 @@ async def test_get_triggers(hass, device_reg, entity_reg): assert triggers == expected_triggers -async def test_get_trigger_capabilities(hass, device_reg, entity_reg): +async def test_get_trigger_capabilities( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected capabilities from a sensor trigger.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -132,7 +134,9 @@ async def test_get_trigger_capabilities(hass, device_reg, entity_reg): assert capabilities == expected_capabilities -async def test_get_trigger_capabilities_none(hass, device_reg, entity_reg): +async def test_get_trigger_capabilities_none( + hass, device_reg, entity_reg, enable_custom_integrations +): """Test we get the expected capabilities from a sensor trigger.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -168,7 +172,9 @@ async def test_get_trigger_capabilities_none(hass, device_reg, entity_reg): assert capabilities == expected_capabilities -async def test_if_fires_not_on_above_below(hass, calls, caplog): +async def test_if_fires_not_on_above_below( + hass, calls, caplog, enable_custom_integrations +): """Test for value triggers firing.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -198,7 +204,7 @@ async def test_if_fires_not_on_above_below(hass, calls, caplog): assert "must contain at least one of below, above" in caplog.text -async def test_if_fires_on_state_above(hass, calls): +async def test_if_fires_on_state_above(hass, calls, enable_custom_integrations): """Test for value triggers firing.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -256,7 +262,7 @@ async def test_if_fires_on_state_above(hass, calls): ) -async def test_if_fires_on_state_below(hass, calls): +async def test_if_fires_on_state_below(hass, calls, enable_custom_integrations): """Test for value triggers firing.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -314,7 +320,7 @@ async def test_if_fires_on_state_below(hass, calls): ) -async def test_if_fires_on_state_between(hass, calls): +async def test_if_fires_on_state_between(hass, calls, enable_custom_integrations): """Test for value triggers firing.""" platform = getattr(hass.components, f"test.{DOMAIN}") platform.init() @@ -384,7 +390,9 @@ async def test_if_fires_on_state_between(hass, calls): ) -async def test_if_fires_on_state_change_with_for(hass, calls): +async def test_if_fires_on_state_change_with_for( + hass, calls, enable_custom_integrations +): """Test for triggers firing with delay.""" platform = getattr(hass.components, f"test.{DOMAIN}") diff --git a/tests/components/switch/test_device_action.py b/tests/components/switch/test_device_action.py index 2a98cd2fad4..9f8d821e74b 100644 --- a/tests/components/switch/test_device_action.py +++ b/tests/components/switch/test_device_action.py @@ -70,7 +70,7 @@ async def test_get_actions(hass, device_reg, entity_reg): assert actions == expected_actions -async def test_action(hass, calls): +async def test_action(hass, calls, enable_custom_integrations): """Test for turn_on and turn_off actions.""" platform = getattr(hass.components, f"test.{DOMAIN}") diff --git a/tests/components/switch/test_device_condition.py b/tests/components/switch/test_device_condition.py index 9273610dee9..e2102976f8d 100644 --- a/tests/components/switch/test_device_condition.py +++ b/tests/components/switch/test_device_condition.py @@ -91,7 +91,7 @@ async def test_get_condition_capabilities(hass, device_reg, entity_reg): assert capabilities == expected_capabilities -async def test_if_state(hass, calls): +async def test_if_state(hass, calls, enable_custom_integrations): """Test for turn_on and turn_off conditions.""" platform = getattr(hass.components, f"test.{DOMAIN}") @@ -165,7 +165,7 @@ async def test_if_state(hass, calls): assert calls[1].data["some"] == "is_off event - test_event2" -async def test_if_fires_on_for_condition(hass, calls): +async def test_if_fires_on_for_condition(hass, calls, enable_custom_integrations): """Test for firing if condition is on with delay.""" point1 = dt_util.utcnow() point2 = point1 + timedelta(seconds=10) diff --git a/tests/components/switch/test_device_trigger.py b/tests/components/switch/test_device_trigger.py index d958dd21911..e871bf6f645 100644 --- a/tests/components/switch/test_device_trigger.py +++ b/tests/components/switch/test_device_trigger.py @@ -91,7 +91,7 @@ async def test_get_trigger_capabilities(hass, device_reg, entity_reg): assert capabilities == expected_capabilities -async def test_if_fires_on_state_change(hass, calls): +async def test_if_fires_on_state_change(hass, calls, enable_custom_integrations): """Test for turn_on and turn_off triggers firing.""" platform = getattr(hass.components, f"test.{DOMAIN}") @@ -176,7 +176,9 @@ async def test_if_fires_on_state_change(hass, calls): ) -async def test_if_fires_on_state_change_with_for(hass, calls): +async def test_if_fires_on_state_change_with_for( + hass, calls, enable_custom_integrations +): """Test for triggers firing with delay.""" platform = getattr(hass.components, f"test.{DOMAIN}") diff --git a/tests/components/switch/test_init.py b/tests/components/switch/test_init.py index cf2933282ea..44302ec311b 100644 --- a/tests/components/switch/test_init.py +++ b/tests/components/switch/test_init.py @@ -17,7 +17,7 @@ def entities(hass): yield platform.ENTITIES -async def test_methods(hass, entities): +async def test_methods(hass, entities, enable_custom_integrations): """Test is_on, turn_on, turn_off methods.""" switch_1, switch_2, switch_3 = entities assert await async_setup_component( @@ -49,7 +49,9 @@ async def test_methods(hass, entities): assert switch.is_on(hass, switch_3.entity_id) -async def test_switch_context(hass, entities, hass_admin_user): +async def test_switch_context( + hass, entities, hass_admin_user, enable_custom_integrations +): """Test that switch context works.""" assert await async_setup_component(hass, "switch", {"switch": {"platform": "test"}}) diff --git a/tests/components/trace/test_websocket_api.py b/tests/components/trace/test_websocket_api.py index 4c6ff88fa1b..2660fa86879 100644 --- a/tests/components/trace/test_websocket_api.py +++ b/tests/components/trace/test_websocket_api.py @@ -108,6 +108,7 @@ async def test_get_trace( trigger, context_key, condition_results, + enable_custom_integrations, ): """Test tracing a script or automation.""" id = 1 @@ -1227,7 +1228,9 @@ async def test_script_mode_2(hass, hass_ws_client, script_mode, script_execution assert trace["script_execution"] == "finished" -async def test_trace_blueprint_automation(hass, hass_ws_client): +async def test_trace_blueprint_automation( + hass, hass_ws_client, enable_custom_integrations +): """Test trace of blueprint automation.""" id = 1 diff --git a/tests/components/webhook/test_init.py b/tests/components/webhook/test_init.py index 44c45c1e9d8..63d4a6e134d 100644 --- a/tests/components/webhook/test_init.py +++ b/tests/components/webhook/test_init.py @@ -141,7 +141,9 @@ async def test_webhook_head(hass, mock_client): assert hooks[0][2].method == "HEAD" -async def test_listing_webhook(hass, hass_ws_client, hass_access_token): +async def test_listing_webhook( + hass, hass_ws_client, hass_access_token, enable_custom_integrations +): """Test unregistering a webhook.""" assert await async_setup_component(hass, "webhook", {}) client = await hass_ws_client(hass, hass_access_token) diff --git a/tests/hassfest/test_version.py b/tests/hassfest/test_version.py index f99ee911a69..7f12fb83fd7 100644 --- a/tests/hassfest/test_version.py +++ b/tests/hassfest/test_version.py @@ -25,10 +25,9 @@ def integration(): def test_validate_version_no_key(integration: Integration): """Test validate version with no key.""" validate_version(integration) - assert ( - "No 'version' key in the manifest file. This will cause a future version of Home Assistant to block this integration." - in [x.error for x in integration.errors] - ) + assert "No 'version' key in the manifest file." in [ + x.error for x in integration.errors + ] def test_validate_custom_integration_manifest(integration: Integration): diff --git a/tests/helpers/test_translation.py b/tests/helpers/test_translation.py index 8f555914682..3a08c423d76 100644 --- a/tests/helpers/test_translation.py +++ b/tests/helpers/test_translation.py @@ -33,25 +33,18 @@ def test_recursive_flatten(): } -async def test_component_translation_path(hass): +async def test_component_translation_path(hass, enable_custom_integrations): """Test the component translation file function.""" assert await async_setup_component( hass, "switch", {"switch": [{"platform": "test"}, {"platform": "test_embedded"}]}, ) - assert await async_setup_component(hass, "test_standalone", {"test_standalone"}) assert await async_setup_component(hass, "test_package", {"test_package"}) - ( - int_test, - int_test_embedded, - int_test_standalone, - int_test_package, - ) = await asyncio.gather( + (int_test, int_test_embedded, int_test_package,) = await asyncio.gather( async_get_integration(hass, "test"), async_get_integration(hass, "test_embedded"), - async_get_integration(hass, "test_standalone"), async_get_integration(hass, "test_package"), ) @@ -71,13 +64,6 @@ async def test_component_translation_path(hass): ) ) - assert ( - translation.component_translation_path( - "test_standalone", "en", int_test_standalone - ) - is None - ) - assert path.normpath( translation.component_translation_path("test_package", "en", int_test_package) ) == path.normpath( @@ -105,7 +91,7 @@ def test_load_translations_files(hass): } -async def test_get_translations(hass, mock_config_flows): +async def test_get_translations(hass, mock_config_flows, enable_custom_integrations): """Test the get translations helper.""" translations = await translation.async_get_translations(hass, "en", "state") assert translations == {} @@ -376,9 +362,8 @@ async def test_caching(hass): assert len(mock_build.mock_calls) > 1 -async def test_custom_component_translations(hass): +async def test_custom_component_translations(hass, enable_custom_integrations): """Test getting translation from custom components.""" - hass.config.components.add("test_standalone") hass.config.components.add("test_embedded") hass.config.components.add("test_package") assert await translation.async_get_translations(hass, "en", "state") == {} diff --git a/tests/test_loader.py b/tests/test_loader.py index 8acc8a7de4f..c2c176b62ab 100644 --- a/tests/test_loader.py +++ b/tests/test_loader.py @@ -1,5 +1,5 @@ """Test to verify that we can load components.""" -from unittest.mock import ANY, patch +from unittest.mock import patch import pytest @@ -97,18 +97,13 @@ async def test_helpers_wrapper(hass): assert result == ["hello"] -async def test_custom_component_name(hass): +async def test_custom_component_name(hass, enable_custom_integrations): """Test the name attribute of custom components.""" - integration = await loader.async_get_integration(hass, "test_standalone") - int_comp = integration.get_component() - assert int_comp.__name__ == "custom_components.test_standalone" - assert int_comp.__package__ == "custom_components" - - comp = hass.components.test_standalone - assert comp.__name__ == "custom_components.test_standalone" - assert comp.__package__ == "custom_components" + with pytest.raises(loader.IntegrationNotFound): + await loader.async_get_integration(hass, "test_standalone") integration = await loader.async_get_integration(hass, "test_package") + int_comp = integration.get_component() assert int_comp.__name__ == "custom_components.test_package" assert int_comp.__package__ == "custom_components.test_package" @@ -128,67 +123,39 @@ async def test_custom_component_name(hass): assert TEST == 5 -async def test_log_warning_custom_component(hass, caplog): +async def test_log_warning_custom_component(hass, caplog, enable_custom_integrations): """Test that we log a warning when loading a custom component.""" - await loader.async_get_integration(hass, "test_standalone") - assert "You are using a custom integration test_standalone" in caplog.text + + await loader.async_get_integration(hass, "test_package") + assert "You are using a custom integration test_package" in caplog.text await loader.async_get_integration(hass, "test") assert "You are using a custom integration test " in caplog.text -async def test_custom_integration_missing_version(hass, caplog): - """Test that we log a warning when custom integrations are missing a version.""" - test_integration_1 = loader.Integration( - hass, "custom_components.test1", None, {"domain": "test1"} - ) - test_integration_2 = loader.Integration( - hass, - "custom_components.test2", - None, - loader.manifest_from_legacy_module("test2", "custom_components.test2"), - ) - - with patch("homeassistant.loader.async_get_custom_components") as mock_get: - mock_get.return_value = { - "test1": test_integration_1, - "test2": test_integration_2, - } - - await loader.async_get_integration(hass, "test1") - assert ( - "No 'version' key in the manifest file for custom integration 'test1'." - in caplog.text - ) - - await loader.async_get_integration(hass, "test2") - assert ( - "No 'version' key in the manifest file for custom integration 'test2'." - in caplog.text - ) - - -async def test_no_version_warning_for_none_custom_integrations(hass, caplog): - """Test that we do not log a warning when core integrations are missing a version.""" - await loader.async_get_integration(hass, "hue") - assert ( - "No 'version' key in the manifest file for custom integration 'hue'." - not in caplog.text - ) - - async def test_custom_integration_version_not_valid(hass, caplog): """Test that we log a warning when custom integrations have a invalid version.""" - test_integration = loader.Integration( - hass, "custom_components.test", None, {"domain": "test", "version": "test"} + test_integration1 = loader.Integration( + hass, "custom_components.test", None, {"domain": "test1", "version": "test"} + ) + test_integration2 = loader.Integration( + hass, "custom_components.test", None, {"domain": "test2"} ) with patch("homeassistant.loader.async_get_custom_components") as mock_get: - mock_get.return_value = {"test": test_integration} + mock_get.return_value = {"test1": test_integration1, "test2": test_integration2} - await loader.async_get_integration(hass, "test") + with pytest.raises(loader.IntegrationNotFound): + await loader.async_get_integration(hass, "test1") assert ( - "'test' is not a valid version for custom integration 'test'." + "The custom integration 'test1' does not have a valid version key (test) in the manifest file and was blocked from loading." + in caplog.text + ) + + with pytest.raises(loader.IntegrationNotFound): + await loader.async_get_integration(hass, "test2") + assert ( + "The custom integration 'test2' does not have a valid version key (None) in the manifest file and was blocked from loading." in caplog.text ) @@ -200,7 +167,7 @@ async def test_get_integration(hass): assert hue_light == integration.get_platform("light") -async def test_get_integration_legacy(hass): +async def test_get_integration_legacy(hass, enable_custom_integrations): """Test resolving integration.""" integration = await loader.async_get_integration(hass, "test_embedded") assert integration.get_component().DOMAIN == "test_embedded" @@ -319,13 +286,6 @@ async def test_integrations_only_once(hass): assert await int_1 is await int_2 -async def test_get_custom_components_internal(hass): - """Test that we can a list of custom components.""" - # pylint: disable=protected-access - integrations = await loader._async_get_custom_components(hass) - assert integrations == {"test": ANY, "test_package": ANY} - - def _get_test_integration(hass, name, config_flow): """Return a generated test integration.""" return loader.Integration( diff --git a/tests/testing_config/custom_components/test/manifest.json b/tests/testing_config/custom_components/test/manifest.json index 70882fece05..125136e70b5 100644 --- a/tests/testing_config/custom_components/test/manifest.json +++ b/tests/testing_config/custom_components/test/manifest.json @@ -4,5 +4,6 @@ "documentation": "http://example.com", "requirements": [], "dependencies": [], - "codeowners": [] + "codeowners": [], + "version": "1.2.3" } diff --git a/tests/testing_config/custom_components/test_embedded/manifest.json b/tests/testing_config/custom_components/test_embedded/manifest.json new file mode 100644 index 00000000000..72206594d0c --- /dev/null +++ b/tests/testing_config/custom_components/test_embedded/manifest.json @@ -0,0 +1,9 @@ +{ + "domain": "test_embedded", + "name": "Test Embedded", + "documentation": "http://test-package.io", + "requirements": [], + "dependencies": [], + "codeowners": [], + "version": "1.2.3" +} diff --git a/tests/testing_config/custom_components/test_package/manifest.json b/tests/testing_config/custom_components/test_package/manifest.json index 320d2768d27..660d0aef1a5 100644 --- a/tests/testing_config/custom_components/test_package/manifest.json +++ b/tests/testing_config/custom_components/test_package/manifest.json @@ -4,5 +4,6 @@ "documentation": "http://test-package.io", "requirements": [], "dependencies": [], - "codeowners": [] + "codeowners": [], + "version": "1.2.3" }