Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add remove intent function for shopping list component #126786

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion homeassistant/components/shopping_list/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,15 @@ async def async_add(
)
return item

async def remove_by_name(
self, name: str, context: Context | None = None
) -> dict[str, JsonValueType] | None:
"""Remove the first item with matching `name`."""
item = next((itm for itm in self.items if itm["name"] == name), None)
if item and isinstance(item["id"], str):
await self.async_remove(str(item["id"]), context)
return item

async def async_remove(
self, item_id: str, context: Context | None = None
) -> dict[str, JsonValueType] | None:
Expand All @@ -241,10 +250,11 @@ async def async_remove_items(
for item_id in item_ids:
_LOGGER.debug(
"Removing %s",
item_id,
)
if not (item := items_dict.pop(item_id, None)):
raise NoMatchingShoppingListItem(
"Item '{item_id}' not found in shopping list"
f"Item '{item_id}' not found in shopping list"
)
removed.append(item)
self.items = list(items_dict.values())
Expand Down
26 changes: 26 additions & 0 deletions homeassistant/components/shopping_list/intent.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@
from . import DOMAIN, EVENT_SHOPPING_LIST_UPDATED

INTENT_ADD_ITEM = "HassShoppingListAddItem"
INTENT_REMOVE_ITEM = "HassShoppingListRemoveItem"
INTENT_LAST_ITEMS = "HassShoppingListLastItems"


async def async_setup_intents(hass: HomeAssistant) -> None:
"""Set up the Shopping List intents."""
intent.async_register(hass, AddItemIntent())
intent.async_register(hass, RemoveItemIntent())
intent.async_register(hass, ListTopItemsIntent())


Expand All @@ -37,6 +39,30 @@ async def async_handle(self, intent_obj: intent.Intent) -> intent.IntentResponse
return response


class RemoveItemIntent(intent.IntentHandler):
"""Handle RemoveItem intents."""

intent_type = INTENT_REMOVE_ITEM
description = "Removes an item from the shopping list"
slot_schema = {"item": cv.string}
platforms = {DOMAIN}

async def async_handle(self, intent_obj: intent.Intent) -> intent.IntentResponse:
"""Handle the intent."""
slots = self.async_validate_slots(intent_obj.slots)
item = slots["item"]["value"]
result = await intent_obj.hass.data[DOMAIN].remove_by_name(item)

response = intent_obj.create_response()
intent_obj.hass.bus.async_fire(EVENT_SHOPPING_LIST_UPDATED)

if not result:
response.async_set_speech(f"{item} is not on your shopping list")
else:
response.async_set_speech(f"Removed {item} from your shopping list")
return response


class ListTopItemsIntent(intent.IntentHandler):
"""Handle AddItem intents."""

Expand Down
22 changes: 22 additions & 0 deletions tests/components/shopping_list/test_intent.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,28 @@
from homeassistant.helpers import intent


async def test_remove_item_intent(hass: HomeAssistant, sl_setup) -> None:
"""Test remove item."""
await intent.async_handle(
hass, "test", "HassShoppingListAddItem", {"item": {"value": "beer"}}
)

response = await intent.async_handle(
hass, "test", "HassShoppingListRemoveItem", {"item": {"value": "beer"}}
)

assert response.speech["plain"]["speech"] == "Removed beer from your shopping list"


async def test_remove_item_intent_not_found(hass: HomeAssistant, sl_setup) -> None:
"""Test remove item."""
response = await intent.async_handle(
hass, "test", "HassShoppingListRemoveItem", {"item": {"value": "beer"}}
)

assert response.speech["plain"]["speech"] == "beer is not on your shopping list"


async def test_recent_items_intent(hass: HomeAssistant, sl_setup) -> None:
"""Test recent items."""
await intent.async_handle(
Expand Down
Loading