"""Test the Hypontech Cloud config flow.""" from unittest.mock import AsyncMock from hyponcloud import AuthenticationError import pytest from homeassistant.components.hypontech.const import DOMAIN from homeassistant.config_entries import SOURCE_USER from homeassistant.const import CONF_PASSWORD, CONF_USERNAME from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType from tests.common import MockConfigEntry TEST_USER_INPUT = { CONF_USERNAME: "test@example.com", CONF_PASSWORD: "test-password", } async def test_user_flow( hass: HomeAssistant, mock_hyponcloud: AsyncMock, mock_setup_entry: AsyncMock ) -> None: """Test a successful user flow.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER} ) assert result["type"] is FlowResultType.FORM assert result["errors"] == {} result = await hass.config_entries.flow.async_configure( result["flow_id"], TEST_USER_INPUT ) assert result["type"] is FlowResultType.CREATE_ENTRY assert result["title"] == "test@example.com" assert result["data"] == TEST_USER_INPUT assert result["result"].unique_id == "2123456789123456789" assert len(mock_setup_entry.mock_calls) == 1 @pytest.mark.parametrize( ("side_effect", "error_message"), [ (AuthenticationError, "invalid_auth"), (ConnectionError, "cannot_connect"), (TimeoutError, "cannot_connect"), (Exception, "unknown"), ], ) @pytest.mark.usefixtures("mock_setup_entry") async def test_form_errors( hass: HomeAssistant, mock_hyponcloud: AsyncMock, side_effect: Exception, error_message: str, ) -> None: """Test we handle errors.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER} ) mock_hyponcloud.connect.side_effect = side_effect result = await hass.config_entries.flow.async_configure( result["flow_id"], TEST_USER_INPUT ) assert result["type"] is FlowResultType.FORM assert result["errors"] == {"base": error_message} mock_hyponcloud.connect.side_effect = None result = await hass.config_entries.flow.async_configure( result["flow_id"], TEST_USER_INPUT, ) assert result["type"] is FlowResultType.CREATE_ENTRY async def test_duplicate_entry( hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_hyponcloud: AsyncMock ) -> None: """Test that duplicate entries are prevented based on account ID.""" mock_config_entry.add_to_hass(hass) result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": SOURCE_USER} ) result = await hass.config_entries.flow.async_configure( result["flow_id"], TEST_USER_INPUT ) assert result["type"] is FlowResultType.ABORT assert result["reason"] == "already_configured" async def test_reauth_flow( hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_hyponcloud: AsyncMock ) -> None: """Test reauthentication flow.""" mock_config_entry.add_to_hass(hass) result = await mock_config_entry.start_reauth_flow(hass) assert result["type"] is FlowResultType.FORM assert result["step_id"] == "user" result = await hass.config_entries.flow.async_configure( result["flow_id"], {**TEST_USER_INPUT, CONF_PASSWORD: "password"}, ) assert result["type"] is FlowResultType.ABORT assert result["reason"] == "reauth_successful" assert mock_config_entry.data[CONF_PASSWORD] == "password" @pytest.mark.parametrize( ("side_effect", "error_message"), [ (AuthenticationError, "invalid_auth"), (ConnectionError, "cannot_connect"), (TimeoutError, "cannot_connect"), (Exception, "unknown"), ], ) async def test_reauth_flow_errors( hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_hyponcloud: AsyncMock, side_effect: Exception, error_message: str, ) -> None: """Test reauthentication flow with errors.""" mock_config_entry.add_to_hass(hass) result = await mock_config_entry.start_reauth_flow(hass) assert result["type"] is FlowResultType.FORM assert result["step_id"] == "user" mock_hyponcloud.connect.side_effect = side_effect result = await hass.config_entries.flow.async_configure( result["flow_id"], {**TEST_USER_INPUT, CONF_PASSWORD: "new-password"}, ) assert result["type"] is FlowResultType.FORM assert result["errors"] == {"base": error_message} mock_hyponcloud.connect.side_effect = None result = await hass.config_entries.flow.async_configure( result["flow_id"], {**TEST_USER_INPUT, CONF_PASSWORD: "new-password"}, ) assert result["type"] is FlowResultType.ABORT assert result["reason"] == "reauth_successful" async def test_reauth_flow_wrong_account( hass: HomeAssistant, mock_config_entry: MockConfigEntry, mock_hyponcloud: AsyncMock ) -> None: """Test reauthentication flow with wrong account.""" mock_config_entry.add_to_hass(hass) result = await mock_config_entry.start_reauth_flow(hass) assert result["type"] is FlowResultType.FORM assert result["step_id"] == "user" mock_hyponcloud.get_admin_info.return_value.id = "different_account_id_456" result = await hass.config_entries.flow.async_configure( result["flow_id"], {**TEST_USER_INPUT, CONF_USERNAME: "different@example.com"}, ) assert result["type"] is FlowResultType.ABORT assert result["reason"] == "wrong_account"