mirror of
https://github.com/home-assistant/core.git
synced 2026-09-03 20:12:16 +01:00
Improve Google Health config flow error messages (#179940)
Co-authored-by: Home Assistant Developer <hello@home-assistant.io>
This commit is contained in:
co-authored by
Home Assistant Developer
parent
52e0c3c6a7
commit
ef8e89180b
@@ -8,7 +8,8 @@ from google_health_api import GoogleHealthApi
|
||||
from google_health_api.const import HealthApiScope
|
||||
from google_health_api.exceptions import (
|
||||
GoogleHealthApiError,
|
||||
HealthApiForbiddenException,
|
||||
HealthApiScopeInsufficientException,
|
||||
HealthApiServiceDisabledException,
|
||||
)
|
||||
|
||||
from homeassistant.config_entries import (
|
||||
@@ -81,19 +82,22 @@ class OAuth2FlowHandler(
|
||||
|
||||
try:
|
||||
identity = await api.get_identity()
|
||||
except HealthApiForbiddenException as err:
|
||||
except HealthApiServiceDisabledException as err:
|
||||
_LOGGER.error("Error getting Google Health identity: %s", err)
|
||||
return self.async_abort(
|
||||
reason="api_not_enabled",
|
||||
description_placeholders={"url": API_CONSOLE_URL},
|
||||
)
|
||||
except HealthApiScopeInsufficientException as err:
|
||||
_LOGGER.error("Error getting Google Health identity: %s", err)
|
||||
return self.async_abort(reason="missing_profile_scope")
|
||||
except GoogleHealthApiError as err:
|
||||
_LOGGER.error("Error getting Google Health identity: %s", err)
|
||||
return self.async_abort(reason="cannot_connect")
|
||||
|
||||
if not identity.health_user_id:
|
||||
_LOGGER.error("Google Health identity has no health_user_id")
|
||||
return self.async_abort(reason="cannot_connect")
|
||||
return self.async_abort(reason="missing_profile_scope")
|
||||
|
||||
await self.async_set_unique_id(identity.health_user_id)
|
||||
if self.source in (SOURCE_REAUTH, SOURCE_RECONFIGURE):
|
||||
@@ -110,7 +114,7 @@ class OAuth2FlowHandler(
|
||||
try:
|
||||
userinfo = await api.get_user_info()
|
||||
display_name = userinfo.given_name or userinfo.name
|
||||
except Exception as err: # pylint: disable=broad-except # noqa: BLE001
|
||||
except GoogleHealthApiError as err:
|
||||
_LOGGER.warning("Error fetching user profile name: %s", err)
|
||||
|
||||
return self.async_create_entry(
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"authorize_url_timeout": "[%key:common::config_flow::abort::oauth2_authorize_url_timeout%]",
|
||||
"cannot_connect": "Failed to connect.",
|
||||
"missing_configuration": "[%key:common::config_flow::abort::oauth2_missing_configuration%]",
|
||||
"missing_profile_scope": "Missing required Google Health profile read permission.",
|
||||
"missing_profile_scope": "Missing required Google Health profile read permission. Please try again and select the right permission.",
|
||||
"no_url_available": "[%key:common::config_flow::abort::oauth2_no_url_available%]",
|
||||
"oauth_error": "[%key:common::config_flow::abort::oauth2_error%]",
|
||||
"oauth_failed": "[%key:common::config_flow::abort::oauth2_failed%]",
|
||||
|
||||
@@ -5,7 +5,8 @@ from unittest.mock import AsyncMock, patch
|
||||
from google_health_api.const import HealthApiScope
|
||||
from google_health_api.exceptions import (
|
||||
GoogleHealthApiError,
|
||||
HealthApiForbiddenException,
|
||||
HealthApiScopeInsufficientException,
|
||||
HealthApiServiceDisabledException,
|
||||
)
|
||||
from google_health_api.model import Identity
|
||||
import pytest
|
||||
@@ -243,8 +244,8 @@ async def test_config_flow_api_not_enabled(
|
||||
mock_google_health_client: AsyncMock,
|
||||
) -> None:
|
||||
"""Test config flow aborts if the Google Health API is not enabled."""
|
||||
mock_google_health_client.get_identity.side_effect = HealthApiForbiddenException(
|
||||
"Forbidden"
|
||||
mock_google_health_client.get_identity.side_effect = (
|
||||
HealthApiServiceDisabledException
|
||||
)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
@@ -280,6 +281,50 @@ async def test_config_flow_api_not_enabled(
|
||||
}
|
||||
|
||||
|
||||
@pytest.mark.usefixtures(
|
||||
"current_request_with_host", "mock_setup_entry", "setup_credentials"
|
||||
)
|
||||
async def test_config_flow_scope_insufficient(
|
||||
hass: HomeAssistant,
|
||||
hass_client_no_auth: ClientSessionGenerator,
|
||||
aioclient_mock: AiohttpClientMocker,
|
||||
mock_google_health_client: AsyncMock,
|
||||
) -> None:
|
||||
"""Test config flow aborts if the OAuth token has insufficient scope."""
|
||||
mock_google_health_client.get_identity.side_effect = (
|
||||
HealthApiScopeInsufficientException
|
||||
)
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": SOURCE_USER}
|
||||
)
|
||||
state = config_entry_oauth2_flow._encode_jwt(
|
||||
hass,
|
||||
{
|
||||
"flow_id": result["flow_id"],
|
||||
"redirect_uri": "https://example.com/auth/external/callback",
|
||||
},
|
||||
)
|
||||
|
||||
client = await hass_client_no_auth()
|
||||
await client.get(f"/auth/external/callback?code=abcd&state={state}")
|
||||
|
||||
aioclient_mock.post(
|
||||
OAUTH2_TOKEN,
|
||||
json={
|
||||
"refresh_token": "mock-refresh-token",
|
||||
"access_token": "mock-access-token",
|
||||
"type": "Bearer",
|
||||
"expires_in": 60,
|
||||
"scope": " ".join(OAUTH_SCOPES),
|
||||
},
|
||||
)
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "missing_profile_scope"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures(
|
||||
"current_request_with_host", "mock_setup_entry", "setup_credentials"
|
||||
)
|
||||
@@ -321,7 +366,7 @@ async def test_config_flow_missing_health_user_id(
|
||||
|
||||
result = await hass.config_entries.flow.async_configure(result["flow_id"])
|
||||
assert result["type"] is FlowResultType.ABORT
|
||||
assert result["reason"] == "cannot_connect"
|
||||
assert result["reason"] == "missing_profile_scope"
|
||||
|
||||
|
||||
@pytest.mark.usefixtures(
|
||||
|
||||
Reference in New Issue
Block a user