diff --git a/tests/components/caldav/test_todo.py b/tests/components/caldav/test_todo.py index 66f6e975453..69a49e0fcbe 100644 --- a/tests/components/caldav/test_todo.py +++ b/tests/components/caldav/test_todo.py @@ -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, ) diff --git a/tests/components/google_tasks/test_todo.py b/tests/components/google_tasks/test_todo.py index afbaabe5cd0..b0ee135d4a9 100644 --- a/tests/components/google_tasks/test_todo.py +++ b/tests/components/google_tasks/test_todo.py @@ -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, ) diff --git a/tests/components/local_todo/test_todo.py b/tests/components/local_todo/test_todo.py index e54ee925437..253adebd757 100644 --- a/tests/components/local_todo/test_todo.py +++ b/tests/components/local_todo/test_todo.py @@ -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, ) diff --git a/tests/components/mealie/test_todo.py b/tests/components/mealie/test_todo.py index 2b65d8b468f..3ed33c78570 100644 --- a/tests/components/mealie/test_todo.py +++ b/tests/components/mealie/test_todo.py @@ -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, ) diff --git a/tests/components/ourgroceries/test_todo.py b/tests/components/ourgroceries/test_todo.py index 672e2e14447..d364881b624 100644 --- a/tests/components/ourgroceries/test_todo.py +++ b/tests/components/ourgroceries/test_todo.py @@ -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 diff --git a/tests/components/picnic/test_todo.py b/tests/components/picnic/test_todo.py index cdd30967058..2db5bc90159 100644 --- a/tests/components/picnic/test_todo.py +++ b/tests/components/picnic/test_todo.py @@ -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, ) diff --git a/tests/components/shopping_list/test_todo.py b/tests/components/shopping_list/test_todo.py index 173544d0be2..f10479adf6c 100644 --- a/tests/components/shopping_list/test_todo.py +++ b/tests/components/shopping_list/test_todo.py @@ -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, ) diff --git a/tests/components/todo/test_init.py b/tests/components/todo/test_init.py index cbb61434f1a..b62505b14b4 100644 --- a/tests/components/todo/test_init.py +++ b/tests/components/todo/test_init.py @@ -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, ) diff --git a/tests/components/todoist/test_todo.py b/tests/components/todoist/test_todo.py index 2aabfcc5755..1c2da67fb02 100644 --- a/tests/components/todoist/test_todo.py +++ b/tests/components/todoist/test_todo.py @@ -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, )