From 93a800a6121f32eb2af9b64e93b1fd0117c81785 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Tue, 20 Aug 2019 00:17:52 -0700 Subject: [PATCH] Convert progress API to WS (#26082) --- .../components/config/config_entries.py | 39 +++++++++++-------- .../components/config/test_config_entries.py | 36 ++++++++++------- 2 files changed, 43 insertions(+), 32 deletions(-) diff --git a/homeassistant/components/config/config_entries.py b/homeassistant/components/config/config_entries.py index 90ae92cae84..b21991a8479 100644 --- a/homeassistant/components/config/config_entries.py +++ b/homeassistant/components/config/config_entries.py @@ -1,4 +1,5 @@ """Http views to control the config manager.""" +import aiohttp.web_exceptions import voluptuous as vol from homeassistant import config_entries, data_entry_flow @@ -28,6 +29,7 @@ async def async_setup(hass): OptionManagerFlowResourceView(hass.config_entries.options.flow) ) + hass.components.websocket_api.async_register_command(config_entries_progress) hass.components.websocket_api.async_register_command(system_options_list) hass.components.websocket_api.async_register_command(system_options_update) @@ -116,23 +118,8 @@ class ConfigManagerFlowIndexView(FlowManagerIndexView): name = "api:config:config_entries:flow" async def get(self, request): - """List flows that are in progress but not started by a user. - - Example of a non-user initiated flow is a discovered Hue hub that - requires user interaction to finish setup. - """ - if not request["hass_user"].is_admin: - raise Unauthorized(perm_category=CAT_CONFIG_ENTRIES, permission="add") - - hass = request.app["hass"] - - return self.json( - [ - flw - for flw in hass.config_entries.flow.async_progress() - if flw["context"]["source"] != config_entries.SOURCE_USER - ] - ) + """Not implemented.""" + raise aiohttp.web_exceptions.HTTPMethodNotAllowed("GET", ["POST"]) # pylint: disable=arguments-differ async def post(self, request): @@ -241,6 +228,24 @@ class OptionManagerFlowResourceView(FlowManagerResourceView): return await super().post(request, flow_id) +@websocket_api.require_admin +@websocket_api.websocket_command({"type": "config_entries/flow/progress"}) +def config_entries_progress(hass, connection, msg): + """List flows that are in progress but not started by a user. + + Example of a non-user initiated flow is a discovered Hue hub that + requires user interaction to finish setup. + """ + connection.send_result( + msg["id"], + [ + flw + for flw in hass.config_entries.flow.async_progress() + if flw["context"]["source"] != config_entries.SOURCE_USER + ], + ) + + @websocket_api.require_admin @websocket_api.async_response @websocket_api.websocket_command( diff --git a/tests/components/config/test_config_entries.py b/tests/components/config/test_config_entries.py index f0815e7ede8..3d22d3ac1a7 100644 --- a/tests/components/config/test_config_entries.py +++ b/tests/components/config/test_config_entries.py @@ -373,40 +373,46 @@ async def test_continue_flow_unauth(hass, client, hass_admin_user): assert resp.status == 401 -@asyncio.coroutine -def test_get_progress_index(hass, client): +async def test_get_progress_index(hass, hass_ws_client): """Test querying for the flows that are in progress.""" + assert await async_setup_component(hass, "config", {}) mock_entity_platform(hass, "config_flow.test", None) + ws_client = await hass_ws_client(hass) class TestFlow(core_ce.ConfigFlow): VERSION = 5 - @asyncio.coroutine - def async_step_hassio(self, info): - return (yield from self.async_step_account()) + async def async_step_hassio(self, info): + return await self.async_step_account() - @asyncio.coroutine - def async_step_account(self, user_input=None): + async def async_step_account(self, user_input=None): return self.async_show_form(step_id="account") with patch.dict(HANDLERS, {"test": TestFlow}): - form = yield from hass.config_entries.flow.async_init( + form = await hass.config_entries.flow.async_init( "test", context={"source": "hassio"} ) - resp = yield from client.get("/api/config/config_entries/flow") - assert resp.status == 200 - data = yield from resp.json() - assert data == [ + await ws_client.send_json({"id": 5, "type": "config_entries/flow/progress"}) + response = await ws_client.receive_json() + + assert response["success"] + assert response["result"] == [ {"flow_id": form["flow_id"], "handler": "test", "context": {"source": "hassio"}} ] -async def test_get_progress_index_unauth(hass, client, hass_admin_user): +async def test_get_progress_index_unauth(hass, hass_ws_client, hass_admin_user): """Test we can't get flows that are in progress.""" + assert await async_setup_component(hass, "config", {}) hass_admin_user.groups = [] - resp = await client.get("/api/config/config_entries/flow") - assert resp.status == 401 + ws_client = await hass_ws_client(hass) + + await ws_client.send_json({"id": 5, "type": "config_entries/flow/progress"}) + response = await ws_client.receive_json() + + assert not response["success"] + assert response["error"]["code"] == "unauthorized" @asyncio.coroutine