Files

118 lines
4.3 KiB
Python

"""Tests for the Honeywell Lyric integration."""
from unittest.mock import AsyncMock, MagicMock, patch
from aiolyric.exceptions import LyricAuthenticationException
from aiolyric.objects.location import LyricLocation
import pytest
from homeassistant.components.lyric.api import OAuth2SessionLyric
from homeassistant.components.lyric.const import DOMAIN
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState
from homeassistant.core import HomeAssistant
from homeassistant.helpers.config_entry_oauth2_flow import (
ImplementationUnavailableError,
)
from .conftest import build_mock_lyric, location_json, lyric_exception, thermostat_json
from tests.common import MockConfigEntry
async def test_oauth_implementation_not_available(
hass: HomeAssistant,
) -> None:
"""Test that unavailable OAuth implementation raises ConfigEntryNotReady."""
entry = MockConfigEntry(
domain=DOMAIN,
data={
"auth_implementation": DOMAIN,
"token": {
"access_token": "mock-access-token",
"refresh_token": "mock-refresh-token",
"expires_at": 9999999999,
"token_type": "Bearer",
},
},
)
entry.add_to_hass(hass)
with patch(
"homeassistant.helpers.config_entry_oauth2_flow.async_get_config_entry_implementation",
side_effect=ImplementationUnavailableError,
):
await hass.config_entries.async_setup(entry.entry_id)
await hass.async_block_till_done()
assert entry.state is ConfigEntryState.SETUP_RETRY
@pytest.mark.usefixtures("setup_credentials")
async def test_setup_retry_on_room_priority_error(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
) -> None:
"""A non-400 error fetching room priority data should mark the entry as not ready."""
location = LyricLocation(
MagicMock(),
location_json(1, [thermostat_json("AABBCC000001", "LCC-AABBCC000001")]),
)
lyric = build_mock_lyric([location])
lyric.get_thermostat_rooms.side_effect = lyric_exception(500)
mock_config_entry.add_to_hass(hass)
with patch("homeassistant.components.lyric.Lyric", return_value=lyric):
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
@pytest.mark.usefixtures("setup_credentials")
async def test_setup_retry_on_unexpected_bad_request_reason(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
) -> None:
"""A 400 for a reason other than GetPriorityFailed should mark the entry as not ready."""
location = LyricLocation(
MagicMock(),
location_json(1, [thermostat_json("AABBCC000001", "LCC-AABBCC000001")]),
)
lyric = build_mock_lyric([location])
lyric.get_thermostat_rooms.side_effect = lyric_exception(400, code="SomeOtherError")
mock_config_entry.add_to_hass(hass)
with patch("homeassistant.components.lyric.Lyric", return_value=lyric):
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert mock_config_entry.state is ConfigEntryState.SETUP_RETRY
@pytest.mark.usefixtures("setup_credentials")
async def test_setup_error_starts_reauth_on_authentication_failure(
hass: HomeAssistant,
mock_config_entry: MockConfigEntry,
) -> None:
"""Authentication errors should fail setup and start a reauth flow."""
location = LyricLocation(
MagicMock(),
location_json(1, [thermostat_json("AABBCC000001", "LCC-AABBCC000001")]),
)
lyric = build_mock_lyric([location])
lyric.get_thermostat_rooms.side_effect = LyricAuthenticationException(
{"request": {}, "response": {}, "status": 401}
)
mock_config_entry.add_to_hass(hass)
with (
patch("homeassistant.components.lyric.Lyric", return_value=lyric),
patch.object(OAuth2SessionLyric, "force_refresh_token", new=AsyncMock()),
):
await hass.config_entries.async_setup(mock_config_entry.entry_id)
await hass.async_block_till_done()
assert mock_config_entry.state is ConfigEntryState.SETUP_ERROR
flows = hass.config_entries.flow.async_progress()
assert any(flow["context"]["source"] == SOURCE_REAUTH for flow in flows)