Improve Google Calendar config flow error message when API disabled (#87889)

This commit is contained in:
Allen Porter 2023-02-12 09:28:44 -08:00 committed by GitHub
parent ffc60d9091
commit 4d186366bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 28 additions and 4 deletions

View File

@ -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")

View File

@ -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%]"

View File

@ -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(