Add type hints to core tests (part 2) (#88492)

This commit is contained in:
epenet 2023-02-21 09:27:13 +01:00 committed by GitHub
parent a102883eff
commit a51cc75f03
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 383 additions and 216 deletions

View file

@ -41,7 +41,7 @@ def manager(hass, store, provider):
return AuthManager(hass, store, {(provider.type, provider.id): provider}, {}) return AuthManager(hass, store, {(provider.type, provider.id): provider}, {})
async def test_create_new_credential(manager, provider): async def test_create_new_credential(manager, provider) -> None:
"""Test that we create a new credential.""" """Test that we create a new credential."""
credentials = await provider.async_get_or_create_credentials( credentials = await provider.async_get_or_create_credentials(
{"username": "good-user", "password": "good-pass"} {"username": "good-user", "password": "good-pass"}
@ -52,7 +52,7 @@ async def test_create_new_credential(manager, provider):
assert user.is_active assert user.is_active
async def test_match_existing_credentials(store, provider): async def test_match_existing_credentials(store, provider) -> None:
"""See if we match existing users.""" """See if we match existing users."""
existing = auth_models.Credentials( existing = auth_models.Credentials(
id=uuid.uuid4(), id=uuid.uuid4(),
@ -68,24 +68,24 @@ async def test_match_existing_credentials(store, provider):
assert credentials is existing assert credentials is existing
async def test_invalid_username(provider): async def test_invalid_username(provider) -> None:
"""Test we raise if incorrect user specified.""" """Test we raise if incorrect user specified."""
with pytest.raises(command_line.InvalidAuthError): with pytest.raises(command_line.InvalidAuthError):
await provider.async_validate_login("bad-user", "good-pass") await provider.async_validate_login("bad-user", "good-pass")
async def test_invalid_password(provider): async def test_invalid_password(provider) -> None:
"""Test we raise if incorrect password specified.""" """Test we raise if incorrect password specified."""
with pytest.raises(command_line.InvalidAuthError): with pytest.raises(command_line.InvalidAuthError):
await provider.async_validate_login("good-user", "bad-pass") await provider.async_validate_login("good-user", "bad-pass")
async def test_good_auth(provider): async def test_good_auth(provider) -> None:
"""Test nothing is raised with good credentials.""" """Test nothing is raised with good credentials."""
await provider.async_validate_login("good-user", "good-pass") await provider.async_validate_login("good-user", "good-pass")
async def test_good_auth_with_meta(manager, provider): async def test_good_auth_with_meta(manager, provider) -> None:
"""Test metadata is added upon successful authentication.""" """Test metadata is added upon successful authentication."""
provider.config[command_line.CONF_ARGS] = ["--with-meta"] provider.config[command_line.CONF_ARGS] = ["--with-meta"]
provider.config[command_line.CONF_META] = True provider.config[command_line.CONF_META] = True
@ -102,7 +102,7 @@ async def test_good_auth_with_meta(manager, provider):
assert user.is_active assert user.is_active
async def test_utf_8_username_password(provider): async def test_utf_8_username_password(provider) -> None:
"""Test that we create a new credential.""" """Test that we create a new credential."""
credentials = await provider.async_get_or_create_credentials( credentials = await provider.async_get_or_create_credentials(
{"username": "ßßß", "password": "äöü"} {"username": "ßßß", "password": "äöü"}
@ -110,7 +110,7 @@ async def test_utf_8_username_password(provider):
assert credentials.is_new is True assert credentials.is_new is True
async def test_login_flow_validates(provider): async def test_login_flow_validates(provider) -> None:
"""Test login flow.""" """Test login flow."""
flow = await provider.async_login_flow({}) flow = await provider.async_login_flow({})
result = await flow.async_step_init() result = await flow.async_step_init()
@ -129,7 +129,7 @@ async def test_login_flow_validates(provider):
assert result["data"]["username"] == "good-user" assert result["data"]["username"] == "good-user"
async def test_strip_username(provider): async def test_strip_username(provider) -> None:
"""Test authentication works with username with whitespace around.""" """Test authentication works with username with whitespace around."""
flow = await provider.async_login_flow({}) flow = await provider.async_login_flow({})
result = await flow.async_step_init( result = await flow.async_step_init(

View file

@ -31,7 +31,7 @@ def legacy_data(hass):
return data return data
async def test_validating_password_invalid_user(data, hass): async def test_validating_password_invalid_user(data, hass: HomeAssistant) -> None:
"""Test validating an invalid user.""" """Test validating an invalid user."""
with pytest.raises(hass_auth.InvalidAuth): with pytest.raises(hass_auth.InvalidAuth):
data.validate_login("non-existing", "pw") data.validate_login("non-existing", "pw")
@ -46,7 +46,7 @@ async def test_not_allow_set_id() -> None:
) )
async def test_new_users_populate_values(hass, data): async def test_new_users_populate_values(hass: HomeAssistant, data) -> None:
"""Test that we populate data for new users.""" """Test that we populate data for new users."""
data.add_auth("hello", "test-pass") data.add_auth("hello", "test-pass")
await data.async_save() await data.async_save()
@ -59,7 +59,7 @@ async def test_new_users_populate_values(hass, data):
assert user.is_active assert user.is_active
async def test_changing_password_raises_invalid_user(data, hass): async def test_changing_password_raises_invalid_user(data, hass: HomeAssistant) -> None:
"""Test that changing password raises invalid user.""" """Test that changing password raises invalid user."""
with pytest.raises(hass_auth.InvalidUser): with pytest.raises(hass_auth.InvalidUser):
data.change_password("non-existing", "pw") data.change_password("non-existing", "pw")
@ -68,20 +68,20 @@ async def test_changing_password_raises_invalid_user(data, hass):
# Modern mode # Modern mode
async def test_adding_user(data, hass): async def test_adding_user(data, hass: HomeAssistant) -> None:
"""Test adding a user.""" """Test adding a user."""
data.add_auth("test-user", "test-pass") data.add_auth("test-user", "test-pass")
data.validate_login(" test-user ", "test-pass") data.validate_login(" test-user ", "test-pass")
async def test_adding_user_duplicate_username(data, hass): async def test_adding_user_duplicate_username(data, hass: HomeAssistant) -> None:
"""Test adding a user with duplicate username.""" """Test adding a user with duplicate username."""
data.add_auth("test-user", "test-pass") data.add_auth("test-user", "test-pass")
with pytest.raises(hass_auth.InvalidUser): with pytest.raises(hass_auth.InvalidUser):
data.add_auth("TEST-user ", "other-pass") data.add_auth("TEST-user ", "other-pass")
async def test_validating_password_invalid_password(data, hass): async def test_validating_password_invalid_password(data, hass: HomeAssistant) -> None:
"""Test validating an invalid password.""" """Test validating an invalid password."""
data.add_auth("test-user", "test-pass") data.add_auth("test-user", "test-pass")
@ -95,7 +95,7 @@ async def test_validating_password_invalid_password(data, hass):
data.validate_login("test-user", "Test-pass") data.validate_login("test-user", "Test-pass")
async def test_changing_password(data, hass): async def test_changing_password(data, hass: HomeAssistant) -> None:
"""Test adding a user.""" """Test adding a user."""
data.add_auth("test-user", "test-pass") data.add_auth("test-user", "test-pass")
data.change_password("TEST-USER ", "new-pass") data.change_password("TEST-USER ", "new-pass")
@ -106,7 +106,7 @@ async def test_changing_password(data, hass):
data.validate_login("test-UsEr", "new-pass") data.validate_login("test-UsEr", "new-pass")
async def test_login_flow_validates(data, hass): async def test_login_flow_validates(data, hass: HomeAssistant) -> None:
"""Test login flow.""" """Test login flow."""
data.add_auth("test-user", "test-pass") data.add_auth("test-user", "test-pass")
await data.async_save() await data.async_save()
@ -137,7 +137,7 @@ async def test_login_flow_validates(data, hass):
assert result["data"]["username"] == "test-USER" assert result["data"]["username"] == "test-USER"
async def test_saving_loading(data, hass): async def test_saving_loading(data, hass: HomeAssistant) -> None:
"""Test saving and loading JSON.""" """Test saving and loading JSON."""
data.add_auth("test-user", "test-pass") data.add_auth("test-user", "test-pass")
data.add_auth("second-user", "second-pass") data.add_auth("second-user", "second-pass")
@ -149,7 +149,7 @@ async def test_saving_loading(data, hass):
data.validate_login("second-user ", "second-pass") data.validate_login("second-user ", "second-pass")
async def test_get_or_create_credentials(hass, data): async def test_get_or_create_credentials(hass: HomeAssistant, data) -> None:
"""Test that we can get or create credentials.""" """Test that we can get or create credentials."""
manager = await auth_manager_from_config(hass, [{"type": "homeassistant"}], []) manager = await auth_manager_from_config(hass, [{"type": "homeassistant"}], [])
provider = manager.auth_providers[0] provider = manager.auth_providers[0]
@ -165,13 +165,15 @@ async def test_get_or_create_credentials(hass, data):
# Legacy mode # Legacy mode
async def test_legacy_adding_user(legacy_data, hass): async def test_legacy_adding_user(legacy_data, hass: HomeAssistant) -> None:
"""Test in legacy mode adding a user.""" """Test in legacy mode adding a user."""
legacy_data.add_auth("test-user", "test-pass") legacy_data.add_auth("test-user", "test-pass")
legacy_data.validate_login("test-user", "test-pass") legacy_data.validate_login("test-user", "test-pass")
async def test_legacy_adding_user_duplicate_username(legacy_data, hass): async def test_legacy_adding_user_duplicate_username(
legacy_data, hass: HomeAssistant
) -> None:
"""Test in legacy mode adding a user with duplicate username.""" """Test in legacy mode adding a user with duplicate username."""
legacy_data.add_auth("test-user", "test-pass") legacy_data.add_auth("test-user", "test-pass")
with pytest.raises(hass_auth.InvalidUser): with pytest.raises(hass_auth.InvalidUser):
@ -181,7 +183,9 @@ async def test_legacy_adding_user_duplicate_username(legacy_data, hass):
legacy_data.add_auth("Test-user", "test-pass") legacy_data.add_auth("Test-user", "test-pass")
async def test_legacy_validating_password_invalid_password(legacy_data, hass): async def test_legacy_validating_password_invalid_password(
legacy_data, hass: HomeAssistant
) -> None:
"""Test in legacy mode validating an invalid password.""" """Test in legacy mode validating an invalid password."""
legacy_data.add_auth("test-user", "test-pass") legacy_data.add_auth("test-user", "test-pass")
@ -189,7 +193,7 @@ async def test_legacy_validating_password_invalid_password(legacy_data, hass):
legacy_data.validate_login("test-user", "invalid-pass") legacy_data.validate_login("test-user", "invalid-pass")
async def test_legacy_changing_password(legacy_data, hass): async def test_legacy_changing_password(legacy_data, hass: HomeAssistant) -> None:
"""Test in legacy mode adding a user.""" """Test in legacy mode adding a user."""
user = "test-user" user = "test-user"
legacy_data.add_auth(user, "test-pass") legacy_data.add_auth(user, "test-pass")
@ -201,13 +205,15 @@ async def test_legacy_changing_password(legacy_data, hass):
legacy_data.validate_login(user, "new-pass") legacy_data.validate_login(user, "new-pass")
async def test_legacy_changing_password_raises_invalid_user(legacy_data, hass): async def test_legacy_changing_password_raises_invalid_user(
legacy_data, hass: HomeAssistant
) -> None:
"""Test in legacy mode that we initialize an empty config.""" """Test in legacy mode that we initialize an empty config."""
with pytest.raises(hass_auth.InvalidUser): with pytest.raises(hass_auth.InvalidUser):
legacy_data.change_password("non-existing", "pw") legacy_data.change_password("non-existing", "pw")
async def test_legacy_login_flow_validates(legacy_data, hass): async def test_legacy_login_flow_validates(legacy_data, hass: HomeAssistant) -> None:
"""Test in legacy mode login flow.""" """Test in legacy mode login flow."""
legacy_data.add_auth("test-user", "test-pass") legacy_data.add_auth("test-user", "test-pass")
await legacy_data.async_save() await legacy_data.async_save()
@ -238,7 +244,7 @@ async def test_legacy_login_flow_validates(legacy_data, hass):
assert result["data"]["username"] == "test-user" assert result["data"]["username"] == "test-user"
async def test_legacy_saving_loading(legacy_data, hass): async def test_legacy_saving_loading(legacy_data, hass: HomeAssistant) -> None:
"""Test in legacy mode saving and loading JSON.""" """Test in legacy mode saving and loading JSON."""
legacy_data.add_auth("test-user", "test-pass") legacy_data.add_auth("test-user", "test-pass")
legacy_data.add_auth("second-user", "second-pass") legacy_data.add_auth("second-user", "second-pass")
@ -254,7 +260,9 @@ async def test_legacy_saving_loading(legacy_data, hass):
legacy_data.validate_login("test-user ", "test-pass") legacy_data.validate_login("test-user ", "test-pass")
async def test_legacy_get_or_create_credentials(hass, legacy_data): async def test_legacy_get_or_create_credentials(
hass: HomeAssistant, legacy_data
) -> None:
"""Test in legacy mode that we can get or create credentials.""" """Test in legacy mode that we can get or create credentials."""
manager = await auth_manager_from_config(hass, [{"type": "homeassistant"}], []) manager = await auth_manager_from_config(hass, [{"type": "homeassistant"}], [])
provider = manager.auth_providers[0] provider = manager.auth_providers[0]

View file

@ -40,7 +40,7 @@ def manager(hass, store, provider):
return AuthManager(hass, store, {(provider.type, provider.id): provider}, {}) return AuthManager(hass, store, {(provider.type, provider.id): provider}, {})
async def test_create_new_credential(manager, provider): async def test_create_new_credential(manager, provider) -> None:
"""Test that we create a new credential.""" """Test that we create a new credential."""
credentials = await provider.async_get_or_create_credentials( credentials = await provider.async_get_or_create_credentials(
{"username": "user-test", "password": "password-test"} {"username": "user-test", "password": "password-test"}
@ -52,7 +52,7 @@ async def test_create_new_credential(manager, provider):
assert user.is_active assert user.is_active
async def test_match_existing_credentials(store, provider): async def test_match_existing_credentials(store, provider) -> None:
"""See if we match existing users.""" """See if we match existing users."""
existing = auth_models.Credentials( existing = auth_models.Credentials(
id=uuid.uuid4(), id=uuid.uuid4(),
@ -68,19 +68,19 @@ async def test_match_existing_credentials(store, provider):
assert credentials is existing assert credentials is existing
async def test_verify_username(provider): async def test_verify_username(provider) -> None:
"""Test we raise if incorrect user specified.""" """Test we raise if incorrect user specified."""
with pytest.raises(insecure_example.InvalidAuthError): with pytest.raises(insecure_example.InvalidAuthError):
await provider.async_validate_login("non-existing-user", "password-test") await provider.async_validate_login("non-existing-user", "password-test")
async def test_verify_password(provider): async def test_verify_password(provider) -> None:
"""Test we raise if incorrect user specified.""" """Test we raise if incorrect user specified."""
with pytest.raises(insecure_example.InvalidAuthError): with pytest.raises(insecure_example.InvalidAuthError):
await provider.async_validate_login("user-test", "incorrect-password") await provider.async_validate_login("user-test", "incorrect-password")
async def test_utf_8_username_password(provider): async def test_utf_8_username_password(provider) -> None:
"""Test that we create a new credential.""" """Test that we create a new credential."""
credentials = await provider.async_get_or_create_credentials( credentials = await provider.async_get_or_create_credentials(
{"username": "🎉", "password": "😎"} {"username": "🎉", "password": "😎"}

View file

@ -4,6 +4,7 @@ import pytest
from homeassistant import auth, data_entry_flow from homeassistant import auth, data_entry_flow
from homeassistant.auth import auth_store from homeassistant.auth import auth_store
from homeassistant.auth.providers import legacy_api_password from homeassistant.auth.providers import legacy_api_password
from homeassistant.core import HomeAssistant
@pytest.fixture @pytest.fixture
@ -26,7 +27,7 @@ def manager(hass, store, provider):
return auth.AuthManager(hass, store, {(provider.type, provider.id): provider}, {}) return auth.AuthManager(hass, store, {(provider.type, provider.id): provider}, {})
async def test_create_new_credential(manager, provider): async def test_create_new_credential(manager, provider) -> None:
"""Test that we create a new credential.""" """Test that we create a new credential."""
credentials = await provider.async_get_or_create_credentials({}) credentials = await provider.async_get_or_create_credentials({})
assert credentials.is_new is True assert credentials.is_new is True
@ -36,7 +37,7 @@ async def test_create_new_credential(manager, provider):
assert user.is_active assert user.is_active
async def test_only_one_credentials(manager, provider): async def test_only_one_credentials(manager, provider) -> None:
"""Call create twice will return same credential.""" """Call create twice will return same credential."""
credentials = await provider.async_get_or_create_credentials({}) credentials = await provider.async_get_or_create_credentials({})
await manager.async_get_or_create_user(credentials) await manager.async_get_or_create_user(credentials)
@ -45,14 +46,14 @@ async def test_only_one_credentials(manager, provider):
assert credentials2.is_new is False assert credentials2.is_new is False
async def test_verify_login(hass, provider): async def test_verify_login(hass: HomeAssistant, provider) -> None:
"""Test login using legacy api password auth provider.""" """Test login using legacy api password auth provider."""
provider.async_validate_login("test-password") provider.async_validate_login("test-password")
with pytest.raises(legacy_api_password.InvalidAuthError): with pytest.raises(legacy_api_password.InvalidAuthError):
provider.async_validate_login("invalid-password") provider.async_validate_login("invalid-password")
async def test_login_flow_works(hass, manager): async def test_login_flow_works(hass: HomeAssistant, manager) -> None:
"""Test wrong config.""" """Test wrong config."""
result = await manager.login_flow.async_init(handler=("legacy_api_password", None)) result = await manager.login_flow.async_init(handler=("legacy_api_password", None))
assert result["type"] == data_entry_flow.FlowResultType.FORM assert result["type"] == data_entry_flow.FlowResultType.FORM

View file

@ -10,6 +10,7 @@ from homeassistant import auth
from homeassistant.auth import auth_store from homeassistant.auth import auth_store
from homeassistant.auth.providers import trusted_networks as tn_auth from homeassistant.auth.providers import trusted_networks as tn_auth
from homeassistant.components.http import CONF_TRUSTED_PROXIES, CONF_USE_X_FORWARDED_FOR from homeassistant.components.http import CONF_TRUSTED_PROXIES, CONF_USE_X_FORWARDED_FOR
from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResultType from homeassistant.data_entry_flow import FlowResultType
from homeassistant.setup import async_setup_component from homeassistant.setup import async_setup_component
@ -115,7 +116,7 @@ def manager_bypass_login(hass, store, provider_bypass_login):
) )
async def test_trusted_networks_credentials(manager, provider): async def test_trusted_networks_credentials(manager, provider) -> None:
"""Test trusted_networks credentials related functions.""" """Test trusted_networks credentials related functions."""
owner = await manager.async_create_user("test-owner") owner = await manager.async_create_user("test-owner")
tn_owner_cred = await provider.async_get_or_create_credentials({"user": owner.id}) tn_owner_cred = await provider.async_get_or_create_credentials({"user": owner.id})
@ -132,7 +133,7 @@ async def test_trusted_networks_credentials(manager, provider):
await provider.async_get_or_create_credentials({"user": "invalid-user"}) await provider.async_get_or_create_credentials({"user": "invalid-user"})
async def test_validate_access(provider): async def test_validate_access(provider) -> None:
"""Test validate access from trusted networks.""" """Test validate access from trusted networks."""
provider.async_validate_access(ip_address("192.168.0.1")) provider.async_validate_access(ip_address("192.168.0.1"))
provider.async_validate_access(ip_address("192.168.128.10")) provider.async_validate_access(ip_address("192.168.128.10"))
@ -147,7 +148,7 @@ async def test_validate_access(provider):
provider.async_validate_access(ip_address("2001:db8::ff00:42:8329")) provider.async_validate_access(ip_address("2001:db8::ff00:42:8329"))
async def test_validate_access_proxy(hass, provider): async def test_validate_access_proxy(hass: HomeAssistant, provider) -> None:
"""Test validate access from trusted networks are blocked from proxy.""" """Test validate access from trusted networks are blocked from proxy."""
await async_setup_component( await async_setup_component(
@ -170,7 +171,7 @@ async def test_validate_access_proxy(hass, provider):
provider.async_validate_access(ip_address("fd00::1")) provider.async_validate_access(ip_address("fd00::1"))
async def test_validate_access_cloud(hass, provider): async def test_validate_access_cloud(hass: HomeAssistant, provider) -> None:
"""Test validate access from trusted networks are blocked from cloud.""" """Test validate access from trusted networks are blocked from cloud."""
await async_setup_component( await async_setup_component(
hass, hass,
@ -191,7 +192,7 @@ async def test_validate_access_cloud(hass, provider):
provider.async_validate_access(ip_address("192.168.128.2")) provider.async_validate_access(ip_address("192.168.128.2"))
async def test_validate_refresh_token(provider): async def test_validate_refresh_token(provider) -> None:
"""Verify re-validation of refresh token.""" """Verify re-validation of refresh token."""
with patch.object(provider, "async_validate_access") as mock: with patch.object(provider, "async_validate_access") as mock:
with pytest.raises(tn_auth.InvalidAuthError): with pytest.raises(tn_auth.InvalidAuthError):
@ -201,7 +202,7 @@ async def test_validate_refresh_token(provider):
mock.assert_called_once_with(ip_address("127.0.0.1")) mock.assert_called_once_with(ip_address("127.0.0.1"))
async def test_login_flow(manager, provider): async def test_login_flow(manager, provider) -> None:
"""Test login flow.""" """Test login flow."""
owner = await manager.async_create_user("test-owner") owner = await manager.async_create_user("test-owner")
user = await manager.async_create_user("test-user") user = await manager.async_create_user("test-user")
@ -228,7 +229,7 @@ async def test_login_flow(manager, provider):
assert step["data"]["user"] == user.id assert step["data"]["user"] == user.id
async def test_trusted_users_login(manager_with_user, provider_with_user): async def test_trusted_users_login(manager_with_user, provider_with_user) -> None:
"""Test available user list changed per different IP.""" """Test available user list changed per different IP."""
owner = await manager_with_user.async_create_user("test-owner") owner = await manager_with_user.async_create_user("test-owner")
sys_user = await manager_with_user.async_create_system_user( sys_user = await manager_with_user.async_create_system_user(
@ -308,7 +309,7 @@ async def test_trusted_users_login(manager_with_user, provider_with_user):
assert schema({"user": sys_user.id}) assert schema({"user": sys_user.id})
async def test_trusted_group_login(manager_with_user, provider_with_user): async def test_trusted_group_login(manager_with_user, provider_with_user) -> None:
"""Test config trusted_user with group_id.""" """Test config trusted_user with group_id."""
owner = await manager_with_user.async_create_user("test-owner") owner = await manager_with_user.async_create_user("test-owner")
# create a user in user group # create a user in user group
@ -361,7 +362,7 @@ async def test_trusted_group_login(manager_with_user, provider_with_user):
assert schema({"user": user.id}) assert schema({"user": user.id})
async def test_bypass_login_flow(manager_bypass_login, provider_bypass_login): async def test_bypass_login_flow(manager_bypass_login, provider_bypass_login) -> None:
"""Test login flow can be bypass if only one user available.""" """Test login flow can be bypass if only one user available."""
owner = await manager_bypass_login.async_create_user("test-owner") owner = await manager_bypass_login.async_create_user("test-owner")

View file

@ -55,7 +55,9 @@ async def test_home_assistant_core_config_validation(hass: HomeAssistant) -> Non
assert result is None assert result is None
async def test_async_enable_logging(hass, caplog): async def test_async_enable_logging(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test to ensure logging is migrated to the queue handlers.""" """Test to ensure logging is migrated to the queue handlers."""
with patch("logging.getLogger"), patch( with patch("logging.getLogger"), patch(
"homeassistant.bootstrap.async_activate_log_queue_handler" "homeassistant.bootstrap.async_activate_log_queue_handler"
@ -97,7 +99,9 @@ async def test_empty_setup(hass: HomeAssistant) -> None:
assert domain in hass.config.components, domain assert domain in hass.config.components, domain
async def test_core_failure_loads_safe_mode(hass, caplog): async def test_core_failure_loads_safe_mode(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test failing core setup aborts further setup.""" """Test failing core setup aborts further setup."""
with patch( with patch(
"homeassistant.components.homeassistant.async_setup", "homeassistant.components.homeassistant.async_setup",
@ -462,7 +466,7 @@ async def test_setup_hass(
mock_mount_local_lib_path, mock_mount_local_lib_path,
mock_ensure_config_exists, mock_ensure_config_exists,
mock_process_ha_config_upgrade, mock_process_ha_config_upgrade,
caplog, caplog: pytest.LogCaptureFixture,
event_loop, event_loop,
) -> None: ) -> None:
"""Test it works.""" """Test it works."""
@ -512,7 +516,7 @@ async def test_setup_hass_takes_longer_than_log_slow_startup(
mock_mount_local_lib_path, mock_mount_local_lib_path,
mock_ensure_config_exists, mock_ensure_config_exists,
mock_process_ha_config_upgrade, mock_process_ha_config_upgrade,
caplog, caplog: pytest.LogCaptureFixture,
event_loop, event_loop,
) -> None: ) -> None:
"""Test it works.""" """Test it works."""
@ -581,7 +585,7 @@ async def test_setup_hass_config_dir_nonexistent(
mock_ensure_config_exists, mock_ensure_config_exists,
mock_process_ha_config_upgrade, mock_process_ha_config_upgrade,
event_loop, event_loop,
): ) -> None:
"""Test it works.""" """Test it works."""
mock_ensure_config_exists.return_value = False mock_ensure_config_exists.return_value = False
@ -608,7 +612,7 @@ async def test_setup_hass_safe_mode(
mock_ensure_config_exists, mock_ensure_config_exists,
mock_process_ha_config_upgrade, mock_process_ha_config_upgrade,
event_loop, event_loop,
): ) -> None:
"""Test it works.""" """Test it works."""
with patch("homeassistant.components.browser.setup") as browser_setup, patch( with patch("homeassistant.components.browser.setup") as browser_setup, patch(
"homeassistant.config_entries.ConfigEntries.async_domains", "homeassistant.config_entries.ConfigEntries.async_domains",
@ -768,7 +772,9 @@ async def test_empty_integrations_list_is_only_sent_at_the_end_of_bootstrap(
@pytest.mark.parametrize("load_registries", [False]) @pytest.mark.parametrize("load_registries", [False])
async def test_warning_logged_on_wrap_up_timeout(hass, caplog): async def test_warning_logged_on_wrap_up_timeout(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test we log a warning on bootstrap timeout.""" """Test we log a warning on bootstrap timeout."""
def gen_domain_setup(domain): def gen_domain_setup(domain):

View file

@ -1,9 +1,9 @@
"""Test config utils.""" """Test config utils."""
from collections import OrderedDict from collections import OrderedDict
import contextlib import contextlib
import copy import copy
import os import os
from typing import Any
from unittest import mock from unittest import mock
from unittest.mock import AsyncMock, Mock, patch from unittest.mock import AsyncMock, Mock, patch
@ -238,7 +238,9 @@ def test_core_config_schema() -> None:
) )
def test_core_config_schema_internal_external_warning(caplog): def test_core_config_schema_internal_external_warning(
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test that we warn for internal/external URL with path.""" """Test that we warn for internal/external URL with path."""
config_util.CORE_CONFIG_SCHEMA( config_util.CORE_CONFIG_SCHEMA(
{ {
@ -300,7 +302,9 @@ async def test_entity_customization(hass: HomeAssistant) -> None:
@patch("homeassistant.config.shutil") @patch("homeassistant.config.shutil")
@patch("homeassistant.config.os") @patch("homeassistant.config.os")
@patch("homeassistant.config.is_docker_env", return_value=False) @patch("homeassistant.config.is_docker_env", return_value=False)
def test_remove_lib_on_upgrade(mock_docker, mock_os, mock_shutil, hass): def test_remove_lib_on_upgrade(
mock_docker, mock_os, mock_shutil, hass: HomeAssistant
) -> None:
"""Test removal of library on upgrade from before 0.50.""" """Test removal of library on upgrade from before 0.50."""
ha_version = "0.49.0" ha_version = "0.49.0"
mock_os.path.isdir = mock.Mock(return_value=True) mock_os.path.isdir = mock.Mock(return_value=True)
@ -322,7 +326,9 @@ def test_remove_lib_on_upgrade(mock_docker, mock_os, mock_shutil, hass):
@patch("homeassistant.config.shutil") @patch("homeassistant.config.shutil")
@patch("homeassistant.config.os") @patch("homeassistant.config.os")
@patch("homeassistant.config.is_docker_env", return_value=True) @patch("homeassistant.config.is_docker_env", return_value=True)
def test_remove_lib_on_upgrade_94(mock_docker, mock_os, mock_shutil, hass): def test_remove_lib_on_upgrade_94(
mock_docker, mock_os, mock_shutil, hass: HomeAssistant
) -> None:
"""Test removal of library on upgrade from before 0.94 and in Docker.""" """Test removal of library on upgrade from before 0.94 and in Docker."""
ha_version = "0.93.0.dev0" ha_version = "0.93.0.dev0"
mock_os.path.isdir = mock.Mock(return_value=True) mock_os.path.isdir = mock.Mock(return_value=True)
@ -386,7 +392,9 @@ def test_config_upgrade_no_file(hass: HomeAssistant) -> None:
assert opened_file.write.call_args == mock.call(__version__) assert opened_file.write.call_args == mock.call(__version__)
async def test_loading_configuration_from_storage(hass, hass_storage): async def test_loading_configuration_from_storage(
hass: HomeAssistant, hass_storage: dict[str, Any]
) -> None:
"""Test loading core config onto hass object.""" """Test loading core config onto hass object."""
hass_storage["core.config"] = { hass_storage["core.config"] = {
"data": { "data": {
@ -426,7 +434,9 @@ async def test_loading_configuration_from_storage(hass, hass_storage):
assert hass.config.config_source is ConfigSource.STORAGE assert hass.config.config_source is ConfigSource.STORAGE
async def test_loading_configuration_from_storage_with_yaml_only(hass, hass_storage): async def test_loading_configuration_from_storage_with_yaml_only(
hass: HomeAssistant, hass_storage: dict[str, Any]
) -> None:
"""Test loading core and YAML config onto hass object.""" """Test loading core and YAML config onto hass object."""
hass_storage["core.config"] = { hass_storage["core.config"] = {
"data": { "data": {
@ -456,7 +466,9 @@ async def test_loading_configuration_from_storage_with_yaml_only(hass, hass_stor
assert hass.config.config_source is ConfigSource.STORAGE assert hass.config.config_source is ConfigSource.STORAGE
async def test_migration_and_updating_configuration(hass, hass_storage): async def test_migration_and_updating_configuration(
hass: HomeAssistant, hass_storage: dict[str, Any]
) -> None:
"""Test updating configuration stores the new configuration.""" """Test updating configuration stores the new configuration."""
core_data = { core_data = {
"data": { "data": {
@ -497,7 +509,9 @@ async def test_migration_and_updating_configuration(hass, hass_storage):
assert hass.config.language == "en" assert hass.config.language == "en"
async def test_override_stored_configuration(hass, hass_storage): async def test_override_stored_configuration(
hass: HomeAssistant, hass_storage: dict[str, Any]
) -> None:
"""Test loading core and YAML config onto hass object.""" """Test loading core and YAML config onto hass object."""
hass_storage["core.config"] = { hass_storage["core.config"] = {
"data": { "data": {
@ -601,8 +615,13 @@ async def test_loading_configuration(hass: HomeAssistant) -> None:
), ),
) )
async def test_language_default( async def test_language_default(
hass, hass_storage, minor_version, users, user_data, default_language hass: HomeAssistant,
): hass_storage: dict[str, Any],
minor_version,
users,
user_data,
default_language,
) -> None:
"""Test language config default to owner user's language during migration. """Test language config default to owner user's language during migration.
This should only happen if the core store version < 1.3 This should only happen if the core store version < 1.3
@ -721,14 +740,14 @@ async def test_loading_configuration_unit_system(
@patch("homeassistant.helpers.check_config.async_check_ha_config_file") @patch("homeassistant.helpers.check_config.async_check_ha_config_file")
async def test_check_ha_config_file_correct(mock_check, hass): async def test_check_ha_config_file_correct(mock_check, hass: HomeAssistant) -> None:
"""Check that restart propagates to stop.""" """Check that restart propagates to stop."""
mock_check.return_value = check_config.HomeAssistantConfig() mock_check.return_value = check_config.HomeAssistantConfig()
assert await config_util.async_check_ha_config_file(hass) is None assert await config_util.async_check_ha_config_file(hass) is None
@patch("homeassistant.helpers.check_config.async_check_ha_config_file") @patch("homeassistant.helpers.check_config.async_check_ha_config_file")
async def test_check_ha_config_file_wrong(mock_check, hass): async def test_check_ha_config_file_wrong(mock_check, hass: HomeAssistant) -> None:
"""Check that restart with a bad config doesn't propagate to stop.""" """Check that restart with a bad config doesn't propagate to stop."""
mock_check.return_value = check_config.HomeAssistantConfig() mock_check.return_value = check_config.HomeAssistantConfig()
mock_check.return_value.add_error("bad") mock_check.return_value.add_error("bad")
@ -770,7 +789,7 @@ def merge_log_err(hass):
yield logerr yield logerr
async def test_merge(merge_log_err, hass): async def test_merge(merge_log_err, hass: HomeAssistant) -> None:
"""Test if we can merge packages.""" """Test if we can merge packages."""
packages = { packages = {
"pack_dict": {"input_boolean": {"ib1": None}}, "pack_dict": {"input_boolean": {"ib1": None}},
@ -805,7 +824,7 @@ async def test_merge(merge_log_err, hass):
assert isinstance(config["wake_on_lan"], OrderedDict) assert isinstance(config["wake_on_lan"], OrderedDict)
async def test_merge_try_falsy(merge_log_err, hass): async def test_merge_try_falsy(merge_log_err, hass: HomeAssistant) -> None:
"""Ensure we don't add falsy items like empty OrderedDict() to list.""" """Ensure we don't add falsy items like empty OrderedDict() to list."""
packages = { packages = {
"pack_falsy_to_lst": {"automation": OrderedDict()}, "pack_falsy_to_lst": {"automation": OrderedDict()},
@ -824,7 +843,7 @@ async def test_merge_try_falsy(merge_log_err, hass):
assert len(config["light"]) == 1 assert len(config["light"]) == 1
async def test_merge_new(merge_log_err, hass): async def test_merge_new(merge_log_err, hass: HomeAssistant) -> None:
"""Test adding new components to outer scope.""" """Test adding new components to outer scope."""
packages = { packages = {
"pack_1": {"light": [{"platform": "one"}]}, "pack_1": {"light": [{"platform": "one"}]},
@ -845,7 +864,7 @@ async def test_merge_new(merge_log_err, hass):
assert len(config["panel_custom"]) == 1 assert len(config["panel_custom"]) == 1
async def test_merge_type_mismatch(merge_log_err, hass): async def test_merge_type_mismatch(merge_log_err, hass: HomeAssistant) -> None:
"""Test if we have a type mismatch for packages.""" """Test if we have a type mismatch for packages."""
packages = { packages = {
"pack_1": {"input_boolean": [{"ib1": None}]}, "pack_1": {"input_boolean": [{"ib1": None}]},
@ -866,7 +885,7 @@ async def test_merge_type_mismatch(merge_log_err, hass):
assert len(config["light"]) == 2 assert len(config["light"]) == 2
async def test_merge_once_only_keys(merge_log_err, hass): async def test_merge_once_only_keys(merge_log_err, hass: HomeAssistant) -> None:
"""Test if we have a merge for a comp that may occur only once. Keys.""" """Test if we have a merge for a comp that may occur only once. Keys."""
packages = {"pack_2": {"api": None}} packages = {"pack_2": {"api": None}}
config = {config_util.CONF_CORE: {config_util.CONF_PACKAGES: packages}, "api": None} config = {config_util.CONF_CORE: {config_util.CONF_PACKAGES: packages}, "api": None}
@ -952,7 +971,7 @@ async def test_merge_id_schema(hass: HomeAssistant) -> None:
assert typ == expected_type, f"{domain} expected {expected_type}, got {typ}" assert typ == expected_type, f"{domain} expected {expected_type}, got {typ}"
async def test_merge_duplicate_keys(merge_log_err, hass): async def test_merge_duplicate_keys(merge_log_err, hass: HomeAssistant) -> None:
"""Test if keys in dicts are duplicates.""" """Test if keys in dicts are duplicates."""
packages = {"pack_1": {"input_select": {"ib1": None}}} packages = {"pack_1": {"input_select": {"ib1": None}}}
config = { config = {
@ -1125,7 +1144,9 @@ async def test_merge_split_component_definition(hass: HomeAssistant) -> None:
assert len(config["light three"]) == 1 assert len(config["light three"]) == 1
async def test_component_config_exceptions(hass, caplog): async def test_component_config_exceptions(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test unexpected exceptions validating component config.""" """Test unexpected exceptions validating component config."""
# Config validator # Config validator
assert ( assert (
@ -1296,7 +1317,7 @@ async def test_component_config_exceptions(hass, caplog):
("openuv", cv.deprecated("openuv"), None), ("openuv", cv.deprecated("openuv"), None),
], ],
) )
def test_identify_config_schema(domain, schema, expected): def test_identify_config_schema(domain, schema, expected) -> None:
"""Test identify config schema.""" """Test identify config schema."""
assert ( assert (
config_util._identify_config_schema(Mock(DOMAIN=domain, CONFIG_SCHEMA=schema)) config_util._identify_config_schema(Mock(DOMAIN=domain, CONFIG_SCHEMA=schema))
@ -1314,7 +1335,9 @@ async def test_core_config_schema_historic_currency(hass: HomeAssistant) -> None
assert issue.translation_placeholders == {"currency": "LTT"} assert issue.translation_placeholders == {"currency": "LTT"}
async def test_core_store_historic_currency(hass, hass_storage): async def test_core_store_historic_currency(
hass: HomeAssistant, hass_storage: dict[str, Any]
) -> None:
"""Test core config store.""" """Test core config store."""
core_data = { core_data = {
"data": { "data": {
@ -1347,7 +1370,9 @@ async def test_core_config_schema_no_country(hass: HomeAssistant) -> None:
assert issue assert issue
async def test_core_store_no_country(hass, hass_storage): async def test_core_store_no_country(
hass: HomeAssistant, hass_storage: dict[str, Any]
) -> None:
"""Test core config store.""" """Test core config store."""
core_data = { core_data = {
"data": {}, "data": {},

View file

@ -4,6 +4,7 @@ from __future__ import annotations
import asyncio import asyncio
from datetime import timedelta from datetime import timedelta
import logging import logging
from typing import Any
from unittest.mock import AsyncMock, Mock, patch from unittest.mock import AsyncMock, Mock, patch
import pytest import pytest
@ -261,7 +262,7 @@ async def test_call_async_migrate_entry_failure_not_supported(
assert not entry.supports_unload assert not entry.supports_unload
async def test_remove_entry(hass, manager): async def test_remove_entry(hass: HomeAssistant, manager) -> None:
"""Test that we can remove an entry.""" """Test that we can remove an entry."""
async def mock_setup_entry(hass, entry): async def mock_setup_entry(hass, entry):
@ -345,7 +346,7 @@ async def test_remove_entry(hass, manager):
assert not entity_entry_list assert not entity_entry_list
async def test_remove_entry_cancels_reauth(hass, manager): async def test_remove_entry_cancels_reauth(hass: HomeAssistant, manager) -> None:
"""Tests that removing a config entry, also aborts existing reauth flows.""" """Tests that removing a config entry, also aborts existing reauth flows."""
entry = MockConfigEntry(title="test_title", domain="test") entry = MockConfigEntry(title="test_title", domain="test")
@ -369,7 +370,9 @@ async def test_remove_entry_cancels_reauth(hass, manager):
assert len(flows) == 0 assert len(flows) == 0
async def test_remove_entry_handles_callback_error(hass, manager): async def test_remove_entry_handles_callback_error(
hass: HomeAssistant, manager
) -> None:
"""Test that exceptions in the remove callback are handled.""" """Test that exceptions in the remove callback are handled."""
mock_setup_entry = AsyncMock(return_value=True) mock_setup_entry = AsyncMock(return_value=True)
mock_unload_entry = AsyncMock(return_value=True) mock_unload_entry = AsyncMock(return_value=True)
@ -402,7 +405,7 @@ async def test_remove_entry_handles_callback_error(hass, manager):
assert [item.entry_id for item in manager.async_entries()] == [] assert [item.entry_id for item in manager.async_entries()] == []
async def test_remove_entry_raises(hass, manager): async def test_remove_entry_raises(hass: HomeAssistant, manager) -> None:
"""Test if a component raises while removing entry.""" """Test if a component raises while removing entry."""
async def mock_unload_entry(hass, entry): async def mock_unload_entry(hass, entry):
@ -429,7 +432,7 @@ async def test_remove_entry_raises(hass, manager):
assert [item.entry_id for item in manager.async_entries()] == ["test1", "test3"] assert [item.entry_id for item in manager.async_entries()] == ["test1", "test3"]
async def test_remove_entry_if_not_loaded(hass, manager): async def test_remove_entry_if_not_loaded(hass: HomeAssistant, manager) -> None:
"""Test that we can remove an entry that is not loaded.""" """Test that we can remove an entry that is not loaded."""
mock_unload_entry = AsyncMock(return_value=True) mock_unload_entry = AsyncMock(return_value=True)
@ -453,7 +456,9 @@ async def test_remove_entry_if_not_loaded(hass, manager):
assert len(mock_unload_entry.mock_calls) == 0 assert len(mock_unload_entry.mock_calls) == 0
async def test_remove_entry_if_integration_deleted(hass, manager): async def test_remove_entry_if_integration_deleted(
hass: HomeAssistant, manager
) -> None:
"""Test that we can remove an entry when the integration is deleted.""" """Test that we can remove an entry when the integration is deleted."""
mock_unload_entry = AsyncMock(return_value=True) mock_unload_entry = AsyncMock(return_value=True)
@ -475,7 +480,7 @@ async def test_remove_entry_if_integration_deleted(hass, manager):
assert len(mock_unload_entry.mock_calls) == 0 assert len(mock_unload_entry.mock_calls) == 0
async def test_add_entry_calls_setup_entry(hass, manager): async def test_add_entry_calls_setup_entry(hass: HomeAssistant, manager) -> None:
"""Test we call setup_config_entry.""" """Test we call setup_config_entry."""
mock_setup_entry = AsyncMock(return_value=True) mock_setup_entry = AsyncMock(return_value=True)
@ -504,7 +509,7 @@ async def test_add_entry_calls_setup_entry(hass, manager):
assert p_entry.data == {"token": "supersecret"} assert p_entry.data == {"token": "supersecret"}
async def test_entries_gets_entries(manager): async def test_entries_gets_entries(manager) -> None:
"""Test entries are filtered by domain.""" """Test entries are filtered by domain."""
MockConfigEntry(domain="test").add_to_manager(manager) MockConfigEntry(domain="test").add_to_manager(manager)
entry1 = MockConfigEntry(domain="test2") entry1 = MockConfigEntry(domain="test2")
@ -515,7 +520,7 @@ async def test_entries_gets_entries(manager):
assert manager.async_entries("test2") == [entry1, entry2] assert manager.async_entries("test2") == [entry1, entry2]
async def test_domains_gets_domains_uniques(manager): async def test_domains_gets_domains_uniques(manager) -> None:
"""Test we only return each domain once.""" """Test we only return each domain once."""
MockConfigEntry(domain="test").add_to_manager(manager) MockConfigEntry(domain="test").add_to_manager(manager)
MockConfigEntry(domain="test2").add_to_manager(manager) MockConfigEntry(domain="test2").add_to_manager(manager)
@ -526,7 +531,7 @@ async def test_domains_gets_domains_uniques(manager):
assert manager.async_domains() == ["test", "test2", "test3"] assert manager.async_domains() == ["test", "test2", "test3"]
async def test_domains_gets_domains_excludes_ignore_and_disabled(manager): async def test_domains_gets_domains_excludes_ignore_and_disabled(manager) -> None:
"""Test we only return each domain once.""" """Test we only return each domain once."""
MockConfigEntry(domain="test").add_to_manager(manager) MockConfigEntry(domain="test").add_to_manager(manager)
MockConfigEntry(domain="test2").add_to_manager(manager) MockConfigEntry(domain="test2").add_to_manager(manager)
@ -832,7 +837,7 @@ async def test_loading_default_config(hass: HomeAssistant) -> None:
assert len(manager.async_entries()) == 0 assert len(manager.async_entries()) == 0
async def test_updating_entry_data(manager): async def test_updating_entry_data(manager) -> None:
"""Test that we can update an entry data.""" """Test that we can update an entry data."""
entry = MockConfigEntry( entry = MockConfigEntry(
domain="test", domain="test",
@ -848,7 +853,7 @@ async def test_updating_entry_data(manager):
assert entry.data == {"second": True} assert entry.data == {"second": True}
async def test_updating_entry_system_options(manager): async def test_updating_entry_system_options(manager) -> None:
"""Test that we can update an entry data.""" """Test that we can update an entry data."""
entry = MockConfigEntry( entry = MockConfigEntry(
domain="test", domain="test",
@ -869,7 +874,9 @@ async def test_updating_entry_system_options(manager):
assert entry.pref_disable_polling is True assert entry.pref_disable_polling is True
async def test_update_entry_options_and_trigger_listener(hass, manager): async def test_update_entry_options_and_trigger_listener(
hass: HomeAssistant, manager
) -> None:
"""Test that we can update entry options and trigger listener.""" """Test that we can update entry options and trigger listener."""
entry = MockConfigEntry(domain="test", options={"first": True}) entry = MockConfigEntry(domain="test", options={"first": True})
entry.add_to_manager(manager) entry.add_to_manager(manager)
@ -885,7 +892,9 @@ async def test_update_entry_options_and_trigger_listener(hass, manager):
assert entry.options == {"second": True} assert entry.options == {"second": True}
async def test_setup_raise_not_ready(hass, caplog): async def test_setup_raise_not_ready(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test a setup raising not ready.""" """Test a setup raising not ready."""
entry = MockConfigEntry(title="test_title", domain="test") entry = MockConfigEntry(title="test_title", domain="test")
@ -919,7 +928,9 @@ async def test_setup_raise_not_ready(hass, caplog):
assert entry.reason is None assert entry.reason is None
async def test_setup_raise_not_ready_from_exception(hass, caplog): async def test_setup_raise_not_ready_from_exception(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test a setup raising not ready from another exception.""" """Test a setup raising not ready from another exception."""
entry = MockConfigEntry(title="test_title", domain="test") entry = MockConfigEntry(title="test_title", domain="test")
@ -1037,7 +1048,7 @@ async def test_create_entry_options(hass: HomeAssistant) -> None:
assert entries[0].options == {"example": "option"} assert entries[0].options == {"example": "option"}
async def test_entry_options(hass, manager): async def test_entry_options(hass: HomeAssistant, manager) -> None:
"""Test that we can set options on an entry.""" """Test that we can set options on an entry."""
entry = MockConfigEntry(domain="test", data={"first": True}, options=None) entry = MockConfigEntry(domain="test", data={"first": True}, options=None)
entry.add_to_manager(manager) entry.add_to_manager(manager)
@ -1071,7 +1082,7 @@ async def test_entry_options(hass, manager):
assert entry.options == {"second": True} assert entry.options == {"second": True}
async def test_entry_options_abort(hass, manager): async def test_entry_options_abort(hass: HomeAssistant, manager) -> None:
"""Test that we can abort options flow.""" """Test that we can abort options flow."""
entry = MockConfigEntry(domain="test", data={"first": True}, options=None) entry = MockConfigEntry(domain="test", data={"first": True}, options=None)
entry.add_to_manager(manager) entry.add_to_manager(manager)
@ -1101,7 +1112,7 @@ async def test_entry_options_abort(hass, manager):
) )
async def test_entry_setup_succeed(hass, manager): async def test_entry_setup_succeed(hass: HomeAssistant, manager) -> None:
"""Test that we can setup an entry.""" """Test that we can setup an entry."""
entry = MockConfigEntry( entry = MockConfigEntry(
domain="comp", state=config_entries.ConfigEntryState.NOT_LOADED domain="comp", state=config_entries.ConfigEntryState.NOT_LOADED
@ -1133,7 +1144,7 @@ async def test_entry_setup_succeed(hass, manager):
config_entries.ConfigEntryState.FAILED_UNLOAD, config_entries.ConfigEntryState.FAILED_UNLOAD,
), ),
) )
async def test_entry_setup_invalid_state(hass, manager, state): async def test_entry_setup_invalid_state(hass: HomeAssistant, manager, state) -> None:
"""Test that we cannot setup an entry with invalid state.""" """Test that we cannot setup an entry with invalid state."""
entry = MockConfigEntry(domain="comp", state=state) entry = MockConfigEntry(domain="comp", state=state)
entry.add_to_hass(hass) entry.add_to_hass(hass)
@ -1154,7 +1165,7 @@ async def test_entry_setup_invalid_state(hass, manager, state):
assert entry.state is state assert entry.state is state
async def test_entry_unload_succeed(hass, manager): async def test_entry_unload_succeed(hass: HomeAssistant, manager) -> None:
"""Test that we can unload an entry.""" """Test that we can unload an entry."""
entry = MockConfigEntry(domain="comp", state=config_entries.ConfigEntryState.LOADED) entry = MockConfigEntry(domain="comp", state=config_entries.ConfigEntryState.LOADED)
entry.add_to_hass(hass) entry.add_to_hass(hass)
@ -1176,7 +1187,7 @@ async def test_entry_unload_succeed(hass, manager):
config_entries.ConfigEntryState.SETUP_RETRY, config_entries.ConfigEntryState.SETUP_RETRY,
), ),
) )
async def test_entry_unload_failed_to_load(hass, manager, state): async def test_entry_unload_failed_to_load(hass: HomeAssistant, manager, state) -> None:
"""Test that we can unload an entry.""" """Test that we can unload an entry."""
entry = MockConfigEntry(domain="comp", state=state) entry = MockConfigEntry(domain="comp", state=state)
entry.add_to_hass(hass) entry.add_to_hass(hass)
@ -1197,7 +1208,7 @@ async def test_entry_unload_failed_to_load(hass, manager, state):
config_entries.ConfigEntryState.FAILED_UNLOAD, config_entries.ConfigEntryState.FAILED_UNLOAD,
), ),
) )
async def test_entry_unload_invalid_state(hass, manager, state): async def test_entry_unload_invalid_state(hass: HomeAssistant, manager, state) -> None:
"""Test that we cannot unload an entry with invalid state.""" """Test that we cannot unload an entry with invalid state."""
entry = MockConfigEntry(domain="comp", state=state) entry = MockConfigEntry(domain="comp", state=state)
entry.add_to_hass(hass) entry.add_to_hass(hass)
@ -1213,7 +1224,7 @@ async def test_entry_unload_invalid_state(hass, manager, state):
assert entry.state is state assert entry.state is state
async def test_entry_reload_succeed(hass, manager): async def test_entry_reload_succeed(hass: HomeAssistant, manager) -> None:
"""Test that we can reload an entry.""" """Test that we can reload an entry."""
entry = MockConfigEntry(domain="comp", state=config_entries.ConfigEntryState.LOADED) entry = MockConfigEntry(domain="comp", state=config_entries.ConfigEntryState.LOADED)
entry.add_to_hass(hass) entry.add_to_hass(hass)
@ -1248,7 +1259,7 @@ async def test_entry_reload_succeed(hass, manager):
config_entries.ConfigEntryState.SETUP_RETRY, config_entries.ConfigEntryState.SETUP_RETRY,
), ),
) )
async def test_entry_reload_not_loaded(hass, manager, state): async def test_entry_reload_not_loaded(hass: HomeAssistant, manager, state) -> None:
"""Test that we can reload an entry.""" """Test that we can reload an entry."""
entry = MockConfigEntry(domain="comp", state=state) entry = MockConfigEntry(domain="comp", state=state)
entry.add_to_hass(hass) entry.add_to_hass(hass)
@ -1282,7 +1293,7 @@ async def test_entry_reload_not_loaded(hass, manager, state):
config_entries.ConfigEntryState.FAILED_UNLOAD, config_entries.ConfigEntryState.FAILED_UNLOAD,
), ),
) )
async def test_entry_reload_error(hass, manager, state): async def test_entry_reload_error(hass: HomeAssistant, manager, state) -> None:
"""Test that we can reload an entry.""" """Test that we can reload an entry."""
entry = MockConfigEntry(domain="comp", state=state) entry = MockConfigEntry(domain="comp", state=state)
entry.add_to_hass(hass) entry.add_to_hass(hass)
@ -1311,7 +1322,7 @@ async def test_entry_reload_error(hass, manager, state):
assert entry.state == state assert entry.state == state
async def test_entry_disable_succeed(hass, manager): async def test_entry_disable_succeed(hass: HomeAssistant, manager) -> None:
"""Test that we can disable an entry.""" """Test that we can disable an entry."""
entry = MockConfigEntry(domain="comp", state=config_entries.ConfigEntryState.LOADED) entry = MockConfigEntry(domain="comp", state=config_entries.ConfigEntryState.LOADED)
entry.add_to_hass(hass) entry.add_to_hass(hass)
@ -1348,7 +1359,9 @@ async def test_entry_disable_succeed(hass, manager):
assert entry.state is config_entries.ConfigEntryState.LOADED assert entry.state is config_entries.ConfigEntryState.LOADED
async def test_entry_disable_without_reload_support(hass, manager): async def test_entry_disable_without_reload_support(
hass: HomeAssistant, manager
) -> None:
"""Test that we can disable an entry without reload support.""" """Test that we can disable an entry without reload support."""
entry = MockConfigEntry(domain="comp", state=config_entries.ConfigEntryState.LOADED) entry = MockConfigEntry(domain="comp", state=config_entries.ConfigEntryState.LOADED)
entry.add_to_hass(hass) entry.add_to_hass(hass)
@ -1385,7 +1398,9 @@ async def test_entry_disable_without_reload_support(hass, manager):
assert entry.state is config_entries.ConfigEntryState.FAILED_UNLOAD assert entry.state is config_entries.ConfigEntryState.FAILED_UNLOAD
async def test_entry_enable_without_reload_support(hass, manager): async def test_entry_enable_without_reload_support(
hass: HomeAssistant, manager
) -> None:
"""Test that we can disable an entry without reload support.""" """Test that we can disable an entry without reload support."""
entry = MockConfigEntry( entry = MockConfigEntry(
domain="comp", disabled_by=config_entries.ConfigEntryDisabler.USER domain="comp", disabled_by=config_entries.ConfigEntryDisabler.USER
@ -1513,7 +1528,7 @@ async def test_reload_entry_entity_registry_works(
assert len(mock_unload_entry.mock_calls) == 2 assert len(mock_unload_entry.mock_calls) == 2
async def test_unique_id_persisted(hass, manager): async def test_unique_id_persisted(hass: HomeAssistant, manager) -> None:
"""Test that a unique ID is stored in the config entry.""" """Test that a unique ID is stored in the config entry."""
mock_setup_entry = AsyncMock(return_value=True) mock_setup_entry = AsyncMock(return_value=True)
@ -1542,7 +1557,7 @@ async def test_unique_id_persisted(hass, manager):
assert p_entry.unique_id == "mock-unique-id" assert p_entry.unique_id == "mock-unique-id"
async def test_unique_id_existing_entry(hass, manager): async def test_unique_id_existing_entry(hass: HomeAssistant, manager) -> None:
"""Test that we remove an entry if there already is an entry with unique ID.""" """Test that we remove an entry if there already is an entry with unique ID."""
hass.config.components.add("comp") hass.config.components.add("comp")
MockConfigEntry( MockConfigEntry(
@ -1595,7 +1610,7 @@ async def test_unique_id_existing_entry(hass, manager):
assert len(async_remove_entry.mock_calls) == 1 assert len(async_remove_entry.mock_calls) == 1
async def test_entry_id_existing_entry(hass, manager): async def test_entry_id_existing_entry(hass: HomeAssistant, manager) -> None:
"""Test that we throw when the entry id collides.""" """Test that we throw when the entry id collides."""
collide_entry_id = "collide" collide_entry_id = "collide"
hass.config.components.add("comp") hass.config.components.add("comp")
@ -1632,7 +1647,9 @@ async def test_entry_id_existing_entry(hass, manager):
) )
async def test_unique_id_update_existing_entry_without_reload(hass, manager): async def test_unique_id_update_existing_entry_without_reload(
hass: HomeAssistant, manager
) -> None:
"""Test that we update an entry if there already is an entry with unique ID.""" """Test that we update an entry if there already is an entry with unique ID."""
hass.config.components.add("comp") hass.config.components.add("comp")
entry = MockConfigEntry( entry = MockConfigEntry(
@ -1676,7 +1693,9 @@ async def test_unique_id_update_existing_entry_without_reload(hass, manager):
assert len(async_reload.mock_calls) == 0 assert len(async_reload.mock_calls) == 0
async def test_unique_id_update_existing_entry_with_reload(hass, manager): async def test_unique_id_update_existing_entry_with_reload(
hass: HomeAssistant, manager
) -> None:
"""Test that we update an entry if there already is an entry with unique ID and we reload on changes.""" """Test that we update an entry if there already is an entry with unique ID and we reload on changes."""
hass.config.components.add("comp") hass.config.components.add("comp")
entry = MockConfigEntry( entry = MockConfigEntry(
@ -1738,7 +1757,9 @@ async def test_unique_id_update_existing_entry_with_reload(hass, manager):
assert len(async_reload.mock_calls) == 0 assert len(async_reload.mock_calls) == 0
async def test_unique_id_from_discovery_in_setup_retry(hass, manager): async def test_unique_id_from_discovery_in_setup_retry(
hass: HomeAssistant, manager
) -> None:
"""Test that we reload when in a setup retry state from discovery.""" """Test that we reload when in a setup retry state from discovery."""
hass.config.components.add("comp") hass.config.components.add("comp")
unique_id = "34:ea:34:b4:3b:5a" unique_id = "34:ea:34:b4:3b:5a"
@ -1807,7 +1828,9 @@ async def test_unique_id_from_discovery_in_setup_retry(hass, manager):
assert len(async_reload.mock_calls) == 1 assert len(async_reload.mock_calls) == 1
async def test_unique_id_not_update_existing_entry(hass, manager): async def test_unique_id_not_update_existing_entry(
hass: HomeAssistant, manager
) -> None:
"""Test that we do not update an entry if existing entry has the data.""" """Test that we do not update an entry if existing entry has the data."""
hass.config.components.add("comp") hass.config.components.add("comp")
entry = MockConfigEntry( entry = MockConfigEntry(
@ -1850,7 +1873,7 @@ async def test_unique_id_not_update_existing_entry(hass, manager):
assert len(async_reload.mock_calls) == 0 assert len(async_reload.mock_calls) == 0
async def test_unique_id_in_progress(hass, manager): async def test_unique_id_in_progress(hass: HomeAssistant, manager) -> None:
"""Test that we abort if there is already a flow in progress with same unique id.""" """Test that we abort if there is already a flow in progress with same unique id."""
mock_integration(hass, MockModule("comp")) mock_integration(hass, MockModule("comp"))
mock_entity_platform(hass, "config_flow.comp", None) mock_entity_platform(hass, "config_flow.comp", None)
@ -1881,7 +1904,7 @@ async def test_unique_id_in_progress(hass, manager):
assert result2["reason"] == "already_in_progress" assert result2["reason"] == "already_in_progress"
async def test_finish_flow_aborts_progress(hass, manager): async def test_finish_flow_aborts_progress(hass: HomeAssistant, manager) -> None:
"""Test that when finishing a flow, we abort other flows in progress with unique ID.""" """Test that when finishing a flow, we abort other flows in progress with unique ID."""
mock_integration( mock_integration(
hass, hass,
@ -1920,7 +1943,7 @@ async def test_finish_flow_aborts_progress(hass, manager):
assert len(hass.config_entries.flow.async_progress()) == 0 assert len(hass.config_entries.flow.async_progress()) == 0
async def test_unique_id_ignore(hass, manager): async def test_unique_id_ignore(hass: HomeAssistant, manager) -> None:
"""Test that we can ignore flows that are in progress and have a unique ID.""" """Test that we can ignore flows that are in progress and have a unique ID."""
async_setup_entry = AsyncMock(return_value=False) async_setup_entry = AsyncMock(return_value=False)
mock_integration(hass, MockModule("comp", async_setup_entry=async_setup_entry)) mock_integration(hass, MockModule("comp", async_setup_entry=async_setup_entry))
@ -1963,7 +1986,7 @@ async def test_unique_id_ignore(hass, manager):
assert entry.title == "Ignored Title" assert entry.title == "Ignored Title"
async def test_manual_add_overrides_ignored_entry(hass, manager): async def test_manual_add_overrides_ignored_entry(hass: HomeAssistant, manager) -> None:
"""Test that we can ignore manually add entry, overriding ignored entry.""" """Test that we can ignore manually add entry, overriding ignored entry."""
hass.config.components.add("comp") hass.config.components.add("comp")
entry = MockConfigEntry( entry = MockConfigEntry(
@ -2008,7 +2031,9 @@ async def test_manual_add_overrides_ignored_entry(hass, manager):
assert len(async_reload.mock_calls) == 0 assert len(async_reload.mock_calls) == 0
async def test_manual_add_overrides_ignored_entry_singleton(hass, manager): async def test_manual_add_overrides_ignored_entry_singleton(
hass: HomeAssistant, manager
) -> None:
"""Test that we can ignore manually add entry, overriding ignored entry.""" """Test that we can ignore manually add entry, overriding ignored entry."""
hass.config.components.add("comp") hass.config.components.add("comp")
entry = MockConfigEntry( entry = MockConfigEntry(
@ -2047,7 +2072,9 @@ async def test_manual_add_overrides_ignored_entry_singleton(hass, manager):
assert p_entry.data == {"token": "supersecret"} assert p_entry.data == {"token": "supersecret"}
async def test__async_current_entries_does_not_skip_ignore_non_user(hass, manager): async def test__async_current_entries_does_not_skip_ignore_non_user(
hass: HomeAssistant, manager
) -> None:
"""Test that _async_current_entries does not skip ignore by default for non user step.""" """Test that _async_current_entries does not skip ignore by default for non user step."""
hass.config.components.add("comp") hass.config.components.add("comp")
entry = MockConfigEntry( entry = MockConfigEntry(
@ -2082,7 +2109,9 @@ async def test__async_current_entries_does_not_skip_ignore_non_user(hass, manage
assert len(mock_setup_entry.mock_calls) == 0 assert len(mock_setup_entry.mock_calls) == 0
async def test__async_current_entries_explicit_skip_ignore(hass, manager): async def test__async_current_entries_explicit_skip_ignore(
hass: HomeAssistant, manager
) -> None:
"""Test that _async_current_entries can explicitly include ignore.""" """Test that _async_current_entries can explicitly include ignore."""
hass.config.components.add("comp") hass.config.components.add("comp")
entry = MockConfigEntry( entry = MockConfigEntry(
@ -2121,7 +2150,9 @@ async def test__async_current_entries_explicit_skip_ignore(hass, manager):
assert p_entry.data == {"token": "supersecret"} assert p_entry.data == {"token": "supersecret"}
async def test__async_current_entries_explicit_include_ignore(hass, manager): async def test__async_current_entries_explicit_include_ignore(
hass: HomeAssistant, manager
) -> None:
"""Test that _async_current_entries can explicitly include ignore.""" """Test that _async_current_entries can explicitly include ignore."""
hass.config.components.add("comp") hass.config.components.add("comp")
entry = MockConfigEntry( entry = MockConfigEntry(
@ -2156,7 +2187,7 @@ async def test__async_current_entries_explicit_include_ignore(hass, manager):
assert len(mock_setup_entry.mock_calls) == 0 assert len(mock_setup_entry.mock_calls) == 0
async def test_unignore_step_form(hass, manager): async def test_unignore_step_form(hass: HomeAssistant, manager) -> None:
"""Test that we can ignore flows that are in progress and have a unique ID, then rediscover them.""" """Test that we can ignore flows that are in progress and have a unique ID, then rediscover them."""
async_setup_entry = AsyncMock(return_value=True) async_setup_entry = AsyncMock(return_value=True)
mock_integration(hass, MockModule("comp", async_setup_entry=async_setup_entry)) mock_integration(hass, MockModule("comp", async_setup_entry=async_setup_entry))
@ -2201,7 +2232,7 @@ async def test_unignore_step_form(hass, manager):
assert len(hass.config_entries.async_entries("comp")) == 0 assert len(hass.config_entries.async_entries("comp")) == 0
async def test_unignore_create_entry(hass, manager): async def test_unignore_create_entry(hass: HomeAssistant, manager) -> None:
"""Test that we can ignore flows that are in progress and have a unique ID, then rediscover them.""" """Test that we can ignore flows that are in progress and have a unique ID, then rediscover them."""
async_setup_entry = AsyncMock(return_value=True) async_setup_entry = AsyncMock(return_value=True)
mock_integration(hass, MockModule("comp", async_setup_entry=async_setup_entry)) mock_integration(hass, MockModule("comp", async_setup_entry=async_setup_entry))
@ -2249,7 +2280,7 @@ async def test_unignore_create_entry(hass, manager):
assert len(hass.config_entries.flow.async_progress_by_handler("comp")) == 0 assert len(hass.config_entries.flow.async_progress_by_handler("comp")) == 0
async def test_unignore_default_impl(hass, manager): async def test_unignore_default_impl(hass: HomeAssistant, manager) -> None:
"""Test that resdicovery is a no-op by default.""" """Test that resdicovery is a no-op by default."""
async_setup_entry = AsyncMock(return_value=True) async_setup_entry = AsyncMock(return_value=True)
mock_integration(hass, MockModule("comp", async_setup_entry=async_setup_entry)) mock_integration(hass, MockModule("comp", async_setup_entry=async_setup_entry))
@ -2281,7 +2312,7 @@ async def test_unignore_default_impl(hass, manager):
assert len(hass.config_entries.flow.async_progress()) == 0 assert len(hass.config_entries.flow.async_progress()) == 0
async def test_partial_flows_hidden(hass, manager): async def test_partial_flows_hidden(hass: HomeAssistant, manager) -> None:
"""Test that flows that don't have a cur_step and haven't finished initing are hidden.""" """Test that flows that don't have a cur_step and haven't finished initing are hidden."""
async_setup_entry = AsyncMock(return_value=True) async_setup_entry = AsyncMock(return_value=True)
mock_integration(hass, MockModule("comp", async_setup_entry=async_setup_entry)) mock_integration(hass, MockModule("comp", async_setup_entry=async_setup_entry))
@ -2522,7 +2553,9 @@ async def test_async_setup_update_entry(hass: HomeAssistant) -> None:
), ),
), ),
) )
async def test_flow_with_default_discovery(hass, manager, discovery_source): async def test_flow_with_default_discovery(
hass: HomeAssistant, manager, discovery_source
) -> None:
"""Test that finishing a default discovery flow removes the unique ID in the entry.""" """Test that finishing a default discovery flow removes the unique ID in the entry."""
mock_integration( mock_integration(
hass, hass,
@ -2570,7 +2603,9 @@ async def test_flow_with_default_discovery(hass, manager, discovery_source):
assert entry.unique_id is None assert entry.unique_id is None
async def test_flow_with_default_discovery_with_unique_id(hass, manager): async def test_flow_with_default_discovery_with_unique_id(
hass: HomeAssistant, manager
) -> None:
"""Test discovery flow using the default discovery is ignored when unique ID is set.""" """Test discovery flow using the default discovery is ignored when unique ID is set."""
mock_integration(hass, MockModule("comp")) mock_integration(hass, MockModule("comp"))
mock_entity_platform(hass, "config_flow.comp", None) mock_entity_platform(hass, "config_flow.comp", None)
@ -2598,7 +2633,9 @@ async def test_flow_with_default_discovery_with_unique_id(hass, manager):
assert flows[0]["context"]["unique_id"] == "mock-unique-id" assert flows[0]["context"]["unique_id"] == "mock-unique-id"
async def test_default_discovery_abort_existing_entries(hass, manager): async def test_default_discovery_abort_existing_entries(
hass: HomeAssistant, manager
) -> None:
"""Test that a flow without discovery implementation aborts when a config entry exists.""" """Test that a flow without discovery implementation aborts when a config entry exists."""
hass.config.components.add("comp") hass.config.components.add("comp")
entry = MockConfigEntry(domain="comp", data={}, unique_id="mock-unique-id") entry = MockConfigEntry(domain="comp", data={}, unique_id="mock-unique-id")
@ -2620,7 +2657,7 @@ async def test_default_discovery_abort_existing_entries(hass, manager):
assert result["reason"] == "already_configured" assert result["reason"] == "already_configured"
async def test_default_discovery_in_progress(hass, manager): async def test_default_discovery_in_progress(hass: HomeAssistant, manager) -> None:
"""Test that a flow using default discovery can only be triggered once.""" """Test that a flow using default discovery can only be triggered once."""
mock_integration(hass, MockModule("comp")) mock_integration(hass, MockModule("comp"))
mock_entity_platform(hass, "config_flow.comp", None) mock_entity_platform(hass, "config_flow.comp", None)
@ -2655,7 +2692,9 @@ async def test_default_discovery_in_progress(hass, manager):
assert flows[0]["context"]["unique_id"] == "mock-unique-id" assert flows[0]["context"]["unique_id"] == "mock-unique-id"
async def test_default_discovery_abort_on_new_unique_flow(hass, manager): async def test_default_discovery_abort_on_new_unique_flow(
hass: HomeAssistant, manager
) -> None:
"""Test that a flow using default discovery is aborted when a second flow with unique ID is created.""" """Test that a flow using default discovery is aborted when a second flow with unique ID is created."""
mock_integration(hass, MockModule("comp")) mock_integration(hass, MockModule("comp"))
mock_entity_platform(hass, "config_flow.comp", None) mock_entity_platform(hass, "config_flow.comp", None)
@ -2692,7 +2731,9 @@ async def test_default_discovery_abort_on_new_unique_flow(hass, manager):
assert flows[0]["context"]["unique_id"] == "mock-unique-id" assert flows[0]["context"]["unique_id"] == "mock-unique-id"
async def test_default_discovery_abort_on_user_flow_complete(hass, manager): async def test_default_discovery_abort_on_user_flow_complete(
hass: HomeAssistant, manager
) -> None:
"""Test that a flow using default discovery is aborted when a second flow completes.""" """Test that a flow using default discovery is aborted when a second flow completes."""
mock_integration(hass, MockModule("comp")) mock_integration(hass, MockModule("comp"))
mock_entity_platform(hass, "config_flow.comp", None) mock_entity_platform(hass, "config_flow.comp", None)
@ -2741,7 +2782,7 @@ async def test_default_discovery_abort_on_user_flow_complete(hass, manager):
assert len(flows) == 0 assert len(flows) == 0
async def test_flow_same_device_multiple_sources(hass, manager): async def test_flow_same_device_multiple_sources(hass: HomeAssistant, manager) -> None:
"""Test discovery of the same devices from multiple discovery sources.""" """Test discovery of the same devices from multiple discovery sources."""
mock_integration( mock_integration(
hass, hass,
@ -2809,7 +2850,7 @@ async def test_flow_same_device_multiple_sources(hass, manager):
assert entry.unique_id == "thisid" assert entry.unique_id == "thisid"
async def test_updating_entry_with_and_without_changes(manager): async def test_updating_entry_with_and_without_changes(manager) -> None:
"""Test that we can update an entry data.""" """Test that we can update an entry data."""
entry = MockConfigEntry( entry = MockConfigEntry(
domain="test", domain="test",
@ -2836,7 +2877,9 @@ async def test_updating_entry_with_and_without_changes(manager):
assert manager.async_update_entry(entry, **change) is False assert manager.async_update_entry(entry, **change) is False
async def test_entry_reload_calls_on_unload_listeners(hass, manager): async def test_entry_reload_calls_on_unload_listeners(
hass: HomeAssistant, manager
) -> None:
"""Test reload calls the on unload listeners.""" """Test reload calls the on unload listeners."""
entry = MockConfigEntry(domain="comp", state=config_entries.ConfigEntryState.LOADED) entry = MockConfigEntry(domain="comp", state=config_entries.ConfigEntryState.LOADED)
entry.add_to_hass(hass) entry.add_to_hass(hass)
@ -2875,7 +2918,9 @@ async def test_entry_reload_calls_on_unload_listeners(hass, manager):
assert entry.state is config_entries.ConfigEntryState.LOADED assert entry.state is config_entries.ConfigEntryState.LOADED
async def test_setup_raise_entry_error(hass, caplog): async def test_setup_raise_entry_error(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test a setup raising ConfigEntryError.""" """Test a setup raising ConfigEntryError."""
entry = MockConfigEntry(title="test_title", domain="test") entry = MockConfigEntry(title="test_title", domain="test")
@ -2896,7 +2941,9 @@ async def test_setup_raise_entry_error(hass, caplog):
assert entry.reason == "Incompatible firmware version" assert entry.reason == "Incompatible firmware version"
async def test_setup_raise_entry_error_from_first_coordinator_update(hass, caplog): async def test_setup_raise_entry_error_from_first_coordinator_update(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test async_config_entry_first_refresh raises ConfigEntryError.""" """Test async_config_entry_first_refresh raises ConfigEntryError."""
entry = MockConfigEntry(title="test_title", domain="test") entry = MockConfigEntry(title="test_title", domain="test")
@ -2931,7 +2978,9 @@ async def test_setup_raise_entry_error_from_first_coordinator_update(hass, caplo
assert entry.reason == "Incompatible firmware version" assert entry.reason == "Incompatible firmware version"
async def test_setup_not_raise_entry_error_from_future_coordinator_update(hass, caplog): async def test_setup_not_raise_entry_error_from_future_coordinator_update(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test a coordinator not raises ConfigEntryError in the future.""" """Test a coordinator not raises ConfigEntryError in the future."""
entry = MockConfigEntry(title="test_title", domain="test") entry = MockConfigEntry(title="test_title", domain="test")
@ -2965,7 +3014,9 @@ async def test_setup_not_raise_entry_error_from_future_coordinator_update(hass,
assert entry.state is config_entries.ConfigEntryState.LOADED assert entry.state is config_entries.ConfigEntryState.LOADED
async def test_setup_raise_auth_failed(hass, caplog): async def test_setup_raise_auth_failed(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test a setup raising ConfigEntryAuthFailed.""" """Test a setup raising ConfigEntryAuthFailed."""
entry = MockConfigEntry(title="test_title", domain="test") entry = MockConfigEntry(title="test_title", domain="test")
@ -3001,7 +3052,9 @@ async def test_setup_raise_auth_failed(hass, caplog):
assert len(flows) == 1 assert len(flows) == 1
async def test_setup_raise_auth_failed_from_first_coordinator_update(hass, caplog): async def test_setup_raise_auth_failed_from_first_coordinator_update(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test async_config_entry_first_refresh raises ConfigEntryAuthFailed.""" """Test async_config_entry_first_refresh raises ConfigEntryAuthFailed."""
entry = MockConfigEntry(title="test_title", domain="test") entry = MockConfigEntry(title="test_title", domain="test")
@ -3048,7 +3101,9 @@ async def test_setup_raise_auth_failed_from_first_coordinator_update(hass, caplo
assert len(flows) == 1 assert len(flows) == 1
async def test_setup_raise_auth_failed_from_future_coordinator_update(hass, caplog): async def test_setup_raise_auth_failed_from_future_coordinator_update(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test a coordinator raises ConfigEntryAuthFailed in the future.""" """Test a coordinator raises ConfigEntryAuthFailed in the future."""
entry = MockConfigEntry(title="test_title", domain="test") entry = MockConfigEntry(title="test_title", domain="test")
@ -3158,7 +3213,9 @@ async def test_setup_retrying_during_shutdown(hass: HomeAssistant) -> None:
), # ensure options takes precedence over data ), # ensure options takes precedence over data
], ],
) )
async def test__async_abort_entries_match(hass, manager, matchers, reason): async def test__async_abort_entries_match(
hass: HomeAssistant, manager, matchers, reason
) -> None:
"""Test aborting if matching config entries exist.""" """Test aborting if matching config entries exist."""
MockConfigEntry( MockConfigEntry(
domain="comp", data={"ip": "1.2.3.4", "host": "4.5.6.7", "port": 23} domain="comp", data={"ip": "1.2.3.4", "host": "4.5.6.7", "port": 23}
@ -3210,7 +3267,9 @@ async def test__async_abort_entries_match(hass, manager, matchers, reason):
assert result["reason"] == reason assert result["reason"] == reason
async def test_loading_old_data(hass, hass_storage): async def test_loading_old_data(
hass: HomeAssistant, hass_storage: dict[str, Any]
) -> None:
"""Test automatically migrating old data.""" """Test automatically migrating old data."""
hass_storage[config_entries.STORAGE_KEY] = { hass_storage[config_entries.STORAGE_KEY] = {
"version": 1, "version": 1,
@ -3242,14 +3301,18 @@ async def test_loading_old_data(hass, hass_storage):
assert entry.pref_disable_new_entities is True assert entry.pref_disable_new_entities is True
async def test_deprecated_disabled_by_str_ctor(hass, caplog): async def test_deprecated_disabled_by_str_ctor(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test deprecated str disabled_by constructor enumizes and logs a warning.""" """Test deprecated str disabled_by constructor enumizes and logs a warning."""
entry = MockConfigEntry(disabled_by=config_entries.ConfigEntryDisabler.USER.value) entry = MockConfigEntry(disabled_by=config_entries.ConfigEntryDisabler.USER.value)
assert entry.disabled_by is config_entries.ConfigEntryDisabler.USER assert entry.disabled_by is config_entries.ConfigEntryDisabler.USER
assert " str for config entry disabled_by. This is deprecated " in caplog.text assert " str for config entry disabled_by. This is deprecated " in caplog.text
async def test_deprecated_disabled_by_str_set(hass, manager, caplog): async def test_deprecated_disabled_by_str_set(
hass: HomeAssistant, manager, caplog: pytest.LogCaptureFixture
) -> None:
"""Test deprecated str set disabled_by enumizes and logs a warning.""" """Test deprecated str set disabled_by enumizes and logs a warning."""
entry = MockConfigEntry() entry = MockConfigEntry()
entry.add_to_manager(manager) entry.add_to_manager(manager)
@ -3260,7 +3323,7 @@ async def test_deprecated_disabled_by_str_set(hass, manager, caplog):
assert " str for config entry disabled_by. This is deprecated " in caplog.text assert " str for config entry disabled_by. This is deprecated " in caplog.text
async def test_entry_reload_concurrency(hass, manager): async def test_entry_reload_concurrency(hass: HomeAssistant, manager) -> None:
"""Test multiple reload calls do not cause a reload race.""" """Test multiple reload calls do not cause a reload race."""
entry = MockConfigEntry(domain="comp", state=config_entries.ConfigEntryState.LOADED) entry = MockConfigEntry(domain="comp", state=config_entries.ConfigEntryState.LOADED)
entry.add_to_hass(hass) entry.add_to_hass(hass)
@ -3368,7 +3431,9 @@ async def test_unique_id_update_while_setup_in_progress(
assert entry.state is config_entries.ConfigEntryState.LOADED assert entry.state is config_entries.ConfigEntryState.LOADED
async def test_disallow_entry_reload_with_setup_in_progresss(hass, manager): async def test_disallow_entry_reload_with_setup_in_progresss(
hass: HomeAssistant, manager
) -> None:
"""Test we do not allow reload while the config entry is still setting up.""" """Test we do not allow reload while the config entry is still setting up."""
entry = MockConfigEntry( entry = MockConfigEntry(
domain="comp", state=config_entries.ConfigEntryState.SETUP_IN_PROGRESS domain="comp", state=config_entries.ConfigEntryState.SETUP_IN_PROGRESS
@ -3463,7 +3528,7 @@ async def test_get_active_flows(hass: HomeAssistant) -> None:
assert active_user_flow is None assert active_user_flow is None
async def test_async_wait_component_dynamic(hass: HomeAssistant): async def test_async_wait_component_dynamic(hass: HomeAssistant) -> None:
"""Test async_wait_component for a config entry which is dynamically loaded.""" """Test async_wait_component for a config entry which is dynamically loaded."""
entry = MockConfigEntry(title="test_title", domain="test") entry = MockConfigEntry(title="test_title", domain="test")
@ -3483,7 +3548,7 @@ async def test_async_wait_component_dynamic(hass: HomeAssistant):
assert await hass.config_entries.async_wait_component(entry) is True assert await hass.config_entries.async_wait_component(entry) is True
async def test_async_wait_component_startup(hass: HomeAssistant): async def test_async_wait_component_startup(hass: HomeAssistant) -> None:
"""Test async_wait_component for a config entry which is loaded at startup.""" """Test async_wait_component for a config entry which is loaded at startup."""
entry = MockConfigEntry(title="test_title", domain="test") entry = MockConfigEntry(title="test_title", domain="test")
@ -3547,7 +3612,9 @@ async def test_options_flow_options_not_mutated() -> None:
assert entry.options == {"sub_dict": {"1": "one"}, "sub_list": ["one"]} assert entry.options == {"sub_dict": {"1": "one"}, "sub_list": ["one"]}
async def test_initializing_flows_canceled_on_shutdown(hass: HomeAssistant, manager): async def test_initializing_flows_canceled_on_shutdown(
hass: HomeAssistant, manager
) -> None:
"""Test that initializing flows are canceled on shutdown.""" """Test that initializing flows are canceled on shutdown."""
class MockFlowHandler(config_entries.ConfigFlow): class MockFlowHandler(config_entries.ConfigFlow):
@ -3575,7 +3642,7 @@ async def test_initializing_flows_canceled_on_shutdown(hass: HomeAssistant, mana
await task await task
async def test_task_tracking(hass): async def test_task_tracking(hass: HomeAssistant) -> None:
"""Test task tracking for a config entry.""" """Test task tracking for a config entry."""
entry = MockConfigEntry(title="test_title", domain="test") entry = MockConfigEntry(title="test_title", domain="test")

View file

@ -86,7 +86,7 @@ def test_async_add_hass_job_schedule_partial_callback() -> None:
assert len(hass.add_job.mock_calls) == 0 assert len(hass.add_job.mock_calls) == 0
def test_async_add_hass_job_schedule_coroutinefunction(event_loop): def test_async_add_hass_job_schedule_coroutinefunction(event_loop) -> None:
"""Test that we schedule coroutines and add jobs to the job pool.""" """Test that we schedule coroutines and add jobs to the job pool."""
hass = MagicMock(loop=MagicMock(wraps=event_loop)) hass = MagicMock(loop=MagicMock(wraps=event_loop))
@ -99,7 +99,7 @@ def test_async_add_hass_job_schedule_coroutinefunction(event_loop):
assert len(hass.add_job.mock_calls) == 0 assert len(hass.add_job.mock_calls) == 0
def test_async_add_hass_job_schedule_partial_coroutinefunction(event_loop): def test_async_add_hass_job_schedule_partial_coroutinefunction(event_loop) -> None:
"""Test that we schedule partial coros and add jobs to the job pool.""" """Test that we schedule partial coros and add jobs to the job pool."""
hass = MagicMock(loop=MagicMock(wraps=event_loop)) hass = MagicMock(loop=MagicMock(wraps=event_loop))
@ -127,7 +127,7 @@ def test_async_add_job_add_hass_threaded_job_to_pool() -> None:
assert len(hass.loop.run_in_executor.mock_calls) == 2 assert len(hass.loop.run_in_executor.mock_calls) == 2
def test_async_create_task_schedule_coroutine(event_loop): def test_async_create_task_schedule_coroutine(event_loop) -> None:
"""Test that we schedule coroutines and add jobs to the job pool.""" """Test that we schedule coroutines and add jobs to the job pool."""
hass = MagicMock(loop=MagicMock(wraps=event_loop)) hass = MagicMock(loop=MagicMock(wraps=event_loop))
@ -181,7 +181,7 @@ async def test_stage_shutdown(hass: HomeAssistant) -> None:
assert len(test_all) == 2 assert len(test_all) == 2
async def test_stage_shutdown_with_exit_code(hass): async def test_stage_shutdown_with_exit_code(hass: HomeAssistant) -> None:
"""Simulate a shutdown, test calling stuff with exit code checks.""" """Simulate a shutdown, test calling stuff with exit code checks."""
test_stop = async_capture_events(hass, EVENT_HOMEASSISTANT_STOP) test_stop = async_capture_events(hass, EVENT_HOMEASSISTANT_STOP)
test_final_write = async_capture_events(hass, EVENT_HOMEASSISTANT_FINAL_WRITE) test_final_write = async_capture_events(hass, EVENT_HOMEASSISTANT_FINAL_WRITE)
@ -222,8 +222,8 @@ async def test_stage_shutdown_with_exit_code(hass):
async def test_shutdown_calls_block_till_done_after_shutdown_run_callback_threadsafe( async def test_shutdown_calls_block_till_done_after_shutdown_run_callback_threadsafe(
hass, hass: HomeAssistant,
): ) -> None:
"""Ensure shutdown_run_callback_threadsafe is called before the final async_block_till_done.""" """Ensure shutdown_run_callback_threadsafe is called before the final async_block_till_done."""
stop_calls = [] stop_calls = []
@ -1179,7 +1179,9 @@ async def test_bad_timezone_raises_value_error(hass: HomeAssistant) -> None:
await hass.config.async_update(time_zone="not_a_timezone") await hass.config.async_update(time_zone="not_a_timezone")
async def test_start_taking_too_long(event_loop, caplog): async def test_start_taking_too_long(
event_loop, caplog: pytest.LogCaptureFixture
) -> None:
"""Test when async_start takes too long.""" """Test when async_start takes too long."""
hass = ha.HomeAssistant() hass = ha.HomeAssistant()
caplog.set_level(logging.WARNING) caplog.set_level(logging.WARNING)
@ -1288,7 +1290,7 @@ async def test_async_functions_with_callback(hass: HomeAssistant) -> None:
@pytest.mark.parametrize("cancel_call", [True, False]) @pytest.mark.parametrize("cancel_call", [True, False])
async def test_cancel_service_task(hass, cancel_call): async def test_cancel_service_task(hass: HomeAssistant, cancel_call) -> None:
"""Test cancellation.""" """Test cancellation."""
service_called = asyncio.Event() service_called = asyncio.Event()
service_cancelled = False service_cancelled = False
@ -1354,7 +1356,9 @@ def test_valid_entity_id() -> None:
assert ha.valid_entity_id(valid), valid assert ha.valid_entity_id(valid), valid
async def test_additional_data_in_core_config(hass, hass_storage): async def test_additional_data_in_core_config(
hass: HomeAssistant, hass_storage: dict[str, Any]
) -> None:
"""Test that we can handle additional data in core configuration.""" """Test that we can handle additional data in core configuration."""
config = ha.Config(hass) config = ha.Config(hass)
hass_storage[ha.CORE_STORAGE_KEY] = { hass_storage[ha.CORE_STORAGE_KEY] = {
@ -1365,7 +1369,9 @@ async def test_additional_data_in_core_config(hass, hass_storage):
assert config.location_name == "Test Name" assert config.location_name == "Test Name"
async def test_incorrect_internal_external_url(hass, hass_storage, caplog): async def test_incorrect_internal_external_url(
hass: HomeAssistant, hass_storage: dict[str, Any], caplog: pytest.LogCaptureFixture
) -> None:
"""Test that we warn when detecting invalid internal/external url.""" """Test that we warn when detecting invalid internal/external url."""
config = ha.Config(hass) config = ha.Config(hass)
@ -1426,7 +1432,9 @@ async def test_start_events(hass: HomeAssistant) -> None:
assert core_states == [ha.CoreState.starting, ha.CoreState.running] assert core_states == [ha.CoreState.starting, ha.CoreState.running]
async def test_log_blocking_events(hass, caplog): async def test_log_blocking_events(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Ensure we log which task is blocking startup when debug logging is on.""" """Ensure we log which task is blocking startup when debug logging is on."""
caplog.set_level(logging.DEBUG) caplog.set_level(logging.DEBUG)
@ -1447,7 +1455,9 @@ async def test_log_blocking_events(hass, caplog):
assert "_wait_a_bit_1" not in caplog.text assert "_wait_a_bit_1" not in caplog.text
async def test_chained_logging_hits_log_timeout(hass, caplog): async def test_chained_logging_hits_log_timeout(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Ensure we log which task is blocking startup when there is a task chain and debug logging is on.""" """Ensure we log which task is blocking startup when there is a task chain and debug logging is on."""
caplog.set_level(logging.DEBUG) caplog.set_level(logging.DEBUG)
@ -1474,7 +1484,9 @@ async def test_chained_logging_hits_log_timeout(hass, caplog):
assert "_task_chain_" in caplog.text assert "_task_chain_" in caplog.text
async def test_chained_logging_misses_log_timeout(hass, caplog): async def test_chained_logging_misses_log_timeout(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Ensure we do not log which task is blocking startup if we do not hit the timeout.""" """Ensure we do not log which task is blocking startup if we do not hit the timeout."""
caplog.set_level(logging.DEBUG) caplog.set_level(logging.DEBUG)
@ -1975,7 +1987,7 @@ async def test_state_changed_events_to_not_leak_contexts(hass: HomeAssistant) ->
assert len(_get_by_type("homeassistant.core.Context")) == init_count assert len(_get_by_type("homeassistant.core.Context")) == init_count
async def test_background_task(hass): async def test_background_task(hass: HomeAssistant) -> None:
"""Test background tasks being quit.""" """Test background tasks being quit."""
result = asyncio.Future() result = asyncio.Future()

View file

@ -46,7 +46,7 @@ def manager():
return mgr return mgr
async def test_configure_reuses_handler_instance(manager): async def test_configure_reuses_handler_instance(manager) -> None:
"""Test that we reuse instances.""" """Test that we reuse instances."""
@manager.mock_reg_handler("test") @manager.mock_reg_handler("test")
@ -109,7 +109,7 @@ async def test_configure_two_steps(manager: data_entry_flow.FlowManager) -> None
assert result["data"] == ["INIT-DATA", "SECOND-DATA"] assert result["data"] == ["INIT-DATA", "SECOND-DATA"]
async def test_show_form(manager): async def test_show_form(manager) -> None:
"""Test that we can show a form.""" """Test that we can show a form."""
schema = vol.Schema({vol.Required("username"): str, vol.Required("password"): str}) schema = vol.Schema({vol.Required("username"): str, vol.Required("password"): str})
@ -128,7 +128,7 @@ async def test_show_form(manager):
assert form["errors"] == {"username": "Should be unique."} assert form["errors"] == {"username": "Should be unique."}
async def test_abort_removes_instance(manager): async def test_abort_removes_instance(manager) -> None:
"""Test that abort removes the flow from progress.""" """Test that abort removes the flow from progress."""
@manager.mock_reg_handler("test") @manager.mock_reg_handler("test")
@ -150,7 +150,7 @@ async def test_abort_removes_instance(manager):
assert len(manager.mock_created_entries) == 0 assert len(manager.mock_created_entries) == 0
async def test_abort_calls_async_remove(manager): async def test_abort_calls_async_remove(manager) -> None:
"""Test abort calling the async_remove FlowHandler method.""" """Test abort calling the async_remove FlowHandler method."""
@manager.mock_reg_handler("test") @manager.mock_reg_handler("test")
@ -168,7 +168,9 @@ async def test_abort_calls_async_remove(manager):
assert len(manager.mock_created_entries) == 0 assert len(manager.mock_created_entries) == 0
async def test_abort_calls_async_remove_with_exception(manager, caplog): async def test_abort_calls_async_remove_with_exception(
manager, caplog: pytest.LogCaptureFixture
) -> None:
"""Test abort calling the async_remove FlowHandler method, with an exception.""" """Test abort calling the async_remove FlowHandler method, with an exception."""
@manager.mock_reg_handler("test") @manager.mock_reg_handler("test")
@ -189,7 +191,7 @@ async def test_abort_calls_async_remove_with_exception(manager, caplog):
assert len(manager.mock_created_entries) == 0 assert len(manager.mock_created_entries) == 0
async def test_create_saves_data(manager): async def test_create_saves_data(manager) -> None:
"""Test creating a config entry.""" """Test creating a config entry."""
@manager.mock_reg_handler("test") @manager.mock_reg_handler("test")
@ -211,7 +213,7 @@ async def test_create_saves_data(manager):
assert entry["source"] is None assert entry["source"] is None
async def test_discovery_init_flow(manager): async def test_discovery_init_flow(manager) -> None:
"""Test a flow initialized by discovery.""" """Test a flow initialized by discovery."""
@manager.mock_reg_handler("test") @manager.mock_reg_handler("test")
@ -283,7 +285,7 @@ async def test_finish_callback_change_result_type(hass: HomeAssistant) -> None:
assert result["result"] == 2 assert result["result"] == 2
async def test_external_step(hass, manager): async def test_external_step(hass: HomeAssistant, manager) -> None:
"""Test external step logic.""" """Test external step logic."""
manager.hass = hass manager.hass = hass
@ -333,7 +335,7 @@ async def test_external_step(hass, manager):
assert result["title"] == "Hello" assert result["title"] == "Hello"
async def test_show_progress(hass, manager): async def test_show_progress(hass: HomeAssistant, manager) -> None:
"""Test show progress logic.""" """Test show progress logic."""
manager.hass = hass manager.hass = hass
@ -405,7 +407,7 @@ async def test_show_progress(hass, manager):
assert result["title"] == "Hello" assert result["title"] == "Hello"
async def test_abort_flow_exception(manager): async def test_abort_flow_exception(manager) -> None:
"""Test that the AbortFlow exception works.""" """Test that the AbortFlow exception works."""
@manager.mock_reg_handler("test") @manager.mock_reg_handler("test")
@ -419,7 +421,7 @@ async def test_abort_flow_exception(manager):
assert form["description_placeholders"] == {"placeholder": "yo"} assert form["description_placeholders"] == {"placeholder": "yo"}
async def test_init_unknown_flow(manager): async def test_init_unknown_flow(manager) -> None:
"""Test that UnknownFlow is raised when async_create_flow returns None.""" """Test that UnknownFlow is raised when async_create_flow returns None."""
with pytest.raises(data_entry_flow.UnknownFlow), patch.object( with pytest.raises(data_entry_flow.UnknownFlow), patch.object(
@ -428,7 +430,7 @@ async def test_init_unknown_flow(manager):
await manager.async_init("test") await manager.async_init("test")
async def test_async_get_unknown_flow(manager): async def test_async_get_unknown_flow(manager) -> None:
"""Test that UnknownFlow is raised when async_get is called with a flow_id that does not exist.""" """Test that UnknownFlow is raised when async_get is called with a flow_id that does not exist."""
with pytest.raises(data_entry_flow.UnknownFlow): with pytest.raises(data_entry_flow.UnknownFlow):
@ -437,7 +439,7 @@ async def test_async_get_unknown_flow(manager):
async def test_async_has_matching_flow( async def test_async_has_matching_flow(
hass: HomeAssistant, manager: data_entry_flow.FlowManager hass: HomeAssistant, manager: data_entry_flow.FlowManager
): ) -> None:
"""Test we can check for matching flows.""" """Test we can check for matching flows."""
manager.hass = hass manager.hass = hass
@ -488,7 +490,9 @@ async def test_async_has_matching_flow(
) )
async def test_move_to_unknown_step_raises_and_removes_from_in_progress(manager): async def test_move_to_unknown_step_raises_and_removes_from_in_progress(
manager,
) -> None:
"""Test that moving to an unknown step raises and removes the flow from in progress.""" """Test that moving to an unknown step raises and removes the flow from in progress."""
@manager.mock_reg_handler("test") @manager.mock_reg_handler("test")
@ -501,13 +505,13 @@ async def test_move_to_unknown_step_raises_and_removes_from_in_progress(manager)
assert manager.async_progress() == [] assert manager.async_progress() == []
async def test_configure_raises_unknown_flow_if_not_in_progress(manager): async def test_configure_raises_unknown_flow_if_not_in_progress(manager) -> None:
"""Test configure raises UnknownFlow if the flow is not in progress.""" """Test configure raises UnknownFlow if the flow is not in progress."""
with pytest.raises(data_entry_flow.UnknownFlow): with pytest.raises(data_entry_flow.UnknownFlow):
await manager.async_configure("wrong_flow_id") await manager.async_configure("wrong_flow_id")
async def test_abort_raises_unknown_flow_if_not_in_progress(manager): async def test_abort_raises_unknown_flow_if_not_in_progress(manager) -> None:
"""Test abort raises UnknownFlow if the flow is not in progress.""" """Test abort raises UnknownFlow if the flow is not in progress."""
with pytest.raises(data_entry_flow.UnknownFlow): with pytest.raises(data_entry_flow.UnknownFlow):
await manager.async_abort("wrong_flow_id") await manager.async_abort("wrong_flow_id")
@ -517,7 +521,7 @@ async def test_abort_raises_unknown_flow_if_not_in_progress(manager):
"menu_options", "menu_options",
(["target1", "target2"], {"target1": "Target 1", "target2": "Target 2"}), (["target1", "target2"], {"target1": "Target 1", "target2": "Target 2"}),
) )
async def test_show_menu(hass, manager, menu_options): async def test_show_menu(hass: HomeAssistant, manager, menu_options) -> None:
"""Test show menu.""" """Test show menu."""
manager.hass = hass manager.hass = hass

View file

@ -83,7 +83,9 @@ async def test_helpers_wrapper(hass: HomeAssistant) -> None:
assert result == ["hello"] assert result == ["hello"]
async def test_custom_component_name(hass, enable_custom_integrations): async def test_custom_component_name(
hass: HomeAssistant, enable_custom_integrations: None
) -> None:
"""Test the name attribute of custom components.""" """Test the name attribute of custom components."""
with pytest.raises(loader.IntegrationNotFound): with pytest.raises(loader.IntegrationNotFound):
await loader.async_get_integration(hass, "test_standalone") await loader.async_get_integration(hass, "test_standalone")
@ -109,7 +111,11 @@ async def test_custom_component_name(hass, enable_custom_integrations):
assert TEST == 5 assert TEST == 5
async def test_log_warning_custom_component(hass, caplog, enable_custom_integrations): async def test_log_warning_custom_component(
hass: HomeAssistant,
caplog: pytest.LogCaptureFixture,
enable_custom_integrations: None,
) -> None:
"""Test that we log a warning when loading a custom component.""" """Test that we log a warning when loading a custom component."""
await loader.async_get_integration(hass, "test_package") await loader.async_get_integration(hass, "test_package")
@ -120,8 +126,10 @@ async def test_log_warning_custom_component(hass, caplog, enable_custom_integrat
async def test_custom_integration_version_not_valid( async def test_custom_integration_version_not_valid(
hass, caplog, enable_custom_integrations hass: HomeAssistant,
): caplog: pytest.LogCaptureFixture,
enable_custom_integrations: None,
) -> None:
"""Test that we log a warning when custom integrations have a invalid version.""" """Test that we log a warning when custom integrations have a invalid version."""
with pytest.raises(loader.IntegrationNotFound): with pytest.raises(loader.IntegrationNotFound):
await loader.async_get_integration(hass, "test_no_version") await loader.async_get_integration(hass, "test_no_version")
@ -161,14 +169,18 @@ async def test_get_integration_exceptions(hass: HomeAssistant) -> None:
assert hue_light == integration.get_platform("light") assert hue_light == integration.get_platform("light")
async def test_get_integration_legacy(hass, enable_custom_integrations): async def test_get_integration_legacy(
hass: HomeAssistant, enable_custom_integrations: None
) -> None:
"""Test resolving integration.""" """Test resolving integration."""
integration = await loader.async_get_integration(hass, "test_embedded") integration = await loader.async_get_integration(hass, "test_embedded")
assert integration.get_component().DOMAIN == "test_embedded" assert integration.get_component().DOMAIN == "test_embedded"
assert integration.get_platform("switch") is not None assert integration.get_platform("switch") is not None
async def test_get_integration_custom_component(hass, enable_custom_integrations): async def test_get_integration_custom_component(
hass: HomeAssistant, enable_custom_integrations: None
) -> None:
"""Test resolving integration.""" """Test resolving integration."""
integration = await loader.async_get_integration(hass, "test_package") integration = await loader.async_get_integration(hass, "test_package")
assert integration.get_component().DOMAIN == "test_package" assert integration.get_component().DOMAIN == "test_package"
@ -461,7 +473,9 @@ def _get_test_integration_with_usb_matcher(hass, name, config_flow):
) )
async def test_get_custom_components(hass, enable_custom_integrations): async def test_get_custom_components(
hass: HomeAssistant, enable_custom_integrations: None
) -> None:
"""Verify that custom components are cached.""" """Verify that custom components are cached."""
test_1_integration = _get_test_integration(hass, "test_1", False) test_1_integration = _get_test_integration(hass, "test_1", False)
test_2_integration = _get_test_integration(hass, "test_2", True) test_2_integration = _get_test_integration(hass, "test_2", True)
@ -663,7 +677,9 @@ async def test_get_custom_components_safe_mode(hass: HomeAssistant) -> None:
assert await loader.async_get_custom_components(hass) == {} assert await loader.async_get_custom_components(hass) == {}
async def test_custom_integration_missing_version(hass, caplog): async def test_custom_integration_missing_version(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test trying to load a custom integration without a version twice does not deadlock.""" """Test trying to load a custom integration without a version twice does not deadlock."""
with pytest.raises(loader.IntegrationNotFound): with pytest.raises(loader.IntegrationNotFound):
await loader.async_get_integration(hass, "test_no_version") await loader.async_get_integration(hass, "test_no_version")
@ -672,7 +688,9 @@ async def test_custom_integration_missing_version(hass, caplog):
await loader.async_get_integration(hass, "test_no_version") await loader.async_get_integration(hass, "test_no_version")
async def test_custom_integration_missing(hass, caplog): async def test_custom_integration_missing(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test trying to load a custom integration that is missing twice not deadlock.""" """Test trying to load a custom integration that is missing twice not deadlock."""
with patch("homeassistant.loader.async_get_custom_components") as mock_get: with patch("homeassistant.loader.async_get_custom_components") as mock_get:
mock_get.return_value = {} mock_get.return_value = {}

View file

@ -6,7 +6,7 @@ from homeassistant.const import REQUIRED_PYTHON_VER
@patch("sys.exit") @patch("sys.exit")
def test_validate_python(mock_exit): def test_validate_python(mock_exit) -> None:
"""Test validate Python version method.""" """Test validate Python version method."""
with patch("sys.version_info", new_callable=PropertyMock(return_value=(2, 7, 8))): with patch("sys.version_info", new_callable=PropertyMock(return_value=(2, 7, 8))):
main.validate_python() main.validate_python()
@ -64,7 +64,7 @@ def test_validate_python(mock_exit):
@patch("sys.exit") @patch("sys.exit")
def test_skip_pip_mutually_exclusive(mock_exit): def test_skip_pip_mutually_exclusive(mock_exit) -> None:
"""Test --skip-pip and --skip-pip-package are mutually exclusive.""" """Test --skip-pip and --skip-pip-package are mutually exclusive."""
def parse_args(*args): def parse_args(*args):

View file

@ -95,7 +95,9 @@ async def test_install_missing_package(hass: HomeAssistant) -> None:
assert len(mock_inst.mock_calls) == 3 assert len(mock_inst.mock_calls) == 3
async def test_install_skipped_package(hass, caplog): async def test_install_skipped_package(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test an install attempt on a dependency that should be skipped.""" """Test an install attempt on a dependency that should be skipped."""
with patch( with patch(
"homeassistant.util.package.install_package", return_value=True "homeassistant.util.package.install_package", return_value=True
@ -453,7 +455,9 @@ async def test_discovery_requirements_ssdp(hass: HomeAssistant) -> None:
"partial_manifest", "partial_manifest",
[{"zeroconf": ["_googlecast._tcp.local."]}, {"homekit": {"models": ["LIFX"]}}], [{"zeroconf": ["_googlecast._tcp.local."]}, {"homekit": {"models": ["LIFX"]}}],
) )
async def test_discovery_requirements_zeroconf(hass, partial_manifest): async def test_discovery_requirements_zeroconf(
hass: HomeAssistant, partial_manifest
) -> None:
"""Test that we load discovery requirements.""" """Test that we load discovery requirements."""
hass.config.skip_pip = False hass.config.skip_pip = False
zeroconf = await loader.async_get_integration(hass, "zeroconf") zeroconf = await loader.async_get_integration(hass, "zeroconf")

View file

@ -1,5 +1,4 @@
"""Test the runner.""" """Test the runner."""
import asyncio import asyncio
import threading import threading
from unittest.mock import patch from unittest.mock import patch
@ -7,6 +6,7 @@ from unittest.mock import patch
import pytest import pytest
from homeassistant import core, runner from homeassistant import core, runner
from homeassistant.core import HomeAssistant
from homeassistant.util import executor, thread from homeassistant.util import executor, thread
# https://github.com/home-assistant/supervisor/blob/main/supervisor/docker/homeassistant.py # https://github.com/home-assistant/supervisor/blob/main/supervisor/docker/homeassistant.py
@ -28,7 +28,7 @@ async def test_cumulative_shutdown_timeout_less_than_supervisor() -> None:
) )
async def test_setup_and_run_hass(hass, tmpdir): async def test_setup_and_run_hass(hass: HomeAssistant, tmpdir) -> None:
"""Test we can setup and run.""" """Test we can setup and run."""
test_dir = tmpdir.mkdir("config") test_dir = tmpdir.mkdir("config")
default_config = runner.RuntimeConfig(test_dir) default_config = runner.RuntimeConfig(test_dir)
@ -42,7 +42,7 @@ async def test_setup_and_run_hass(hass, tmpdir):
assert mock_run.called assert mock_run.called
def test_run(hass, tmpdir): def test_run(hass: HomeAssistant, tmpdir) -> None:
"""Test we can run.""" """Test we can run."""
test_dir = tmpdir.mkdir("config") test_dir = tmpdir.mkdir("config")
default_config = runner.RuntimeConfig(test_dir) default_config = runner.RuntimeConfig(test_dir)
@ -57,7 +57,7 @@ def test_run(hass, tmpdir):
assert mock_run.called assert mock_run.called
def test_run_executor_shutdown_throws(hass, tmpdir): def test_run_executor_shutdown_throws(hass: HomeAssistant, tmpdir) -> None:
"""Test we can run and we still shutdown if the executor shutdown throws.""" """Test we can run and we still shutdown if the executor shutdown throws."""
test_dir = tmpdir.mkdir("config") test_dir = tmpdir.mkdir("config")
default_config = runner.RuntimeConfig(test_dir) default_config = runner.RuntimeConfig(test_dir)
@ -78,7 +78,9 @@ def test_run_executor_shutdown_throws(hass, tmpdir):
assert mock_run.called assert mock_run.called
def test_run_does_not_block_forever_with_shielded_task(hass, tmpdir, caplog): def test_run_does_not_block_forever_with_shielded_task(
hass: HomeAssistant, tmpdir, caplog: pytest.LogCaptureFixture
) -> None:
"""Test we can shutdown and not block forever.""" """Test we can shutdown and not block forever."""
test_dir = tmpdir.mkdir("config") test_dir = tmpdir.mkdir("config")
default_config = runner.RuntimeConfig(test_dir) default_config = runner.RuntimeConfig(test_dir)
@ -119,7 +121,9 @@ def test_run_does_not_block_forever_with_shielded_task(hass, tmpdir, caplog):
) )
async def test_unhandled_exception_traceback(hass, caplog): async def test_unhandled_exception_traceback(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test an unhandled exception gets a traceback in debug mode.""" """Test an unhandled exception gets a traceback in debug mode."""
raised = asyncio.Event() raised = asyncio.Event()
@ -142,7 +146,7 @@ async def test_unhandled_exception_traceback(hass, caplog):
assert "_unhandled_exception" in caplog.text assert "_unhandled_exception" in caplog.text
def test__enable_posix_spawn(): def test__enable_posix_spawn() -> None:
"""Test that we can enable posix_spawn on Alpine.""" """Test that we can enable posix_spawn on Alpine."""
def _mock_alpine_exists(path): def _mock_alpine_exists(path):

View file

@ -80,7 +80,9 @@ async def test_validate_component_config(hass: HomeAssistant) -> None:
) )
async def test_validate_platform_config(hass, caplog): async def test_validate_platform_config(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test validating platform configuration.""" """Test validating platform configuration."""
platform_schema = PLATFORM_SCHEMA.extend({"hello": str}) platform_schema = PLATFORM_SCHEMA.extend({"hello": str})
platform_schema_base = PLATFORM_SCHEMA_BASE.extend({}) platform_schema_base = PLATFORM_SCHEMA_BASE.extend({})
@ -139,7 +141,9 @@ async def test_validate_platform_config(hass, caplog):
assert not config["platform_conf"] # empty assert not config["platform_conf"] # empty
async def test_validate_platform_config_2(hass, caplog): async def test_validate_platform_config_2(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test component PLATFORM_SCHEMA_BASE prio over PLATFORM_SCHEMA.""" """Test component PLATFORM_SCHEMA_BASE prio over PLATFORM_SCHEMA."""
platform_schema = PLATFORM_SCHEMA.extend({"hello": str}) platform_schema = PLATFORM_SCHEMA.extend({"hello": str})
platform_schema_base = PLATFORM_SCHEMA_BASE.extend({"hello": "world"}) platform_schema_base = PLATFORM_SCHEMA_BASE.extend({"hello": "world"})
@ -171,7 +175,9 @@ async def test_validate_platform_config_2(hass, caplog):
) )
async def test_validate_platform_config_3(hass, caplog): async def test_validate_platform_config_3(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test fallback to component PLATFORM_SCHEMA.""" """Test fallback to component PLATFORM_SCHEMA."""
component_schema = PLATFORM_SCHEMA_BASE.extend({"hello": str}) component_schema = PLATFORM_SCHEMA_BASE.extend({"hello": str})
platform_schema = PLATFORM_SCHEMA.extend({"cheers": str, "hello": "world"}) platform_schema = PLATFORM_SCHEMA.extend({"cheers": str, "hello": "world"})
@ -500,7 +506,9 @@ async def test_platform_no_warn_slow(hass: HomeAssistant) -> None:
assert len(mock_call.mock_calls) == 0 assert len(mock_call.mock_calls) == 0
async def test_platform_error_slow_setup(hass, caplog): async def test_platform_error_slow_setup(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Don't block startup more than SLOW_SETUP_MAX_WAIT.""" """Don't block startup more than SLOW_SETUP_MAX_WAIT."""
with patch.object(setup, "SLOW_SETUP_MAX_WAIT", 0.1): with patch.object(setup, "SLOW_SETUP_MAX_WAIT", 0.1):
@ -589,7 +597,7 @@ async def test_setup_import_blows_up(hass: HomeAssistant) -> None:
assert not await setup.async_setup_component(hass, "sun", {}) assert not await setup.async_setup_component(hass, "sun", {})
async def test_parallel_entry_setup(hass, mock_handlers): async def test_parallel_entry_setup(hass: HomeAssistant, mock_handlers) -> None:
"""Test config entries are set up in parallel.""" """Test config entries are set up in parallel."""
MockConfigEntry(domain="comp", data={"value": 1}).add_to_hass(hass) MockConfigEntry(domain="comp", data={"value": 1}).add_to_hass(hass)
MockConfigEntry(domain="comp", data={"value": 2}).add_to_hass(hass) MockConfigEntry(domain="comp", data={"value": 2}).add_to_hass(hass)
@ -616,7 +624,9 @@ async def test_parallel_entry_setup(hass, mock_handlers):
assert calls == [1, 2, 1, 2] assert calls == [1, 2, 1, 2]
async def test_integration_disabled(hass, caplog): async def test_integration_disabled(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test we can disable an integration.""" """Test we can disable an integration."""
disabled_reason = "Dependency contains code that breaks Home Assistant" disabled_reason = "Dependency contains code that breaks Home Assistant"
mock_integration( mock_integration(
@ -628,7 +638,9 @@ async def test_integration_disabled(hass, caplog):
assert disabled_reason in caplog.text assert disabled_reason in caplog.text
async def test_integration_logs_is_custom(hass, caplog): async def test_integration_logs_is_custom(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test we highlight it's a custom component when errors happen.""" """Test we highlight it's a custom component when errors happen."""
mock_integration( mock_integration(
hass, hass,
@ -662,7 +674,9 @@ async def test_async_get_loaded_integrations(hass: HomeAssistant) -> None:
} }
async def test_integration_no_setup(hass, caplog): async def test_integration_no_setup(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
) -> None:
"""Test we fail integration setup without setup functions.""" """Test we fail integration setup without setup functions."""
mock_integration( mock_integration(
hass, hass,

View file

@ -13,7 +13,7 @@ def test_sockets_disabled() -> None:
socket.socket() socket.socket()
def test_sockets_enabled(socket_enabled): def test_sockets_enabled(socket_enabled) -> None:
"""Test we can't connect to an address different from 127.0.0.1.""" """Test we can't connect to an address different from 127.0.0.1."""
mysocket = socket.socket() mysocket = socket.socket()
with pytest.raises(pytest_socket.SocketConnectBlockedError): with pytest.raises(pytest_socket.SocketConnectBlockedError):

View file

@ -11,6 +11,7 @@ import pytest
import yaml as pyyaml import yaml as pyyaml
from homeassistant.config import YAML_CONFIG_FILE, load_yaml_config_file from homeassistant.config import YAML_CONFIG_FILE, load_yaml_config_file
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
import homeassistant.util.yaml as yaml import homeassistant.util.yaml as yaml
from homeassistant.util.yaml import loader as yaml_loader from homeassistant.util.yaml import loader as yaml_loader
@ -52,7 +53,7 @@ def try_both_dumpers(request):
importlib.reload(yaml_loader) importlib.reload(yaml_loader)
def test_simple_list(try_both_loaders): def test_simple_list(try_both_loaders) -> None:
"""Test simple list.""" """Test simple list."""
conf = "config:\n - simple\n - list" conf = "config:\n - simple\n - list"
with io.StringIO(conf) as file: with io.StringIO(conf) as file:
@ -60,7 +61,7 @@ def test_simple_list(try_both_loaders):
assert doc["config"] == ["simple", "list"] assert doc["config"] == ["simple", "list"]
def test_simple_dict(try_both_loaders): def test_simple_dict(try_both_loaders) -> None:
"""Test simple dict.""" """Test simple dict."""
conf = "key: value" conf = "key: value"
with io.StringIO(conf) as file: with io.StringIO(conf) as file:
@ -82,7 +83,7 @@ def test_no_key(try_both_loaders, mock_hass_config_yaml: None) -> None:
yaml.load_yaml(YAML_CONFIG_FILE) yaml.load_yaml(YAML_CONFIG_FILE)
def test_environment_variable(try_both_loaders): def test_environment_variable(try_both_loaders) -> None:
"""Test config file with environment variable.""" """Test config file with environment variable."""
os.environ["PASSWORD"] = "secret_password" os.environ["PASSWORD"] = "secret_password"
conf = "password: !env_var PASSWORD" conf = "password: !env_var PASSWORD"
@ -92,7 +93,7 @@ def test_environment_variable(try_both_loaders):
del os.environ["PASSWORD"] del os.environ["PASSWORD"]
def test_environment_variable_default(try_both_loaders): def test_environment_variable_default(try_both_loaders) -> None:
"""Test config file with default value for environment variable.""" """Test config file with default value for environment variable."""
conf = "password: !env_var PASSWORD secret_password" conf = "password: !env_var PASSWORD secret_password"
with io.StringIO(conf) as file: with io.StringIO(conf) as file:
@ -100,7 +101,7 @@ def test_environment_variable_default(try_both_loaders):
assert doc["password"] == "secret_password" assert doc["password"] == "secret_password"
def test_invalid_environment_variable(try_both_loaders): def test_invalid_environment_variable(try_both_loaders) -> None:
"""Test config file with no environment variable sat.""" """Test config file with no environment variable sat."""
conf = "password: !env_var PASSWORD" conf = "password: !env_var PASSWORD"
with pytest.raises(HomeAssistantError), io.StringIO(conf) as file: with pytest.raises(HomeAssistantError), io.StringIO(conf) as file:
@ -323,19 +324,19 @@ def test_include_dir_merge_named_recursive(
@patch("homeassistant.util.yaml.loader.open", create=True) @patch("homeassistant.util.yaml.loader.open", create=True)
def test_load_yaml_encoding_error(mock_open, try_both_loaders): def test_load_yaml_encoding_error(mock_open, try_both_loaders) -> None:
"""Test raising a UnicodeDecodeError.""" """Test raising a UnicodeDecodeError."""
mock_open.side_effect = UnicodeDecodeError("", b"", 1, 0, "") mock_open.side_effect = UnicodeDecodeError("", b"", 1, 0, "")
with pytest.raises(HomeAssistantError): with pytest.raises(HomeAssistantError):
yaml_loader.load_yaml("test") yaml_loader.load_yaml("test")
def test_dump(try_both_dumpers): def test_dump(try_both_dumpers) -> None:
"""The that the dump method returns empty None values.""" """The that the dump method returns empty None values."""
assert yaml.dump({"a": None, "b": "b"}) == "a:\nb: b\n" assert yaml.dump({"a": None, "b": "b"}) == "a:\nb: b\n"
def test_dump_unicode(try_both_dumpers): def test_dump_unicode(try_both_dumpers) -> None:
"""The that the dump method returns empty None values.""" """The that the dump method returns empty None values."""
assert yaml.dump({"a": None, "b": "привет"}) == "a:\nb: привет\n" assert yaml.dump({"a": None, "b": "привет"}) == "a:\nb: привет\n"
@ -522,7 +523,7 @@ def test_input_class() -> None:
assert len({input, input2}) == 1 assert len({input, input2}) == 1
def test_input(try_both_loaders, try_both_dumpers): def test_input(try_both_loaders, try_both_dumpers) -> None:
"""Test loading inputs.""" """Test loading inputs."""
data = {"hello": yaml.Input("test_name")} data = {"hello": yaml.Input("test_name")}
assert yaml.parse_yaml(yaml.dump(data)) == data assert yaml.parse_yaml(yaml.dump(data)) == data
@ -537,7 +538,9 @@ def test_c_loader_is_available_in_ci() -> None:
assert yaml.loader.HAS_C_LOADER is True assert yaml.loader.HAS_C_LOADER is True
async def test_loading_actual_file_with_syntax(hass, try_both_loaders): async def test_loading_actual_file_with_syntax(
hass: HomeAssistant, try_both_loaders
) -> None:
"""Test loading a real file with syntax errors.""" """Test loading a real file with syntax errors."""
with pytest.raises(HomeAssistantError): with pytest.raises(HomeAssistantError):
fixture_path = pathlib.Path(__file__).parent.joinpath( fixture_path = pathlib.Path(__file__).parent.joinpath(