diff --git a/homeassistant/components/tibber/config_flow.py b/homeassistant/components/tibber/config_flow.py index b5cb4486cc9..fbd2345fb80 100644 --- a/homeassistant/components/tibber/config_flow.py +++ b/homeassistant/components/tibber/config_flow.py @@ -16,6 +16,9 @@ from homeassistant.helpers.aiohttp_client import async_get_clientsession from .const import DOMAIN DATA_SCHEMA = vol.Schema({vol.Required(CONF_ACCESS_TOKEN): str}) +ERR_TIMEOUT = "timeout" +ERR_CLIENT = "cannot_connect" +ERR_TOKEN = "invalid_access_token" class TibberConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): @@ -43,15 +46,15 @@ class TibberConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): try: await tibber_connection.update_info() except asyncio.TimeoutError: - errors[CONF_ACCESS_TOKEN] = "timeout" + errors[CONF_ACCESS_TOKEN] = ERR_TIMEOUT except tibber.InvalidLogin: - errors[CONF_ACCESS_TOKEN] = "invalid_access_token" + errors[CONF_ACCESS_TOKEN] = ERR_TOKEN except ( aiohttp.ClientError, tibber.RetryableHttpException, tibber.FatalHttpException, ): - errors[CONF_ACCESS_TOKEN] = "cannot_connect" + errors[CONF_ACCESS_TOKEN] = ERR_CLIENT if errors: return self.async_show_form( diff --git a/tests/components/tibber/test_config_flow.py b/tests/components/tibber/test_config_flow.py index d50e60b1588..e07e4d66cd2 100644 --- a/tests/components/tibber/test_config_flow.py +++ b/tests/components/tibber/test_config_flow.py @@ -1,13 +1,22 @@ """Tests for Tibber config flow.""" +from asyncio import TimeoutError from unittest.mock import AsyncMock, MagicMock, PropertyMock, patch +from aiohttp import ClientError import pytest +from tibber import FatalHttpException, InvalidLogin, RetryableHttpException from homeassistant import config_entries from homeassistant.components.recorder import Recorder +from homeassistant.components.tibber.config_flow import ( + ERR_CLIENT, + ERR_TIMEOUT, + ERR_TOKEN, +) from homeassistant.components.tibber.const import DOMAIN from homeassistant.const import CONF_ACCESS_TOKEN from homeassistant.core import HomeAssistant +from homeassistant.data_entry_flow import FlowResultType @pytest.fixture(name="tibber_setup", autouse=True) @@ -23,7 +32,7 @@ async def test_show_config_form(recorder_mock: Recorder, hass: HomeAssistant) -> DOMAIN, context={"source": config_entries.SOURCE_USER} ) - assert result["type"] == "form" + assert result["type"] == FlowResultType.FORM assert result["step_id"] == "user" @@ -46,14 +55,45 @@ async def test_create_entry(recorder_mock: Recorder, hass: HomeAssistant) -> Non DOMAIN, context={"source": config_entries.SOURCE_USER}, data=test_data ) - assert result["type"] == "create_entry" + assert result["type"] == FlowResultType.CREATE_ENTRY assert result["title"] == title assert result["data"] == test_data -async def test_flow_entry_already_exists( - recorder_mock: Recorder, hass: HomeAssistant, config_entry -) -> None: +@pytest.mark.parametrize( + ("exception", "expected_error"), + [ + (TimeoutError, ERR_TIMEOUT), + (ClientError, ERR_CLIENT), + (InvalidLogin(401), ERR_TOKEN), + (RetryableHttpException(503), ERR_CLIENT), + (FatalHttpException(404), ERR_CLIENT), + ], +) +async def test_create_entry_exceptions(recorder_mock, hass, exception, expected_error): + """Test create entry from user input.""" + test_data = { + CONF_ACCESS_TOKEN: "valid", + } + + unique_user_id = "unique_user_id" + title = "title" + + tibber_mock = MagicMock() + type(tibber_mock).update_info = AsyncMock(side_effect=exception) + type(tibber_mock).user_id = PropertyMock(return_value=unique_user_id) + type(tibber_mock).name = PropertyMock(return_value=title) + + with patch("tibber.Tibber", return_value=tibber_mock): + result = await hass.config_entries.flow.async_init( + DOMAIN, context={"source": config_entries.SOURCE_USER}, data=test_data + ) + + assert result["type"] == FlowResultType.FORM + assert result["errors"][CONF_ACCESS_TOKEN] == expected_error + + +async def test_flow_entry_already_exists(recorder_mock, hass, config_entry): """Test user input for config_entry that already exists.""" test_data = { CONF_ACCESS_TOKEN: "valid", @@ -64,5 +104,5 @@ async def test_flow_entry_already_exists( DOMAIN, context={"source": config_entries.SOURCE_USER}, data=test_data ) - assert result["type"] == "abort" + assert result["type"] == FlowResultType.ABORT assert result["reason"] == "already_configured"