"""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 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, ) -> 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) 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