mirror of
https://github.com/home-assistant/core.git
synced 2026-09-24 07:25:52 -05:00
Handle Mastodon auth fail in coordinator (#163234)
This commit is contained in:
@@ -6,13 +6,20 @@ from dataclasses import dataclass
|
||||
from datetime import timedelta
|
||||
|
||||
from mastodon import Mastodon
|
||||
from mastodon.Mastodon import Account, Instance, InstanceV2, MastodonError
|
||||
from mastodon.Mastodon import (
|
||||
Account,
|
||||
Instance,
|
||||
InstanceV2,
|
||||
MastodonError,
|
||||
MastodonUnauthorizedError,
|
||||
)
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryAuthFailed
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
|
||||
from .const import LOGGER
|
||||
from .const import DOMAIN, LOGGER
|
||||
|
||||
|
||||
@dataclass
|
||||
@@ -51,6 +58,11 @@ class MastodonCoordinator(DataUpdateCoordinator[Account]):
|
||||
account: Account = await self.hass.async_add_executor_job(
|
||||
self.client.account_verify_credentials
|
||||
)
|
||||
except MastodonUnauthorizedError as error:
|
||||
raise ConfigEntryAuthFailed(
|
||||
translation_domain=DOMAIN,
|
||||
translation_key="auth_failed",
|
||||
) from error
|
||||
except MastodonError as ex:
|
||||
raise UpdateFailed(ex) from ex
|
||||
|
||||
|
||||
@@ -1,21 +1,33 @@
|
||||
"""Tests for the Mastodon integration."""
|
||||
|
||||
from datetime import timedelta
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
from mastodon.Mastodon import MastodonNotFoundError, MastodonUnauthorizedError
|
||||
from freezegun.api import FrozenDateTimeFactory
|
||||
from mastodon.Mastodon import (
|
||||
MastodonError,
|
||||
MastodonNotFoundError,
|
||||
MastodonUnauthorizedError,
|
||||
)
|
||||
import pytest
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.components.mastodon.config_flow import MastodonConfigFlow
|
||||
from homeassistant.components.mastodon.const import CONF_BASE_URL, DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntryState
|
||||
from homeassistant.const import CONF_ACCESS_TOKEN, CONF_CLIENT_ID, CONF_CLIENT_SECRET
|
||||
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState
|
||||
from homeassistant.const import (
|
||||
CONF_ACCESS_TOKEN,
|
||||
CONF_CLIENT_ID,
|
||||
CONF_CLIENT_SECRET,
|
||||
STATE_ON,
|
||||
STATE_UNAVAILABLE,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import device_registry as dr
|
||||
|
||||
from . import setup_integration
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.common import MockConfigEntry, async_fire_time_changed
|
||||
|
||||
|
||||
async def test_device_info(
|
||||
@@ -107,3 +119,62 @@ async def test_migrate(
|
||||
assert config_entry.version == MastodonConfigFlow.VERSION
|
||||
assert config_entry.minor_version == MastodonConfigFlow.MINOR_VERSION
|
||||
assert config_entry.unique_id == "trwnh_mastodon_social"
|
||||
|
||||
|
||||
async def test_coordinator_general_error(
|
||||
hass: HomeAssistant,
|
||||
mock_mastodon_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test general error during coordinator update makes entities unavailable."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
state = hass.states.get("binary_sensor.mastodon_trwnh_mastodon_social_bot")
|
||||
assert state is not None
|
||||
assert state.state == STATE_ON
|
||||
|
||||
mock_mastodon_client.account_verify_credentials.side_effect = MastodonError
|
||||
|
||||
freezer.tick(timedelta(hours=1))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
state = hass.states.get("binary_sensor.mastodon_trwnh_mastodon_social_bot")
|
||||
assert state is not None
|
||||
assert state.state == STATE_UNAVAILABLE
|
||||
|
||||
# No reauth flow should be triggered (unlike auth errors)
|
||||
flows = hass.config_entries.flow.async_progress()
|
||||
assert len(flows) == 0
|
||||
|
||||
|
||||
async def test_coordinator_auth_failure_triggers_reauth(
|
||||
hass: HomeAssistant,
|
||||
mock_mastodon_client: AsyncMock,
|
||||
mock_config_entry: MockConfigEntry,
|
||||
freezer: FrozenDateTimeFactory,
|
||||
) -> None:
|
||||
"""Test auth failure during coordinator update triggers reauth flow."""
|
||||
await setup_integration(hass, mock_config_entry)
|
||||
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
mock_mastodon_client.account_verify_credentials.side_effect = (
|
||||
MastodonUnauthorizedError
|
||||
)
|
||||
|
||||
freezer.tick(timedelta(hours=1))
|
||||
async_fire_time_changed(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert mock_config_entry.state is ConfigEntryState.LOADED
|
||||
|
||||
flows = hass.config_entries.flow.async_progress()
|
||||
assert len(flows) == 1
|
||||
|
||||
flow = flows[0]
|
||||
assert flow["context"]["source"] == SOURCE_REAUTH
|
||||
assert flow["context"]["entry_id"] == mock_config_entry.entry_id
|
||||
|
||||
Reference in New Issue
Block a user