core/tests/components/habitica/test_init.py

172 lines
4.9 KiB
Python

"""Test the habitica module."""
import datetime
import logging
from unittest.mock import AsyncMock
from freezegun.api import FrozenDateTimeFactory
import pytest
from homeassistant.components.habitica.const import (
ATTR_ARGS,
ATTR_DATA,
ATTR_PATH,
DOMAIN,
EVENT_API_CALL_SUCCESS,
SERVICE_API_CALL,
)
from homeassistant.config_entries import SOURCE_REAUTH, ConfigEntryState
from homeassistant.const import ATTR_NAME
from homeassistant.core import Event, HomeAssistant
from .conftest import (
ERROR_BAD_REQUEST,
ERROR_NOT_AUTHORIZED,
ERROR_NOT_FOUND,
ERROR_TOO_MANY_REQUESTS,
)
from tests.common import MockConfigEntry, async_capture_events, async_fire_time_changed
@pytest.fixture
def capture_api_call_success(hass: HomeAssistant) -> list[Event]:
"""Capture api_call events."""
return async_capture_events(hass, EVENT_API_CALL_SUCCESS)
@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.usefixtures("habitica")
async def test_service_call(
hass: HomeAssistant,
config_entry: MockConfigEntry,
capture_api_call_success: list[Event],
) -> None:
"""Test integration setup, service call 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 len(capture_api_call_success) == 0
TEST_SERVICE_DATA = {
ATTR_NAME: "test-user",
ATTR_PATH: ["tasks", "user", "post"],
ATTR_ARGS: {"text": "Use API from Home Assistant", "type": "todo"},
}
await hass.services.async_call(
DOMAIN, SERVICE_API_CALL, TEST_SERVICE_DATA, blocking=True
)
assert len(capture_api_call_success) == 1
captured_data = capture_api_call_success[0].data
captured_data[ATTR_ARGS] = captured_data[ATTR_DATA]
del captured_data[ATTR_DATA]
assert captured_data == TEST_SERVICE_DATA
@pytest.mark.parametrize(
("exception"),
[
ERROR_BAD_REQUEST,
ERROR_TOO_MANY_REQUESTS,
],
ids=["BadRequestError", "TooManyRequestsError"],
)
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
async def test_coordinator_update_failed(
hass: HomeAssistant,
config_entry: MockConfigEntry,
habitica: AsyncMock,
) -> None:
"""Test coordinator update failed."""
habitica.get_tasks.side_effect = ERROR_NOT_FOUND
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