Handle 403 error in remote calendar (#141839)

* Handle 403 error in remote calendar

* tests
This commit is contained in:
Thomas55555 2025-03-31 11:40:14 +02:00 committed by GitHub
parent f6308368b0
commit 6aeb7f36f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 21 additions and 3 deletions

View File

@ -1,5 +1,6 @@
"""Config flow for Remote Calendar integration.""" """Config flow for Remote Calendar integration."""
from http import HTTPStatus
import logging import logging
from typing import Any from typing import Any
@ -50,6 +51,13 @@ class RemoteCalendarConfigFlow(ConfigFlow, domain=DOMAIN):
client = get_async_client(self.hass) client = get_async_client(self.hass)
try: try:
res = await client.get(user_input[CONF_URL], follow_redirects=True) res = await client.get(user_input[CONF_URL], follow_redirects=True)
if res.status_code == HTTPStatus.FORBIDDEN:
errors["base"] = "forbidden"
return self.async_show_form(
step_id="user",
data_schema=STEP_USER_DATA_SCHEMA,
errors=errors,
)
res.raise_for_status() res.raise_for_status()
except (HTTPError, InvalidURL) as err: except (HTTPError, InvalidURL) as err:
errors["base"] = "cannot_connect" errors["base"] = "cannot_connect"

View File

@ -19,6 +19,7 @@
}, },
"error": { "error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]", "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"forbidden": "The server understood the request but refuses to authorize it.",
"invalid_ics_file": "[%key:component::local_calendar::config::error::invalid_ics_file%]" "invalid_ics_file": "[%key:component::local_calendar::config::error::invalid_ics_file%]"
} }
}, },

View File

@ -165,8 +165,17 @@ async def test_unsupported_inputs(
## and then the exception isn't raised anymore. ## and then the exception isn't raised anymore.
@pytest.mark.parametrize(
("http_status", "error"),
[
(401, "cannot_connect"),
(403, "forbidden"),
],
)
@respx.mock @respx.mock
async def test_form_http_status_error(hass: HomeAssistant, ics_content: str) -> None: async def test_form_http_status_error(
hass: HomeAssistant, ics_content: str, http_status: int, error: str
) -> None:
"""Test we http status.""" """Test we http status."""
result = await hass.config_entries.flow.async_init( result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER} DOMAIN, context={"source": SOURCE_USER}
@ -174,7 +183,7 @@ async def test_form_http_status_error(hass: HomeAssistant, ics_content: str) ->
assert result["type"] is FlowResultType.FORM assert result["type"] is FlowResultType.FORM
respx.get(CALENDER_URL).mock( respx.get(CALENDER_URL).mock(
return_value=Response( return_value=Response(
status_code=403, status_code=http_status,
) )
) )
@ -186,7 +195,7 @@ async def test_form_http_status_error(hass: HomeAssistant, ics_content: str) ->
}, },
) )
assert result2["type"] is FlowResultType.FORM assert result2["type"] is FlowResultType.FORM
assert result2["errors"] == {"base": "cannot_connect"} assert result2["errors"] == {"base": error}
respx.get(CALENDER_URL).mock( respx.get(CALENDER_URL).mock(
return_value=Response( return_value=Response(
status_code=200, status_code=200,