core/tests/components/husqvarna_automower/test_calendar.py

155 lines
4.7 KiB
Python

"""Tests for calendar platform."""
from collections.abc import Awaitable, Callable
import datetime
from http import HTTPStatus
from typing import Any
from unittest.mock import AsyncMock
import urllib
import zoneinfo
from aioautomower.utils import mower_list_to_dictionary_dataclass
from freezegun.api import FrozenDateTimeFactory
import pytest
from syrupy import SnapshotAssertion
from homeassistant.components.calendar import (
DOMAIN as CALENDAR_DOMAIN,
EVENT_END_DATETIME,
EVENT_START_DATETIME,
SERVICE_GET_EVENTS,
)
from homeassistant.components.husqvarna_automower.const import DOMAIN
from homeassistant.components.husqvarna_automower.coordinator import SCAN_INTERVAL
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import HomeAssistant
from homeassistant.helpers import entity_registry as er
from . import setup_integration
from tests.common import (
MockConfigEntry,
async_fire_time_changed,
load_json_value_fixture,
)
from tests.typing import ClientSessionGenerator
TEST_ENTITY = "calendar.test_mower_1"
type GetEventsFn = Callable[[str, str], Awaitable[dict[str, Any]]]
@pytest.fixture(name="get_events")
def get_events_fixture(
hass_client: ClientSessionGenerator,
) -> GetEventsFn:
"""Fetch calendar events from the HTTP API."""
async def _fetch(start: str, end: str) -> list[dict[str, Any]]:
client = await hass_client()
response = await client.get(
f"/api/calendars/{TEST_ENTITY}?start={urllib.parse.quote(start)}&end={urllib.parse.quote(end)}"
)
assert response.status == HTTPStatus.OK
results = await response.json()
return [{k: event[k] for k in ("summary", "start", "end")} for event in results]
return _fetch
@pytest.mark.freeze_time(datetime.datetime(2023, 6, 5, 12))
async def test_calendar_state_off(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
mock_automower_client: AsyncMock,
mock_config_entry: MockConfigEntry,
freezer: FrozenDateTimeFactory,
) -> None:
"""State test of the calendar."""
await setup_integration(hass, mock_config_entry)
state = hass.states.get("calendar.test_mower_1")
assert state is not None
assert state.state == "off"
@pytest.mark.freeze_time(datetime.datetime(2023, 6, 5, 19))
async def test_calendar_state_on(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
mock_automower_client: AsyncMock,
mock_config_entry: MockConfigEntry,
freezer: FrozenDateTimeFactory,
) -> None:
"""State test of the calendar."""
await setup_integration(hass, mock_config_entry)
state = hass.states.get("calendar.test_mower_1")
assert state is not None
assert state.state == "on"
@pytest.mark.freeze_time(datetime.datetime(2023, 6, 5))
async def test_empty_calendar(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
mock_automower_client: AsyncMock,
mock_config_entry: MockConfigEntry,
freezer: FrozenDateTimeFactory,
get_events: GetEventsFn,
mower_time_zone: zoneinfo.ZoneInfo,
) -> None:
"""State if there is no schedule set."""
await setup_integration(hass, mock_config_entry)
json_values = load_json_value_fixture("mower.json", DOMAIN)
json_values["data"][0]["attributes"]["calendar"]["tasks"] = []
values = mower_list_to_dictionary_dataclass(
json_values,
mower_time_zone,
)
mock_automower_client.get_status.return_value = values
freezer.tick(SCAN_INTERVAL)
async_fire_time_changed(hass)
await hass.async_block_till_done()
state = hass.states.get("calendar.test_mower_1")
assert state is not None
assert state.state == "off"
events = await get_events("2023-06-05T00:00:00", "2023-06-12T00:00:00")
assert events == []
@pytest.mark.freeze_time(datetime.datetime(2023, 6, 5))
@pytest.mark.parametrize(
(
"start_date",
"end_date",
),
[
(
datetime.datetime(2023, 6, 5, tzinfo=datetime.UTC),
datetime.datetime(2023, 6, 12, tzinfo=datetime.UTC),
),
],
)
async def test_calendar_snapshot(
hass: HomeAssistant,
entity_registry: er.EntityRegistry,
mock_automower_client: AsyncMock,
mock_config_entry: MockConfigEntry,
snapshot: SnapshotAssertion,
start_date: datetime,
end_date: datetime,
) -> None:
"""Snapshot test of the calendar entity."""
await setup_integration(hass, mock_config_entry)
events = await hass.services.async_call(
CALENDAR_DOMAIN,
SERVICE_GET_EVENTS,
{
ATTR_ENTITY_ID: ["calendar.test_mower_1", "calendar.test_mower_2"],
EVENT_START_DATETIME: start_date,
EVENT_END_DATETIME: end_date,
},
blocking=True,
return_response=True,
)
assert events == snapshot