mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Update calendar tests to use mock entities instead of demo platform (#105317)
* Update calendar tests to use mock entities instead of demo platform * Add Generator type to fixture * Fix generator syntax --------- Co-authored-by: Martin Hjelmare <marhje52@gmail.com>
This commit is contained in:
parent
18d395821d
commit
1069693292
@ -1,14 +1,29 @@
|
|||||||
"""Test fixtures for calendar sensor platforms."""
|
"""Test fixtures for calendar sensor platforms."""
|
||||||
|
from collections.abc import Generator
|
||||||
|
import datetime
|
||||||
|
import secrets
|
||||||
|
from typing import Any
|
||||||
|
from unittest.mock import AsyncMock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
from homeassistant.components.calendar import DOMAIN, CalendarEntity, CalendarEvent
|
||||||
|
from homeassistant.config_entries import ConfigEntry, ConfigFlow
|
||||||
|
from homeassistant.const import Platform
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||||
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
|
from tests.common import (
|
||||||
|
MockConfigEntry,
|
||||||
|
MockModule,
|
||||||
|
MockPlatform,
|
||||||
|
mock_config_flow,
|
||||||
|
mock_integration,
|
||||||
|
mock_platform,
|
||||||
|
)
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
TEST_DOMAIN = "test"
|
||||||
async def setup_homeassistant(hass: HomeAssistant):
|
|
||||||
"""Set up the homeassistant integration."""
|
|
||||||
await async_setup_component(hass, "homeassistant", {})
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
@ -17,3 +32,161 @@ def set_time_zone(hass: HomeAssistant) -> None:
|
|||||||
# Set our timezone to CST/Regina so we can check calculations
|
# Set our timezone to CST/Regina so we can check calculations
|
||||||
# This keeps UTC-6 all year round
|
# This keeps UTC-6 all year round
|
||||||
hass.config.set_time_zone("America/Regina")
|
hass.config.set_time_zone("America/Regina")
|
||||||
|
|
||||||
|
|
||||||
|
class MockFlow(ConfigFlow):
|
||||||
|
"""Test flow."""
|
||||||
|
|
||||||
|
|
||||||
|
class MockCalendarEntity(CalendarEntity):
|
||||||
|
"""Test Calendar entity."""
|
||||||
|
|
||||||
|
_attr_has_entity_name = True
|
||||||
|
|
||||||
|
def __init__(self, name: str, events: list[CalendarEvent] | None = None) -> None:
|
||||||
|
"""Initialize entity."""
|
||||||
|
self._attr_name = name.capitalize()
|
||||||
|
self._events = events or []
|
||||||
|
|
||||||
|
@property
|
||||||
|
def event(self) -> CalendarEvent | None:
|
||||||
|
"""Return the next upcoming event."""
|
||||||
|
return self._events[0] if self._events else None
|
||||||
|
|
||||||
|
def create_event(
|
||||||
|
self,
|
||||||
|
start: datetime.datetime,
|
||||||
|
end: datetime.datetime,
|
||||||
|
summary: str | None = None,
|
||||||
|
description: str | None = None,
|
||||||
|
location: str | None = None,
|
||||||
|
) -> dict[str, Any]:
|
||||||
|
"""Create a new fake event, used by tests."""
|
||||||
|
event = CalendarEvent(
|
||||||
|
start=start,
|
||||||
|
end=end,
|
||||||
|
summary=summary if summary else f"Event {secrets.token_hex(16)}",
|
||||||
|
description=description,
|
||||||
|
location=location,
|
||||||
|
)
|
||||||
|
self._events.append(event)
|
||||||
|
return event.as_dict()
|
||||||
|
|
||||||
|
async def async_get_events(
|
||||||
|
self,
|
||||||
|
hass: HomeAssistant,
|
||||||
|
start_date: datetime.datetime,
|
||||||
|
end_date: datetime.datetime,
|
||||||
|
) -> list[CalendarEvent]:
|
||||||
|
"""Return calendar events within a datetime range."""
|
||||||
|
assert start_date < end_date
|
||||||
|
events = []
|
||||||
|
for event in self._events:
|
||||||
|
if event.start_datetime_local >= end_date:
|
||||||
|
continue
|
||||||
|
if event.end_datetime_local < start_date:
|
||||||
|
continue
|
||||||
|
events.append(event)
|
||||||
|
return events
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def config_flow_fixture(hass: HomeAssistant) -> Generator[None, None, None]:
|
||||||
|
"""Mock config flow."""
|
||||||
|
mock_platform(hass, f"{TEST_DOMAIN}.config_flow")
|
||||||
|
|
||||||
|
with mock_config_flow(TEST_DOMAIN, MockFlow):
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mock_setup_integration(hass: HomeAssistant, config_flow_fixture: None) -> None:
|
||||||
|
"""Fixture to set up a mock integration."""
|
||||||
|
|
||||||
|
async def async_setup_entry_init(
|
||||||
|
hass: HomeAssistant, config_entry: ConfigEntry
|
||||||
|
) -> bool:
|
||||||
|
"""Set up test config entry."""
|
||||||
|
await hass.config_entries.async_forward_entry_setup(config_entry, DOMAIN)
|
||||||
|
return True
|
||||||
|
|
||||||
|
async def async_unload_entry_init(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: ConfigEntry,
|
||||||
|
) -> bool:
|
||||||
|
await hass.config_entries.async_unload_platforms(
|
||||||
|
config_entry, [Platform.CALENDAR]
|
||||||
|
)
|
||||||
|
return True
|
||||||
|
|
||||||
|
mock_platform(hass, f"{TEST_DOMAIN}.config_flow")
|
||||||
|
mock_integration(
|
||||||
|
hass,
|
||||||
|
MockModule(
|
||||||
|
TEST_DOMAIN,
|
||||||
|
async_setup_entry=async_setup_entry_init,
|
||||||
|
async_unload_entry=async_unload_entry_init,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def create_mock_platform(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
entities: list[CalendarEntity],
|
||||||
|
) -> MockConfigEntry:
|
||||||
|
"""Create a calendar platform with the specified entities."""
|
||||||
|
|
||||||
|
async def async_setup_entry_platform(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
config_entry: ConfigEntry,
|
||||||
|
async_add_entities: AddEntitiesCallback,
|
||||||
|
) -> None:
|
||||||
|
"""Set up test event platform via config entry."""
|
||||||
|
async_add_entities(entities)
|
||||||
|
|
||||||
|
mock_platform(
|
||||||
|
hass,
|
||||||
|
f"{TEST_DOMAIN}.{DOMAIN}",
|
||||||
|
MockPlatform(async_setup_entry=async_setup_entry_platform),
|
||||||
|
)
|
||||||
|
|
||||||
|
config_entry = MockConfigEntry(domain=TEST_DOMAIN)
|
||||||
|
config_entry.add_to_hass(hass)
|
||||||
|
assert await hass.config_entries.async_setup(config_entry.entry_id)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
return config_entry
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="test_entities")
|
||||||
|
def mock_test_entities() -> list[MockCalendarEntity]:
|
||||||
|
"""Fixture to create fake entities used in the test."""
|
||||||
|
half_hour_from_now = dt_util.now() + datetime.timedelta(minutes=30)
|
||||||
|
entity1 = MockCalendarEntity(
|
||||||
|
"Calendar 1",
|
||||||
|
[
|
||||||
|
CalendarEvent(
|
||||||
|
start=half_hour_from_now,
|
||||||
|
end=half_hour_from_now + datetime.timedelta(minutes=60),
|
||||||
|
summary="Future Event",
|
||||||
|
description="Future Description",
|
||||||
|
location="Future Location",
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
entity1.async_get_events = AsyncMock(wraps=entity1.async_get_events)
|
||||||
|
|
||||||
|
middle_of_event = dt_util.now() - datetime.timedelta(minutes=30)
|
||||||
|
entity2 = MockCalendarEntity(
|
||||||
|
"Calendar 2",
|
||||||
|
[
|
||||||
|
CalendarEvent(
|
||||||
|
start=middle_of_event,
|
||||||
|
end=middle_of_event + datetime.timedelta(minutes=60),
|
||||||
|
summary="Current Event",
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)
|
||||||
|
entity2.async_get_events = AsyncMock(wraps=entity2.async_get_events)
|
||||||
|
|
||||||
|
return [entity1, entity2]
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# serializer version: 1
|
# serializer version: 1
|
||||||
# name: test_list_events_service_duration[calendar.calendar_1-00:15:00-get_events]
|
# name: test_list_events_service_duration[frozen_time-calendar.calendar_1-00:15:00-get_events]
|
||||||
dict({
|
dict({
|
||||||
'calendar.calendar_1': dict({
|
'calendar.calendar_1': dict({
|
||||||
'events': list([
|
'events': list([
|
||||||
@ -7,59 +7,59 @@
|
|||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
# ---
|
# ---
|
||||||
# name: test_list_events_service_duration[calendar.calendar_1-00:15:00-list_events]
|
# name: test_list_events_service_duration[frozen_time-calendar.calendar_1-00:15:00-list_events]
|
||||||
dict({
|
dict({
|
||||||
'events': list([
|
'events': list([
|
||||||
]),
|
]),
|
||||||
})
|
})
|
||||||
# ---
|
# ---
|
||||||
# name: test_list_events_service_duration[calendar.calendar_1-01:00:00-get_events]
|
# name: test_list_events_service_duration[frozen_time-calendar.calendar_1-01:00:00-get_events]
|
||||||
dict({
|
dict({
|
||||||
'calendar.calendar_1': dict({
|
'calendar.calendar_1': dict({
|
||||||
'events': list([
|
'events': list([
|
||||||
dict({
|
dict({
|
||||||
'description': 'Future Description',
|
'description': 'Future Description',
|
||||||
'end': '2023-10-19T08:20:05-07:00',
|
'end': '2023-10-19T09:20:05-06:00',
|
||||||
'location': 'Future Location',
|
'location': 'Future Location',
|
||||||
'start': '2023-10-19T07:20:05-07:00',
|
'start': '2023-10-19T08:20:05-06:00',
|
||||||
'summary': 'Future Event',
|
'summary': 'Future Event',
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
# ---
|
# ---
|
||||||
# name: test_list_events_service_duration[calendar.calendar_1-01:00:00-list_events]
|
# name: test_list_events_service_duration[frozen_time-calendar.calendar_1-01:00:00-list_events]
|
||||||
dict({
|
dict({
|
||||||
'events': list([
|
'events': list([
|
||||||
dict({
|
dict({
|
||||||
'description': 'Future Description',
|
'description': 'Future Description',
|
||||||
'end': '2023-10-19T08:20:05-07:00',
|
'end': '2023-10-19T09:20:05-06:00',
|
||||||
'location': 'Future Location',
|
'location': 'Future Location',
|
||||||
'start': '2023-10-19T07:20:05-07:00',
|
'start': '2023-10-19T08:20:05-06:00',
|
||||||
'summary': 'Future Event',
|
'summary': 'Future Event',
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
})
|
})
|
||||||
# ---
|
# ---
|
||||||
# name: test_list_events_service_duration[calendar.calendar_2-00:15:00-get_events]
|
# name: test_list_events_service_duration[frozen_time-calendar.calendar_2-00:15:00-get_events]
|
||||||
dict({
|
dict({
|
||||||
'calendar.calendar_2': dict({
|
'calendar.calendar_2': dict({
|
||||||
'events': list([
|
'events': list([
|
||||||
dict({
|
dict({
|
||||||
'end': '2023-10-19T07:20:05-07:00',
|
'end': '2023-10-19T08:20:05-06:00',
|
||||||
'start': '2023-10-19T06:20:05-07:00',
|
'start': '2023-10-19T07:20:05-06:00',
|
||||||
'summary': 'Current Event',
|
'summary': 'Current Event',
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
# ---
|
# ---
|
||||||
# name: test_list_events_service_duration[calendar.calendar_2-00:15:00-list_events]
|
# name: test_list_events_service_duration[frozen_time-calendar.calendar_2-00:15:00-list_events]
|
||||||
dict({
|
dict({
|
||||||
'events': list([
|
'events': list([
|
||||||
dict({
|
dict({
|
||||||
'end': '2023-10-19T07:20:05-07:00',
|
'end': '2023-10-19T08:20:05-06:00',
|
||||||
'start': '2023-10-19T06:20:05-07:00',
|
'start': '2023-10-19T07:20:05-06:00',
|
||||||
'summary': 'Current Event',
|
'summary': 'Current Event',
|
||||||
}),
|
}),
|
||||||
]),
|
]),
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
"""The tests for the calendar component."""
|
"""The tests for the calendar component."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from collections.abc import Generator
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from unittest.mock import patch
|
|
||||||
|
|
||||||
from freezegun import freeze_time
|
from freezegun import freeze_time
|
||||||
import pytest
|
import pytest
|
||||||
from syrupy.assertion import SnapshotAssertion
|
from syrupy.assertion import SnapshotAssertion
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant.bootstrap import async_setup_component
|
|
||||||
from homeassistant.components.calendar import (
|
from homeassistant.components.calendar import (
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
LEGACY_SERVICE_LIST_EVENTS,
|
LEGACY_SERVICE_LIST_EVENTS,
|
||||||
@ -22,15 +21,46 @@ from homeassistant.exceptions import HomeAssistantError
|
|||||||
from homeassistant.helpers.issue_registry import IssueRegistry
|
from homeassistant.helpers.issue_registry import IssueRegistry
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
|
from .conftest import TEST_DOMAIN, MockCalendarEntity, create_mock_platform
|
||||||
|
|
||||||
from tests.typing import ClientSessionGenerator, WebSocketGenerator
|
from tests.typing import ClientSessionGenerator, WebSocketGenerator
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="frozen_time")
|
||||||
|
def mock_frozen_time() -> None:
|
||||||
|
"""Fixture to set a frozen time used in tests.
|
||||||
|
|
||||||
|
This is needed so that it can run before other fixtures.
|
||||||
|
"""
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(autouse=True)
|
||||||
|
def mock_set_frozen_time(frozen_time: Any) -> Generator[None, None, None]:
|
||||||
|
"""Fixture to freeze time that also can work for other fixtures."""
|
||||||
|
if not frozen_time:
|
||||||
|
yield
|
||||||
|
else:
|
||||||
|
with freeze_time(frozen_time):
|
||||||
|
yield
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="setup_platform", autouse=True)
|
||||||
|
async def mock_setup_platform(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
set_time_zone: Any,
|
||||||
|
frozen_time: Any,
|
||||||
|
mock_setup_integration: Any,
|
||||||
|
test_entities: list[MockCalendarEntity],
|
||||||
|
) -> None:
|
||||||
|
"""Fixture to setup platforms used in the test and fixtures are set up in the right order."""
|
||||||
|
await create_mock_platform(hass, test_entities)
|
||||||
|
|
||||||
|
|
||||||
async def test_events_http_api(
|
async def test_events_http_api(
|
||||||
hass: HomeAssistant, hass_client: ClientSessionGenerator
|
hass: HomeAssistant, hass_client: ClientSessionGenerator
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the calendar demo view."""
|
"""Test the calendar demo view."""
|
||||||
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
client = await hass_client()
|
client = await hass_client()
|
||||||
start = dt_util.now()
|
start = dt_util.now()
|
||||||
end = start + timedelta(days=1)
|
end = start + timedelta(days=1)
|
||||||
@ -46,40 +76,34 @@ async def test_events_http_api_missing_fields(
|
|||||||
hass: HomeAssistant, hass_client: ClientSessionGenerator
|
hass: HomeAssistant, hass_client: ClientSessionGenerator
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the calendar demo view."""
|
"""Test the calendar demo view."""
|
||||||
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
client = await hass_client()
|
client = await hass_client()
|
||||||
response = await client.get("/api/calendars/calendar.calendar_2")
|
response = await client.get("/api/calendars/calendar.calendar_2")
|
||||||
assert response.status == HTTPStatus.BAD_REQUEST
|
assert response.status == HTTPStatus.BAD_REQUEST
|
||||||
|
|
||||||
|
|
||||||
async def test_events_http_api_error(
|
async def test_events_http_api_error(
|
||||||
hass: HomeAssistant, hass_client: ClientSessionGenerator
|
hass: HomeAssistant,
|
||||||
|
hass_client: ClientSessionGenerator,
|
||||||
|
test_entities: list[MockCalendarEntity],
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the calendar demo view."""
|
"""Test the calendar demo view."""
|
||||||
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
client = await hass_client()
|
client = await hass_client()
|
||||||
start = dt_util.now()
|
start = dt_util.now()
|
||||||
end = start + timedelta(days=1)
|
end = start + timedelta(days=1)
|
||||||
|
|
||||||
with patch(
|
test_entities[0].async_get_events.side_effect = HomeAssistantError("Failure")
|
||||||
"homeassistant.components.demo.calendar.DemoCalendar.async_get_events",
|
|
||||||
side_effect=HomeAssistantError("Failure"),
|
response = await client.get(
|
||||||
):
|
f"/api/calendars/calendar.calendar_1?start={start.isoformat()}&end={end.isoformat()}"
|
||||||
response = await client.get(
|
)
|
||||||
f"/api/calendars/calendar.calendar_1?start={start.isoformat()}&end={end.isoformat()}"
|
assert response.status == HTTPStatus.INTERNAL_SERVER_ERROR
|
||||||
)
|
assert await response.json() == {"message": "Error reading events: Failure"}
|
||||||
assert response.status == HTTPStatus.INTERNAL_SERVER_ERROR
|
|
||||||
assert await response.json() == {"message": "Error reading events: Failure"}
|
|
||||||
|
|
||||||
|
|
||||||
async def test_events_http_api_dates_wrong_order(
|
async def test_events_http_api_dates_wrong_order(
|
||||||
hass: HomeAssistant, hass_client: ClientSessionGenerator
|
hass: HomeAssistant, hass_client: ClientSessionGenerator
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the calendar demo view."""
|
"""Test the calendar demo view."""
|
||||||
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
client = await hass_client()
|
client = await hass_client()
|
||||||
start = dt_util.now()
|
start = dt_util.now()
|
||||||
end = start + timedelta(days=-1)
|
end = start + timedelta(days=-1)
|
||||||
@ -93,8 +117,6 @@ async def test_calendars_http_api(
|
|||||||
hass: HomeAssistant, hass_client: ClientSessionGenerator
|
hass: HomeAssistant, hass_client: ClientSessionGenerator
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the calendar demo view."""
|
"""Test the calendar demo view."""
|
||||||
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
client = await hass_client()
|
client = await hass_client()
|
||||||
response = await client.get("/api/calendars")
|
response = await client.get("/api/calendars")
|
||||||
assert response.status == HTTPStatus.OK
|
assert response.status == HTTPStatus.OK
|
||||||
@ -180,8 +202,6 @@ async def test_unsupported_websocket(
|
|||||||
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, payload, code
|
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, payload, code
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test unsupported websocket command."""
|
"""Test unsupported websocket command."""
|
||||||
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
client = await hass_ws_client(hass)
|
client = await hass_ws_client(hass)
|
||||||
await client.send_json(
|
await client.send_json(
|
||||||
{
|
{
|
||||||
@ -198,9 +218,6 @@ async def test_unsupported_websocket(
|
|||||||
async def test_unsupported_create_event_service(hass: HomeAssistant) -> None:
|
async def test_unsupported_create_event_service(hass: HomeAssistant) -> None:
|
||||||
"""Test unsupported service call."""
|
"""Test unsupported service call."""
|
||||||
|
|
||||||
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
with pytest.raises(HomeAssistantError, match="does not support this service"):
|
with pytest.raises(HomeAssistantError, match="does not support this service"):
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
@ -377,9 +394,6 @@ async def test_create_event_service_invalid_params(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Test creating an event using the create_event service."""
|
"""Test creating an event using the create_event service."""
|
||||||
|
|
||||||
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
with pytest.raises(expected_error, match=error_match):
|
with pytest.raises(expected_error, match=error_match):
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
"calendar",
|
"calendar",
|
||||||
@ -393,7 +407,9 @@ async def test_create_event_service_invalid_params(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@freeze_time("2023-06-22 10:30:00+00:00")
|
@pytest.mark.parametrize(
|
||||||
|
"frozen_time", ["2023-06-22 10:30:00+00:00"], ids=["frozen_time"]
|
||||||
|
)
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
("service", "expected"),
|
("service", "expected"),
|
||||||
[
|
[
|
||||||
@ -439,7 +455,6 @@ async def test_create_event_service_invalid_params(
|
|||||||
)
|
)
|
||||||
async def test_list_events_service(
|
async def test_list_events_service(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
set_time_zone: None,
|
|
||||||
start_time: str,
|
start_time: str,
|
||||||
end_time: str,
|
end_time: str,
|
||||||
service: str,
|
service: str,
|
||||||
@ -451,9 +466,6 @@ async def test_list_events_service(
|
|||||||
string output values.
|
string output values.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
response = await hass.services.async_call(
|
response = await hass.services.async_call(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
service,
|
service,
|
||||||
@ -487,7 +499,7 @@ async def test_list_events_service(
|
|||||||
("calendar.calendar_2", "00:15:00"),
|
("calendar.calendar_2", "00:15:00"),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.freeze_time("2023-10-19 13:50:05")
|
@pytest.mark.parametrize("frozen_time", ["2023-10-19 13:50:05"], ids=["frozen_time"])
|
||||||
async def test_list_events_service_duration(
|
async def test_list_events_service_duration(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
entity: str,
|
entity: str,
|
||||||
@ -496,9 +508,6 @@ async def test_list_events_service_duration(
|
|||||||
snapshot: SnapshotAssertion,
|
snapshot: SnapshotAssertion,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test listing events using a time duration."""
|
"""Test listing events using a time duration."""
|
||||||
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
response = await hass.services.async_call(
|
response = await hass.services.async_call(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
service,
|
service,
|
||||||
@ -514,9 +523,6 @@ async def test_list_events_service_duration(
|
|||||||
|
|
||||||
async def test_list_events_positive_duration(hass: HomeAssistant) -> None:
|
async def test_list_events_positive_duration(hass: HomeAssistant) -> None:
|
||||||
"""Test listing events requires a positive duration."""
|
"""Test listing events requires a positive duration."""
|
||||||
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
with pytest.raises(vol.Invalid, match="should be positive"):
|
with pytest.raises(vol.Invalid, match="should be positive"):
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
@ -532,9 +538,6 @@ async def test_list_events_positive_duration(hass: HomeAssistant) -> None:
|
|||||||
|
|
||||||
async def test_list_events_exclusive_fields(hass: HomeAssistant) -> None:
|
async def test_list_events_exclusive_fields(hass: HomeAssistant) -> None:
|
||||||
"""Test listing events specifying fields that are exclusive."""
|
"""Test listing events specifying fields that are exclusive."""
|
||||||
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
end = dt_util.now() + timedelta(days=1)
|
end = dt_util.now() + timedelta(days=1)
|
||||||
|
|
||||||
with pytest.raises(vol.Invalid, match="at most one of"):
|
with pytest.raises(vol.Invalid, match="at most one of"):
|
||||||
@ -553,9 +556,6 @@ async def test_list_events_exclusive_fields(hass: HomeAssistant) -> None:
|
|||||||
|
|
||||||
async def test_list_events_missing_fields(hass: HomeAssistant) -> None:
|
async def test_list_events_missing_fields(hass: HomeAssistant) -> None:
|
||||||
"""Test listing events missing some required fields."""
|
"""Test listing events missing some required fields."""
|
||||||
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
with pytest.raises(vol.Invalid, match="at least one of"):
|
with pytest.raises(vol.Invalid, match="at least one of"):
|
||||||
await hass.services.async_call(
|
await hass.services.async_call(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
@ -575,9 +575,6 @@ async def test_issue_deprecated_service_calendar_list_events(
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Test the issue is raised on deprecated service weather.get_forecast."""
|
"""Test the issue is raised on deprecated service weather.get_forecast."""
|
||||||
|
|
||||||
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
_ = await hass.services.async_call(
|
_ = await hass.services.async_call(
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
LEGACY_SERVICE_LIST_EVENTS,
|
LEGACY_SERVICE_LIST_EVENTS,
|
||||||
@ -594,7 +591,7 @@ async def test_issue_deprecated_service_calendar_list_events(
|
|||||||
"calendar", "deprecated_service_calendar_list_events"
|
"calendar", "deprecated_service_calendar_list_events"
|
||||||
)
|
)
|
||||||
assert issue
|
assert issue
|
||||||
assert issue.issue_domain == "demo"
|
assert issue.issue_domain == TEST_DOMAIN
|
||||||
assert issue.issue_id == "deprecated_service_calendar_list_events"
|
assert issue.issue_id == "deprecated_service_calendar_list_events"
|
||||||
assert issue.translation_key == "deprecated_service_calendar_list_events"
|
assert issue.translation_key == "deprecated_service_calendar_list_events"
|
||||||
|
|
||||||
|
@ -1,41 +1,36 @@
|
|||||||
"""The tests for calendar recorder."""
|
"""The tests for calendar recorder."""
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
from unittest.mock import patch
|
from typing import Any
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.recorder import Recorder
|
from homeassistant.components.recorder import Recorder
|
||||||
from homeassistant.components.recorder.history import get_significant_states
|
from homeassistant.components.recorder.history import get_significant_states
|
||||||
from homeassistant.const import ATTR_FRIENDLY_NAME, Platform
|
from homeassistant.const import ATTR_FRIENDLY_NAME
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.setup import async_setup_component
|
|
||||||
from homeassistant.util import dt as dt_util
|
from homeassistant.util import dt as dt_util
|
||||||
|
|
||||||
|
from .conftest import MockCalendarEntity, create_mock_platform
|
||||||
|
|
||||||
from tests.common import async_fire_time_changed
|
from tests.common import async_fire_time_changed
|
||||||
from tests.components.recorder.common import async_wait_recording_done
|
from tests.components.recorder.common import async_wait_recording_done
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
async def setup_homeassistant():
|
async def mock_setup_dependencies(
|
||||||
"""Override the fixture in calendar.conftest."""
|
recorder_mock: Recorder,
|
||||||
|
hass: HomeAssistant,
|
||||||
|
set_time_zone: Any,
|
||||||
|
mock_setup_integration: None,
|
||||||
|
test_entities: list[MockCalendarEntity],
|
||||||
|
) -> None:
|
||||||
|
"""Fixture that ensures the recorder is setup in the right order."""
|
||||||
|
await create_mock_platform(hass, test_entities)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
async def test_exclude_attributes(hass: HomeAssistant) -> None:
|
||||||
async def calendar_only() -> None:
|
|
||||||
"""Enable only the calendar platform."""
|
|
||||||
with patch(
|
|
||||||
"homeassistant.components.demo.COMPONENTS_WITH_CONFIG_ENTRY_DEMO_PLATFORM",
|
|
||||||
[Platform.CALENDAR],
|
|
||||||
):
|
|
||||||
yield
|
|
||||||
|
|
||||||
|
|
||||||
async def test_exclude_attributes(recorder_mock: Recorder, hass: HomeAssistant) -> None:
|
|
||||||
"""Test sensor attributes to be excluded."""
|
"""Test sensor attributes to be excluded."""
|
||||||
now = dt_util.utcnow()
|
now = dt_util.utcnow()
|
||||||
await async_setup_component(hass, "homeassistant", {})
|
|
||||||
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
|
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
state = hass.states.get("calendar.calendar_1")
|
state = hass.states.get("calendar.calendar_1")
|
||||||
assert state
|
assert state
|
||||||
|
@ -12,7 +12,6 @@ from collections.abc import AsyncIterator, Callable, Generator
|
|||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
import datetime
|
import datetime
|
||||||
import logging
|
import logging
|
||||||
import secrets
|
|
||||||
from typing import Any
|
from typing import Any
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
import zoneinfo
|
import zoneinfo
|
||||||
@ -28,13 +27,14 @@ from homeassistant.core import HomeAssistant
|
|||||||
from homeassistant.setup import async_setup_component
|
from homeassistant.setup import async_setup_component
|
||||||
import homeassistant.util.dt as dt_util
|
import homeassistant.util.dt as dt_util
|
||||||
|
|
||||||
|
from .conftest import MockCalendarEntity, create_mock_platform
|
||||||
|
|
||||||
from tests.common import async_fire_time_changed, async_mock_service
|
from tests.common import async_fire_time_changed, async_mock_service
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
CALENDAR_ENTITY_ID = "calendar.calendar_2"
|
CALENDAR_ENTITY_ID = "calendar.calendar_2"
|
||||||
CONFIG = {calendar.DOMAIN: {"platform": "demo"}}
|
|
||||||
|
|
||||||
TEST_AUTOMATION_ACTION = {
|
TEST_AUTOMATION_ACTION = {
|
||||||
"service": "test.automation",
|
"service": "test.automation",
|
||||||
@ -59,44 +59,6 @@ class FakeSchedule:
|
|||||||
"""Initiailize FakeSchedule."""
|
"""Initiailize FakeSchedule."""
|
||||||
self.hass = hass
|
self.hass = hass
|
||||||
self.freezer = freezer
|
self.freezer = freezer
|
||||||
# Map of event start time to event
|
|
||||||
self.events: list[calendar.CalendarEvent] = []
|
|
||||||
|
|
||||||
def create_event(
|
|
||||||
self,
|
|
||||||
start: datetime.datetime,
|
|
||||||
end: datetime.datetime,
|
|
||||||
summary: str | None = None,
|
|
||||||
description: str | None = None,
|
|
||||||
location: str | None = None,
|
|
||||||
) -> dict[str, Any]:
|
|
||||||
"""Create a new fake event, used by tests."""
|
|
||||||
event = calendar.CalendarEvent(
|
|
||||||
start=start,
|
|
||||||
end=end,
|
|
||||||
summary=summary if summary else f"Event {secrets.token_hex(16)}",
|
|
||||||
description=description,
|
|
||||||
location=location,
|
|
||||||
)
|
|
||||||
self.events.append(event)
|
|
||||||
return event.as_dict()
|
|
||||||
|
|
||||||
async def async_get_events(
|
|
||||||
self,
|
|
||||||
hass: HomeAssistant,
|
|
||||||
start_date: datetime.datetime,
|
|
||||||
end_date: datetime.datetime,
|
|
||||||
) -> list[calendar.CalendarEvent]:
|
|
||||||
"""Get all events in a specific time frame, used by the demo calendar."""
|
|
||||||
assert start_date < end_date
|
|
||||||
values = []
|
|
||||||
for event in self.events:
|
|
||||||
if event.start_datetime_local >= end_date:
|
|
||||||
continue
|
|
||||||
if event.end_datetime_local < start_date:
|
|
||||||
continue
|
|
||||||
values.append(event)
|
|
||||||
return values
|
|
||||||
|
|
||||||
async def fire_time(self, trigger_time: datetime.datetime) -> None:
|
async def fire_time(self, trigger_time: datetime.datetime) -> None:
|
||||||
"""Fire an alarm and wait."""
|
"""Fire an alarm and wait."""
|
||||||
@ -130,19 +92,23 @@ def fake_schedule(
|
|||||||
# Setup start time for all tests
|
# Setup start time for all tests
|
||||||
freezer.move_to("2022-04-19 10:31:02+00:00")
|
freezer.move_to("2022-04-19 10:31:02+00:00")
|
||||||
|
|
||||||
schedule = FakeSchedule(hass, freezer)
|
return FakeSchedule(hass, freezer)
|
||||||
with patch(
|
|
||||||
"homeassistant.components.demo.calendar.DemoCalendar.async_get_events",
|
|
||||||
new=schedule.async_get_events,
|
|
||||||
):
|
|
||||||
yield schedule
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(name="test_entity")
|
||||||
async def setup_calendar(hass: HomeAssistant, fake_schedule: FakeSchedule) -> None:
|
def mock_test_entity(test_entities: list[MockCalendarEntity]) -> MockCalendarEntity:
|
||||||
"""Initialize the demo calendar."""
|
"""Fixture to expose the calendar entity used in tests."""
|
||||||
assert await async_setup_component(hass, calendar.DOMAIN, CONFIG)
|
return test_entities[1]
|
||||||
await hass.async_block_till_done()
|
|
||||||
|
|
||||||
|
@pytest.fixture(name="setup_platform", autouse=True)
|
||||||
|
async def mock_setup_platform(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
mock_setup_integration: Any,
|
||||||
|
test_entities: list[MockCalendarEntity],
|
||||||
|
) -> None:
|
||||||
|
"""Fixture to setup platforms used in the test."""
|
||||||
|
await create_mock_platform(hass, test_entities)
|
||||||
|
|
||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
@ -207,9 +173,10 @@ async def test_event_start_trigger(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
calls: Callable[[], list[dict[str, Any]]],
|
calls: Callable[[], list[dict[str, Any]]],
|
||||||
fake_schedule: FakeSchedule,
|
fake_schedule: FakeSchedule,
|
||||||
|
test_entity: MockCalendarEntity,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the a calendar trigger based on start time."""
|
"""Test the a calendar trigger based on start time."""
|
||||||
event_data = fake_schedule.create_event(
|
event_data = test_entity.create_event(
|
||||||
start=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
start=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
||||||
end=datetime.datetime.fromisoformat("2022-04-19 11:30:00+00:00"),
|
end=datetime.datetime.fromisoformat("2022-04-19 11:30:00+00:00"),
|
||||||
)
|
)
|
||||||
@ -240,11 +207,12 @@ async def test_event_start_trigger_with_offset(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
calls: Callable[[], list[dict[str, Any]]],
|
calls: Callable[[], list[dict[str, Any]]],
|
||||||
fake_schedule: FakeSchedule,
|
fake_schedule: FakeSchedule,
|
||||||
|
test_entity: MockCalendarEntity,
|
||||||
offset_str,
|
offset_str,
|
||||||
offset_delta,
|
offset_delta,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the a calendar trigger based on start time with an offset."""
|
"""Test the a calendar trigger based on start time with an offset."""
|
||||||
event_data = fake_schedule.create_event(
|
event_data = test_entity.create_event(
|
||||||
start=datetime.datetime.fromisoformat("2022-04-19 12:00:00+00:00"),
|
start=datetime.datetime.fromisoformat("2022-04-19 12:00:00+00:00"),
|
||||||
end=datetime.datetime.fromisoformat("2022-04-19 12:30:00+00:00"),
|
end=datetime.datetime.fromisoformat("2022-04-19 12:30:00+00:00"),
|
||||||
)
|
)
|
||||||
@ -272,9 +240,10 @@ async def test_event_end_trigger(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
calls: Callable[[], list[dict[str, Any]]],
|
calls: Callable[[], list[dict[str, Any]]],
|
||||||
fake_schedule: FakeSchedule,
|
fake_schedule: FakeSchedule,
|
||||||
|
test_entity: MockCalendarEntity,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the a calendar trigger based on end time."""
|
"""Test the a calendar trigger based on end time."""
|
||||||
event_data = fake_schedule.create_event(
|
event_data = test_entity.create_event(
|
||||||
start=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
start=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
||||||
end=datetime.datetime.fromisoformat("2022-04-19 12:00:00+00:00"),
|
end=datetime.datetime.fromisoformat("2022-04-19 12:00:00+00:00"),
|
||||||
)
|
)
|
||||||
@ -309,11 +278,12 @@ async def test_event_end_trigger_with_offset(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
calls: Callable[[], list[dict[str, Any]]],
|
calls: Callable[[], list[dict[str, Any]]],
|
||||||
fake_schedule: FakeSchedule,
|
fake_schedule: FakeSchedule,
|
||||||
|
test_entity: MockCalendarEntity,
|
||||||
offset_str,
|
offset_str,
|
||||||
offset_delta,
|
offset_delta,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the a calendar trigger based on end time with an offset."""
|
"""Test the a calendar trigger based on end time with an offset."""
|
||||||
event_data = fake_schedule.create_event(
|
event_data = test_entity.create_event(
|
||||||
start=datetime.datetime.fromisoformat("2022-04-19 12:00:00+00:00"),
|
start=datetime.datetime.fromisoformat("2022-04-19 12:00:00+00:00"),
|
||||||
end=datetime.datetime.fromisoformat("2022-04-19 12:30:00+00:00"),
|
end=datetime.datetime.fromisoformat("2022-04-19 12:30:00+00:00"),
|
||||||
)
|
)
|
||||||
@ -356,14 +326,15 @@ async def test_multiple_start_events(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
calls: Callable[[], list[dict[str, Any]]],
|
calls: Callable[[], list[dict[str, Any]]],
|
||||||
fake_schedule: FakeSchedule,
|
fake_schedule: FakeSchedule,
|
||||||
|
test_entity: MockCalendarEntity,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test that a trigger fires for multiple events."""
|
"""Test that a trigger fires for multiple events."""
|
||||||
|
|
||||||
event_data1 = fake_schedule.create_event(
|
event_data1 = test_entity.create_event(
|
||||||
start=datetime.datetime.fromisoformat("2022-04-19 10:45:00+00:00"),
|
start=datetime.datetime.fromisoformat("2022-04-19 10:45:00+00:00"),
|
||||||
end=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
end=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
||||||
)
|
)
|
||||||
event_data2 = fake_schedule.create_event(
|
event_data2 = test_entity.create_event(
|
||||||
start=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
start=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
||||||
end=datetime.datetime.fromisoformat("2022-04-19 11:15:00+00:00"),
|
end=datetime.datetime.fromisoformat("2022-04-19 11:15:00+00:00"),
|
||||||
)
|
)
|
||||||
@ -389,14 +360,15 @@ async def test_multiple_end_events(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
calls: Callable[[], list[dict[str, Any]]],
|
calls: Callable[[], list[dict[str, Any]]],
|
||||||
fake_schedule: FakeSchedule,
|
fake_schedule: FakeSchedule,
|
||||||
|
test_entity: MockCalendarEntity,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test that a trigger fires for multiple events."""
|
"""Test that a trigger fires for multiple events."""
|
||||||
|
|
||||||
event_data1 = fake_schedule.create_event(
|
event_data1 = test_entity.create_event(
|
||||||
start=datetime.datetime.fromisoformat("2022-04-19 10:45:00+00:00"),
|
start=datetime.datetime.fromisoformat("2022-04-19 10:45:00+00:00"),
|
||||||
end=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
end=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
||||||
)
|
)
|
||||||
event_data2 = fake_schedule.create_event(
|
event_data2 = test_entity.create_event(
|
||||||
start=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
start=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
||||||
end=datetime.datetime.fromisoformat("2022-04-19 11:15:00+00:00"),
|
end=datetime.datetime.fromisoformat("2022-04-19 11:15:00+00:00"),
|
||||||
)
|
)
|
||||||
@ -423,14 +395,15 @@ async def test_multiple_events_sharing_start_time(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
calls: Callable[[], list[dict[str, Any]]],
|
calls: Callable[[], list[dict[str, Any]]],
|
||||||
fake_schedule: FakeSchedule,
|
fake_schedule: FakeSchedule,
|
||||||
|
test_entity: MockCalendarEntity,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test that a trigger fires for every event sharing a start time."""
|
"""Test that a trigger fires for every event sharing a start time."""
|
||||||
|
|
||||||
event_data1 = fake_schedule.create_event(
|
event_data1 = test_entity.create_event(
|
||||||
start=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
start=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
||||||
end=datetime.datetime.fromisoformat("2022-04-19 11:30:00+00:00"),
|
end=datetime.datetime.fromisoformat("2022-04-19 11:30:00+00:00"),
|
||||||
)
|
)
|
||||||
event_data2 = fake_schedule.create_event(
|
event_data2 = test_entity.create_event(
|
||||||
start=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
start=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
||||||
end=datetime.datetime.fromisoformat("2022-04-19 11:30:00+00:00"),
|
end=datetime.datetime.fromisoformat("2022-04-19 11:30:00+00:00"),
|
||||||
)
|
)
|
||||||
@ -457,14 +430,15 @@ async def test_overlap_events(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
calls: Callable[[], list[dict[str, Any]]],
|
calls: Callable[[], list[dict[str, Any]]],
|
||||||
fake_schedule: FakeSchedule,
|
fake_schedule: FakeSchedule,
|
||||||
|
test_entity: MockCalendarEntity,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test that a trigger fires for events that overlap."""
|
"""Test that a trigger fires for events that overlap."""
|
||||||
|
|
||||||
event_data1 = fake_schedule.create_event(
|
event_data1 = test_entity.create_event(
|
||||||
start=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
start=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
||||||
end=datetime.datetime.fromisoformat("2022-04-19 11:30:00+00:00"),
|
end=datetime.datetime.fromisoformat("2022-04-19 11:30:00+00:00"),
|
||||||
)
|
)
|
||||||
event_data2 = fake_schedule.create_event(
|
event_data2 = test_entity.create_event(
|
||||||
start=datetime.datetime.fromisoformat("2022-04-19 11:15:00+00:00"),
|
start=datetime.datetime.fromisoformat("2022-04-19 11:15:00+00:00"),
|
||||||
end=datetime.datetime.fromisoformat("2022-04-19 11:45:00+00:00"),
|
end=datetime.datetime.fromisoformat("2022-04-19 11:45:00+00:00"),
|
||||||
)
|
)
|
||||||
@ -533,10 +507,11 @@ async def test_update_next_event(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
calls: Callable[[], list[dict[str, Any]]],
|
calls: Callable[[], list[dict[str, Any]]],
|
||||||
fake_schedule: FakeSchedule,
|
fake_schedule: FakeSchedule,
|
||||||
|
test_entity: MockCalendarEntity,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test detection of a new event after initial trigger is setup."""
|
"""Test detection of a new event after initial trigger is setup."""
|
||||||
|
|
||||||
event_data1 = fake_schedule.create_event(
|
event_data1 = test_entity.create_event(
|
||||||
start=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
start=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
||||||
end=datetime.datetime.fromisoformat("2022-04-19 11:15:00+00:00"),
|
end=datetime.datetime.fromisoformat("2022-04-19 11:15:00+00:00"),
|
||||||
)
|
)
|
||||||
@ -548,7 +523,7 @@ async def test_update_next_event(
|
|||||||
assert len(calls()) == 0
|
assert len(calls()) == 0
|
||||||
|
|
||||||
# Create a new event between now and when the event fires
|
# Create a new event between now and when the event fires
|
||||||
event_data2 = fake_schedule.create_event(
|
event_data2 = test_entity.create_event(
|
||||||
start=datetime.datetime.fromisoformat("2022-04-19 10:55:00+00:00"),
|
start=datetime.datetime.fromisoformat("2022-04-19 10:55:00+00:00"),
|
||||||
end=datetime.datetime.fromisoformat("2022-04-19 11:05:00+00:00"),
|
end=datetime.datetime.fromisoformat("2022-04-19 11:05:00+00:00"),
|
||||||
)
|
)
|
||||||
@ -575,10 +550,11 @@ async def test_update_missed(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
calls: Callable[[], list[dict[str, Any]]],
|
calls: Callable[[], list[dict[str, Any]]],
|
||||||
fake_schedule: FakeSchedule,
|
fake_schedule: FakeSchedule,
|
||||||
|
test_entity: MockCalendarEntity,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test that new events are missed if they arrive outside the update interval."""
|
"""Test that new events are missed if they arrive outside the update interval."""
|
||||||
|
|
||||||
event_data1 = fake_schedule.create_event(
|
event_data1 = test_entity.create_event(
|
||||||
start=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
start=datetime.datetime.fromisoformat("2022-04-19 11:00:00+00:00"),
|
||||||
end=datetime.datetime.fromisoformat("2022-04-19 11:30:00+00:00"),
|
end=datetime.datetime.fromisoformat("2022-04-19 11:30:00+00:00"),
|
||||||
)
|
)
|
||||||
@ -590,7 +566,7 @@ async def test_update_missed(
|
|||||||
)
|
)
|
||||||
assert len(calls()) == 0
|
assert len(calls()) == 0
|
||||||
|
|
||||||
fake_schedule.create_event(
|
test_entity.create_event(
|
||||||
start=datetime.datetime.fromisoformat("2022-04-19 10:40:00+00:00"),
|
start=datetime.datetime.fromisoformat("2022-04-19 10:40:00+00:00"),
|
||||||
end=datetime.datetime.fromisoformat("2022-04-19 10:55:00+00:00"),
|
end=datetime.datetime.fromisoformat("2022-04-19 10:55:00+00:00"),
|
||||||
)
|
)
|
||||||
@ -664,13 +640,14 @@ async def test_event_payload(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
calls: Callable[[], list[dict[str, Any]]],
|
calls: Callable[[], list[dict[str, Any]]],
|
||||||
fake_schedule: FakeSchedule,
|
fake_schedule: FakeSchedule,
|
||||||
|
test_entity: MockCalendarEntity,
|
||||||
set_time_zone: None,
|
set_time_zone: None,
|
||||||
create_data,
|
create_data,
|
||||||
fire_time,
|
fire_time,
|
||||||
payload_data,
|
payload_data,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test the fields in the calendar event payload are set."""
|
"""Test the fields in the calendar event payload are set."""
|
||||||
fake_schedule.create_event(**create_data)
|
test_entity.create_event(**create_data)
|
||||||
async with create_automation(hass, EVENT_START):
|
async with create_automation(hass, EVENT_START):
|
||||||
assert len(calls()) == 0
|
assert len(calls()) == 0
|
||||||
|
|
||||||
@ -688,13 +665,14 @@ async def test_trigger_timestamp_window_edge(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
calls: Callable[[], list[dict[str, Any]]],
|
calls: Callable[[], list[dict[str, Any]]],
|
||||||
fake_schedule: FakeSchedule,
|
fake_schedule: FakeSchedule,
|
||||||
|
test_entity: MockCalendarEntity,
|
||||||
freezer: FrozenDateTimeFactory,
|
freezer: FrozenDateTimeFactory,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test that events in the edge of a scan are included."""
|
"""Test that events in the edge of a scan are included."""
|
||||||
freezer.move_to("2022-04-19 11:00:00+00:00")
|
freezer.move_to("2022-04-19 11:00:00+00:00")
|
||||||
# Exactly at a TEST_UPDATE_INTERVAL boundary the start time,
|
# Exactly at a TEST_UPDATE_INTERVAL boundary the start time,
|
||||||
# making this excluded from the first window.
|
# making this excluded from the first window.
|
||||||
event_data = fake_schedule.create_event(
|
event_data = test_entity.create_event(
|
||||||
start=datetime.datetime.fromisoformat("2022-04-19 11:14:00+00:00"),
|
start=datetime.datetime.fromisoformat("2022-04-19 11:14:00+00:00"),
|
||||||
end=datetime.datetime.fromisoformat("2022-04-19 11:30:00+00:00"),
|
end=datetime.datetime.fromisoformat("2022-04-19 11:30:00+00:00"),
|
||||||
)
|
)
|
||||||
@ -717,6 +695,7 @@ async def test_event_start_trigger_dst(
|
|||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
calls: Callable[[], list[dict[str, Any]]],
|
calls: Callable[[], list[dict[str, Any]]],
|
||||||
fake_schedule: FakeSchedule,
|
fake_schedule: FakeSchedule,
|
||||||
|
test_entity: MockCalendarEntity,
|
||||||
freezer: FrozenDateTimeFactory,
|
freezer: FrozenDateTimeFactory,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Test a calendar event trigger happening at the start of daylight savings time."""
|
"""Test a calendar event trigger happening at the start of daylight savings time."""
|
||||||
@ -725,19 +704,19 @@ async def test_event_start_trigger_dst(
|
|||||||
freezer.move_to("2023-03-12 01:00:00-08:00")
|
freezer.move_to("2023-03-12 01:00:00-08:00")
|
||||||
|
|
||||||
# Before DST transition starts
|
# Before DST transition starts
|
||||||
event1_data = fake_schedule.create_event(
|
event1_data = test_entity.create_event(
|
||||||
summary="Event 1",
|
summary="Event 1",
|
||||||
start=datetime.datetime(2023, 3, 12, 1, 30, tzinfo=tzinfo),
|
start=datetime.datetime(2023, 3, 12, 1, 30, tzinfo=tzinfo),
|
||||||
end=datetime.datetime(2023, 3, 12, 1, 45, tzinfo=tzinfo),
|
end=datetime.datetime(2023, 3, 12, 1, 45, tzinfo=tzinfo),
|
||||||
)
|
)
|
||||||
# During DST transition (Clocks are turned forward at 2am to 3am)
|
# During DST transition (Clocks are turned forward at 2am to 3am)
|
||||||
event2_data = fake_schedule.create_event(
|
event2_data = test_entity.create_event(
|
||||||
summary="Event 2",
|
summary="Event 2",
|
||||||
start=datetime.datetime(2023, 3, 12, 2, 30, tzinfo=tzinfo),
|
start=datetime.datetime(2023, 3, 12, 2, 30, tzinfo=tzinfo),
|
||||||
end=datetime.datetime(2023, 3, 12, 2, 45, tzinfo=tzinfo),
|
end=datetime.datetime(2023, 3, 12, 2, 45, tzinfo=tzinfo),
|
||||||
)
|
)
|
||||||
# After DST transition has ended
|
# After DST transition has ended
|
||||||
event3_data = fake_schedule.create_event(
|
event3_data = test_entity.create_event(
|
||||||
summary="Event 3",
|
summary="Event 3",
|
||||||
start=datetime.datetime(2023, 3, 12, 3, 30, tzinfo=tzinfo),
|
start=datetime.datetime(2023, 3, 12, 3, 30, tzinfo=tzinfo),
|
||||||
end=datetime.datetime(2023, 3, 12, 3, 45, tzinfo=tzinfo),
|
end=datetime.datetime(2023, 3, 12, 3, 45, tzinfo=tzinfo),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user