Use new constants in todo tests (#121727)

This commit is contained in:
Joost Lekkerkerker 2024-07-11 00:01:17 +02:00 committed by GitHub
parent 2fce71ea52
commit 0462582da3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 446 additions and 372 deletions

View File

@ -8,8 +8,17 @@ from caldav.lib.error import DAVError, NotFoundError
from caldav.objects import Todo
import pytest
from homeassistant.components.todo import DOMAIN as TODO_DOMAIN
from homeassistant.const import Platform
from homeassistant.components.todo import (
ATTR_DESCRIPTION,
ATTR_DUE_DATE,
ATTR_DUE_DATETIME,
ATTR_ITEM,
ATTR_RENAME,
ATTR_STATUS,
DOMAIN as TODO_DOMAIN,
TodoServices,
)
from homeassistant.const import ATTR_ENTITY_ID, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
@ -226,12 +235,12 @@ async def test_supported_components(
RESULT_ITEM,
),
(
{"due_date": "2023-11-18"},
{ATTR_DUE_DATE: "2023-11-18"},
{"status": "NEEDS-ACTION", "summary": "Cheese", "due": date(2023, 11, 18)},
{**RESULT_ITEM, "due": "2023-11-18"},
),
(
{"due_datetime": "2023-11-18T08:30:00-06:00"},
{ATTR_DUE_DATETIME: "2023-11-18T08:30:00-06:00"},
{
"status": "NEEDS-ACTION",
"summary": "Cheese",
@ -240,7 +249,7 @@ async def test_supported_components(
{**RESULT_ITEM, "due": "2023-11-18T08:30:00-06:00"},
),
(
{"description": "Make sure to get Swiss"},
{ATTR_DESCRIPTION: "Make sure to get Swiss"},
{
"status": "NEEDS-ACTION",
"summary": "Cheese",
@ -278,9 +287,9 @@ async def test_add_item(
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
{"item": "Cheese", **item_data},
target={"entity_id": TEST_ENTITY},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "Cheese", **item_data},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -306,9 +315,9 @@ async def test_add_item_failure(
with pytest.raises(HomeAssistantError, match="CalDAV save error"):
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
{"item": "Cheese"},
target={"entity_id": TEST_ENTITY},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "Cheese"},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -317,7 +326,7 @@ async def test_add_item_failure(
("update_data", "expected_ics", "expected_state", "expected_item"),
[
(
{"rename": "Swiss Cheese"},
{ATTR_RENAME: "Swiss Cheese"},
[
"DESCRIPTION:Any kind will do",
"DUE;VALUE=DATE:20171126",
@ -334,7 +343,7 @@ async def test_add_item_failure(
},
),
(
{"status": "needs_action"},
{ATTR_STATUS: "needs_action"},
[
"DESCRIPTION:Any kind will do",
"DUE;VALUE=DATE:20171126",
@ -351,7 +360,7 @@ async def test_add_item_failure(
},
),
(
{"status": "completed"},
{ATTR_STATUS: "completed"},
[
"DESCRIPTION:Any kind will do",
"DUE;VALUE=DATE:20171126",
@ -368,7 +377,7 @@ async def test_add_item_failure(
},
),
(
{"rename": "Swiss Cheese", "status": "needs_action"},
{ATTR_RENAME: "Swiss Cheese", ATTR_STATUS: "needs_action"},
[
"DESCRIPTION:Any kind will do",
"DUE;VALUE=DATE:20171126",
@ -385,7 +394,7 @@ async def test_add_item_failure(
},
),
(
{"due_date": "2023-11-18"},
{ATTR_DUE_DATE: "2023-11-18"},
[
"DESCRIPTION:Any kind will do",
"DUE;VALUE=DATE:20231118",
@ -402,7 +411,7 @@ async def test_add_item_failure(
},
),
(
{"due_datetime": "2023-11-18T08:30:00-06:00"},
{ATTR_DUE_DATETIME: "2023-11-18T08:30:00-06:00"},
[
"DESCRIPTION:Any kind will do",
"DUE;TZID=America/Regina:20231118T083000",
@ -419,7 +428,7 @@ async def test_add_item_failure(
},
),
(
{"due_datetime": None},
{ATTR_DUE_DATETIME: None},
[
"DESCRIPTION:Any kind will do",
"STATUS:NEEDS-ACTION",
@ -434,7 +443,7 @@ async def test_add_item_failure(
},
),
(
{"description": "Make sure to get Swiss"},
{ATTR_DESCRIPTION: "Make sure to get Swiss"},
[
"DESCRIPTION:Make sure to get Swiss",
"DUE;VALUE=DATE:20171126",
@ -451,7 +460,7 @@ async def test_add_item_failure(
},
),
(
{"description": None},
{ATTR_DESCRIPTION: None},
["DUE;VALUE=DATE:20171126", "STATUS:NEEDS-ACTION", "SUMMARY:Cheese"],
"1",
{
@ -501,12 +510,12 @@ async def test_update_item(
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
TodoServices.UPDATE_ITEM,
{
"item": "Cheese",
ATTR_ITEM: "Cheese",
**update_data,
},
target={"entity_id": TEST_ENTITY},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -520,9 +529,9 @@ async def test_update_item(
result = await hass.services.async_call(
TODO_DOMAIN,
"get_items",
TodoServices.GET_ITEMS,
{},
target={"entity_id": TEST_ENTITY},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
return_response=True,
)
@ -548,12 +557,12 @@ async def test_update_item_failure(
with pytest.raises(HomeAssistantError, match="CalDAV save error"):
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
TodoServices.UPDATE_ITEM,
{
"item": "Cheese",
"status": "completed",
ATTR_ITEM: "Cheese",
ATTR_STATUS: "completed",
},
target={"entity_id": TEST_ENTITY},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -582,12 +591,12 @@ async def test_update_item_lookup_failure(
with pytest.raises(HomeAssistantError, match=match):
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
TodoServices.UPDATE_ITEM,
{
"item": "Cheese",
"status": "completed",
ATTR_ITEM: "Cheese",
ATTR_STATUS: "completed",
},
target={"entity_id": TEST_ENTITY},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -635,9 +644,9 @@ async def test_remove_item(
await hass.services.async_call(
TODO_DOMAIN,
"remove_item",
{"item": uids_to_delete},
target={"entity_id": TEST_ENTITY},
TodoServices.REMOVE_ITEM,
{ATTR_ITEM: uids_to_delete},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -668,9 +677,9 @@ async def test_remove_item_lookup_failure(
with pytest.raises(HomeAssistantError, match=match):
await hass.services.async_call(
TODO_DOMAIN,
"remove_item",
{"item": "Cheese"},
target={"entity_id": TEST_ENTITY},
TodoServices.REMOVE_ITEM,
{ATTR_ITEM: "Cheese"},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -697,9 +706,9 @@ async def test_remove_item_failure(
with pytest.raises(HomeAssistantError, match="CalDAV delete error"):
await hass.services.async_call(
TODO_DOMAIN,
"remove_item",
{"item": "Cheese"},
target={"entity_id": TEST_ENTITY},
TodoServices.REMOVE_ITEM,
{ATTR_ITEM: "Cheese"},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -725,9 +734,9 @@ async def test_remove_item_not_found(
with pytest.raises(HomeAssistantError, match="Could not find"):
await hass.services.async_call(
TODO_DOMAIN,
"remove_item",
{"item": "Cheese"},
target={"entity_id": TEST_ENTITY},
TodoServices.REMOVE_ITEM,
{ATTR_ITEM: "Cheese"},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -779,12 +788,12 @@ async def test_subscribe(
]
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
TodoServices.UPDATE_ITEM,
{
"item": "Cheese",
"rename": "Milk",
ATTR_ITEM: "Cheese",
ATTR_RENAME: "Milk",
},
target={"entity_id": TEST_ENTITY},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)

View File

@ -10,8 +10,16 @@ from httplib2 import Response
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.todo import DOMAIN as TODO_DOMAIN
from homeassistant.const import Platform
from homeassistant.components.todo import (
ATTR_DESCRIPTION,
ATTR_DUE_DATE,
ATTR_ITEM,
ATTR_RENAME,
ATTR_STATUS,
DOMAIN as TODO_DOMAIN,
TodoServices,
)
from homeassistant.const import ATTR_ENTITY_ID, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
@ -376,8 +384,8 @@ async def test_task_items_error_response(
("api_responses", "item_data"),
[
(CREATE_API_RESPONSES, {}),
(CREATE_API_RESPONSES, {"due_date": "2023-11-18"}),
(CREATE_API_RESPONSES, {"description": "6-pack"}),
(CREATE_API_RESPONSES, {ATTR_DUE_DATE: "2023-11-18"}),
(CREATE_API_RESPONSES, {ATTR_DESCRIPTION: "6-pack"}),
],
ids=["summary", "due", "description"],
)
@ -399,9 +407,9 @@ async def test_create_todo_list_item(
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
{"item": "Soda", **item_data},
target={"entity_id": "todo.my_tasks"},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "Soda", **item_data},
target={ATTR_ENTITY_ID: "todo.my_tasks"},
blocking=True,
)
assert len(mock_http_response.call_args_list) == 4
@ -439,9 +447,9 @@ async def test_create_todo_list_item_error(
with pytest.raises(HomeAssistantError, match="Invalid task ID"):
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
{"item": "Soda"},
target={"entity_id": "todo.my_tasks"},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "Soda"},
target={ATTR_ENTITY_ID: "todo.my_tasks"},
blocking=True,
)
@ -464,9 +472,9 @@ async def test_update_todo_list_item(
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
{"item": "some-task-id", "rename": "Soda", "status": "completed"},
target={"entity_id": "todo.my_tasks"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "some-task-id", ATTR_RENAME: "Soda", ATTR_STATUS: "completed"},
target={ATTR_ENTITY_ID: "todo.my_tasks"},
blocking=True,
)
assert len(mock_http_response.call_args_list) == 4
@ -504,9 +512,9 @@ async def test_update_todo_list_item_error(
with pytest.raises(HomeAssistantError, match="Invalid task ID"):
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
{"item": "some-task-id", "rename": "Soda", "status": "completed"},
target={"entity_id": "todo.my_tasks"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "some-task-id", ATTR_RENAME: "Soda", ATTR_STATUS: "completed"},
target={ATTR_ENTITY_ID: "todo.my_tasks"},
blocking=True,
)
@ -514,12 +522,12 @@ async def test_update_todo_list_item_error(
@pytest.mark.parametrize(
("api_responses", "item_data"),
[
(UPDATE_API_RESPONSES, {"rename": "Soda"}),
(UPDATE_API_RESPONSES, {"due_date": "2023-11-18"}),
(UPDATE_API_RESPONSES, {"due_date": None}),
(UPDATE_API_RESPONSES, {"description": "At least one gallon"}),
(UPDATE_API_RESPONSES, {"description": ""}),
(UPDATE_API_RESPONSES, {"description": None}),
(UPDATE_API_RESPONSES, {ATTR_RENAME: "Soda"}),
(UPDATE_API_RESPONSES, {ATTR_DUE_DATE: "2023-11-18"}),
(UPDATE_API_RESPONSES, {ATTR_DUE_DATE: None}),
(UPDATE_API_RESPONSES, {ATTR_DESCRIPTION: "At least one gallon"}),
(UPDATE_API_RESPONSES, {ATTR_DESCRIPTION: ""}),
(UPDATE_API_RESPONSES, {ATTR_DESCRIPTION: None}),
],
ids=(
"rename",
@ -548,9 +556,9 @@ async def test_partial_update(
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
{"item": "some-task-id", **item_data},
target={"entity_id": "todo.my_tasks"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "some-task-id", **item_data},
target={ATTR_ENTITY_ID: "todo.my_tasks"},
blocking=True,
)
assert len(mock_http_response.call_args_list) == 4
@ -578,9 +586,9 @@ async def test_partial_update_status(
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
{"item": "some-task-id", "status": "needs_action"},
target={"entity_id": "todo.my_tasks"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "some-task-id", ATTR_STATUS: "needs_action"},
target={ATTR_ENTITY_ID: "todo.my_tasks"},
blocking=True,
)
assert len(mock_http_response.call_args_list) == 4
@ -622,9 +630,9 @@ async def test_delete_todo_list_item(
await hass.services.async_call(
TODO_DOMAIN,
"remove_item",
{"item": ["some-task-id-1", "some-task-id-2", "some-task-id-3"]},
target={"entity_id": "todo.my_tasks"},
TodoServices.REMOVE_ITEM,
{ATTR_ITEM: ["some-task-id-1", "some-task-id-2", "some-task-id-3"]},
target={ATTR_ENTITY_ID: "todo.my_tasks"},
blocking=True,
)
assert len(mock_http_response.call_args_list) == 4
@ -670,9 +678,9 @@ async def test_delete_partial_failure(
with pytest.raises(HomeAssistantError, match="Invalid task ID"):
await hass.services.async_call(
TODO_DOMAIN,
"remove_item",
{"item": ["some-task-id-1", "some-task-id-2", "some-task-id-3"]},
target={"entity_id": "todo.my_tasks"},
TodoServices.REMOVE_ITEM,
{ATTR_ITEM: ["some-task-id-1", "some-task-id-2", "some-task-id-3"]},
target={ATTR_ENTITY_ID: "todo.my_tasks"},
blocking=True,
)
@ -711,9 +719,9 @@ async def test_delete_invalid_json_response(
with pytest.raises(HomeAssistantError, match="unexpected response"):
await hass.services.async_call(
TODO_DOMAIN,
"remove_item",
{"item": ["some-task-id-1"]},
target={"entity_id": "todo.my_tasks"},
TodoServices.REMOVE_ITEM,
{ATTR_ITEM: ["some-task-id-1"]},
target={ATTR_ENTITY_ID: "todo.my_tasks"},
blocking=True,
)
@ -750,9 +758,9 @@ async def test_delete_server_error(
with pytest.raises(HomeAssistantError, match="responded with error"):
await hass.services.async_call(
TODO_DOMAIN,
"remove_item",
{"item": ["some-task-id-1"]},
target={"entity_id": "todo.my_tasks"},
TodoServices.REMOVE_ITEM,
{ATTR_ITEM: ["some-task-id-1"]},
target={ATTR_ENTITY_ID: "todo.my_tasks"},
blocking=True,
)
@ -942,9 +950,9 @@ async def test_susbcribe(
# Rename item
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
{"item": uid, "rename": "Milk"},
target={"entity_id": "todo.my_tasks"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: uid, ATTR_RENAME: "Milk"},
target={ATTR_ENTITY_ID: "todo.my_tasks"},
blocking=True,
)

View File

@ -7,7 +7,17 @@ from typing import Any
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.todo import DOMAIN as TODO_DOMAIN
from homeassistant.components.todo import (
ATTR_DESCRIPTION,
ATTR_DUE_DATE,
ATTR_DUE_DATETIME,
ATTR_ITEM,
ATTR_RENAME,
ATTR_STATUS,
DOMAIN as TODO_DOMAIN,
TodoServices,
)
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import HomeAssistant
from .conftest import TEST_ENTITY
@ -76,17 +86,17 @@ EXPECTED_ADD_ITEM = {
("item_data", "expected_item_data"),
[
({}, EXPECTED_ADD_ITEM),
({"due_date": "2023-11-17"}, {**EXPECTED_ADD_ITEM, "due": "2023-11-17"}),
({ATTR_DUE_DATE: "2023-11-17"}, {**EXPECTED_ADD_ITEM, "due": "2023-11-17"}),
(
{"due_datetime": "2023-11-17T11:30:00+00:00"},
{ATTR_DUE_DATETIME: "2023-11-17T11:30:00+00:00"},
{**EXPECTED_ADD_ITEM, "due": "2023-11-17T05:30:00-06:00"},
),
(
{"description": "Additional detail"},
{ATTR_DESCRIPTION: "Additional detail"},
{**EXPECTED_ADD_ITEM, "description": "Additional detail"},
),
({"description": ""}, {**EXPECTED_ADD_ITEM, "description": ""}),
({"description": None}, EXPECTED_ADD_ITEM),
({ATTR_DESCRIPTION: ""}, {**EXPECTED_ADD_ITEM, "description": ""}),
({ATTR_DESCRIPTION: None}, EXPECTED_ADD_ITEM),
],
)
async def test_add_item(
@ -105,9 +115,9 @@ async def test_add_item(
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
{"item": "replace batteries", **item_data},
target={"entity_id": TEST_ENTITY},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "replace batteries", **item_data},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -127,12 +137,12 @@ async def test_add_item(
("item_data", "expected_item_data"),
[
({}, {}),
({"due_date": "2023-11-17"}, {"due": "2023-11-17"}),
({ATTR_DUE_DATE: "2023-11-17"}, {"due": "2023-11-17"}),
(
{"due_datetime": "2023-11-17T11:30:00+00:00"},
{"due": "2023-11-17T05:30:00-06:00"},
),
({"description": "Additional detail"}, {"description": "Additional detail"}),
({ATTR_DESCRIPTION: "Additional detail"}, {"description": "Additional detail"}),
],
)
async def test_remove_item(
@ -145,9 +155,9 @@ async def test_remove_item(
"""Test removing a todo item."""
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
{"item": "replace batteries", **item_data},
target={"entity_id": TEST_ENTITY},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "replace batteries", **item_data},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -165,9 +175,9 @@ async def test_remove_item(
await hass.services.async_call(
TODO_DOMAIN,
"remove_item",
{"item": [items[0]["uid"]]},
target={"entity_id": TEST_ENTITY},
TodoServices.REMOVE_ITEM,
{ATTR_ITEM: [items[0]["uid"]]},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -188,9 +198,9 @@ async def test_bulk_remove(
for i in range(5):
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
{"item": f"soda #{i}"},
target={"entity_id": TEST_ENTITY},
TodoServices.ADD_ITEM,
{ATTR_ITEM: f"soda #{i}"},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -204,9 +214,9 @@ async def test_bulk_remove(
await hass.services.async_call(
TODO_DOMAIN,
"remove_item",
{"item": uids},
target={"entity_id": TEST_ENTITY},
TodoServices.REMOVE_ITEM,
{ATTR_ITEM: uids},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -227,19 +237,23 @@ EXPECTED_UPDATE_ITEM = {
@pytest.mark.parametrize(
("item_data", "expected_item_data", "expected_state"),
[
({"status": "completed"}, {**EXPECTED_UPDATE_ITEM, "status": "completed"}, "0"),
(
{"due_date": "2023-11-17"},
{ATTR_STATUS: "completed"},
{**EXPECTED_UPDATE_ITEM, "status": "completed"},
"0",
),
(
{ATTR_DUE_DATE: "2023-11-17"},
{**EXPECTED_UPDATE_ITEM, "due": "2023-11-17"},
"1",
),
(
{"due_datetime": "2023-11-17T11:30:00+00:00"},
{ATTR_DUE_DATETIME: "2023-11-17T11:30:00+00:00"},
{**EXPECTED_UPDATE_ITEM, "due": "2023-11-17T05:30:00-06:00"},
"1",
),
(
{"description": "Additional detail"},
{ATTR_DESCRIPTION: "Additional detail"},
{**EXPECTED_UPDATE_ITEM, "description": "Additional detail"},
"1",
),
@ -258,9 +272,9 @@ async def test_update_item(
# Create new item
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
{"item": "soda"},
target={"entity_id": TEST_ENTITY},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "soda"},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -279,9 +293,9 @@ async def test_update_item(
# Update item
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
{"item": item["uid"], **item_data},
target={"entity_id": TEST_ENTITY},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: item["uid"], **item_data},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -303,7 +317,7 @@ async def test_update_item(
("item_data", "expected_item_data"),
[
(
{"status": "completed"},
{ATTR_STATUS: "completed"},
{
"summary": "soda",
"status": "completed",
@ -312,7 +326,7 @@ async def test_update_item(
},
),
(
{"due_date": "2024-01-02"},
{ATTR_DUE_DATE: "2024-01-02"},
{
"summary": "soda",
"status": "needs_action",
@ -321,7 +335,7 @@ async def test_update_item(
},
),
(
{"due_date": None},
{ATTR_DUE_DATE: None},
{
"summary": "soda",
"status": "needs_action",
@ -329,7 +343,7 @@ async def test_update_item(
},
),
(
{"due_datetime": "2024-01-01 10:30:00"},
{ATTR_DUE_DATETIME: "2024-01-01 10:30:00"},
{
"summary": "soda",
"status": "needs_action",
@ -338,7 +352,7 @@ async def test_update_item(
},
),
(
{"due_datetime": None},
{ATTR_DUE_DATETIME: None},
{
"summary": "soda",
"status": "needs_action",
@ -346,7 +360,7 @@ async def test_update_item(
},
),
(
{"description": "updated description"},
{ATTR_DESCRIPTION: "updated description"},
{
"summary": "soda",
"status": "needs_action",
@ -355,7 +369,7 @@ async def test_update_item(
},
),
(
{"description": None},
{ATTR_DESCRIPTION: None},
{"summary": "soda", "status": "needs_action", "due": "2024-01-01"},
),
],
@ -381,9 +395,13 @@ async def test_update_existing_field(
# Create new item
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
{"item": "soda", "description": "Additional detail", "due_date": "2024-01-01"},
target={"entity_id": TEST_ENTITY},
TodoServices.ADD_ITEM,
{
ATTR_ITEM: "soda",
ATTR_DESCRIPTION: "Additional detail",
ATTR_DUE_DATE: "2024-01-01",
},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -398,9 +416,9 @@ async def test_update_existing_field(
# Perform update
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
{"item": item["uid"], **item_data},
target={"entity_id": TEST_ENTITY},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: item["uid"], **item_data},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -424,9 +442,9 @@ async def test_rename(
# Create new item
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
{"item": "soda"},
target={"entity_id": TEST_ENTITY},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "soda"},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -444,9 +462,9 @@ async def test_rename(
# Rename item
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
{"item": item["uid"], "rename": "water"},
target={"entity_id": TEST_ENTITY},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: item["uid"], ATTR_RENAME: "water"},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -501,9 +519,9 @@ async def test_move_item(
for i in range(1, 5):
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
{"item": f"item {i}"},
target={"entity_id": TEST_ENTITY},
TodoServices.ADD_ITEM,
{ATTR_ITEM: f"item {i}"},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -559,9 +577,9 @@ async def test_move_item_previous_unknown(
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
{"item": "item 1"},
target={"entity_id": TEST_ENTITY},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "item 1"},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
items = await ws_get_items()
@ -732,9 +750,9 @@ async def test_susbcribe(
# Create new item
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
{"item": "soda"},
target={"entity_id": TEST_ENTITY},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "soda"},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -765,9 +783,9 @@ async def test_susbcribe(
# Rename item
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
{"item": uid, "rename": "milk"},
target={"entity_id": TEST_ENTITY},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: uid, ATTR_RENAME: "milk"},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)

View File

@ -6,7 +6,13 @@ from aiomealie.exceptions import MealieError
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.todo import DOMAIN as TODO_DOMAIN
from homeassistant.components.todo import (
ATTR_ITEM,
ATTR_RENAME,
ATTR_STATUS,
DOMAIN as TODO_DOMAIN,
TodoServices,
)
from homeassistant.const import ATTR_ENTITY_ID, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
@ -41,8 +47,8 @@ async def test_add_todo_list_item(
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
{"item": "Soda"},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "Soda"},
target={ATTR_ENTITY_ID: "todo.mealie_supermarket"},
blocking=True,
)
@ -63,8 +69,8 @@ async def test_add_todo_list_item_error(
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
{"item": "Soda"},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "Soda"},
target={ATTR_ENTITY_ID: "todo.mealie_supermarket"},
blocking=True,
)
@ -80,8 +86,8 @@ async def test_update_todo_list_item(
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
{"item": "aubergine", "rename": "Eggplant", "status": "completed"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "aubergine", ATTR_RENAME: "Eggplant", ATTR_STATUS: "completed"},
target={ATTR_ENTITY_ID: "todo.mealie_supermarket"},
blocking=True,
)
@ -102,8 +108,8 @@ async def test_update_todo_list_item_error(
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
{"item": "aubergine", "rename": "Eggplant", "status": "completed"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "aubergine", ATTR_RENAME: "Eggplant", ATTR_STATUS: "completed"},
target={ATTR_ENTITY_ID: "todo.mealie_supermarket"},
blocking=True,
)
@ -119,8 +125,8 @@ async def test_delete_todo_list_item(
await hass.services.async_call(
TODO_DOMAIN,
"remove_item",
{"item": "aubergine"},
TodoServices.REMOVE_ITEM,
{ATTR_ITEM: "aubergine"},
target={ATTR_ENTITY_ID: "todo.mealie_supermarket"},
blocking=True,
)
@ -142,8 +148,8 @@ async def test_delete_todo_list_item_error(
with pytest.raises(HomeAssistantError):
await hass.services.async_call(
TODO_DOMAIN,
"remove_item",
{"item": "aubergine"},
TodoServices.REMOVE_ITEM,
{ATTR_ITEM: "aubergine"},
target={ATTR_ENTITY_ID: "todo.mealie_supermarket"},
blocking=True,
)

View File

@ -7,8 +7,14 @@ from freezegun.api import FrozenDateTimeFactory
import pytest
from homeassistant.components.ourgroceries.coordinator import SCAN_INTERVAL
from homeassistant.components.todo import DOMAIN as TODO_DOMAIN
from homeassistant.const import STATE_UNAVAILABLE
from homeassistant.components.todo import (
ATTR_ITEM,
ATTR_RENAME,
ATTR_STATUS,
DOMAIN as TODO_DOMAIN,
TodoServices,
)
from homeassistant.const import ATTR_ENTITY_ID, STATE_UNAVAILABLE
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_component import async_update_entity
@ -69,9 +75,9 @@ async def test_add_todo_list_item(
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
{"item": "Soda"},
target={"entity_id": "todo.test_list"},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "Soda"},
target={ATTR_ENTITY_ID: "todo.test_list"},
blocking=True,
)
@ -108,9 +114,9 @@ async def test_update_todo_item_status(
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
{"item": "12345", "status": "completed"},
target={"entity_id": "todo.test_list"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "12345", ATTR_STATUS: "completed"},
target={ATTR_ENTITY_ID: "todo.test_list"},
blocking=True,
)
assert ourgroceries.toggle_item_crossed_off.called
@ -132,9 +138,9 @@ async def test_update_todo_item_status(
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
{"item": "12345", "status": "needs_action"},
target={"entity_id": "todo.test_list"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "12345", ATTR_STATUS: "needs_action"},
target={ATTR_ENTITY_ID: "todo.test_list"},
blocking=True,
)
assert ourgroceries.toggle_item_crossed_off.called
@ -181,9 +187,9 @@ async def test_update_todo_item_summary(
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
{"item": "12345", "rename": "Milk"},
target={"entity_id": "todo.test_list"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "12345", ATTR_RENAME: "Milk"},
target={ATTR_ENTITY_ID: "todo.test_list"},
blocking=True,
)
assert ourgroceries.change_item_on_list
@ -218,9 +224,9 @@ async def test_remove_todo_item(
await hass.services.async_call(
TODO_DOMAIN,
"remove_item",
{"item": ["12345", "54321"]},
target={"entity_id": "todo.test_list"},
TodoServices.REMOVE_ITEM,
{ATTR_ITEM: ["12345", "54321"]},
target={ATTR_ENTITY_ID: "todo.test_list"},
blocking=True,
)
assert ourgroceries.remove_item_from_list.call_count == 2

View File

@ -5,7 +5,8 @@ from unittest.mock import MagicMock, Mock
import pytest
from syrupy.assertion import SnapshotAssertion
from homeassistant.components.todo import DOMAIN
from homeassistant.components.todo import ATTR_ITEM, DOMAIN, TodoServices
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ServiceValidationError
@ -91,9 +92,9 @@ async def test_create_todo_list_item(
await hass.services.async_call(
DOMAIN,
"add_item",
{"item": "Melk"},
target={"entity_id": ENTITY_ID},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "Melk"},
target={ATTR_ENTITY_ID: ENTITY_ID},
blocking=True,
)
@ -119,8 +120,8 @@ async def test_create_todo_list_item_not_found(
with pytest.raises(ServiceValidationError):
await hass.services.async_call(
DOMAIN,
"add_item",
{"item": "Melk"},
target={"entity_id": ENTITY_ID},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "Melk"},
target={ATTR_ENTITY_ID: ENTITY_ID},
blocking=True,
)

View File

@ -5,7 +5,14 @@ from typing import Any
import pytest
from homeassistant.components.todo import DOMAIN as TODO_DOMAIN
from homeassistant.components.todo import (
ATTR_ITEM,
ATTR_RENAME,
ATTR_STATUS,
DOMAIN as TODO_DOMAIN,
TodoServices,
)
from homeassistant.const import ATTR_ENTITY_ID
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import ServiceValidationError
@ -98,11 +105,11 @@ async def test_add_item(
"""Test adding shopping_list item and listing it."""
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
TodoServices.ADD_ITEM,
{
"item": "soda",
ATTR_ITEM: "soda",
},
target={"entity_id": TEST_ENTITY},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -125,9 +132,9 @@ async def test_remove_item(
"""Test removing a todo item."""
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
{"item": "soda"},
target={"entity_id": TEST_ENTITY},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "soda"},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
items = await ws_get_items()
@ -142,11 +149,11 @@ async def test_remove_item(
await hass.services.async_call(
TODO_DOMAIN,
"remove_item",
TodoServices.REMOVE_ITEM,
{
"item": [items[0]["uid"]],
ATTR_ITEM: [items[0]["uid"]],
},
target={"entity_id": TEST_ENTITY},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -168,11 +175,11 @@ async def test_bulk_remove(
for _i in range(5):
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
TodoServices.ADD_ITEM,
{
"item": "soda",
ATTR_ITEM: "soda",
},
target={"entity_id": TEST_ENTITY},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -186,11 +193,11 @@ async def test_bulk_remove(
await hass.services.async_call(
TODO_DOMAIN,
"remove_item",
TodoServices.REMOVE_ITEM,
{
"item": uids,
ATTR_ITEM: uids,
},
target={"entity_id": TEST_ENTITY},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -212,11 +219,11 @@ async def test_update_item(
# Create new item
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
TodoServices.ADD_ITEM,
{
"item": "soda",
ATTR_ITEM: "soda",
},
target={"entity_id": TEST_ENTITY},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -234,12 +241,12 @@ async def test_update_item(
# Mark item completed
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
TodoServices.UPDATE_ITEM,
{
"item": "soda",
"status": "completed",
ATTR_ITEM: "soda",
ATTR_STATUS: "completed",
},
target={"entity_id": TEST_ENTITY},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -265,11 +272,11 @@ async def test_partial_update_item(
# Create new item
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
TodoServices.ADD_ITEM,
{
"item": "soda",
ATTR_ITEM: "soda",
},
target={"entity_id": TEST_ENTITY},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -287,12 +294,12 @@ async def test_partial_update_item(
# Mark item completed without changing the summary
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
TodoServices.UPDATE_ITEM,
{
"item": item["uid"],
"status": "completed",
ATTR_ITEM: item["uid"],
ATTR_STATUS: "completed",
},
target={"entity_id": TEST_ENTITY},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -310,12 +317,12 @@ async def test_partial_update_item(
# Change the summary without changing the status
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
TodoServices.UPDATE_ITEM,
{
"item": item["uid"],
"rename": "other summary",
ATTR_ITEM: item["uid"],
ATTR_RENAME: "other summary",
},
target={"entity_id": TEST_ENTITY},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -341,12 +348,12 @@ async def test_update_invalid_item(
with pytest.raises(ServiceValidationError, match="Unable to find"):
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
TodoServices.UPDATE_ITEM,
{
"item": "invalid-uid",
"rename": "Example task",
ATTR_ITEM: "invalid-uid",
ATTR_RENAME: "Example task",
},
target={"entity_id": TEST_ENTITY},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -391,11 +398,11 @@ async def test_move_item(
for i in range(1, 5):
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
TodoServices.ADD_ITEM,
{
"item": f"item {i}",
ATTR_ITEM: f"item {i}",
},
target={"entity_id": TEST_ENTITY},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -429,9 +436,9 @@ async def test_move_invalid_item(
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
{"item": "soda"},
target={"entity_id": TEST_ENTITY},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "soda"},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -456,11 +463,11 @@ async def test_subscribe_item(
# Create new item
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
TodoServices.ADD_ITEM,
{
"item": "soda",
ATTR_ITEM: "soda",
},
target={"entity_id": TEST_ENTITY},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)
@ -491,12 +498,12 @@ async def test_subscribe_item(
# Rename item item completed
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
TodoServices.UPDATE_ITEM,
{
"item": "soda",
"rename": "milk",
ATTR_ITEM: "soda",
ATTR_RENAME: "milk",
},
target={"entity_id": TEST_ENTITY},
target={ATTR_ENTITY_ID: TEST_ENTITY},
blocking=True,
)

View File

@ -12,15 +12,22 @@ import voluptuous as vol
from homeassistant.components import conversation
from homeassistant.components.homeassistant.exposed_entities import async_expose_entity
from homeassistant.components.todo import (
ATTR_DESCRIPTION,
ATTR_DUE_DATE,
ATTR_DUE_DATETIME,
ATTR_ITEM,
ATTR_RENAME,
ATTR_STATUS,
DOMAIN,
TodoItem,
TodoItemStatus,
TodoListEntity,
TodoListEntityFeature,
TodoServices,
intent as todo_intent,
)
from homeassistant.config_entries import ConfigEntry, ConfigEntryState, ConfigFlow
from homeassistant.const import Platform
from homeassistant.const import ATTR_ENTITY_ID, ATTR_SUPPORTED_FEATURES, Platform
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
from homeassistant.helpers import intent
@ -230,11 +237,11 @@ async def test_list_todo_items(
[
({}, [ITEM_1, ITEM_2]),
(
{"status": [TodoItemStatus.COMPLETED, TodoItemStatus.NEEDS_ACTION]},
{ATTR_STATUS: [TodoItemStatus.COMPLETED, TodoItemStatus.NEEDS_ACTION]},
[ITEM_1, ITEM_2],
),
({"status": [TodoItemStatus.NEEDS_ACTION]}, [ITEM_1]),
({"status": [TodoItemStatus.COMPLETED]}, [ITEM_2]),
({ATTR_STATUS: [TodoItemStatus.NEEDS_ACTION]}, [ITEM_1]),
({ATTR_STATUS: [TodoItemStatus.COMPLETED]}, [ITEM_2]),
],
)
async def test_get_items_service(
@ -251,13 +258,13 @@ async def test_get_items_service(
state = hass.states.get("todo.entity1")
assert state
assert state.state == "1"
assert state.attributes == {"supported_features": 15}
assert state.attributes == {ATTR_SUPPORTED_FEATURES: 15}
result = await hass.services.async_call(
DOMAIN,
"get_items",
TodoServices.GET_ITEMS,
service_data,
target={"entity_id": "todo.entity1"},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
return_response=True,
)
@ -297,9 +304,9 @@ async def test_add_item_service(
await hass.services.async_call(
DOMAIN,
"add_item",
{"item": "New item"},
target={"entity_id": "todo.entity1"},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "New item"},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -324,9 +331,9 @@ async def test_add_item_service_raises(
with pytest.raises(HomeAssistantError, match="Ooops"):
await hass.services.async_call(
DOMAIN,
"add_item",
{"item": "New item"},
target={"entity_id": "todo.entity1"},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "New item"},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -335,21 +342,21 @@ async def test_add_item_service_raises(
("item_data", "expected_exception", "expected_error"),
[
({}, vol.Invalid, "required key not provided"),
({"item": ""}, vol.Invalid, "length of value must be at least 1"),
({ATTR_ITEM: ""}, vol.Invalid, "length of value must be at least 1"),
(
{"item": "Submit forms", "description": "Submit tax forms"},
{ATTR_ITEM: "Submit forms", ATTR_DESCRIPTION: "Submit tax forms"},
ServiceValidationError,
"does not support setting field: description",
),
(
{"item": "Submit forms", "due_date": "2023-11-17"},
{ATTR_ITEM: "Submit forms", ATTR_DUE_DATE: "2023-11-17"},
ServiceValidationError,
"does not support setting field: due_date",
),
(
{
"item": "Submit forms",
"due_datetime": f"2023-11-17T17:00:00{TEST_OFFSET}",
ATTR_ITEM: "Submit forms",
ATTR_DUE_DATETIME: f"2023-11-17T17:00:00{TEST_OFFSET}",
},
ServiceValidationError,
"does not support setting field: due_datetime",
@ -370,9 +377,9 @@ async def test_add_item_service_invalid_input(
with pytest.raises(expected_exception) as exc:
await hass.services.async_call(
DOMAIN,
"add_item",
TodoServices.ADD_ITEM,
item_data,
target={"entity_id": "todo.entity1"},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -384,7 +391,7 @@ async def test_add_item_service_invalid_input(
[
(
TodoListEntityFeature.SET_DUE_DATE_ON_ITEM,
{"item": "New item", "due_date": "2023-11-13"},
{ATTR_ITEM: "New item", ATTR_DUE_DATE: "2023-11-13"},
TodoItem(
summary="New item",
status=TodoItemStatus.NEEDS_ACTION,
@ -393,7 +400,10 @@ async def test_add_item_service_invalid_input(
),
(
TodoListEntityFeature.SET_DUE_DATETIME_ON_ITEM,
{"item": "New item", "due_datetime": f"2023-11-13T17:00:00{TEST_OFFSET}"},
{
ATTR_ITEM: "New item",
ATTR_DUE_DATETIME: f"2023-11-13T17:00:00{TEST_OFFSET}",
},
TodoItem(
summary="New item",
status=TodoItemStatus.NEEDS_ACTION,
@ -402,7 +412,7 @@ async def test_add_item_service_invalid_input(
),
(
TodoListEntityFeature.SET_DUE_DATETIME_ON_ITEM,
{"item": "New item", "due_datetime": "2023-11-13T17:00:00+00:00"},
{ATTR_ITEM: "New item", ATTR_DUE_DATETIME: "2023-11-13T17:00:00+00:00"},
TodoItem(
summary="New item",
status=TodoItemStatus.NEEDS_ACTION,
@ -411,7 +421,7 @@ async def test_add_item_service_invalid_input(
),
(
TodoListEntityFeature.SET_DUE_DATETIME_ON_ITEM,
{"item": "New item", "due_datetime": "2023-11-13"},
{ATTR_ITEM: "New item", ATTR_DUE_DATETIME: "2023-11-13"},
TodoItem(
summary="New item",
status=TodoItemStatus.NEEDS_ACTION,
@ -420,7 +430,7 @@ async def test_add_item_service_invalid_input(
),
(
TodoListEntityFeature.SET_DESCRIPTION_ON_ITEM,
{"item": "New item", "description": "Submit revised draft"},
{ATTR_ITEM: "New item", ATTR_DESCRIPTION: "Submit revised draft"},
TodoItem(
summary="New item",
status=TodoItemStatus.NEEDS_ACTION,
@ -443,9 +453,9 @@ async def test_add_item_service_extended_fields(
await hass.services.async_call(
DOMAIN,
"add_item",
{"item": "New item", **item_data},
target={"entity_id": "todo.entity1"},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "New item", **item_data},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -465,9 +475,9 @@ async def test_update_todo_item_service_by_id(
await hass.services.async_call(
DOMAIN,
"update_item",
{"item": "1", "rename": "Updated item", "status": "completed"},
target={"entity_id": "todo.entity1"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "1", ATTR_RENAME: "Updated item", ATTR_STATUS: "completed"},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -490,9 +500,9 @@ async def test_update_todo_item_service_by_id_status_only(
await hass.services.async_call(
DOMAIN,
"update_item",
{"item": "1", "status": "completed"},
target={"entity_id": "todo.entity1"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "1", ATTR_STATUS: "completed"},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -515,9 +525,9 @@ async def test_update_todo_item_service_by_id_rename(
await hass.services.async_call(
DOMAIN,
"update_item",
{"item": "1", "rename": "Updated item"},
target={"entity_id": "todo.entity1"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "1", "rename": "Updated item"},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -540,9 +550,9 @@ async def test_update_todo_item_service_raises(
await hass.services.async_call(
DOMAIN,
"update_item",
{"item": "1", "rename": "Updated item", "status": "completed"},
target={"entity_id": "todo.entity1"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "1", "rename": "Updated item", "status": "completed"},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -550,9 +560,9 @@ async def test_update_todo_item_service_raises(
with pytest.raises(HomeAssistantError, match="Ooops"):
await hass.services.async_call(
DOMAIN,
"update_item",
{"item": "1", "rename": "Updated item", "status": "completed"},
target={"entity_id": "todo.entity1"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "1", "rename": "Updated item", "status": "completed"},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -567,9 +577,9 @@ async def test_update_todo_item_service_by_summary(
await hass.services.async_call(
DOMAIN,
"update_item",
{"item": "Item #1", "rename": "Something else", "status": "completed"},
target={"entity_id": "todo.entity1"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "Item #1", "rename": "Something else", "status": "completed"},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -592,9 +602,9 @@ async def test_update_todo_item_service_by_summary_only_status(
await hass.services.async_call(
DOMAIN,
"update_item",
{"item": "Item #1", "rename": "Something else"},
target={"entity_id": "todo.entity1"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "Item #1", "rename": "Something else"},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -618,9 +628,9 @@ async def test_update_todo_item_service_by_summary_not_found(
with pytest.raises(ServiceValidationError, match="Unable to find"):
await hass.services.async_call(
DOMAIN,
"update_item",
{"item": "Item #7", "status": "completed"},
target={"entity_id": "todo.entity1"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "Item #7", "status": "completed"},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -652,7 +662,7 @@ async def test_update_item_service_invalid_input(
DOMAIN,
"update_item",
item_data,
target={"entity_id": "todo.entity1"},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -677,9 +687,9 @@ async def test_update_todo_item_field_unsupported(
with pytest.raises(ServiceValidationError, match="does not support"):
await hass.services.async_call(
DOMAIN,
"update_item",
{"item": "1", **update_data},
target={"entity_id": "todo.entity1"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "1", **update_data},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -733,9 +743,9 @@ async def test_update_todo_item_extended_fields(
await hass.services.async_call(
DOMAIN,
"update_item",
{"item": "1", **update_data},
target={"entity_id": "todo.entity1"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "1", **update_data},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -823,9 +833,9 @@ async def test_update_todo_item_extended_fields_overwrite_existing_values(
await hass.services.async_call(
DOMAIN,
"update_item",
{"item": "1", **update_data},
target={"entity_id": "todo.entity1"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "1", **update_data},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -845,9 +855,9 @@ async def test_remove_todo_item_service_by_id(
await hass.services.async_call(
DOMAIN,
"remove_item",
{"item": ["1", "2"]},
target={"entity_id": "todo.entity1"},
TodoServices.REMOVE_ITEM,
{ATTR_ITEM: ["1", "2"]},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -868,9 +878,9 @@ async def test_remove_todo_item_service_raises(
with pytest.raises(HomeAssistantError, match="Ooops"):
await hass.services.async_call(
DOMAIN,
"remove_item",
{"item": ["1", "2"]},
target={"entity_id": "todo.entity1"},
TodoServices.REMOVE_ITEM,
{ATTR_ITEM: ["1", "2"]},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -888,9 +898,9 @@ async def test_remove_todo_item_service_invalid_input(
):
await hass.services.async_call(
DOMAIN,
"remove_item",
TodoServices.REMOVE_ITEM,
{},
target={"entity_id": "todo.entity1"},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -905,9 +915,9 @@ async def test_remove_todo_item_service_by_summary(
await hass.services.async_call(
DOMAIN,
"remove_item",
{"item": ["Item #1"]},
target={"entity_id": "todo.entity1"},
TodoServices.REMOVE_ITEM,
{ATTR_ITEM: ["Item #1"]},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -927,9 +937,9 @@ async def test_remove_todo_item_service_by_summary_not_found(
with pytest.raises(ServiceValidationError, match="Unable to find"):
await hass.services.async_call(
DOMAIN,
"remove_item",
{"item": ["Item #7"]},
target={"entity_id": "todo.entity1"},
TodoServices.REMOVE_ITEM,
{ATTR_ITEM: ["Item #7"]},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -1035,26 +1045,26 @@ async def test_move_todo_item_service_invalid_input(
("service_name", "payload"),
[
(
"add_item",
TodoServices.ADD_ITEM,
{
"item": "New item",
ATTR_ITEM: "New item",
},
),
(
"remove_item",
TodoServices.REMOVE_ITEM,
{
"item": ["1"],
ATTR_ITEM: ["1"],
},
),
(
"update_item",
TodoServices.UPDATE_ITEM,
{
"item": "1",
"rename": "Updated item",
ATTR_ITEM: "1",
ATTR_RENAME: "Updated item",
},
),
(
"remove_completed_items",
TodoServices.REMOVE_COMPLETED_ITEMS,
None,
),
],
@ -1078,7 +1088,7 @@ async def test_unsupported_service(
DOMAIN,
service_name,
payload,
target={"entity_id": "todo.entity1"},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -1131,7 +1141,7 @@ async def test_add_item_intent(
hass,
"test",
todo_intent.INTENT_LIST_ADD_ITEM,
{"item": {"value": "beer"}, "name": {"value": "list 1"}},
{ATTR_ITEM: {"value": "beer"}, "name": {"value": "list 1"}},
assistant=conversation.DOMAIN,
)
assert response.response_type == intent.IntentResponseType.ACTION_DONE
@ -1147,7 +1157,7 @@ async def test_add_item_intent(
hass,
"test",
todo_intent.INTENT_LIST_ADD_ITEM,
{"item": {"value": "cheese"}, "name": {"value": "List 2"}},
{ATTR_ITEM: {"value": "cheese"}, "name": {"value": "List 2"}},
assistant=conversation.DOMAIN,
)
assert response.response_type == intent.IntentResponseType.ACTION_DONE
@ -1162,7 +1172,7 @@ async def test_add_item_intent(
hass,
"test",
todo_intent.INTENT_LIST_ADD_ITEM,
{"item": {"value": "wine"}, "name": {"value": "lIST 2"}},
{ATTR_ITEM: {"value": "wine"}, "name": {"value": "lIST 2"}},
assistant=conversation.DOMAIN,
)
assert response.response_type == intent.IntentResponseType.ACTION_DONE
@ -1224,8 +1234,8 @@ async def test_remove_completed_items_service(
await hass.services.async_call(
DOMAIN,
"remove_completed_items",
target={"entity_id": "todo.entity1"},
TodoServices.REMOVE_COMPLETED_ITEMS,
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -1238,8 +1248,8 @@ async def test_remove_completed_items_service(
# calling service multiple times will not call the entity method
await hass.services.async_call(
DOMAIN,
"remove_completed_items",
target={"entity_id": "todo.entity1"},
TodoServices.REMOVE_COMPLETED_ITEMS,
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
test_entity.async_delete_todo_items.assert_not_called()
@ -1257,8 +1267,8 @@ async def test_remove_completed_items_service_raises(
with pytest.raises(HomeAssistantError, match="Ooops"):
await hass.services.async_call(
DOMAIN,
"remove_completed_items",
target={"entity_id": "todo.entity1"},
TodoServices.REMOVE_COMPLETED_ITEMS,
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
)
@ -1423,7 +1433,7 @@ async def test_list_todo_items_extended_fields(
DOMAIN,
"get_items",
{},
target={"entity_id": "todo.entity1"},
target={ATTR_ENTITY_ID: "todo.entity1"},
blocking=True,
return_response=True,
)

View File

@ -6,8 +6,17 @@ from unittest.mock import AsyncMock
import pytest
from todoist_api_python.models import Due, Task
from homeassistant.components.todo import DOMAIN as TODO_DOMAIN
from homeassistant.const import Platform
from homeassistant.components.todo import (
ATTR_DESCRIPTION,
ATTR_DUE_DATE,
ATTR_DUE_DATETIME,
ATTR_ITEM,
ATTR_RENAME,
ATTR_STATUS,
DOMAIN as TODO_DOMAIN,
TodoServices,
)
from homeassistant.const import ATTR_ENTITY_ID, Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_component import async_update_entity
@ -86,7 +95,7 @@ async def test_todo_item_state(
),
(
[],
{"due_date": "2023-11-18"},
{ATTR_DUE_DATE: "2023-11-18"},
[
make_api_task(
id="task-id-1",
@ -105,7 +114,7 @@ async def test_todo_item_state(
),
(
[],
{"due_datetime": "2023-11-18T06:30:00"},
{ATTR_DUE_DATETIME: "2023-11-18T06:30:00"},
[
make_api_task(
id="task-id-1",
@ -132,7 +141,7 @@ async def test_todo_item_state(
),
(
[],
{"description": "6-pack"},
{ATTR_DESCRIPTION: "6-pack"},
[
make_api_task(
id="task-id-1",
@ -173,9 +182,9 @@ async def test_add_todo_list_item(
await hass.services.async_call(
TODO_DOMAIN,
"add_item",
{"item": "Soda", **item_data},
target={"entity_id": "todo.name"},
TodoServices.ADD_ITEM,
{ATTR_ITEM: "Soda", **item_data},
target={ATTR_ENTITY_ID: "todo.name"},
blocking=True,
)
@ -190,9 +199,9 @@ async def test_add_todo_list_item(
result = await hass.services.async_call(
TODO_DOMAIN,
"get_items",
TodoServices.GET_ITEMS,
{},
target={"entity_id": "todo.name"},
target={ATTR_ENTITY_ID: "todo.name"},
blocking=True,
return_response=True,
)
@ -223,9 +232,9 @@ async def test_update_todo_item_status(
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
{"item": "task-id-1", "status": "completed"},
target={"entity_id": "todo.name"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "task-id-1", ATTR_STATUS: "completed"},
target={ATTR_ENTITY_ID: "todo.name"},
blocking=True,
)
assert api.close_task.called
@ -246,9 +255,9 @@ async def test_update_todo_item_status(
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
{"item": "task-id-1", "status": "needs_action"},
target={"entity_id": "todo.name"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "task-id-1", ATTR_STATUS: "needs_action"},
target={ATTR_ENTITY_ID: "todo.name"},
blocking=True,
)
assert api.reopen_task.called
@ -274,7 +283,7 @@ async def test_update_todo_item_status(
description="desc",
)
],
{"rename": "Milk"},
{ATTR_RENAME: "Milk"},
[
make_api_task(
id="task-id-1",
@ -298,7 +307,7 @@ async def test_update_todo_item_status(
),
(
[make_api_task(id="task-id-1", content="Soda", is_completed=False)],
{"due_date": "2023-11-18"},
{ATTR_DUE_DATE: "2023-11-18"},
[
make_api_task(
id="task-id-1",
@ -322,7 +331,7 @@ async def test_update_todo_item_status(
),
(
[make_api_task(id="task-id-1", content="Soda", is_completed=False)],
{"due_datetime": "2023-11-18T06:30:00"},
{ATTR_DUE_DATETIME: "2023-11-18T06:30:00"},
[
make_api_task(
id="task-id-1",
@ -351,7 +360,7 @@ async def test_update_todo_item_status(
),
(
[make_api_task(id="task-id-1", content="Soda", is_completed=False)],
{"description": "6-pack"},
{ATTR_DESCRIPTION: "6-pack"},
[
make_api_task(
id="task-id-1",
@ -382,7 +391,7 @@ async def test_update_todo_item_status(
is_completed=False,
)
],
{"description": None},
{ATTR_DESCRIPTION: None},
[
make_api_task(
id="task-id-1",
@ -415,7 +424,7 @@ async def test_update_todo_item_status(
due=Due(date="2024-01-01", is_recurring=True, string="every day"),
)
],
{"due_date": "2024-02-01"},
{ATTR_DUE_DATE: "2024-02-01"},
[
make_api_task(
id="task-id-1",
@ -472,9 +481,9 @@ async def test_update_todo_items(
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
{"item": "task-id-1", **update_data},
target={"entity_id": "todo.name"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "task-id-1", **update_data},
target={ATTR_ENTITY_ID: "todo.name"},
blocking=True,
)
assert api.update_task.called
@ -484,9 +493,9 @@ async def test_update_todo_items(
result = await hass.services.async_call(
TODO_DOMAIN,
"get_items",
TodoServices.GET_ITEMS,
{},
target={"entity_id": "todo.name"},
target={ATTR_ENTITY_ID: "todo.name"},
blocking=True,
return_response=True,
)
@ -519,9 +528,9 @@ async def test_remove_todo_item(
await hass.services.async_call(
TODO_DOMAIN,
"remove_item",
{"item": ["task-id-1", "task-id-2"]},
target={"entity_id": "todo.name"},
TodoServices.REMOVE_ITEM,
{ATTR_ITEM: ["task-id-1", "task-id-2"]},
target={ATTR_ENTITY_ID: "todo.name"},
blocking=True,
)
assert api.delete_task.call_count == 2
@ -575,9 +584,9 @@ async def test_subscribe(
]
await hass.services.async_call(
TODO_DOMAIN,
"update_item",
{"item": "Cheese", "rename": "Wine"},
target={"entity_id": "todo.name"},
TodoServices.UPDATE_ITEM,
{ATTR_ITEM: "Cheese", ATTR_RENAME: "Wine"},
target={ATTR_ENTITY_ID: "todo.name"},
blocking=True,
)