mirror of
https://github.com/home-assistant/core.git
synced 2025-07-27 15:17:35 +00:00
Improve Google Calendar config flow error message when API disabled (#87889)
This commit is contained in:
parent
ffc60d9091
commit
4d186366bd
@ -6,7 +6,7 @@ import logging
|
|||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from gcal_sync.api import GoogleCalendarService
|
from gcal_sync.api import GoogleCalendarService
|
||||||
from gcal_sync.exceptions import ApiException
|
from gcal_sync.exceptions import ApiException, ApiForbiddenException
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
@ -146,6 +146,12 @@ class OAuth2FlowHandler(
|
|||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
primary_calendar = await calendar_service.async_get_calendar("primary")
|
primary_calendar = await calendar_service.async_get_calendar("primary")
|
||||||
|
except ApiForbiddenException as err:
|
||||||
|
_LOGGER.error(
|
||||||
|
"Error reading primary calendar, make sure Google Calendar API is enabled: %s",
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
return self.async_abort(reason="api_disabled")
|
||||||
except ApiException as err:
|
except ApiException as err:
|
||||||
_LOGGER.error("Error reading primary calendar: %s", err)
|
_LOGGER.error("Error reading primary calendar: %s", err)
|
||||||
return self.async_abort(reason="cannot_connect")
|
return self.async_abort(reason="cannot_connect")
|
||||||
|
@ -21,7 +21,8 @@
|
|||||||
"missing_configuration": "[%key:common::config_flow::abort::oauth2_missing_configuration%]",
|
"missing_configuration": "[%key:common::config_flow::abort::oauth2_missing_configuration%]",
|
||||||
"code_expired": "Authentication code expired or credential setup is invalid, please try again.",
|
"code_expired": "Authentication code expired or credential setup is invalid, please try again.",
|
||||||
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
|
"reauth_successful": "[%key:common::config_flow::abort::reauth_successful%]",
|
||||||
"invalid_access_token": "[%key:common::config_flow::error::invalid_access_token%]"
|
"invalid_access_token": "[%key:common::config_flow::error::invalid_access_token%]",
|
||||||
|
"api_disabled": "You must enable the Google Calendar API in the Google Cloud Console"
|
||||||
},
|
},
|
||||||
"create_entry": {
|
"create_entry": {
|
||||||
"default": "[%key:common::config_flow::create_entry::authenticated%]"
|
"default": "[%key:common::config_flow::create_entry::authenticated%]"
|
||||||
|
@ -4,6 +4,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
import datetime
|
import datetime
|
||||||
|
from http import HTTPStatus
|
||||||
from unittest.mock import Mock, patch
|
from unittest.mock import Mock, patch
|
||||||
|
|
||||||
from aiohttp.client_exceptions import ClientError
|
from aiohttp.client_exceptions import ClientError
|
||||||
@ -95,10 +96,17 @@ async def primary_calendar_error() -> ClientError | None:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
async def primary_calendar_status() -> HTTPStatus | None:
|
||||||
|
"""Fixture for tests to inject an error during calendar lookup."""
|
||||||
|
return HTTPStatus.OK
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
async def primary_calendar(
|
async def primary_calendar(
|
||||||
mock_calendar_get: Callable[[...], None],
|
mock_calendar_get: Callable[[...], None],
|
||||||
primary_calendar_error: ClientError | None,
|
primary_calendar_error: ClientError | None,
|
||||||
|
primary_calendar_status: HTTPStatus | None,
|
||||||
primary_calendar_email: str,
|
primary_calendar_email: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Fixture to return the primary calendar."""
|
"""Fixture to return the primary calendar."""
|
||||||
@ -106,6 +114,7 @@ async def primary_calendar(
|
|||||||
"primary",
|
"primary",
|
||||||
{"id": primary_calendar_email, "summary": "Personal", "accessRole": "owner"},
|
{"id": primary_calendar_email, "summary": "Personal", "accessRole": "owner"},
|
||||||
exc=primary_calendar_error,
|
exc=primary_calendar_error,
|
||||||
|
status=primary_calendar_status,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -515,11 +524,19 @@ async def test_reauth_flow(
|
|||||||
assert len(mock_setup.mock_calls) == 1
|
assert len(mock_setup.mock_calls) == 1
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("primary_calendar_error", [ClientError()])
|
@pytest.mark.parametrize(
|
||||||
|
"primary_calendar_error,primary_calendar_status,reason",
|
||||||
|
[
|
||||||
|
(ClientError(), None, "cannot_connect"),
|
||||||
|
(None, HTTPStatus.FORBIDDEN, "api_disabled"),
|
||||||
|
(None, HTTPStatus.SERVICE_UNAVAILABLE, "cannot_connect"),
|
||||||
|
],
|
||||||
|
)
|
||||||
async def test_calendar_lookup_failure(
|
async def test_calendar_lookup_failure(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
mock_code_flow: Mock,
|
mock_code_flow: Mock,
|
||||||
mock_exchange: Mock,
|
mock_exchange: Mock,
|
||||||
|
reason: str,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test successful config flow and title fetch fails gracefully."""
|
"""Test successful config flow and title fetch fails gracefully."""
|
||||||
await async_import_client_credential(
|
await async_import_client_credential(
|
||||||
@ -544,7 +561,7 @@ async def test_calendar_lookup_failure(
|
|||||||
)
|
)
|
||||||
|
|
||||||
assert result.get("type") == "abort"
|
assert result.get("type") == "abort"
|
||||||
assert result.get("reason") == "cannot_connect"
|
assert result.get("reason") == reason
|
||||||
|
|
||||||
|
|
||||||
async def test_options_flow_triggers_reauth(
|
async def test_options_flow_triggers_reauth(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user