diff --git a/homeassistant/components/frontend/__init__.py b/homeassistant/components/frontend/__init__.py index d3d25255508..362c54fabbd 100644 --- a/homeassistant/components/frontend/__init__.py +++ b/homeassistant/components/frontend/__init__.py @@ -21,16 +21,14 @@ from homeassistant.components import websocket_api from homeassistant.config import find_config_file, load_yaml_config_file from homeassistant.const import CONF_NAME, EVENT_THEMES_UPDATED from homeassistant.core import callback -from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.translation import async_get_translations from homeassistant.loader import bind_hass -from homeassistant.util.yaml import load_yaml REQUIREMENTS = ['home-assistant-frontend==20180924.0'] DOMAIN = 'frontend' DEPENDENCIES = ['api', 'websocket_api', 'http', 'system_log', - 'auth', 'onboarding'] + 'auth', 'onboarding', 'lovelace'] CONF_THEMES = 'themes' CONF_EXTRA_HTML_URL = 'extra_html_url' @@ -108,10 +106,6 @@ SCHEMA_GET_TRANSLATIONS = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({ vol.Required('type'): WS_TYPE_GET_TRANSLATIONS, vol.Required('language'): str, }) -WS_TYPE_GET_LOVELACE_UI = 'frontend/lovelace_config' -SCHEMA_GET_LOVELACE_UI = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({ - vol.Required('type'): WS_TYPE_GET_LOVELACE_UI, -}) class Panel: @@ -208,9 +202,6 @@ async def async_setup(hass, config): hass.components.websocket_api.async_register_command( WS_TYPE_GET_TRANSLATIONS, websocket_get_translations, SCHEMA_GET_TRANSLATIONS) - hass.components.websocket_api.async_register_command( - WS_TYPE_GET_LOVELACE_UI, websocket_lovelace_config, - SCHEMA_GET_LOVELACE_UI) hass.http.register_view(ManifestJSONView) conf = config.get(DOMAIN, {}) @@ -530,28 +521,3 @@ def websocket_get_translations(hass, connection, msg): )) hass.async_add_job(send_translations()) - - -def websocket_lovelace_config(hass, connection, msg): - """Send lovelace UI config over websocket config.""" - async def send_exp_config(): - """Send lovelace frontend config.""" - error = None - try: - config = await hass.async_add_job( - load_yaml, hass.config.path('ui-lovelace.yaml')) - message = websocket_api.result_message( - msg['id'], config - ) - except FileNotFoundError: - error = ('file_not_found', - 'Could not find ui-lovelace.yaml in your config dir.') - except HomeAssistantError as err: - error = 'load_error', str(err) - - if error is not None: - message = websocket_api.error_message(msg['id'], *error) - - connection.send_message_outside(message) - - hass.async_add_job(send_exp_config()) diff --git a/homeassistant/components/lovelace/__init__.py b/homeassistant/components/lovelace/__init__.py new file mode 100644 index 00000000000..4336f50def4 --- /dev/null +++ b/homeassistant/components/lovelace/__init__.py @@ -0,0 +1,51 @@ +"""Lovelace UI.""" +import voluptuous as vol + +from homeassistant.components import websocket_api +from homeassistant.util.yaml import load_yaml +from homeassistant.exceptions import HomeAssistantError + +DOMAIN = 'lovelace' + +OLD_WS_TYPE_GET_LOVELACE_UI = 'frontend/lovelace_config' +WS_TYPE_GET_LOVELACE_UI = 'lovelace/config' +SCHEMA_GET_LOVELACE_UI = websocket_api.BASE_COMMAND_MESSAGE_SCHEMA.extend({ + vol.Required('type'): vol.Any(WS_TYPE_GET_LOVELACE_UI, + OLD_WS_TYPE_GET_LOVELACE_UI), +}) + + +async def async_setup(hass, config): + """Set up the Lovelace commands.""" + # Backwards compat. Added in 0.80. Remove after 0.85 + hass.components.websocket_api.async_register_command( + OLD_WS_TYPE_GET_LOVELACE_UI, websocket_lovelace_config, + SCHEMA_GET_LOVELACE_UI) + + hass.components.websocket_api.async_register_command( + WS_TYPE_GET_LOVELACE_UI, websocket_lovelace_config, + SCHEMA_GET_LOVELACE_UI) + + return True + + +@websocket_api.async_response +async def websocket_lovelace_config(hass, connection, msg): + """Send lovelace UI config over websocket config.""" + error = None + try: + config = await hass.async_add_job( + load_yaml, hass.config.path('ui-lovelace.yaml')) + message = websocket_api.result_message( + msg['id'], config + ) + except FileNotFoundError: + error = ('file_not_found', + 'Could not find ui-lovelace.yaml in your config dir.') + except HomeAssistantError as err: + error = 'load_error', str(err) + + if error is not None: + message = websocket_api.error_message(msg['id'], *error) + + connection.send_message_outside(message) diff --git a/tests/components/frontend/test_init.py b/tests/components/frontend/test_init.py index 17bf3d953ef..e4daf686bfe 100644 --- a/tests/components/frontend/test_init.py +++ b/tests/components/frontend/test_init.py @@ -5,7 +5,6 @@ from unittest.mock import patch import pytest -from homeassistant.exceptions import HomeAssistantError from homeassistant.setup import async_setup_component from homeassistant.components.frontend import ( DOMAIN, CONF_JS_VERSION, CONF_THEMES, CONF_EXTRA_HTML_URL, @@ -281,63 +280,6 @@ async def test_get_translations(hass, hass_ws_client): assert msg['result'] == {'resources': {'lang': 'nl'}} -async def test_lovelace_ui(hass, hass_ws_client): - """Test lovelace_ui command.""" - await async_setup_component(hass, 'frontend') - client = await hass_ws_client(hass) - - with patch('homeassistant.components.frontend.load_yaml', - return_value={'hello': 'world'}): - await client.send_json({ - 'id': 5, - 'type': 'frontend/lovelace_config', - }) - msg = await client.receive_json() - - assert msg['id'] == 5 - assert msg['type'] == wapi.TYPE_RESULT - assert msg['success'] - assert msg['result'] == {'hello': 'world'} - - -async def test_lovelace_ui_not_found(hass, hass_ws_client): - """Test lovelace_ui command cannot find file.""" - await async_setup_component(hass, 'frontend') - client = await hass_ws_client(hass) - - with patch('homeassistant.components.frontend.load_yaml', - side_effect=FileNotFoundError): - await client.send_json({ - 'id': 5, - 'type': 'frontend/lovelace_config', - }) - msg = await client.receive_json() - - assert msg['id'] == 5 - assert msg['type'] == wapi.TYPE_RESULT - assert msg['success'] is False - assert msg['error']['code'] == 'file_not_found' - - -async def test_lovelace_ui_load_err(hass, hass_ws_client): - """Test lovelace_ui command cannot find file.""" - await async_setup_component(hass, 'frontend') - client = await hass_ws_client(hass) - - with patch('homeassistant.components.frontend.load_yaml', - side_effect=HomeAssistantError): - await client.send_json({ - 'id': 5, - 'type': 'frontend/lovelace_config', - }) - msg = await client.receive_json() - - assert msg['id'] == 5 - assert msg['type'] == wapi.TYPE_RESULT - assert msg['success'] is False - assert msg['error']['code'] == 'load_error' - - async def test_auth_load(mock_http_client): """Test auth component loaded by default.""" resp = await mock_http_client.get('/auth/providers') diff --git a/tests/components/lovelace/__init__.py b/tests/components/lovelace/__init__.py new file mode 100644 index 00000000000..fea220146ca --- /dev/null +++ b/tests/components/lovelace/__init__.py @@ -0,0 +1 @@ +"""Tests for Lovelace.""" diff --git a/tests/components/lovelace/test_init.py b/tests/components/lovelace/test_init.py new file mode 100644 index 00000000000..3bb7c0675ea --- /dev/null +++ b/tests/components/lovelace/test_init.py @@ -0,0 +1,120 @@ +"""Test the Lovelace initialization.""" +from unittest.mock import patch + +from homeassistant.exceptions import HomeAssistantError +from homeassistant.setup import async_setup_component +from homeassistant.components import websocket_api as wapi + + +async def test_deprecated_lovelace_ui(hass, hass_ws_client): + """Test lovelace_ui command.""" + await async_setup_component(hass, 'lovelace') + client = await hass_ws_client(hass) + + with patch('homeassistant.components.lovelace.load_yaml', + return_value={'hello': 'world'}): + await client.send_json({ + 'id': 5, + 'type': 'frontend/lovelace_config', + }) + msg = await client.receive_json() + + assert msg['id'] == 5 + assert msg['type'] == wapi.TYPE_RESULT + assert msg['success'] + assert msg['result'] == {'hello': 'world'} + + +async def test_deprecated_lovelace_ui_not_found(hass, hass_ws_client): + """Test lovelace_ui command cannot find file.""" + await async_setup_component(hass, 'lovelace') + client = await hass_ws_client(hass) + + with patch('homeassistant.components.lovelace.load_yaml', + side_effect=FileNotFoundError): + await client.send_json({ + 'id': 5, + 'type': 'frontend/lovelace_config', + }) + msg = await client.receive_json() + + assert msg['id'] == 5 + assert msg['type'] == wapi.TYPE_RESULT + assert msg['success'] is False + assert msg['error']['code'] == 'file_not_found' + + +async def test_deprecated_lovelace_ui_load_err(hass, hass_ws_client): + """Test lovelace_ui command cannot find file.""" + await async_setup_component(hass, 'lovelace') + client = await hass_ws_client(hass) + + with patch('homeassistant.components.lovelace.load_yaml', + side_effect=HomeAssistantError): + await client.send_json({ + 'id': 5, + 'type': 'frontend/lovelace_config', + }) + msg = await client.receive_json() + + assert msg['id'] == 5 + assert msg['type'] == wapi.TYPE_RESULT + assert msg['success'] is False + assert msg['error']['code'] == 'load_error' + + +async def test_lovelace_ui(hass, hass_ws_client): + """Test lovelace_ui command.""" + await async_setup_component(hass, 'lovelace') + client = await hass_ws_client(hass) + + with patch('homeassistant.components.lovelace.load_yaml', + return_value={'hello': 'world'}): + await client.send_json({ + 'id': 5, + 'type': 'lovelace/config', + }) + msg = await client.receive_json() + + assert msg['id'] == 5 + assert msg['type'] == wapi.TYPE_RESULT + assert msg['success'] + assert msg['result'] == {'hello': 'world'} + + +async def test_lovelace_ui_not_found(hass, hass_ws_client): + """Test lovelace_ui command cannot find file.""" + await async_setup_component(hass, 'lovelace') + client = await hass_ws_client(hass) + + with patch('homeassistant.components.lovelace.load_yaml', + side_effect=FileNotFoundError): + await client.send_json({ + 'id': 5, + 'type': 'lovelace/config', + }) + msg = await client.receive_json() + + assert msg['id'] == 5 + assert msg['type'] == wapi.TYPE_RESULT + assert msg['success'] is False + assert msg['error']['code'] == 'file_not_found' + + +async def test_lovelace_ui_load_err(hass, hass_ws_client): + """Test lovelace_ui command cannot find file.""" + await async_setup_component(hass, 'lovelace') + client = await hass_ws_client(hass) + + with patch('homeassistant.components.lovelace.load_yaml', + side_effect=HomeAssistantError): + await client.send_json({ + 'id': 5, + 'type': 'lovelace/config', + }) + msg = await client.receive_json() + + assert msg['id'] == 5 + assert msg['type'] == wapi.TYPE_RESULT + assert msg['success'] is False + assert msg['error']['code'] == 'load_error'