Improve type hints in cloud tests (#120420)

This commit is contained in:
epenet 2024-06-25 17:07:50 +02:00 committed by GitHub
parent 4feca36ca6
commit 6e5bc0da94
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 96 additions and 56 deletions

View File

@ -1,5 +1,6 @@
"""Tests for the cloud component."""
from typing import Any
from unittest.mock import AsyncMock, patch
from homeassistant.components.cloud.const import (
@ -14,7 +15,9 @@ from homeassistant.components.cloud.const import (
from homeassistant.components.cloud.prefs import (
ALEXA_SETTINGS_VERSION,
GOOGLE_SETTINGS_VERSION,
CloudPreferences,
)
from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
PIPELINE_DATA = {
@ -66,7 +69,7 @@ PIPELINE_DATA = {
}
async def mock_cloud(hass, config=None):
async def mock_cloud(hass: HomeAssistant, config: dict[str, Any] | None = None) -> None:
"""Mock cloud."""
# The homeassistant integration is needed by cloud. It's not in it's requirements
# because it's always setup by bootstrap. Set it up manually in tests.
@ -78,7 +81,7 @@ async def mock_cloud(hass, config=None):
await cloud_inst.initialize()
def mock_cloud_prefs(hass, prefs):
def mock_cloud_prefs(hass: HomeAssistant, prefs: dict[str, Any]) -> CloudPreferences:
"""Fixture for cloud component."""
prefs_to_set = {
PREF_ALEXA_SETTINGS_VERSION: ALEXA_SETTINGS_VERSION,

View File

@ -15,7 +15,7 @@ from hass_nabucasa.remote import RemoteUI
from hass_nabucasa.voice import Voice
import jwt
import pytest
from typing_extensions import AsyncGenerator
from typing_extensions import AsyncGenerator, Generator
from homeassistant.components.cloud.client import CloudClient
from homeassistant.components.cloud.const import DATA_CLOUD
@ -199,21 +199,21 @@ def tts_mutagen_mock_fixture_autouse(tts_mutagen_mock: MagicMock) -> None:
@pytest.fixture(autouse=True)
def mock_user_data():
def mock_user_data() -> Generator[MagicMock]:
"""Mock os module."""
with patch("hass_nabucasa.Cloud._write_user_info") as writer:
yield writer
@pytest.fixture
def mock_cloud_fixture(hass):
def mock_cloud_fixture(hass: HomeAssistant) -> CloudPreferences:
"""Fixture for cloud component."""
hass.loop.run_until_complete(mock_cloud(hass))
return mock_cloud_prefs(hass, {})
@pytest.fixture
async def cloud_prefs(hass):
async def cloud_prefs(hass: HomeAssistant) -> CloudPreferences:
"""Fixture for cloud preferences."""
cloud_prefs = CloudPreferences(hass)
await cloud_prefs.async_initialize()
@ -221,13 +221,13 @@ async def cloud_prefs(hass):
@pytest.fixture
async def mock_cloud_setup(hass):
async def mock_cloud_setup(hass: HomeAssistant) -> None:
"""Set up the cloud."""
await mock_cloud(hass)
@pytest.fixture
def mock_cloud_login(hass, mock_cloud_setup):
def mock_cloud_login(hass: HomeAssistant, mock_cloud_setup: None) -> Generator[None]:
"""Mock cloud is logged in."""
hass.data[DATA_CLOUD].id_token = jwt.encode(
{
@ -242,7 +242,7 @@ def mock_cloud_login(hass, mock_cloud_setup):
@pytest.fixture(name="mock_auth")
def mock_auth_fixture():
def mock_auth_fixture() -> Generator[None]:
"""Mock check token."""
with (
patch("hass_nabucasa.auth.CognitoAuth.async_check_token"),
@ -252,7 +252,7 @@ def mock_auth_fixture():
@pytest.fixture
def mock_expired_cloud_login(hass, mock_cloud_setup):
def mock_expired_cloud_login(hass: HomeAssistant, mock_cloud_setup: None) -> None:
"""Mock cloud is logged in."""
hass.data[DATA_CLOUD].id_token = jwt.encode(
{

View File

@ -6,6 +6,7 @@ from time import time
from unittest.mock import AsyncMock, Mock, patch
import pytest
from typing_extensions import Generator
from homeassistant import config_entries
from homeassistant.components.cloud import account_link
@ -21,7 +22,9 @@ TEST_DOMAIN = "oauth2_test"
@pytest.fixture
def flow_handler(hass):
def flow_handler(
hass: HomeAssistant,
) -> Generator[type[config_entry_oauth2_flow.AbstractOAuth2FlowHandler]]:
"""Return a registered config flow."""
mock_platform(hass, f"{TEST_DOMAIN}.config_flow")
@ -180,7 +183,10 @@ async def test_get_services_error(hass: HomeAssistant) -> None:
@pytest.mark.usefixtures("current_request_with_host")
async def test_implementation(hass: HomeAssistant, flow_handler) -> None:
async def test_implementation(
hass: HomeAssistant,
flow_handler: type[config_entry_oauth2_flow.AbstractOAuth2FlowHandler],
) -> None:
"""Test Cloud OAuth2 implementation."""
hass.data[DATA_CLOUD] = None

View File

@ -34,7 +34,7 @@ from tests.test_util.aiohttp import AiohttpClientMocker
@pytest.fixture
def cloud_stub():
def cloud_stub() -> Mock:
"""Stub the cloud."""
return Mock(is_logged_in=True, subscription_expired=False)
@ -51,7 +51,10 @@ def expose_entity(hass: HomeAssistant, entity_id: str, should_expose: bool) -> N
async def test_alexa_config_expose_entity_prefs(
hass: HomeAssistant, cloud_prefs, cloud_stub, entity_registry: er.EntityRegistry
hass: HomeAssistant,
cloud_prefs: CloudPreferences,
cloud_stub: Mock,
entity_registry: er.EntityRegistry,
) -> None:
"""Test Alexa config should expose using prefs."""
assert await async_setup_component(hass, "homeassistant", {})
@ -133,7 +136,7 @@ async def test_alexa_config_expose_entity_prefs(
async def test_alexa_config_report_state(
hass: HomeAssistant, cloud_prefs, cloud_stub
hass: HomeAssistant, cloud_prefs: CloudPreferences, cloud_stub: Mock
) -> None:
"""Test Alexa config should expose using prefs."""
assert await async_setup_component(hass, "homeassistant", {})
@ -168,7 +171,9 @@ async def test_alexa_config_report_state(
async def test_alexa_config_invalidate_token(
hass: HomeAssistant, cloud_prefs, aioclient_mock: AiohttpClientMocker
hass: HomeAssistant,
cloud_prefs: CloudPreferences,
aioclient_mock: AiohttpClientMocker,
) -> None:
"""Test Alexa config should expose using prefs."""
assert await async_setup_component(hass, "homeassistant", {})
@ -218,11 +223,11 @@ async def test_alexa_config_invalidate_token(
)
async def test_alexa_config_fail_refresh_token(
hass: HomeAssistant,
cloud_prefs,
cloud_prefs: CloudPreferences,
aioclient_mock: AiohttpClientMocker,
entity_registry: er.EntityRegistry,
reject_reason,
expected_exception,
reject_reason: str,
expected_exception: type[Exception],
) -> None:
"""Test Alexa config failing to refresh token."""
assert await async_setup_component(hass, "homeassistant", {})
@ -342,7 +347,10 @@ def patch_sync_helper():
async def test_alexa_update_expose_trigger_sync(
hass: HomeAssistant, entity_registry: er.EntityRegistry, cloud_prefs, cloud_stub
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
cloud_prefs: CloudPreferences,
cloud_stub: Mock,
) -> None:
"""Test Alexa config responds to updating exposed entities."""
assert await async_setup_component(hass, "homeassistant", {})
@ -415,11 +423,11 @@ async def test_alexa_update_expose_trigger_sync(
]
@pytest.mark.usefixtures("mock_cloud_login")
async def test_alexa_entity_registry_sync(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
mock_cloud_login,
cloud_prefs,
cloud_prefs: CloudPreferences,
) -> None:
"""Test Alexa config responds to entity registry."""
# Enable exposing new entities to Alexa
@ -475,7 +483,7 @@ async def test_alexa_entity_registry_sync(
async def test_alexa_update_report_state(
hass: HomeAssistant, cloud_prefs, cloud_stub
hass: HomeAssistant, cloud_prefs: CloudPreferences, cloud_stub: Mock
) -> None:
"""Test Alexa config responds to reporting state."""
assert await async_setup_component(hass, "homeassistant", {})
@ -502,8 +510,9 @@ async def test_alexa_update_report_state(
assert len(mock_sync.mock_calls) == 1
@pytest.mark.usefixtures("mock_expired_cloud_login")
def test_enabled_requires_valid_sub(
hass: HomeAssistant, mock_expired_cloud_login, cloud_prefs
hass: HomeAssistant, cloud_prefs: CloudPreferences
) -> None:
"""Test that alexa config enabled requires a valid Cloud sub."""
assert cloud_prefs.alexa_enabled
@ -518,7 +527,7 @@ def test_enabled_requires_valid_sub(
async def test_alexa_handle_logout(
hass: HomeAssistant, cloud_prefs, cloud_stub
hass: HomeAssistant, cloud_prefs: CloudPreferences, cloud_stub: Mock
) -> None:
"""Test Alexa config responds to logging out."""
assert await async_setup_component(hass, "homeassistant", {})
@ -561,7 +570,7 @@ async def test_alexa_handle_logout(
async def test_alexa_config_migrate_expose_entity_prefs(
hass: HomeAssistant,
cloud_prefs: CloudPreferences,
cloud_stub,
cloud_stub: Mock,
entity_registry: er.EntityRegistry,
alexa_settings_version: int,
) -> None:
@ -755,7 +764,7 @@ async def test_alexa_config_migrate_expose_entity_prefs_v2_exposed(
async def test_alexa_config_migrate_expose_entity_prefs_default_none(
hass: HomeAssistant,
cloud_prefs: CloudPreferences,
cloud_stub,
cloud_stub: Mock,
entity_registry: er.EntityRegistry,
) -> None:
"""Test migrating Alexa entity config."""
@ -793,7 +802,7 @@ async def test_alexa_config_migrate_expose_entity_prefs_default_none(
async def test_alexa_config_migrate_expose_entity_prefs_default(
hass: HomeAssistant,
cloud_prefs: CloudPreferences,
cloud_stub,
cloud_stub: Mock,
entity_registry: er.EntityRegistry,
) -> None:
"""Test migrating Alexa entity config."""

View File

@ -1,6 +1,7 @@
"""Test the cloud.iot module."""
from datetime import timedelta
from typing import Any
from unittest.mock import AsyncMock, MagicMock, Mock, PropertyMock, patch
import aiohttp
@ -20,6 +21,7 @@ from homeassistant.components.cloud.const import (
PREF_ENABLE_ALEXA,
PREF_ENABLE_GOOGLE,
)
from homeassistant.components.cloud.prefs import CloudPreferences
from homeassistant.components.homeassistant.exposed_entities import (
DATA_EXPOSED_ENTITIES,
async_expose_entity,
@ -37,7 +39,7 @@ from tests.components.alexa import test_smart_home as test_alexa
@pytest.fixture
def mock_cloud_inst():
def mock_cloud_inst() -> MagicMock:
"""Mock cloud class."""
return MagicMock(subscription_expired=False)
@ -81,7 +83,9 @@ async def test_handler_alexa(hass: HomeAssistant) -> None:
assert device["manufacturerName"] == "Home Assistant"
async def test_handler_alexa_disabled(hass: HomeAssistant, mock_cloud_fixture) -> None:
async def test_handler_alexa_disabled(
hass: HomeAssistant, mock_cloud_fixture: CloudPreferences
) -> None:
"""Test handler Alexa when user has disabled it."""
mock_cloud_fixture._prefs[PREF_ENABLE_ALEXA] = False
cloud = hass.data[DATA_CLOUD]
@ -154,7 +158,10 @@ async def test_handler_google_actions(hass: HomeAssistant) -> None:
],
)
async def test_handler_google_actions_disabled(
hass: HomeAssistant, mock_cloud_fixture, intent, response_payload
hass: HomeAssistant,
mock_cloud_fixture: CloudPreferences,
intent: str,
response_payload: dict[str, Any],
) -> None:
"""Test handler Google Actions when user has disabled it."""
mock_cloud_fixture._prefs[PREF_ENABLE_GOOGLE] = False
@ -253,11 +260,10 @@ async def test_webhook_msg(
assert '{"nonexisting": "payload"}' in caplog.text
@pytest.mark.usefixtures("mock_cloud_setup", "mock_cloud_login")
async def test_google_config_expose_entity(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
mock_cloud_setup,
mock_cloud_login,
) -> None:
"""Test Google config exposing entity method uses latest config."""
@ -281,11 +287,10 @@ async def test_google_config_expose_entity(
assert not gconf.should_expose(state)
@pytest.mark.usefixtures("mock_cloud_setup", "mock_cloud_login")
async def test_google_config_should_2fa(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
mock_cloud_setup,
mock_cloud_login,
) -> None:
"""Test Google config disabling 2FA method uses latest config."""

View File

@ -36,7 +36,7 @@ from tests.common import async_fire_time_changed
@pytest.fixture
def mock_conf(hass, cloud_prefs):
def mock_conf(hass: HomeAssistant, cloud_prefs: CloudPreferences) -> CloudGoogleConfig:
"""Mock Google conf."""
return CloudGoogleConfig(
hass,
@ -59,7 +59,7 @@ def expose_entity(hass: HomeAssistant, entity_id: str, should_expose: bool) -> N
async def test_google_update_report_state(
mock_conf, hass: HomeAssistant, cloud_prefs
mock_conf: CloudGoogleConfig, hass: HomeAssistant, cloud_prefs: CloudPreferences
) -> None:
"""Test Google config responds to updating preference."""
assert await async_setup_component(hass, "homeassistant", {})
@ -83,7 +83,7 @@ async def test_google_update_report_state(
async def test_google_update_report_state_subscription_expired(
mock_conf, hass: HomeAssistant, cloud_prefs
mock_conf: CloudGoogleConfig, hass: HomeAssistant, cloud_prefs: CloudPreferences
) -> None:
"""Test Google config not reporting state when subscription has expired."""
assert await async_setup_component(hass, "homeassistant", {})
@ -106,7 +106,9 @@ async def test_google_update_report_state_subscription_expired(
assert len(mock_report_state.mock_calls) == 0
async def test_sync_entities(mock_conf, hass: HomeAssistant, cloud_prefs) -> None:
async def test_sync_entities(
mock_conf: CloudGoogleConfig, hass: HomeAssistant, cloud_prefs: CloudPreferences
) -> None:
"""Test sync devices."""
assert await async_setup_component(hass, "homeassistant", {})
@ -129,7 +131,9 @@ async def test_sync_entities(mock_conf, hass: HomeAssistant, cloud_prefs) -> Non
async def test_google_update_expose_trigger_sync(
hass: HomeAssistant, entity_registry: er.EntityRegistry, cloud_prefs
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
cloud_prefs: CloudPreferences,
) -> None:
"""Test Google config responds to updating exposed entities."""
assert await async_setup_component(hass, "homeassistant", {})
@ -185,11 +189,11 @@ async def test_google_update_expose_trigger_sync(
assert len(mock_sync.mock_calls) == 1
@pytest.mark.usefixtures("mock_cloud_login")
async def test_google_entity_registry_sync(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
mock_cloud_login,
cloud_prefs,
cloud_prefs: CloudPreferences,
) -> None:
"""Test Google config responds to entity registry."""
@ -257,11 +261,11 @@ async def test_google_entity_registry_sync(
assert len(mock_sync.mock_calls) == 3
@pytest.mark.usefixtures("mock_cloud_login")
async def test_google_device_registry_sync(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
mock_cloud_login,
cloud_prefs,
cloud_prefs: CloudPreferences,
) -> None:
"""Test Google config responds to device registry."""
config = CloudGoogleConfig(
@ -329,8 +333,9 @@ async def test_google_device_registry_sync(
assert len(mock_sync.mock_calls) == 1
@pytest.mark.usefixtures("mock_cloud_login")
async def test_sync_google_when_started(
hass: HomeAssistant, mock_cloud_login, cloud_prefs
hass: HomeAssistant, cloud_prefs: CloudPreferences
) -> None:
"""Test Google config syncs on init."""
config = CloudGoogleConfig(
@ -342,8 +347,9 @@ async def test_sync_google_when_started(
assert len(mock_sync.mock_calls) == 1
@pytest.mark.usefixtures("mock_cloud_login")
async def test_sync_google_on_home_assistant_start(
hass: HomeAssistant, mock_cloud_login, cloud_prefs
hass: HomeAssistant, cloud_prefs: CloudPreferences
) -> None:
"""Test Google config syncs when home assistant started."""
config = CloudGoogleConfig(
@ -361,7 +367,10 @@ async def test_sync_google_on_home_assistant_start(
async def test_google_config_expose_entity_prefs(
hass: HomeAssistant, mock_conf, cloud_prefs, entity_registry: er.EntityRegistry
hass: HomeAssistant,
mock_conf: CloudGoogleConfig,
cloud_prefs: CloudPreferences,
entity_registry: er.EntityRegistry,
) -> None:
"""Test Google config should expose using prefs."""
assert await async_setup_component(hass, "homeassistant", {})
@ -437,8 +446,9 @@ async def test_google_config_expose_entity_prefs(
assert not mock_conf.should_expose(state_not_exposed)
@pytest.mark.usefixtures("mock_expired_cloud_login")
def test_enabled_requires_valid_sub(
hass: HomeAssistant, mock_expired_cloud_login, cloud_prefs
hass: HomeAssistant, cloud_prefs: CloudPreferences
) -> None:
"""Test that google config enabled requires a valid Cloud sub."""
assert cloud_prefs.google_enabled
@ -453,7 +463,7 @@ def test_enabled_requires_valid_sub(
async def test_setup_google_assistant(
hass: HomeAssistant, mock_conf, cloud_prefs
hass: HomeAssistant, mock_conf: CloudGoogleConfig, cloud_prefs: CloudPreferences
) -> None:
"""Test that we set up the google_assistant integration if enabled in cloud."""
assert await async_setup_component(hass, "homeassistant", {})
@ -472,8 +482,9 @@ async def test_setup_google_assistant(
assert "google_assistant" in hass.config.components
@pytest.mark.usefixtures("mock_cloud_login")
async def test_google_handle_logout(
hass: HomeAssistant, cloud_prefs, mock_cloud_login
hass: HomeAssistant, cloud_prefs: CloudPreferences
) -> None:
"""Test Google config responds to logging out."""
gconf = CloudGoogleConfig(
@ -853,8 +864,9 @@ async def test_google_config_migrate_expose_entity_prefs_default(
}
@pytest.mark.usefixtures("mock_cloud_login")
async def test_google_config_get_agent_user_id(
hass: HomeAssistant, mock_cloud_login, cloud_prefs
hass: HomeAssistant, cloud_prefs: CloudPreferences
) -> None:
"""Test overridden get_agent_user_id_from_webhook method."""
config = CloudGoogleConfig(
@ -867,8 +879,9 @@ async def test_google_config_get_agent_user_id(
assert config.get_agent_user_id_from_webhook("other_id") != config.agent_user_id
@pytest.mark.usefixtures("mock_cloud_login")
async def test_google_config_get_agent_users(
hass: HomeAssistant, mock_cloud_login, cloud_prefs
hass: HomeAssistant, cloud_prefs: CloudPreferences
) -> None:
"""Test overridden async_get_agent_users method."""
username_mock = PropertyMock(return_value="blah")

View File

@ -67,8 +67,9 @@ async def test_constructor_loads_info_from_config(hass: HomeAssistant) -> None:
assert cl.remotestate_server == "test-remotestate-server"
@pytest.mark.usefixtures("mock_cloud_fixture")
async def test_remote_services(
hass: HomeAssistant, mock_cloud_fixture, hass_read_only_user: MockUser
hass: HomeAssistant, hass_read_only_user: MockUser
) -> None:
"""Setup cloud component and test services."""
cloud = hass.data[DATA_CLOUD]
@ -114,7 +115,8 @@ async def test_remote_services(
assert mock_disconnect.called is False
async def test_shutdown_event(hass: HomeAssistant, mock_cloud_fixture) -> None:
@pytest.mark.usefixtures("mock_cloud_fixture")
async def test_shutdown_event(hass: HomeAssistant) -> None:
"""Test if the cloud will stop on shutdown event."""
with patch("hass_nabucasa.Cloud.stop") as mock_stop:
hass.bus.async_fire(EVENT_HOMEASSISTANT_STOP)
@ -149,7 +151,8 @@ async def test_setup_existing_cloud_user(
assert hass_storage[STORAGE_KEY]["data"]["cloud_user"] == user.id
async def test_on_connect(hass: HomeAssistant, mock_cloud_fixture) -> None:
@pytest.mark.usefixtures("mock_cloud_fixture")
async def test_on_connect(hass: HomeAssistant) -> None:
"""Test cloud on connect triggers."""
cl = hass.data[DATA_CLOUD]
@ -206,7 +209,8 @@ async def test_on_connect(hass: HomeAssistant, mock_cloud_fixture) -> None:
assert cloud_states[-1] == CloudConnectionState.CLOUD_DISCONNECTED
async def test_remote_ui_url(hass: HomeAssistant, mock_cloud_fixture) -> None:
@pytest.mark.usefixtures("mock_cloud_fixture")
async def test_remote_ui_url(hass: HomeAssistant) -> None:
"""Test getting remote ui url."""
cl = hass.data[DATA_CLOUD]