Fix Todoist timed calendar event duration (#182121)

This commit is contained in:
Andre Faria
2026-09-21 13:37:42 +02:00
committed by GitHub
parent 37b44a6636
commit 58aaf6fa97
2 changed files with 72 additions and 11 deletions
+7 -2
View File
@@ -518,10 +518,15 @@ class TodoistProjectData:
start = parse_due_date(task.due)
if start is None:
continue
duration = (
timedelta(minutes=30)
if isinstance(start, datetime)
else timedelta(days=1)
)
event = CalendarEvent(
summary=task.content,
start=start,
end=start + timedelta(days=1),
end=start + duration,
)
if (
event.start_datetime_local is not None
@@ -530,7 +535,7 @@ class TodoistProjectData:
continue
if (
event.end_datetime_local is not None
and event.end_datetime_local < start_date
and event.end_datetime_local <= start_date
):
continue
events.append(event)
+65 -9
View File
@@ -221,6 +221,39 @@ async def test_calendar_custom_project_unique_id(
assert entity is None
@pytest.mark.parametrize(
("due", "expected_start", "expected_end"),
[
(
make_api_due(date="2023-03-30", string="Mar 30"),
{"date": "2023-03-30"},
{"date": "2023-03-31"},
),
(
make_api_due(date="2023-03-30T18:00:00", string="Mar 30 6:00 PM"),
{"dateTime": "2023-03-30T18:00:00-06:00"},
{"dateTime": "2023-03-30T18:30:00-06:00"},
),
],
ids=("all_day", "timed"),
)
async def test_event_duration(
hass: HomeAssistant,
hass_client: ClientSessionGenerator,
expected_start: dict[str, str],
expected_end: dict[str, str],
) -> None:
"""Test date-only tasks last one day and timed tasks last 30 minutes."""
client = await hass_client()
response = await client.get(
get_events_url(
"calendar.name", "2023-03-30T00:00:00.000Z", "2023-04-01T00:00:00.000Z"
)
)
assert response.status == HTTPStatus.OK
assert await response.json() == [get_events_response(expected_start, expected_end)]
@pytest.mark.parametrize(
("due", "start", "end", "expected_response"),
[
@@ -254,6 +287,12 @@ async def test_calendar_custom_project_unique_id(
"2023-04-01T08:00:00.000Z",
[],
),
(
make_api_due(date="2023-03-30", is_recurring=False, string="Mar 30"),
"2023-03-31T06:00:00.000Z",
"2023-04-01T06:00:00.000Z",
[],
),
(
make_api_due(date="2023-03-30", is_recurring=False, string="Mar 30"),
"2023-03-29T06:00:00.000Z",
@@ -261,7 +300,15 @@ async def test_calendar_custom_project_unique_id(
[],
),
],
ids=("included", "exact", "overlap_start", "overlap_end", "after", "before"),
ids=(
"included",
"exact",
"overlap_start",
"overlap_end",
"after",
"end_boundary",
"before",
),
)
async def test_all_day_event(
hass: HomeAssistant,
@@ -374,14 +421,14 @@ async def test_task_due_datetime(
has_task_response = [
get_events_response(
{"dateTime": "2023-03-30T18:00:00-06:00"},
{"dateTime": "2023-03-31T18:00:00-06:00"},
{"dateTime": "2023-03-30T18:30:00-06:00"},
)
]
# Completely includes the start/end of the task
response = await client.get(
get_events_url(
"calendar.name", "2023-03-30T08:00:00.000Z", "2023-03-31T08:00:00.000Z"
"calendar.name", "2023-03-30T23:00:00.000Z", "2023-03-31T01:00:00.000Z"
),
)
assert response.status == HTTPStatus.OK
@@ -390,7 +437,7 @@ async def test_task_due_datetime(
# Overlap with the start of the event
response = await client.get(
get_events_url(
"calendar.name", "2023-03-29T20:00:00.000Z", "2023-03-31T02:00:00.000Z"
"calendar.name", "2023-03-30T23:30:00.000Z", "2023-03-31T00:15:00.000Z"
),
)
assert response.status == HTTPStatus.OK
@@ -399,7 +446,7 @@ async def test_task_due_datetime(
# Overlap with the end of the event
response = await client.get(
get_events_url(
"calendar.name", "2023-03-31T20:00:00.000Z", "2023-04-01T02:00:00.000Z"
"calendar.name", "2023-03-31T00:15:00.000Z", "2023-03-31T01:00:00.000Z"
),
)
assert response.status == HTTPStatus.OK
@@ -408,7 +455,7 @@ async def test_task_due_datetime(
# Task is active, but range does not include start/end
response = await client.get(
get_events_url(
"calendar.name", "2023-03-31T10:00:00.000Z", "2023-03-31T11:00:00.000Z"
"calendar.name", "2023-03-31T00:10:00.000Z", "2023-03-31T00:20:00.000Z"
),
)
assert response.status == HTTPStatus.OK
@@ -417,7 +464,16 @@ async def test_task_due_datetime(
# Query is before the task starts (no results)
response = await client.get(
get_events_url(
"calendar.name", "2023-03-28T00:00:00.000Z", "2023-03-29T00:00:00.000Z"
"calendar.name", "2023-03-30T22:00:00.000Z", "2023-03-30T23:00:00.000Z"
),
)
assert response.status == HTTPStatus.OK
assert await response.json() == []
# Query starts exactly when the task ends (no results)
response = await client.get(
get_events_url(
"calendar.name", "2023-03-31T00:30:00.000Z", "2023-03-31T01:00:00.000Z"
),
)
assert response.status == HTTPStatus.OK
@@ -426,7 +482,7 @@ async def test_task_due_datetime(
# Query is after the task ends (no results)
response = await client.get(
get_events_url(
"calendar.name", "2023-04-01T07:00:00.000Z", "2023-04-02T07:00:00.000Z"
"calendar.name", "2023-03-31T01:00:00.000Z", "2023-03-31T02:00:00.000Z"
),
)
assert response.status == HTTPStatus.OK
@@ -535,6 +591,6 @@ async def test_config_entry(
assert await response.json() == [
get_events_response(
{"dateTime": "2023-03-30T18:00:00-06:00"},
{"dateTime": "2023-03-31T18:00:00-06:00"},
{"dateTime": "2023-03-30T18:30:00-06:00"},
)
]