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 gcal_sync.api import GoogleCalendarService
from gcal_sync.exceptions import ApiException
from gcal_sync.exceptions import ApiException, ApiForbiddenException
import voluptuous as vol
from homeassistant import config_entries
@ -146,6 +146,12 @@ class OAuth2FlowHandler(
)
try:
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:
_LOGGER.error("Error reading primary calendar: %s", err)
return self.async_abort(reason="cannot_connect")

View File

@ -21,7 +21,8 @@
"missing_configuration": "[%key:common::config_flow::abort::oauth2_missing_configuration%]",
"code_expired": "Authentication code expired or credential setup is invalid, please try again.",
"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": {
"default": "[%key:common::config_flow::create_entry::authenticated%]"

View File

@ -4,6 +4,7 @@ from __future__ import annotations
from collections.abc import Callable
import datetime
from http import HTTPStatus
from unittest.mock import Mock, patch
from aiohttp.client_exceptions import ClientError
@ -95,10 +96,17 @@ async def primary_calendar_error() -> ClientError | 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)
async def primary_calendar(
mock_calendar_get: Callable[[...], None],
primary_calendar_error: ClientError | None,
primary_calendar_status: HTTPStatus | None,
primary_calendar_email: str,
) -> None:
"""Fixture to return the primary calendar."""
@ -106,6 +114,7 @@ async def primary_calendar(
"primary",
{"id": primary_calendar_email, "summary": "Personal", "accessRole": "owner"},
exc=primary_calendar_error,
status=primary_calendar_status,
)
@ -515,11 +524,19 @@ async def test_reauth_flow(
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(
hass: HomeAssistant,
mock_code_flow: Mock,
mock_exchange: Mock,
reason: str,
) -> None:
"""Test successful config flow and title fetch fails gracefully."""
await async_import_client_credential(
@ -544,7 +561,7 @@ async def test_calendar_lookup_failure(
)
assert result.get("type") == "abort"
assert result.get("reason") == "cannot_connect"
assert result.get("reason") == reason
async def test_options_flow_triggers_reauth(