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:
Allen Porter 2024-01-29 21:36:14 -08:00 committed by GitHub
parent 18d395821d
commit 1069693292
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 306 additions and 162 deletions

View file

@ -1,14 +1,29 @@
"""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
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.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)
async def setup_homeassistant(hass: HomeAssistant):
"""Set up the homeassistant integration."""
await async_setup_component(hass, "homeassistant", {})
TEST_DOMAIN = "test"
@pytest.fixture
@ -17,3 +32,161 @@ def set_time_zone(hass: HomeAssistant) -> None:
# Set our timezone to CST/Regina so we can check calculations
# This keeps UTC-6 all year round
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]

View file

@ -1,5 +1,5 @@
# 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({
'calendar.calendar_1': dict({
'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({
'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({
'calendar.calendar_1': dict({
'events': list([
dict({
'description': 'Future Description',
'end': '2023-10-19T08:20:05-07:00',
'end': '2023-10-19T09:20:05-06:00',
'location': 'Future Location',
'start': '2023-10-19T07:20:05-07:00',
'start': '2023-10-19T08:20:05-06:00',
'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({
'events': list([
dict({
'description': 'Future Description',
'end': '2023-10-19T08:20:05-07:00',
'end': '2023-10-19T09:20:05-06:00',
'location': 'Future Location',
'start': '2023-10-19T07:20:05-07:00',
'start': '2023-10-19T08:20:05-06:00',
'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({
'calendar.calendar_2': dict({
'events': list([
dict({
'end': '2023-10-19T07:20:05-07:00',
'start': '2023-10-19T06:20:05-07:00',
'end': '2023-10-19T08:20:05-06:00',
'start': '2023-10-19T07:20:05-06:00',
'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({
'events': list([
dict({
'end': '2023-10-19T07:20:05-07:00',
'start': '2023-10-19T06:20:05-07:00',
'end': '2023-10-19T08:20:05-06:00',
'start': '2023-10-19T07:20:05-06:00',
'summary': 'Current Event',
}),
]),

View file

@ -1,17 +1,16 @@
"""The tests for the calendar component."""
from __future__ import annotations
from collections.abc import Generator
from datetime import timedelta
from http import HTTPStatus
from typing import Any
from unittest.mock import patch
from freezegun import freeze_time
import pytest
from syrupy.assertion import SnapshotAssertion
import voluptuous as vol
from homeassistant.bootstrap import async_setup_component
from homeassistant.components.calendar import (
DOMAIN,
LEGACY_SERVICE_LIST_EVENTS,
@ -22,15 +21,46 @@ from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.issue_registry import IssueRegistry
import homeassistant.util.dt as dt_util
from .conftest import TEST_DOMAIN, MockCalendarEntity, create_mock_platform
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(
hass: HomeAssistant, hass_client: ClientSessionGenerator
) -> None:
"""Test the calendar demo view."""
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
await hass.async_block_till_done()
client = await hass_client()
start = dt_util.now()
end = start + timedelta(days=1)
@ -46,27 +76,23 @@ async def test_events_http_api_missing_fields(
hass: HomeAssistant, hass_client: ClientSessionGenerator
) -> None:
"""Test the calendar demo view."""
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
await hass.async_block_till_done()
client = await hass_client()
response = await client.get("/api/calendars/calendar.calendar_2")
assert response.status == HTTPStatus.BAD_REQUEST
async def test_events_http_api_error(
hass: HomeAssistant, hass_client: ClientSessionGenerator
hass: HomeAssistant,
hass_client: ClientSessionGenerator,
test_entities: list[MockCalendarEntity],
) -> None:
"""Test the calendar demo view."""
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
await hass.async_block_till_done()
client = await hass_client()
start = dt_util.now()
end = start + timedelta(days=1)
with patch(
"homeassistant.components.demo.calendar.DemoCalendar.async_get_events",
side_effect=HomeAssistantError("Failure"),
):
test_entities[0].async_get_events.side_effect = HomeAssistantError("Failure")
response = await client.get(
f"/api/calendars/calendar.calendar_1?start={start.isoformat()}&end={end.isoformat()}"
)
@ -78,8 +104,6 @@ async def test_events_http_api_dates_wrong_order(
hass: HomeAssistant, hass_client: ClientSessionGenerator
) -> None:
"""Test the calendar demo view."""
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
await hass.async_block_till_done()
client = await hass_client()
start = dt_util.now()
end = start + timedelta(days=-1)
@ -93,8 +117,6 @@ async def test_calendars_http_api(
hass: HomeAssistant, hass_client: ClientSessionGenerator
) -> None:
"""Test the calendar demo view."""
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
await hass.async_block_till_done()
client = await hass_client()
response = await client.get("/api/calendars")
assert response.status == HTTPStatus.OK
@ -180,8 +202,6 @@ async def test_unsupported_websocket(
hass: HomeAssistant, hass_ws_client: WebSocketGenerator, payload, code
) -> None:
"""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)
await client.send_json(
{
@ -198,9 +218,6 @@ async def test_unsupported_websocket(
async def test_unsupported_create_event_service(hass: HomeAssistant) -> None:
"""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"):
await hass.services.async_call(
DOMAIN,
@ -377,9 +394,6 @@ async def test_create_event_service_invalid_params(
) -> None:
"""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):
await hass.services.async_call(
"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(
("service", "expected"),
[
@ -439,7 +455,6 @@ async def test_create_event_service_invalid_params(
)
async def test_list_events_service(
hass: HomeAssistant,
set_time_zone: None,
start_time: str,
end_time: str,
service: str,
@ -451,9 +466,6 @@ async def test_list_events_service(
string output values.
"""
await async_setup_component(hass, "calendar", {"calendar": {"platform": "demo"}})
await hass.async_block_till_done()
response = await hass.services.async_call(
DOMAIN,
service,
@ -487,7 +499,7 @@ async def test_list_events_service(
("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(
hass: HomeAssistant,
entity: str,
@ -496,9 +508,6 @@ async def test_list_events_service_duration(
snapshot: SnapshotAssertion,
) -> None:
"""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(
DOMAIN,
service,
@ -514,9 +523,6 @@ async def test_list_events_service_duration(
async def test_list_events_positive_duration(hass: HomeAssistant) -> None:
"""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"):
await hass.services.async_call(
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:
"""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)
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:
"""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"):
await hass.services.async_call(
DOMAIN,
@ -575,9 +575,6 @@ async def test_issue_deprecated_service_calendar_list_events(
) -> None:
"""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(
DOMAIN,
LEGACY_SERVICE_LIST_EVENTS,
@ -594,7 +591,7 @@ async def test_issue_deprecated_service_calendar_list_events(
"calendar", "deprecated_service_calendar_list_events"
)
assert issue
assert issue.issue_domain == "demo"
assert issue.issue_domain == TEST_DOMAIN
assert issue.issue_id == "deprecated_service_calendar_list_events"
assert issue.translation_key == "deprecated_service_calendar_list_events"

View file

@ -1,41 +1,36 @@
"""The tests for calendar recorder."""
from datetime import timedelta
from unittest.mock import patch
from typing import Any
import pytest
from homeassistant.components.recorder import Recorder
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.setup import async_setup_component
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.components.recorder.common import async_wait_recording_done
@pytest.fixture(autouse=True)
async def setup_homeassistant():
"""Override the fixture in calendar.conftest."""
async def mock_setup_dependencies(
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 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:
async def test_exclude_attributes(hass: HomeAssistant) -> None:
"""Test sensor attributes to be excluded."""
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")
assert state

View file

@ -12,7 +12,6 @@ from collections.abc import AsyncIterator, Callable, Generator
from contextlib import asynccontextmanager
import datetime
import logging
import secrets
from typing import Any
from unittest.mock import patch
import zoneinfo
@ -28,13 +27,14 @@ from homeassistant.core import HomeAssistant
from homeassistant.setup import async_setup_component
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
_LOGGER = logging.getLogger(__name__)
CALENDAR_ENTITY_ID = "calendar.calendar_2"
CONFIG = {calendar.DOMAIN: {"platform": "demo"}}
TEST_AUTOMATION_ACTION = {
"service": "test.automation",
@ -59,44 +59,6 @@ class FakeSchedule:
"""Initiailize FakeSchedule."""
self.hass = hass
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:
"""Fire an alarm and wait."""
@ -130,19 +92,23 @@ def fake_schedule(
# Setup start time for all tests
freezer.move_to("2022-04-19 10:31:02+00:00")
schedule = FakeSchedule(hass, freezer)
with patch(
"homeassistant.components.demo.calendar.DemoCalendar.async_get_events",
new=schedule.async_get_events,
):
yield schedule
return FakeSchedule(hass, freezer)
@pytest.fixture(autouse=True)
async def setup_calendar(hass: HomeAssistant, fake_schedule: FakeSchedule) -> None:
"""Initialize the demo calendar."""
assert await async_setup_component(hass, calendar.DOMAIN, CONFIG)
await hass.async_block_till_done()
@pytest.fixture(name="test_entity")
def mock_test_entity(test_entities: list[MockCalendarEntity]) -> MockCalendarEntity:
"""Fixture to expose the calendar entity used in tests."""
return test_entities[1]
@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
@ -207,9 +173,10 @@ async def test_event_start_trigger(
hass: HomeAssistant,
calls: Callable[[], list[dict[str, Any]]],
fake_schedule: FakeSchedule,
test_entity: MockCalendarEntity,
) -> None:
"""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"),
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,
calls: Callable[[], list[dict[str, Any]]],
fake_schedule: FakeSchedule,
test_entity: MockCalendarEntity,
offset_str,
offset_delta,
) -> None:
"""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"),
end=datetime.datetime.fromisoformat("2022-04-19 12:30:00+00:00"),
)
@ -272,9 +240,10 @@ async def test_event_end_trigger(
hass: HomeAssistant,
calls: Callable[[], list[dict[str, Any]]],
fake_schedule: FakeSchedule,
test_entity: MockCalendarEntity,
) -> None:
"""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"),
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,
calls: Callable[[], list[dict[str, Any]]],
fake_schedule: FakeSchedule,
test_entity: MockCalendarEntity,
offset_str,
offset_delta,
) -> None:
"""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"),
end=datetime.datetime.fromisoformat("2022-04-19 12:30:00+00:00"),
)
@ -356,14 +326,15 @@ async def test_multiple_start_events(
hass: HomeAssistant,
calls: Callable[[], list[dict[str, Any]]],
fake_schedule: FakeSchedule,
test_entity: MockCalendarEntity,
) -> None:
"""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"),
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"),
end=datetime.datetime.fromisoformat("2022-04-19 11:15:00+00:00"),
)
@ -389,14 +360,15 @@ async def test_multiple_end_events(
hass: HomeAssistant,
calls: Callable[[], list[dict[str, Any]]],
fake_schedule: FakeSchedule,
test_entity: MockCalendarEntity,
) -> None:
"""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"),
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"),
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,
calls: Callable[[], list[dict[str, Any]]],
fake_schedule: FakeSchedule,
test_entity: MockCalendarEntity,
) -> None:
"""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"),
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"),
end=datetime.datetime.fromisoformat("2022-04-19 11:30:00+00:00"),
)
@ -457,14 +430,15 @@ async def test_overlap_events(
hass: HomeAssistant,
calls: Callable[[], list[dict[str, Any]]],
fake_schedule: FakeSchedule,
test_entity: MockCalendarEntity,
) -> None:
"""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"),
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"),
end=datetime.datetime.fromisoformat("2022-04-19 11:45:00+00:00"),
)
@ -533,10 +507,11 @@ async def test_update_next_event(
hass: HomeAssistant,
calls: Callable[[], list[dict[str, Any]]],
fake_schedule: FakeSchedule,
test_entity: MockCalendarEntity,
) -> None:
"""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"),
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
# 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"),
end=datetime.datetime.fromisoformat("2022-04-19 11:05:00+00:00"),
)
@ -575,10 +550,11 @@ async def test_update_missed(
hass: HomeAssistant,
calls: Callable[[], list[dict[str, Any]]],
fake_schedule: FakeSchedule,
test_entity: MockCalendarEntity,
) -> None:
"""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"),
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
fake_schedule.create_event(
test_entity.create_event(
start=datetime.datetime.fromisoformat("2022-04-19 10:40: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,
calls: Callable[[], list[dict[str, Any]]],
fake_schedule: FakeSchedule,
test_entity: MockCalendarEntity,
set_time_zone: None,
create_data,
fire_time,
payload_data,
) -> None:
"""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):
assert len(calls()) == 0
@ -688,13 +665,14 @@ async def test_trigger_timestamp_window_edge(
hass: HomeAssistant,
calls: Callable[[], list[dict[str, Any]]],
fake_schedule: FakeSchedule,
test_entity: MockCalendarEntity,
freezer: FrozenDateTimeFactory,
) -> None:
"""Test that events in the edge of a scan are included."""
freezer.move_to("2022-04-19 11:00:00+00:00")
# Exactly at a TEST_UPDATE_INTERVAL boundary the start time,
# 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"),
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,
calls: Callable[[], list[dict[str, Any]]],
fake_schedule: FakeSchedule,
test_entity: MockCalendarEntity,
freezer: FrozenDateTimeFactory,
) -> None:
"""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")
# Before DST transition starts
event1_data = fake_schedule.create_event(
event1_data = test_entity.create_event(
summary="Event 1",
start=datetime.datetime(2023, 3, 12, 1, 30, tzinfo=tzinfo),
end=datetime.datetime(2023, 3, 12, 1, 45, tzinfo=tzinfo),
)
# 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",
start=datetime.datetime(2023, 3, 12, 2, 30, tzinfo=tzinfo),
end=datetime.datetime(2023, 3, 12, 2, 45, tzinfo=tzinfo),
)
# After DST transition has ended
event3_data = fake_schedule.create_event(
event3_data = test_entity.create_event(
summary="Event 3",
start=datetime.datetime(2023, 3, 12, 3, 30, tzinfo=tzinfo),
end=datetime.datetime(2023, 3, 12, 3, 45, tzinfo=tzinfo),