From 44b33d45b1a6abc23f353b072eb1a9a42a69f935 Mon Sep 17 00:00:00 2001 From: Ian Richardson Date: Tue, 20 Nov 2018 05:44:17 -0600 Subject: [PATCH] Add websocket calls to shopping-list (#18392) * Add websocket calls to shopping-list Plan to deprecate API calls once shopping-list panel is removed from UI and replaced fully by Lovelace card * Address ci-bot issues * Fix violations * Address travis complaints * Address review comments * Update test_shopping_list.py --- homeassistant/components/shopping_list.py | 20 +++++++++++++ tests/components/test_shopping_list.py | 34 ++++++++++++++++++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/homeassistant/components/shopping_list.py b/homeassistant/components/shopping_list.py index f113561429a..45650ece621 100644 --- a/homeassistant/components/shopping_list.py +++ b/homeassistant/components/shopping_list.py @@ -13,6 +13,7 @@ from homeassistant.components.http.data_validator import ( from homeassistant.helpers import intent import homeassistant.helpers.config_validation as cv from homeassistant.util.json import load_json, save_json +from homeassistant.components import websocket_api ATTR_NAME = 'name' @@ -36,6 +37,13 @@ SERVICE_ITEM_SCHEMA = vol.Schema({ vol.Required(ATTR_NAME): vol.Any(None, cv.string) }) +WS_TYPE_SHOPPING_LIST_ITEMS = 'shopping_list/items' + +SCHEMA_WEBSOCKET_ITEMS = \ + websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({ + vol.Required('type'): WS_TYPE_SHOPPING_LIST_ITEMS + }) + @asyncio.coroutine def async_setup(hass, config): @@ -91,6 +99,11 @@ def async_setup(hass, config): yield from hass.components.frontend.async_register_built_in_panel( 'shopping-list', 'shopping_list', 'mdi:cart') + hass.components.websocket_api.async_register_command( + WS_TYPE_SHOPPING_LIST_ITEMS, + websocket_handle_items, + SCHEMA_WEBSOCKET_ITEMS) + return True @@ -256,3 +269,10 @@ class ClearCompletedItemsView(http.HomeAssistantView): hass.data[DOMAIN].async_clear_completed() hass.bus.async_fire(EVENT) return self.json_message('Cleared completed items.') + + +@callback +def websocket_handle_items(hass, connection, msg): + """Handle get shopping_list items.""" + connection.send_message(websocket_api.result_message( + msg['id'], hass.data[DOMAIN].items)) diff --git a/tests/components/test_shopping_list.py b/tests/components/test_shopping_list.py index 3131ae092a3..e64b9a5ae26 100644 --- a/tests/components/test_shopping_list.py +++ b/tests/components/test_shopping_list.py @@ -6,6 +6,7 @@ import pytest from homeassistant.bootstrap import async_setup_component from homeassistant.helpers import intent +from homeassistant.components.websocket_api.const import TYPE_RESULT @pytest.fixture(autouse=True) @@ -54,7 +55,7 @@ def test_recent_items_intent(hass): @asyncio.coroutine -def test_api_get_all(hass, aiohttp_client): +def test_deprecated_api_get_all(hass, aiohttp_client): """Test the API.""" yield from async_setup_component(hass, 'shopping_list', {}) @@ -77,6 +78,37 @@ def test_api_get_all(hass, aiohttp_client): assert not data[1]['complete'] +async def test_ws_get_items(hass, hass_ws_client): + """Test get shopping_list items websocket command.""" + await async_setup_component(hass, 'shopping_list', {}) + + await intent.async_handle( + hass, 'test', 'HassShoppingListAddItem', {'item': {'value': 'beer'}} + ) + await intent.async_handle( + hass, 'test', 'HassShoppingListAddItem', {'item': {'value': 'wine'}} + ) + + client = await hass_ws_client(hass) + + await client.send_json({ + 'id': 5, + 'type': 'shopping_list/items', + }) + msg = await client.receive_json() + assert msg['success'] is True + + assert msg['id'] == 5 + assert msg['type'] == TYPE_RESULT + assert msg['success'] + data = msg['result'] + assert len(data) == 2 + assert data[0]['name'] == 'beer' + assert not data[0]['complete'] + assert data[1]['name'] == 'wine' + assert not data[1]['complete'] + + @asyncio.coroutine def test_api_update(hass, aiohttp_client): """Test the API."""