Show how user input is malformed in the UI on error (#60057)

pull/60246/head
J. Nick Koston 2021-11-23 15:50:54 -06:00 committed by GitHub
parent 135778fe91
commit af51aeb6dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 80 additions and 2 deletions

View File

@ -110,8 +110,10 @@ class FlowManagerResourceView(_BaseFlowManagerView):
result = await self._flow_mgr.async_configure(flow_id, data)
except data_entry_flow.UnknownFlow:
return self.json_message("Invalid flow specified", HTTPStatus.NOT_FOUND)
except vol.Invalid:
return self.json_message("User input malformed", HTTPStatus.BAD_REQUEST)
except vol.Invalid as ex:
return self.json_message(
f"User input malformed: {ex}", HTTPStatus.BAD_REQUEST
)
result = self._prepare_result_json(result)

View File

@ -12,6 +12,7 @@ from homeassistant.components.config import config_entries
from homeassistant.config_entries import HANDLERS
from homeassistant.core import callback
from homeassistant.generated import config_flows
import homeassistant.helpers.config_validation as cv
from homeassistant.setup import async_setup_component
from tests.common import (
@ -689,6 +690,81 @@ async def test_two_step_options_flow(hass, client):
}
async def test_options_flow_with_invalid_data(hass, client):
"""Test an options flow with invalid_data."""
mock_integration(
hass, MockModule("test", async_setup_entry=AsyncMock(return_value=True))
)
class TestFlow(core_ce.ConfigFlow):
@staticmethod
@callback
def async_get_options_flow(config_entry):
class OptionsFlowHandler(data_entry_flow.FlowHandler):
async def async_step_init(self, user_input=None):
return self.async_show_form(
step_id="finish",
data_schema=vol.Schema(
{
vol.Required(
"choices", default=["invalid", "valid"]
): cv.multi_select({"valid": "Valid"})
}
),
)
async def async_step_finish(self, user_input=None):
return self.async_create_entry(
title="Enable disable", data=user_input
)
return OptionsFlowHandler()
MockConfigEntry(
domain="test",
entry_id="test1",
source="bla",
).add_to_hass(hass)
entry = hass.config_entries.async_entries()[0]
with patch.dict(HANDLERS, {"test": TestFlow}):
url = "/api/config/config_entries/options/flow"
resp = await client.post(url, json={"handler": entry.entry_id})
assert resp.status == HTTPStatus.OK
data = await resp.json()
flow_id = data.pop("flow_id")
assert data == {
"type": "form",
"handler": "test1",
"step_id": "finish",
"data_schema": [
{
"default": ["invalid", "valid"],
"name": "choices",
"options": {"valid": "Valid"},
"required": True,
"type": "multi_select",
}
],
"description_placeholders": None,
"errors": None,
"last_step": None,
}
with patch.dict(HANDLERS, {"test": TestFlow}):
resp = await client.post(
f"/api/config/config_entries/options/flow/{flow_id}",
json={"choices": ["valid", "invalid"]},
)
assert resp.status == HTTPStatus.BAD_REQUEST
data = await resp.json()
assert data == {
"message": "User input malformed: invalid is not a valid option for "
"dictionary value @ data['choices']"
}
async def test_update_prefrences(hass, hass_ws_client):
"""Test that we can update system options."""
assert await async_setup_component(hass, "config", {})