"""Test the Ridwell config flow.""" from unittest.mock import AsyncMock, patch from aioridwell.errors import InvalidCredentialsError, RidwellError import pytest from homeassistant import config_entries from homeassistant.components.ridwell.const import DOMAIN from homeassistant.const import CONF_PASSWORD, CONF_USERNAME from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import ( RESULT_TYPE_ABORT, RESULT_TYPE_CREATE_ENTRY, RESULT_TYPE_FORM, ) from tests.common import MockConfigEntry @pytest.fixture(name="client") def client_fixture(): """Define a fixture for an aioridwell client.""" return AsyncMock(return_value=None) @pytest.fixture(name="client_login") def client_login_fixture(client): """Define a fixture for patching the aioridwell coroutine to get a client.""" with patch( "homeassistant.components.ridwell.config_flow.async_get_client" ) as mock_client: mock_client.side_effect = client yield mock_client async def test_duplicate_error(hass: HomeAssistant): """Test that errors are shown when duplicate entries are added.""" MockConfigEntry( domain=DOMAIN, unique_id="user@email.com", data={CONF_USERNAME: "user@email.com", CONF_PASSWORD: "password"}, ).add_to_hass(hass) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER}, data={CONF_USERNAME: "user@email.com", CONF_PASSWORD: "password"}, ) assert result["type"] == RESULT_TYPE_ABORT assert result["reason"] == "already_configured" async def test_show_form_user(hass: HomeAssistant) -> None: """Test showing the form to input credentials.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} ) assert result["type"] == RESULT_TYPE_FORM assert result["step_id"] == "user" assert result["errors"] is None async def test_step_reauth(hass: HomeAssistant, client_login) -> None: """Test a full reauth flow.""" MockConfigEntry( domain=DOMAIN, unique_id="user@email.com", data={CONF_USERNAME: "user@email.com", CONF_PASSWORD: "password"}, ).add_to_hass(hass) with patch( "homeassistant.components.ridwell.async_setup_entry", return_value=True, ): result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_REAUTH}, data={CONF_USERNAME: "user@email.com", CONF_PASSWORD: "password"}, ) result = await hass.config_entries.flow.async_configure( result["flow_id"], user_input={CONF_PASSWORD: "password"}, ) await hass.async_block_till_done() assert result["type"] == RESULT_TYPE_ABORT assert result["reason"] == "reauth_successful" assert len(hass.config_entries.async_entries()) == 1 async def test_step_user(hass: HomeAssistant, client_login) -> None: """Test that the full user step succeeds.""" with patch( "homeassistant.components.ridwell.async_setup_entry", return_value=True, ): result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER}, data={CONF_USERNAME: "user@email.com", CONF_PASSWORD: "password"}, ) await hass.async_block_till_done() assert result["type"] == RESULT_TYPE_CREATE_ENTRY @pytest.mark.parametrize( "client,error", [ (AsyncMock(side_effect=InvalidCredentialsError), "invalid_auth"), (AsyncMock(side_effect=RidwellError), "unknown"), ], ) async def test_step_user_invalid_credentials( hass: HomeAssistant, client_login, error ) -> None: """Test that invalid credentials are handled correctly.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER}, data={CONF_USERNAME: "user@email.com", CONF_PASSWORD: "password"}, ) assert result["type"] == RESULT_TYPE_FORM assert result["errors"]["base"] == error