From e4be3d8435c37177ca206232e1c765b97977d2bb Mon Sep 17 00:00:00 2001 From: Brett Adams Date: Sat, 8 Jun 2024 06:11:35 +1000 Subject: [PATCH] Improve the reliability of tests in Tessie (#118596) --- .../components/tessie/config_flow.py | 6 +- tests/components/tessie/common.py | 12 +-- tests/components/tessie/conftest.py | 8 +- tests/components/tessie/test_config_flow.py | 101 ++++++++++++------ tests/components/tessie/test_init.py | 21 ++-- 5 files changed, 89 insertions(+), 59 deletions(-) diff --git a/homeassistant/components/tessie/config_flow.py b/homeassistant/components/tessie/config_flow.py index 7eb365a139f..f3761d4c4ce 100644 --- a/homeassistant/components/tessie/config_flow.py +++ b/homeassistant/components/tessie/config_flow.py @@ -93,13 +93,9 @@ class TessieConfigFlow(ConfigFlow, domain=DOMAIN): except ClientConnectionError: errors["base"] = "cannot_connect" else: - self.hass.config_entries.async_update_entry( + return self.async_update_reload_and_abort( self._reauth_entry, data=user_input ) - self.hass.async_create_task( - self.hass.config_entries.async_reload(self._reauth_entry.entry_id) - ) - return self.async_abort(reason="reauth_successful") return self.async_show_form( step_id="reauth_confirm", diff --git a/tests/components/tessie/common.py b/tests/components/tessie/common.py index 2f213c4e798..7182e28837a 100644 --- a/tests/components/tessie/common.py +++ b/tests/components/tessie/common.py @@ -7,6 +7,7 @@ from aiohttp import ClientConnectionError, ClientResponseError from aiohttp.client import RequestInfo from syrupy import SnapshotAssertion +from homeassistant.components.tessie import PLATFORMS from homeassistant.components.tessie.const import DOMAIN, TessieStatus from homeassistant.const import CONF_ACCESS_TOKEN, Platform from homeassistant.core import HomeAssistant @@ -47,7 +48,7 @@ ERROR_CONNECTION = ClientConnectionError() async def setup_platform( - hass: HomeAssistant, platforms: list[Platform] = [], side_effect=None + hass: HomeAssistant, platforms: list[Platform] = PLATFORMS ) -> MockConfigEntry: """Set up the Tessie platform.""" @@ -57,14 +58,7 @@ async def setup_platform( ) mock_entry.add_to_hass(hass) - with ( - patch( - "homeassistant.components.tessie.get_state_of_all_vehicles", - return_value=TEST_STATE_OF_ALL_VEHICLES, - side_effect=side_effect, - ), - patch("homeassistant.components.tessie.PLATFORMS", platforms), - ): + with patch("homeassistant.components.tessie.PLATFORMS", platforms): await hass.config_entries.async_setup(mock_entry.entry_id) await hass.async_block_till_done() diff --git a/tests/components/tessie/conftest.py b/tests/components/tessie/conftest.py index f38ef6c7e3f..77d1e3fd3e2 100644 --- a/tests/components/tessie/conftest.py +++ b/tests/components/tessie/conftest.py @@ -13,7 +13,7 @@ from .common import ( ) -@pytest.fixture +@pytest.fixture(autouse=True) def mock_get_state(): """Mock get_state function.""" with patch( @@ -23,7 +23,7 @@ def mock_get_state(): yield mock_get_state -@pytest.fixture +@pytest.fixture(autouse=True) def mock_get_status(): """Mock get_status function.""" with patch( @@ -33,11 +33,11 @@ def mock_get_status(): yield mock_get_status -@pytest.fixture +@pytest.fixture(autouse=True) def mock_get_state_of_all_vehicles(): """Mock get_state_of_all_vehicles function.""" with patch( - "homeassistant.components.tessie.config_flow.get_state_of_all_vehicles", + "homeassistant.components.tessie.get_state_of_all_vehicles", return_value=TEST_STATE_OF_ALL_VEHICLES, ) as mock_get_state_of_all_vehicles: yield mock_get_state_of_all_vehicles diff --git a/tests/components/tessie/test_config_flow.py b/tests/components/tessie/test_config_flow.py index ac3217f864b..f3dc98e6e18 100644 --- a/tests/components/tessie/test_config_flow.py +++ b/tests/components/tessie/test_config_flow.py @@ -6,7 +6,7 @@ import pytest from homeassistant import config_entries from homeassistant.components.tessie.const import DOMAIN -from homeassistant.const import CONF_ACCESS_TOKEN, Platform +from homeassistant.const import CONF_ACCESS_TOKEN from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType @@ -15,13 +15,37 @@ from .common import ( ERROR_CONNECTION, ERROR_UNKNOWN, TEST_CONFIG, - setup_platform, + TEST_STATE_OF_ALL_VEHICLES, ) from tests.common import MockConfigEntry -async def test_form(hass: HomeAssistant, mock_get_state_of_all_vehicles) -> None: +@pytest.fixture(autouse=True) +def mock_config_flow_get_state_of_all_vehicles(): + """Mock get_state_of_all_vehicles in config flow.""" + with patch( + "homeassistant.components.tessie.config_flow.get_state_of_all_vehicles", + return_value=TEST_STATE_OF_ALL_VEHICLES, + ) as mock_config_flow_get_state_of_all_vehicles: + yield mock_config_flow_get_state_of_all_vehicles + + +@pytest.fixture(autouse=True) +def mock_async_setup_entry(): + """Mock async_setup_entry.""" + with patch( + "homeassistant.components.tessie.async_setup_entry", + return_value=True, + ) as mock_async_setup_entry: + yield mock_async_setup_entry + + +async def test_form( + hass: HomeAssistant, + mock_config_flow_get_state_of_all_vehicles, + mock_async_setup_entry, +) -> None: """Test we get the form.""" result1 = await hass.config_entries.flow.async_init( @@ -30,17 +54,13 @@ async def test_form(hass: HomeAssistant, mock_get_state_of_all_vehicles) -> None assert result1["type"] is FlowResultType.FORM assert not result1["errors"] - with patch( - "homeassistant.components.tessie.async_setup_entry", - return_value=True, - ) as mock_setup_entry: - result2 = await hass.config_entries.flow.async_configure( - result1["flow_id"], - TEST_CONFIG, - ) - await hass.async_block_till_done() - assert len(mock_setup_entry.mock_calls) == 1 - assert len(mock_get_state_of_all_vehicles.mock_calls) == 1 + result2 = await hass.config_entries.flow.async_configure( + result1["flow_id"], + TEST_CONFIG, + ) + await hass.async_block_till_done() + assert len(mock_async_setup_entry.mock_calls) == 1 + assert len(mock_config_flow_get_state_of_all_vehicles.mock_calls) == 1 assert result2["type"] is FlowResultType.CREATE_ENTRY assert result2["title"] == "Tessie" @@ -56,7 +76,7 @@ async def test_form(hass: HomeAssistant, mock_get_state_of_all_vehicles) -> None ], ) async def test_form_errors( - hass: HomeAssistant, side_effect, error, mock_get_state_of_all_vehicles + hass: HomeAssistant, side_effect, error, mock_config_flow_get_state_of_all_vehicles ) -> None: """Test errors are handled.""" @@ -64,7 +84,7 @@ async def test_form_errors( DOMAIN, context={"source": config_entries.SOURCE_USER} ) - mock_get_state_of_all_vehicles.side_effect = side_effect + mock_config_flow_get_state_of_all_vehicles.side_effect = side_effect result2 = await hass.config_entries.flow.async_configure( result1["flow_id"], TEST_CONFIG, @@ -74,15 +94,20 @@ async def test_form_errors( assert result2["errors"] == error # Complete the flow - mock_get_state_of_all_vehicles.side_effect = None + mock_config_flow_get_state_of_all_vehicles.side_effect = None result3 = await hass.config_entries.flow.async_configure( result2["flow_id"], TEST_CONFIG, ) + assert "errors" not in result3 assert result3["type"] is FlowResultType.CREATE_ENTRY -async def test_reauth(hass: HomeAssistant, mock_get_state_of_all_vehicles) -> None: +async def test_reauth( + hass: HomeAssistant, + mock_config_flow_get_state_of_all_vehicles, + mock_async_setup_entry, +) -> None: """Test reauth flow.""" mock_entry = MockConfigEntry( @@ -104,17 +129,13 @@ async def test_reauth(hass: HomeAssistant, mock_get_state_of_all_vehicles) -> No assert result1["step_id"] == "reauth_confirm" assert not result1["errors"] - with patch( - "homeassistant.components.tessie.async_setup_entry", - return_value=True, - ) as mock_setup_entry: - result2 = await hass.config_entries.flow.async_configure( - result1["flow_id"], - TEST_CONFIG, - ) - await hass.async_block_till_done() - assert len(mock_setup_entry.mock_calls) == 1 - assert len(mock_get_state_of_all_vehicles.mock_calls) == 1 + result2 = await hass.config_entries.flow.async_configure( + result1["flow_id"], + TEST_CONFIG, + ) + await hass.async_block_till_done() + assert len(mock_async_setup_entry.mock_calls) == 1 + assert len(mock_config_flow_get_state_of_all_vehicles.mock_calls) == 1 assert result2["type"] is FlowResultType.ABORT assert result2["reason"] == "reauth_successful" @@ -130,14 +151,23 @@ async def test_reauth(hass: HomeAssistant, mock_get_state_of_all_vehicles) -> No ], ) async def test_reauth_errors( - hass: HomeAssistant, mock_get_state_of_all_vehicles, side_effect, error + hass: HomeAssistant, + mock_config_flow_get_state_of_all_vehicles, + mock_async_setup_entry, + side_effect, + error, ) -> None: """Test reauth flows that fail.""" - mock_entry = await setup_platform(hass, [Platform.BINARY_SENSOR]) - mock_get_state_of_all_vehicles.side_effect = side_effect + mock_config_flow_get_state_of_all_vehicles.side_effect = side_effect - result = await hass.config_entries.flow.async_init( + mock_entry = MockConfigEntry( + domain=DOMAIN, + data=TEST_CONFIG, + ) + mock_entry.add_to_hass(hass) + + result1 = await hass.config_entries.flow.async_init( DOMAIN, context={ "source": config_entries.SOURCE_REAUTH, @@ -148,7 +178,7 @@ async def test_reauth_errors( ) result2 = await hass.config_entries.flow.async_configure( - result["flow_id"], + result1["flow_id"], TEST_CONFIG, ) await hass.async_block_till_done() @@ -157,7 +187,7 @@ async def test_reauth_errors( assert result2["errors"] == error # Complete the flow - mock_get_state_of_all_vehicles.side_effect = None + mock_config_flow_get_state_of_all_vehicles.side_effect = None result3 = await hass.config_entries.flow.async_configure( result2["flow_id"], TEST_CONFIG, @@ -166,3 +196,4 @@ async def test_reauth_errors( assert result3["type"] is FlowResultType.ABORT assert result3["reason"] == "reauth_successful" assert mock_entry.data == TEST_CONFIG + assert len(mock_async_setup_entry.mock_calls) == 1 diff --git a/tests/components/tessie/test_init.py b/tests/components/tessie/test_init.py index 68d6fcf7777..81d1d758edf 100644 --- a/tests/components/tessie/test_init.py +++ b/tests/components/tessie/test_init.py @@ -16,22 +16,31 @@ async def test_load_unload(hass: HomeAssistant) -> None: assert entry.state is ConfigEntryState.NOT_LOADED -async def test_auth_failure(hass: HomeAssistant) -> None: +async def test_auth_failure( + hass: HomeAssistant, mock_get_state_of_all_vehicles +) -> None: """Test init with an authentication error.""" - entry = await setup_platform(hass, side_effect=ERROR_AUTH) + mock_get_state_of_all_vehicles.side_effect = ERROR_AUTH + entry = await setup_platform(hass) assert entry.state is ConfigEntryState.SETUP_ERROR -async def test_unknown_failure(hass: HomeAssistant) -> None: +async def test_unknown_failure( + hass: HomeAssistant, mock_get_state_of_all_vehicles +) -> None: """Test init with an client response error.""" - entry = await setup_platform(hass, side_effect=ERROR_UNKNOWN) + mock_get_state_of_all_vehicles.side_effect = ERROR_UNKNOWN + entry = await setup_platform(hass) assert entry.state is ConfigEntryState.SETUP_ERROR -async def test_connection_failure(hass: HomeAssistant) -> None: +async def test_connection_failure( + hass: HomeAssistant, mock_get_state_of_all_vehicles +) -> None: """Test init with a network connection error.""" - entry = await setup_platform(hass, side_effect=ERROR_CONNECTION) + mock_get_state_of_all_vehicles.side_effect = ERROR_CONNECTION + entry = await setup_platform(hass) assert entry.state is ConfigEntryState.SETUP_RETRY