"""Test the Webmin config flow.""" from __future__ import annotations from http import HTTPStatus from unittest.mock import AsyncMock, patch from xmlrpc.client import Fault from aiohttp.client_exceptions import ClientConnectionError, ClientResponseError import pytest from homeassistant import config_entries from homeassistant.components.webmin.const import DOMAIN from homeassistant.const import CONF_HOST from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType from .conftest import TEST_USER_INPUT from tests.common import load_json_object_fixture pytestmark = pytest.mark.usefixtures("mock_setup_entry") @pytest.fixture async def user_flow(hass: HomeAssistant) -> str: """Return a user-initiated flow after filling in host info.""" result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} ) assert result["type"] == FlowResultType.FORM assert result["errors"] is None return result["flow_id"] async def test_form_user( hass: HomeAssistant, user_flow: str, mock_setup_entry: AsyncMock, ) -> None: """Test a successful user initiated flow.""" with patch( "homeassistant.components.webmin.helpers.WebminInstance.update", return_value=load_json_object_fixture("webmin_update.json", DOMAIN), ): result = await hass.config_entries.flow.async_configure( user_flow, TEST_USER_INPUT ) await hass.async_block_till_done() assert result["type"] == FlowResultType.CREATE_ENTRY assert result["title"] == TEST_USER_INPUT[CONF_HOST] assert result["options"] == TEST_USER_INPUT assert len(mock_setup_entry.mock_calls) == 1 @pytest.mark.parametrize( ("exception", "error_type"), [ ( ClientResponseError( request_info=None, history=None, status=HTTPStatus.UNAUTHORIZED ), "invalid_auth", ), ( ClientResponseError( request_info=None, history=None, status=HTTPStatus.BAD_REQUEST ), "cannot_connect", ), (ClientConnectionError, "cannot_connect"), (Exception, "unknown"), ( Fault("5", "Webmin module net does not exist"), "Fault 5: Webmin module net does not exist", ), ], ) async def test_form_user_errors( hass: HomeAssistant, user_flow: str, exception: Exception, error_type: str ) -> None: """Test we handle errors.""" with patch( "homeassistant.components.webmin.helpers.WebminInstance.update", side_effect=exception, ): result = await hass.config_entries.flow.async_configure( user_flow, TEST_USER_INPUT ) assert result["type"] == FlowResultType.FORM assert result["step_id"] == "user" assert result["errors"] == {"base": error_type} with patch( "homeassistant.components.webmin.helpers.WebminInstance.update", return_value=load_json_object_fixture("webmin_update.json", DOMAIN), ): result = await hass.config_entries.flow.async_configure( result["flow_id"], TEST_USER_INPUT ) assert result["type"] == FlowResultType.CREATE_ENTRY assert result["title"] == TEST_USER_INPUT[CONF_HOST] assert result["options"] == TEST_USER_INPUT async def test_duplicate_entry( hass: HomeAssistant, user_flow: str, mock_setup_entry: AsyncMock, ) -> None: """Test a successful user initiated flow.""" with patch( "homeassistant.components.webmin.helpers.WebminInstance.update", return_value=load_json_object_fixture("webmin_update.json", DOMAIN), ): result = await hass.config_entries.flow.async_configure( user_flow, TEST_USER_INPUT ) await hass.async_block_till_done() assert result["type"] == FlowResultType.CREATE_ENTRY assert result["title"] == TEST_USER_INPUT[CONF_HOST] assert result["options"] == TEST_USER_INPUT with patch( "homeassistant.components.webmin.helpers.WebminInstance.update", return_value=load_json_object_fixture("webmin_update.json", DOMAIN), ): result = await hass.config_entries.flow.async_init( DOMAIN, context={"source": config_entries.SOURCE_USER} ) result = await hass.config_entries.flow.async_configure( result["flow_id"], TEST_USER_INPUT ) await hass.async_block_till_done() assert result["type"] == FlowResultType.ABORT assert result["reason"] == "already_configured"