mirror of
https://github.com/home-assistant/core.git
synced 2026-08-03 20:24:55 +02:00
d345d37aa2
Co-authored-by: Markus Tuominen <3738613+Markus98@users.noreply.github.com>
219 lines
6.6 KiB
Python
219 lines
6.6 KiB
Python
"""Test the habitica module."""
|
|
|
|
import datetime
|
|
import logging
|
|
from unittest.mock import AsyncMock
|
|
|
|
from aiohttp import ClientError
|
|
from freezegun.api import FrozenDateTimeFactory
|
|
from habiticalib import HabiticaUserResponse
|
|
import pytest
|
|
|
|
from homeassistant.components.habitica.const import DOMAIN
|
|
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers import device_registry as dr
|
|
|
|
from .conftest import (
|
|
ERROR_BAD_REQUEST,
|
|
ERROR_NOT_AUTHORIZED,
|
|
ERROR_NOT_FOUND,
|
|
ERROR_TOO_MANY_REQUESTS,
|
|
)
|
|
|
|
from tests.common import MockConfigEntry, async_fire_time_changed, async_load_fixture
|
|
|
|
|
|
@pytest.mark.usefixtures("habitica")
|
|
async def test_entry_setup_unload(
|
|
hass: HomeAssistant, config_entry: MockConfigEntry
|
|
) -> None:
|
|
"""Test integration setup and unload."""
|
|
|
|
config_entry.add_to_hass(hass)
|
|
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
assert config_entry.state is ConfigEntryState.LOADED
|
|
|
|
assert await hass.config_entries.async_unload(config_entry.entry_id)
|
|
|
|
assert config_entry.state is ConfigEntryState.NOT_LOADED
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
("exception"),
|
|
[ERROR_BAD_REQUEST, ERROR_TOO_MANY_REQUESTS, ClientError],
|
|
ids=[
|
|
"BadRequestError",
|
|
"TooManyRequestsError",
|
|
"ClientError",
|
|
],
|
|
)
|
|
async def test_config_entry_not_ready(
|
|
hass: HomeAssistant,
|
|
config_entry: MockConfigEntry,
|
|
habitica: AsyncMock,
|
|
exception: Exception,
|
|
) -> None:
|
|
"""Test config entry not ready."""
|
|
|
|
habitica.get_user.side_effect = exception
|
|
config_entry.add_to_hass(hass)
|
|
await hass.config_entries.async_setup(config_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
assert config_entry.state is ConfigEntryState.SETUP_RETRY
|
|
|
|
|
|
async def test_config_entry_auth_failed(
|
|
hass: HomeAssistant, config_entry: MockConfigEntry, habitica: AsyncMock
|
|
) -> None:
|
|
"""Test config entry auth failed setup error."""
|
|
|
|
habitica.get_user.side_effect = ERROR_NOT_AUTHORIZED
|
|
config_entry.add_to_hass(hass)
|
|
await hass.config_entries.async_setup(config_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
assert config_entry.state is ConfigEntryState.SETUP_ERROR
|
|
|
|
flows = hass.config_entries.flow.async_progress()
|
|
assert len(flows) == 1
|
|
|
|
flow = flows[0]
|
|
assert flow.get("step_id") == "reauth_confirm"
|
|
assert flow.get("handler") == DOMAIN
|
|
|
|
assert "context" in flow
|
|
assert flow["context"].get("source") == SOURCE_REAUTH
|
|
assert flow["context"].get("entry_id") == config_entry.entry_id
|
|
|
|
|
|
@pytest.mark.parametrize("exception", [ERROR_NOT_FOUND, ClientError])
|
|
async def test_coordinator_update_failed(
|
|
hass: HomeAssistant,
|
|
config_entry: MockConfigEntry,
|
|
habitica: AsyncMock,
|
|
exception: Exception,
|
|
) -> None:
|
|
"""Test coordinator update failed."""
|
|
|
|
habitica.get_tasks.side_effect = exception
|
|
config_entry.add_to_hass(hass)
|
|
await hass.config_entries.async_setup(config_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
assert config_entry.state is ConfigEntryState.SETUP_RETRY
|
|
|
|
|
|
async def test_coordinator_rate_limited(
|
|
hass: HomeAssistant,
|
|
config_entry: MockConfigEntry,
|
|
habitica: AsyncMock,
|
|
caplog: pytest.LogCaptureFixture,
|
|
freezer: FrozenDateTimeFactory,
|
|
) -> None:
|
|
"""Test coordinator when rate limited."""
|
|
|
|
config_entry.add_to_hass(hass)
|
|
await hass.config_entries.async_setup(config_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
assert config_entry.state is ConfigEntryState.LOADED
|
|
|
|
habitica.get_user.side_effect = ERROR_TOO_MANY_REQUESTS
|
|
|
|
with caplog.at_level(logging.DEBUG):
|
|
freezer.tick(datetime.timedelta(seconds=60))
|
|
async_fire_time_changed(hass)
|
|
await hass.async_block_till_done()
|
|
|
|
assert "Rate limit exceeded, will try again later" in caplog.text
|
|
|
|
|
|
async def test_remove_party_and_reload(
|
|
hass: HomeAssistant,
|
|
config_entry: MockConfigEntry,
|
|
habitica: AsyncMock,
|
|
freezer: FrozenDateTimeFactory,
|
|
device_registry: dr.DeviceRegistry,
|
|
) -> None:
|
|
"""Test we leave the party and device/notifiers are removed."""
|
|
group_id = "1e87097c-4c03-4f8c-a475-67cc7da7f409"
|
|
config_entry.add_to_hass(hass)
|
|
await hass.config_entries.async_setup(config_entry.entry_id)
|
|
await hass.async_block_till_done()
|
|
|
|
assert config_entry.state is ConfigEntryState.LOADED
|
|
|
|
assert (
|
|
device_registry.async_get_device(
|
|
{(DOMAIN, f"{config_entry.unique_id}_{group_id}")}
|
|
)
|
|
is not None
|
|
)
|
|
|
|
assert hass.states.get("notify.test_user_party_chat")
|
|
assert hass.states.get(
|
|
"notify.test_user_private_message_test_partymember_displayname"
|
|
)
|
|
|
|
habitica.get_user.return_value = HabiticaUserResponse.from_json(
|
|
await async_load_fixture(hass, "user_no_party.json", DOMAIN)
|
|
)
|
|
|
|
freezer.tick(datetime.timedelta(seconds=60))
|
|
async_fire_time_changed(hass)
|
|
await hass.async_block_till_done()
|
|
|
|
assert (
|
|
device_registry.async_get_device(
|
|
{(DOMAIN, f"{config_entry.unique_id}_{group_id}")}
|
|
)
|
|
is None
|
|
)
|
|
|
|
assert hass.states.get("notify.test_user_party_chat") is None
|
|
assert (
|
|
hass.states.get("notify.test_user_private_message_test_partymember_displayname")
|
|
is None
|
|
)
|
|
|
|
|
|
@pytest.mark.usefixtures("habitica")
|
|
async def test_device_via_device_links(
|
|
hass: HomeAssistant,
|
|
config_entry_with_subentry: MockConfigEntry,
|
|
device_registry: dr.DeviceRegistry,
|
|
) -> None:
|
|
"""Test the via_device links between user, party and party member devices."""
|
|
group_id = "1e87097c-4c03-4f8c-a475-67cc7da7f409"
|
|
member_id = "ffce870c-3ff3-4fa4-bad1-87612e52b8e7"
|
|
|
|
config_entry_with_subentry.add_to_hass(hass)
|
|
await hass.config_entries.async_setup(config_entry_with_subentry.entry_id)
|
|
|
|
assert config_entry_with_subentry.state is ConfigEntryState.LOADED
|
|
|
|
unique_id = config_entry_with_subentry.unique_id
|
|
entry_id = config_entry_with_subentry.entry_id
|
|
|
|
user_device = device_registry.async_get_device_by_identifier(
|
|
(DOMAIN, unique_id), entry_id
|
|
)
|
|
assert user_device is not None
|
|
assert user_device.via_device_id is None
|
|
|
|
party_device = device_registry.async_get_device_by_identifier(
|
|
(DOMAIN, f"{unique_id}_{group_id}"), entry_id
|
|
)
|
|
assert party_device is not None
|
|
assert party_device.via_device_id == user_device.id
|
|
|
|
member_device = device_registry.async_get_device_by_identifier(
|
|
(DOMAIN, member_id), entry_id
|
|
)
|
|
assert member_device is not None
|
|
assert member_device.via_device_id == party_device.id
|