From 48b650c48602d13f90610e092695a96f46718541 Mon Sep 17 00:00:00 2001 From: Franck Nijhof Date: Sat, 25 Apr 2026 11:03:15 +0200 Subject: [PATCH] Modernize RDW config flow tests (#169129) --- tests/components/rdw/conftest.py | 27 ++---- tests/components/rdw/test_config_flow.py | 101 ++++++++++++----------- 2 files changed, 60 insertions(+), 68 deletions(-) diff --git a/tests/components/rdw/conftest.py b/tests/components/rdw/conftest.py index 328f347f3ee9..cba499e62360 100644 --- a/tests/components/rdw/conftest.py +++ b/tests/components/rdw/conftest.py @@ -33,32 +33,19 @@ def mock_setup_entry() -> Generator[None]: @pytest.fixture -def mock_rdw_config_flow() -> Generator[MagicMock]: +def mock_rdw() -> Generator[MagicMock]: """Return a mocked RDW client.""" - with patch( - "homeassistant.components.rdw.config_flow.RDW", autospec=True - ) as rdw_mock: + with ( + patch( + "homeassistant.components.rdw.coordinator.RDW", autospec=True + ) as rdw_mock, + patch("homeassistant.components.rdw.config_flow.RDW", new=rdw_mock), + ): rdw = rdw_mock.return_value rdw.vehicle.return_value = Vehicle.from_json(load_fixture("rdw/11ZKZ3.json")) yield rdw -@pytest.fixture -def mock_rdw(request: pytest.FixtureRequest) -> Generator[MagicMock]: - """Return a mocked WLED client.""" - fixture: str = "rdw/11ZKZ3.json" - if hasattr(request, "param") and request.param: - fixture = request.param - - vehicle = Vehicle.from_json(load_fixture(fixture)) - with patch( - "homeassistant.components.rdw.coordinator.RDW", autospec=True - ) as rdw_mock: - rdw = rdw_mock.return_value - rdw.vehicle.return_value = vehicle - yield rdw - - @pytest.fixture async def init_integration( hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_rdw: MagicMock diff --git a/tests/components/rdw/test_config_flow.py b/tests/components/rdw/test_config_flow.py index 2aa39f2c2d34..7db70a5deb09 100644 --- a/tests/components/rdw/test_config_flow.py +++ b/tests/components/rdw/test_config_flow.py @@ -2,6 +2,7 @@ from unittest.mock import MagicMock +import pytest from vehicle.exceptions import RDWConnectionError, RDWUnknownLicensePlateError from homeassistant.components.rdw.const import CONF_LICENSE_PLATE, DOMAIN @@ -9,81 +10,85 @@ from homeassistant.config_entries import SOURCE_USER from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType +from tests.common import MockConfigEntry -async def test_full_user_flow( - hass: HomeAssistant, mock_rdw_config_flow: MagicMock, mock_setup_entry: MagicMock -) -> None: +pytestmark = pytest.mark.usefixtures("mock_setup_entry") + + +@pytest.mark.usefixtures("mock_rdw") +async def test_full_user_flow(hass: HomeAssistant) -> None: """Test the full user configuration flow.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER} ) + assert result["type"] is FlowResultType.FORM + assert result["step_id"] == "user" - assert result.get("type") is FlowResultType.FORM - assert result.get("step_id") == "user" - - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], - user_input={ - CONF_LICENSE_PLATE: "11-ZKZ-3", - }, + user_input={CONF_LICENSE_PLATE: "11-ZKZ-3"}, ) - assert result2.get("type") is FlowResultType.CREATE_ENTRY - assert result2.get("title") == "11-ZKZ-3" - assert result2.get("data") == {CONF_LICENSE_PLATE: "11ZKZ3"} + assert result["type"] is FlowResultType.CREATE_ENTRY + assert result["title"] == "11-ZKZ-3" + assert result["data"] == {CONF_LICENSE_PLATE: "11ZKZ3"} + assert result["result"].unique_id == "11ZKZ3" -async def test_full_flow_with_authentication_error( - hass: HomeAssistant, mock_rdw_config_flow: MagicMock, mock_setup_entry: MagicMock +@pytest.mark.parametrize( + ("side_effect", "expected_error"), + [ + (RDWUnknownLicensePlateError, {"base": "unknown_license_plate"}), + (RDWConnectionError, {"base": "cannot_connect"}), + ], +) +async def test_user_flow_errors( + hass: HomeAssistant, + mock_rdw: MagicMock, + side_effect: type[Exception], + expected_error: dict[str, str], ) -> None: - """Test the full user configuration flow with incorrect license plate. + """Test the user flow with errors and recovery.""" + mock_rdw.vehicle.side_effect = side_effect - This tests tests a full config flow, with a case the user enters an invalid - license plate, but recover by entering the correct one. - """ result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER} ) - assert result.get("type") is FlowResultType.FORM - assert result.get("step_id") == "user" - - mock_rdw_config_flow.vehicle.side_effect = RDWUnknownLicensePlateError - result2 = await hass.config_entries.flow.async_configure( + result = await hass.config_entries.flow.async_configure( result["flow_id"], - user_input={ - CONF_LICENSE_PLATE: "0001TJ", - }, + user_input={CONF_LICENSE_PLATE: "0001TJ"}, ) - assert result2.get("type") is FlowResultType.FORM - assert result2.get("step_id") == "user" - assert result2.get("errors") == {"base": "unknown_license_plate"} + assert result["type"] is FlowResultType.FORM + assert result["errors"] == expected_error - mock_rdw_config_flow.vehicle.side_effect = None - result3 = await hass.config_entries.flow.async_configure( - result2["flow_id"], - user_input={ - CONF_LICENSE_PLATE: "11-ZKZ-3", - }, + mock_rdw.vehicle.side_effect = None + + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + user_input={CONF_LICENSE_PLATE: "11-ZKZ-3"}, ) - assert result3.get("type") is FlowResultType.CREATE_ENTRY - assert result3.get("title") == "11-ZKZ-3" - assert result3.get("data") == {CONF_LICENSE_PLATE: "11ZKZ3"} + assert result["type"] is FlowResultType.CREATE_ENTRY -async def test_connection_error( - hass: HomeAssistant, mock_rdw_config_flow: MagicMock +@pytest.mark.usefixtures("mock_rdw") +async def test_user_flow_already_configured( + hass: HomeAssistant, + mock_config_entry: MockConfigEntry, ) -> None: - """Test API connection error.""" - mock_rdw_config_flow.vehicle.side_effect = RDWConnectionError + """Test the user flow when the vehicle is already configured.""" + mock_config_entry.add_to_hass(hass) result = await hass.config_entries.flow.async_init( - DOMAIN, - context={"source": SOURCE_USER}, - data={CONF_LICENSE_PLATE: "0001TJ"}, + DOMAIN, context={"source": SOURCE_USER} ) - assert result.get("type") is FlowResultType.FORM - assert result.get("errors") == {"base": "cannot_connect"} + result = await hass.config_entries.flow.async_configure( + result["flow_id"], + user_input={CONF_LICENSE_PLATE: "11-ZKZ-3"}, + ) + + assert result["type"] is FlowResultType.ABORT + assert result["reason"] == "already_configured"