Remove dead code and increase test coverage for google config flow (#128690)

This commit is contained in:
Allen Porter 2024-10-19 00:48:36 -07:00 committed by GitHub
parent 22491afa58
commit 5816342bed
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 35 additions and 36 deletions

View File

@ -175,7 +175,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
except aiohttp.ClientError as err: except aiohttp.ClientError as err:
raise ConfigEntryNotReady from err raise ConfigEntryNotReady from err
if not async_entry_has_scopes(hass, entry): if not async_entry_has_scopes(entry):
raise ConfigEntryAuthFailed( raise ConfigEntryAuthFailed(
"Required scopes are not available, reauth required" "Required scopes are not available, reauth required"
) )
@ -198,7 +198,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
hass.config_entries.async_update_entry(entry, unique_id=primary_calendar.id) hass.config_entries.async_update_entry(entry, unique_id=primary_calendar.id)
# Only expose the add event service if we have the correct permissions # Only expose the add event service if we have the correct permissions
if get_feature_access(hass, entry) is FeatureAccess.read_write: if get_feature_access(entry) is FeatureAccess.read_write:
await async_setup_add_event_service(hass, calendar_service) await async_setup_add_event_service(hass, calendar_service)
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
@ -208,9 +208,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return True return True
def async_entry_has_scopes(hass: HomeAssistant, entry: ConfigEntry) -> bool: def async_entry_has_scopes(entry: ConfigEntry) -> bool:
"""Verify that the config entry desired scope is present in the oauth token.""" """Verify that the config entry desired scope is present in the oauth token."""
access = get_feature_access(hass, entry) access = get_feature_access(entry)
token_scopes = entry.data.get("token", {}).get("scope", []) token_scopes = entry.data.get("token", {}).get("scope", [])
return access.scope in token_scopes return access.scope in token_scopes
@ -224,7 +224,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
async def async_reload_entry(hass: HomeAssistant, entry: ConfigEntry) -> None: async def async_reload_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
"""Reload config entry if the access options change.""" """Reload config entry if the access options change."""
if not async_entry_has_scopes(hass, entry): if not async_entry_has_scopes(entry):
await hass.config_entries.async_reload(entry.entry_id) await hass.config_entries.async_reload(entry.entry_id)

View File

@ -26,13 +26,7 @@ from homeassistant.helpers.event import (
) )
from homeassistant.util import dt as dt_util from homeassistant.util import dt as dt_util
from .const import ( from .const import CONF_CALENDAR_ACCESS, DEFAULT_FEATURE_ACCESS, FeatureAccess
CONF_CALENDAR_ACCESS,
DATA_CONFIG,
DEFAULT_FEATURE_ACCESS,
DOMAIN,
FeatureAccess,
)
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
@ -161,27 +155,11 @@ class DeviceFlow:
self._listener() self._listener()
def get_feature_access( def get_feature_access(config_entry: ConfigEntry) -> FeatureAccess:
hass: HomeAssistant, config_entry: ConfigEntry | None = None
) -> FeatureAccess:
"""Return the desired calendar feature access.""" """Return the desired calendar feature access."""
if ( if config_entry.options and CONF_CALENDAR_ACCESS in config_entry.options:
config_entry
and config_entry.options
and CONF_CALENDAR_ACCESS in config_entry.options
):
return FeatureAccess[config_entry.options[CONF_CALENDAR_ACCESS]] return FeatureAccess[config_entry.options[CONF_CALENDAR_ACCESS]]
return DEFAULT_FEATURE_ACCESS
# This may be called during config entry setup without integration setup running when there
# is no google entry in configuration.yaml
return cast(
FeatureAccess,
(
hass.data.get(DOMAIN, {})
.get(DATA_CONFIG, {})
.get(CONF_CALENDAR_ACCESS, DEFAULT_FEATURE_ACCESS)
),
)
async def async_create_device_flow( async def async_create_device_flow(

View File

@ -132,7 +132,7 @@ def _get_entity_descriptions(
) )
read_only = not ( read_only = not (
calendar_item.access_role.is_writer calendar_item.access_role.is_writer
and get_feature_access(hass, config_entry) is FeatureAccess.read_write and get_feature_access(config_entry) is FeatureAccess.read_write
) )
# Prefer calendar sync down of resources when possible. However, # Prefer calendar sync down of resources when possible. However,
# sync does not work for search. Also free-busy calendars denormalize # sync does not work for search. Also free-busy calendars denormalize
@ -304,7 +304,7 @@ async def async_setup_entry(
platform = entity_platform.async_get_current_platform() platform = entity_platform.async_get_current_platform()
if ( if (
any(calendar_item.access_role.is_writer for calendar_item in result.items) any(calendar_item.access_role.is_writer for calendar_item in result.items)
and get_feature_access(hass, config_entry) is FeatureAccess.read_write and get_feature_access(config_entry) is FeatureAccess.read_write
): ):
platform.async_register_entity_service( platform.async_register_entity_service(
SERVICE_CREATE_EVENT, SERVICE_CREATE_EVENT,

View File

@ -24,7 +24,6 @@ from .api import (
InvalidCredential, InvalidCredential,
OAuthError, OAuthError,
async_create_device_flow, async_create_device_flow,
get_feature_access,
) )
from .const import ( from .const import (
CONF_CALENDAR_ACCESS, CONF_CALENDAR_ACCESS,
@ -117,7 +116,7 @@ class OAuth2FlowHandler(
self.flow_impl, self.flow_impl,
) )
return self.async_abort(reason="oauth_error") return self.async_abort(reason="oauth_error")
calendar_access = get_feature_access(self.hass) calendar_access = DEFAULT_FEATURE_ACCESS
if self._reauth_config_entry and self._reauth_config_entry.options: if self._reauth_config_entry and self._reauth_config_entry.options:
calendar_access = FeatureAccess[ calendar_access = FeatureAccess[
self._reauth_config_entry.options[CONF_CALENDAR_ACCESS] self._reauth_config_entry.options[CONF_CALENDAR_ACCESS]
@ -214,7 +213,7 @@ class OAuth2FlowHandler(
title=primary_calendar.id, title=primary_calendar.id,
data=data, data=data,
options={ options={
CONF_CALENDAR_ACCESS: get_feature_access(self.hass).name, CONF_CALENDAR_ACCESS: DEFAULT_FEATURE_ACCESS.name,
}, },
) )

View File

@ -26,9 +26,11 @@ from homeassistant.components.application_credentials import (
async_import_client_credential, async_import_client_credential,
) )
from homeassistant.components.google.const import ( from homeassistant.components.google.const import (
CONF_CALENDAR_ACCESS,
CONF_CREDENTIAL_TYPE, CONF_CREDENTIAL_TYPE,
DOMAIN, DOMAIN,
CredentialType, CredentialType,
FeatureAccess,
) )
from homeassistant.config_entries import ConfigEntryState from homeassistant.config_entries import ConfigEntryState
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
@ -474,10 +476,27 @@ async def test_wrong_configuration(
assert result.get("reason") == "oauth_error" assert result.get("reason") == "oauth_error"
@pytest.mark.parametrize(
("options"),
[
({}),
(
{
CONF_CALENDAR_ACCESS: FeatureAccess.read_write.name,
}
),
(
{
CONF_CALENDAR_ACCESS: FeatureAccess.read_only.name,
}
),
],
)
async def test_reauth_flow( async def test_reauth_flow(
hass: HomeAssistant, hass: HomeAssistant,
mock_code_flow: Mock, mock_code_flow: Mock,
mock_exchange: Mock, mock_exchange: Mock,
options: dict[str, Any] | None,
) -> None: ) -> None:
"""Test reauth of an existing config entry.""" """Test reauth of an existing config entry."""
config_entry = MockConfigEntry( config_entry = MockConfigEntry(
@ -486,6 +505,7 @@ async def test_reauth_flow(
"auth_implementation": DOMAIN, "auth_implementation": DOMAIN,
"token": {"access_token": "OLD_ACCESS_TOKEN"}, "token": {"access_token": "OLD_ACCESS_TOKEN"},
}, },
options=options,
) )
config_entry.add_to_hass(hass) config_entry.add_to_hass(hass)
await async_import_client_credential( await async_import_client_credential(
@ -540,6 +560,8 @@ async def test_reauth_flow(
}, },
"credential_type": "device_auth", "credential_type": "device_auth",
} }
# Options are preserved during reauth
assert entries[0].options == options
assert len(mock_setup.mock_calls) == 1 assert len(mock_setup.mock_calls) == 1