172 lines
4.9 KiB
Python
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
|