Refactor fibaro config flow test (#102604)

* Refactor fibaro config flow test

* Use constants from FlowResultType

* Extend tests with recovery after failure

* Add recovery from failure in all tests
This commit is contained in:
rappenze 2023-11-06 01:30:06 +01:00 committed by GitHub
parent 43cab28700
commit 17acb04fb8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,5 +1,5 @@
"""Test the Fibaro config flow.""" """Test the Fibaro config flow."""
from unittest.mock import Mock, patch from unittest.mock import Mock
import pytest import pytest
from requests.exceptions import HTTPError from requests.exceptions import HTTPError
@ -10,52 +10,53 @@ from homeassistant.components.fibaro.config_flow import _normalize_url
from homeassistant.components.fibaro.const import CONF_IMPORT_PLUGINS from homeassistant.components.fibaro.const import CONF_IMPORT_PLUGINS
from homeassistant.const import CONF_PASSWORD, CONF_URL, CONF_USERNAME from homeassistant.const import CONF_PASSWORD, CONF_URL, CONF_USERNAME
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.data_entry_flow import FlowResult, FlowResultType
from .conftest import TEST_NAME, TEST_PASSWORD, TEST_URL, TEST_USERNAME
from tests.common import MockConfigEntry from tests.common import MockConfigEntry
TEST_SERIALNUMBER = "HC2-111111" pytestmark = pytest.mark.usefixtures("mock_setup_entry", "mock_fibaro_client")
TEST_NAME = "my_fibaro_home_center"
TEST_URL = "http://192.168.1.1/api/"
TEST_USERNAME = "user"
TEST_PASSWORD = "password"
TEST_VERSION = "4.360"
pytestmark = pytest.mark.usefixtures("mock_setup_entry")
@pytest.fixture(name="fibaro_client", autouse=True) async def _recovery_after_failure_works(
def fibaro_client_fixture(): hass: HomeAssistant, mock_fibaro_client: Mock, result: FlowResult
"""Mock common methods and attributes of fibaro client.""" ) -> None:
info_mock = Mock() mock_fibaro_client.connect.side_effect = None
info_mock.return_value.serial_number = TEST_SERIALNUMBER mock_fibaro_client.connect.return_value = True
info_mock.return_value.hc_name = TEST_NAME
info_mock.return_value.current_version = TEST_VERSION
client_mock = Mock() result = await hass.config_entries.flow.async_configure(
client_mock.base_url.return_value = TEST_URL result["flow_id"],
{
CONF_URL: TEST_URL,
CONF_USERNAME: TEST_USERNAME,
CONF_PASSWORD: TEST_PASSWORD,
},
)
with patch( assert result["type"] == FlowResultType.CREATE_ENTRY
"homeassistant.components.fibaro.FibaroClient.__init__", assert result["title"] == TEST_NAME
return_value=None, assert result["data"] == {
), patch( CONF_URL: TEST_URL,
"homeassistant.components.fibaro.FibaroClient.read_info", CONF_USERNAME: TEST_USERNAME,
info_mock, CONF_PASSWORD: TEST_PASSWORD,
create=True, CONF_IMPORT_PLUGINS: False,
), patch( }
"homeassistant.components.fibaro.FibaroClient.read_rooms",
return_value=[],
), patch( async def _recovery_after_reauth_failure_works(
"homeassistant.components.fibaro.FibaroClient.read_devices", hass: HomeAssistant, mock_fibaro_client: Mock, result: FlowResult
return_value=[], ) -> None:
), patch( mock_fibaro_client.connect.side_effect = None
"homeassistant.components.fibaro.FibaroClient.read_scenes", mock_fibaro_client.connect.return_value = True
return_value=[],
), patch( result = await hass.config_entries.flow.async_configure(
"homeassistant.components.fibaro.FibaroClient._rest_client", result["flow_id"],
client_mock, user_input={CONF_PASSWORD: "other_fake_password"},
create=True, )
):
yield assert result["type"] == FlowResultType.ABORT
assert result["reason"] == "reauth_successful"
async def test_config_flow_user_initiated_success(hass: HomeAssistant) -> None: async def test_config_flow_user_initiated_success(hass: HomeAssistant) -> None:
@ -64,270 +65,239 @@ async def test_config_flow_user_initiated_success(hass: HomeAssistant) -> None:
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
assert result["type"] == "form" assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "user" assert result["step_id"] == "user"
assert result["errors"] == {} assert result["errors"] == {}
with patch( result = await hass.config_entries.flow.async_configure(
"homeassistant.components.fibaro.FibaroClient.connect", result["flow_id"],
return_value=True, {
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_URL: TEST_URL,
CONF_USERNAME: TEST_USERNAME,
CONF_PASSWORD: TEST_PASSWORD,
},
)
assert result["type"] == "create_entry"
assert result["title"] == TEST_NAME
assert result["data"] == {
CONF_URL: TEST_URL, CONF_URL: TEST_URL,
CONF_USERNAME: TEST_USERNAME, CONF_USERNAME: TEST_USERNAME,
CONF_PASSWORD: TEST_PASSWORD, CONF_PASSWORD: TEST_PASSWORD,
CONF_IMPORT_PLUGINS: False, },
} )
assert result["type"] == FlowResultType.CREATE_ENTRY
assert result["title"] == TEST_NAME
assert result["data"] == {
CONF_URL: TEST_URL,
CONF_USERNAME: TEST_USERNAME,
CONF_PASSWORD: TEST_PASSWORD,
CONF_IMPORT_PLUGINS: False,
}
async def test_config_flow_user_initiated_connect_failure(hass: HomeAssistant) -> None: async def test_config_flow_user_initiated_connect_failure(
hass: HomeAssistant, mock_fibaro_client: Mock
) -> None:
"""Connect failure in flow manually initialized by the user.""" """Connect failure in flow manually initialized by the user."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
assert result["type"] == "form" assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "user" assert result["step_id"] == "user"
assert result["errors"] == {} assert result["errors"] == {}
with patch( mock_fibaro_client.connect.return_value = False
"homeassistant.components.fibaro.FibaroClient.connect",
return_value=False,
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_URL: TEST_URL,
CONF_USERNAME: TEST_USERNAME,
CONF_PASSWORD: TEST_PASSWORD,
},
)
assert result["type"] == "form" result = await hass.config_entries.flow.async_configure(
assert result["step_id"] == "user" result["flow_id"],
assert result["errors"] == {"base": "cannot_connect"} {
CONF_URL: TEST_URL,
CONF_USERNAME: TEST_USERNAME,
CONF_PASSWORD: TEST_PASSWORD,
},
)
assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"] == {"base": "cannot_connect"}
await _recovery_after_failure_works(hass, mock_fibaro_client, result)
async def test_config_flow_user_initiated_auth_failure(hass: HomeAssistant) -> None: async def test_config_flow_user_initiated_auth_failure(
hass: HomeAssistant, mock_fibaro_client: Mock
) -> None:
"""Authentication failure in flow manually initialized by the user.""" """Authentication failure in flow manually initialized by the user."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
assert result["type"] == "form" assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "user" assert result["step_id"] == "user"
assert result["errors"] == {} assert result["errors"] == {}
login_mock = Mock() mock_fibaro_client.connect.side_effect = HTTPError(response=Mock(status_code=403))
login_mock.side_effect = HTTPError(response=Mock(status_code=403))
with patch(
"homeassistant.components.fibaro.FibaroClient.connect", login_mock, create=True
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_URL: TEST_URL,
CONF_USERNAME: TEST_USERNAME,
CONF_PASSWORD: TEST_PASSWORD,
},
)
assert result["type"] == "form" result = await hass.config_entries.flow.async_configure(
assert result["step_id"] == "user" result["flow_id"],
assert result["errors"] == {"base": "invalid_auth"} {
CONF_URL: TEST_URL,
CONF_USERNAME: TEST_USERNAME,
CONF_PASSWORD: TEST_PASSWORD,
},
)
assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"] == {"base": "invalid_auth"}
await _recovery_after_failure_works(hass, mock_fibaro_client, result)
async def test_config_flow_user_initiated_unknown_failure_1( async def test_config_flow_user_initiated_unknown_failure_1(
hass: HomeAssistant, hass: HomeAssistant, mock_fibaro_client: Mock
) -> None: ) -> None:
"""Unknown failure in flow manually initialized by the user.""" """Unknown failure in flow manually initialized by the user."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
assert result["type"] == "form" assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "user" assert result["step_id"] == "user"
assert result["errors"] == {} assert result["errors"] == {}
login_mock = Mock() mock_fibaro_client.connect.side_effect = HTTPError(response=Mock(status_code=500))
login_mock.side_effect = HTTPError(response=Mock(status_code=500))
with patch(
"homeassistant.components.fibaro.FibaroClient.connect", login_mock, create=True
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_URL: TEST_URL,
CONF_USERNAME: TEST_USERNAME,
CONF_PASSWORD: TEST_PASSWORD,
},
)
assert result["type"] == "form" result = await hass.config_entries.flow.async_configure(
assert result["step_id"] == "user" result["flow_id"],
assert result["errors"] == {"base": "cannot_connect"} {
CONF_URL: TEST_URL,
CONF_USERNAME: TEST_USERNAME,
CONF_PASSWORD: TEST_PASSWORD,
},
)
assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"] == {"base": "cannot_connect"}
await _recovery_after_failure_works(hass, mock_fibaro_client, result)
async def test_config_flow_user_initiated_unknown_failure_2( async def test_config_flow_user_initiated_unknown_failure_2(
hass: HomeAssistant, hass: HomeAssistant, mock_fibaro_client: Mock
) -> None: ) -> None:
"""Unknown failure in flow manually initialized by the user.""" """Unknown failure in flow manually initialized by the user."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": config_entries.SOURCE_USER} DOMAIN, context={"source": config_entries.SOURCE_USER}
) )
assert result["type"] == "form" assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "user" assert result["step_id"] == "user"
assert result["errors"] == {} assert result["errors"] == {}
login_mock = Mock() mock_fibaro_client.connect.side_effect = Exception()
login_mock.side_effect = Exception()
with patch(
"homeassistant.components.fibaro.FibaroClient.connect", login_mock, create=True
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
{
CONF_URL: TEST_URL,
CONF_USERNAME: TEST_USERNAME,
CONF_PASSWORD: TEST_PASSWORD,
},
)
assert result["type"] == "form" result = await hass.config_entries.flow.async_configure(
assert result["step_id"] == "user" result["flow_id"],
assert result["errors"] == {"base": "cannot_connect"} {
async def test_reauth_success(hass: HomeAssistant) -> None:
"""Successful reauth flow initialized by the user."""
mock_config = MockConfigEntry(
domain=DOMAIN,
entry_id=TEST_SERIALNUMBER,
data={
CONF_URL: TEST_URL, CONF_URL: TEST_URL,
CONF_USERNAME: TEST_USERNAME, CONF_USERNAME: TEST_USERNAME,
CONF_PASSWORD: TEST_PASSWORD, CONF_PASSWORD: TEST_PASSWORD,
CONF_IMPORT_PLUGINS: False,
}, },
) )
mock_config.add_to_hass(hass)
assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "user"
assert result["errors"] == {"base": "cannot_connect"}
await _recovery_after_failure_works(hass, mock_fibaro_client, result)
async def test_reauth_success(
hass: HomeAssistant, mock_config_entry: MockConfigEntry
) -> None:
"""Successful reauth flow initialized by the user."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, DOMAIN,
context={ context={
"source": config_entries.SOURCE_REAUTH, "source": config_entries.SOURCE_REAUTH,
"entry_id": mock_config.entry_id, "entry_id": mock_config_entry.entry_id,
}, },
) )
assert result["type"] == "form" assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "reauth_confirm" assert result["step_id"] == "reauth_confirm"
assert result["errors"] == {} assert result["errors"] == {}
with patch( result = await hass.config_entries.flow.async_configure(
"homeassistant.components.fibaro.FibaroClient.connect", return_value=True result["flow_id"],
): user_input={CONF_PASSWORD: "other_fake_password"},
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={CONF_PASSWORD: "other_fake_password"},
)
assert result["type"] == "abort"
assert result["reason"] == "reauth_successful"
async def test_reauth_connect_failure(hass: HomeAssistant) -> None:
"""Successful reauth flow initialized by the user."""
mock_config = MockConfigEntry(
domain=DOMAIN,
entry_id=TEST_SERIALNUMBER,
data={
CONF_URL: TEST_URL,
CONF_USERNAME: TEST_USERNAME,
CONF_PASSWORD: TEST_PASSWORD,
CONF_IMPORT_PLUGINS: False,
},
) )
mock_config.add_to_hass(hass)
assert result["type"] == FlowResultType.ABORT
assert result["reason"] == "reauth_successful"
async def test_reauth_connect_failure(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_fibaro_client: Mock,
) -> None:
"""Successful reauth flow initialized by the user."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, DOMAIN,
context={ context={
"source": config_entries.SOURCE_REAUTH, "source": config_entries.SOURCE_REAUTH,
"entry_id": mock_config.entry_id, "entry_id": mock_config_entry.entry_id,
}, },
) )
assert result["type"] == "form" assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "reauth_confirm" assert result["step_id"] == "reauth_confirm"
assert result["errors"] == {} assert result["errors"] == {}
login_mock = Mock() mock_fibaro_client.connect.side_effect = Exception()
login_mock.side_effect = Exception()
with patch(
"homeassistant.components.fibaro.FibaroClient.connect", login_mock, create=True
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={CONF_PASSWORD: "other_fake_password"},
)
assert result["type"] == "form" result = await hass.config_entries.flow.async_configure(
assert result["step_id"] == "reauth_confirm" result["flow_id"],
assert result["errors"] == {"base": "cannot_connect"} user_input={CONF_PASSWORD: "other_fake_password"},
async def test_reauth_auth_failure(hass: HomeAssistant) -> None:
"""Successful reauth flow initialized by the user."""
mock_config = MockConfigEntry(
domain=DOMAIN,
entry_id=TEST_SERIALNUMBER,
data={
CONF_URL: TEST_URL,
CONF_USERNAME: TEST_USERNAME,
CONF_PASSWORD: TEST_PASSWORD,
CONF_IMPORT_PLUGINS: False,
},
) )
mock_config.add_to_hass(hass)
assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "reauth_confirm"
assert result["errors"] == {"base": "cannot_connect"}
await _recovery_after_reauth_failure_works(hass, mock_fibaro_client, result)
async def test_reauth_auth_failure(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
mock_fibaro_client: Mock,
) -> None:
"""Successful reauth flow initialized by the user."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, DOMAIN,
context={ context={
"source": config_entries.SOURCE_REAUTH, "source": config_entries.SOURCE_REAUTH,
"entry_id": mock_config.entry_id, "entry_id": mock_config_entry.entry_id,
}, },
) )
assert result["type"] == "form" assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "reauth_confirm" assert result["step_id"] == "reauth_confirm"
assert result["errors"] == {} assert result["errors"] == {}
login_mock = Mock() mock_fibaro_client.connect.side_effect = HTTPError(response=Mock(status_code=403))
login_mock.side_effect = HTTPError(response=Mock(status_code=403))
with patch(
"homeassistant.components.fibaro.FibaroClient.connect", login_mock, create=True
):
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={CONF_PASSWORD: "other_fake_password"},
)
assert result["type"] == "form" result = await hass.config_entries.flow.async_configure(
assert result["step_id"] == "reauth_confirm" result["flow_id"],
assert result["errors"] == {"base": "invalid_auth"} user_input={CONF_PASSWORD: "other_fake_password"},
)
assert result["type"] == FlowResultType.FORM
assert result["step_id"] == "reauth_confirm"
assert result["errors"] == {"base": "invalid_auth"}
await _recovery_after_reauth_failure_works(hass, mock_fibaro_client, result)
@pytest.mark.parametrize("url_path", ["/api/", "/api", "/", ""]) @pytest.mark.parametrize("url_path", ["/api/", "/api", "/", ""])