Send recurrence data when updating a task in todoist (#108269)

* Send recurrence data when updating a task in todoist

* Update tests/components/todoist/test_todo.py

Co-authored-by: Allen Porter <allen.porter@gmail.com>

* Move logic into _task_api_data.

* Add comment about sending potentinally stale data.

---------

Co-authored-by: Allen Porter <allen.porter@gmail.com>
This commit is contained in:
Aaron Godfrey 2024-01-21 15:09:08 -08:00 committed by GitHub
parent e90b42d3d0
commit 71e636572f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 56 additions and 3 deletions

View file

@ -4,6 +4,8 @@ import asyncio
import datetime
from typing import Any, cast
from todoist_api_python.models import Task
from homeassistant.components.todo import (
TodoItem,
TodoItemStatus,
@ -32,7 +34,7 @@ async def async_setup_entry(
)
def _task_api_data(item: TodoItem) -> dict[str, Any]:
def _task_api_data(item: TodoItem, api_data: Task | None = None) -> dict[str, Any]:
"""Convert a TodoItem to the set of add or update arguments."""
item_data: dict[str, Any] = {
"content": item.summary,
@ -44,6 +46,12 @@ def _task_api_data(item: TodoItem) -> dict[str, Any]:
item_data["due_datetime"] = due.isoformat()
else:
item_data["due_date"] = due.isoformat()
# In order to not lose any recurrence metadata for the task, we need to
# ensure that we send the `due_string` param if the task has it set.
# NOTE: It's ok to send stale data for non-recurring tasks. Any provided
# date/datetime will override this string.
if api_data and api_data.due:
item_data["due_string"] = api_data.due.string
else:
# Special flag "no date" clears the due date/datetime.
# See https://developer.todoist.com/rest/v2/#update-a-task for more.
@ -126,7 +134,8 @@ class TodoistTodoListEntity(CoordinatorEntity[TodoistCoordinator], TodoListEntit
async def async_update_todo_item(self, item: TodoItem) -> None:
"""Update a To-do item."""
uid: str = cast(str, item.uid)
if update_data := _task_api_data(item):
api_data = next((d for d in self.coordinator.data if d.id == uid), None)
if update_data := _task_api_data(item, api_data):
await self.coordinator.api.update_task(task_id=uid, **update_data)
if item.status is not None:
# Only update status if changed

View file

@ -402,8 +402,52 @@ async def test_update_todo_item_status(
"status": "needs_action",
},
),
(
[
make_api_task(
id="task-id-1",
content="Soda",
description="6-pack",
is_completed=False,
# Create a mock task with a string value in the Due object and verify it
# gets preserved when verifying the kwargs to update below
due=Due(date="2024-01-01", is_recurring=True, string="every day"),
)
],
{"due_date": "2024-02-01"},
[
make_api_task(
id="task-id-1",
content="Soda",
description="6-pack",
is_completed=False,
due=Due(date="2024-02-01", is_recurring=True, string="every day"),
)
],
{
"task_id": "task-id-1",
"content": "Soda",
"description": "6-pack",
"due_date": "2024-02-01",
"due_string": "every day",
},
{
"uid": "task-id-1",
"summary": "Soda",
"status": "needs_action",
"description": "6-pack",
"due": "2024-02-01",
},
),
],
ids=[
"rename",
"due_date",
"due_datetime",
"description",
"clear_description",
"due_date_with_recurrence",
],
ids=["rename", "due_date", "due_datetime", "description", "clear_description"],
)
async def test_update_todo_items(
hass: HomeAssistant,