Catch IPPParseError during config flow (#33769)

* Update config_flow.py

* Update strings.json

* Update config_flow.py

* squash.
This commit is contained in:
Chris Talkington 2020-04-07 11:32:43 -05:00 committed by GitHub
parent 60eb488d0c
commit 1f7803c541
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 59 additions and 7 deletions

View file

@ -2,7 +2,13 @@
import logging import logging
from typing import Any, Dict, Optional from typing import Any, Dict, Optional
from pyipp import IPP, IPPConnectionError, IPPConnectionUpgradeRequired from pyipp import (
IPP,
IPPConnectionError,
IPPConnectionUpgradeRequired,
IPPParseError,
IPPResponseError,
)
import voluptuous as vol import voluptuous as vol
from homeassistant.config_entries import CONN_CLASS_LOCAL_POLL, ConfigFlow from homeassistant.config_entries import CONN_CLASS_LOCAL_POLL, ConfigFlow
@ -63,8 +69,12 @@ class IPPFlowHandler(ConfigFlow, domain=DOMAIN):
info = await validate_input(self.hass, user_input) info = await validate_input(self.hass, user_input)
except IPPConnectionUpgradeRequired: except IPPConnectionUpgradeRequired:
return self._show_setup_form({"base": "connection_upgrade"}) return self._show_setup_form({"base": "connection_upgrade"})
except IPPConnectionError: except (IPPConnectionError, IPPResponseError):
return self._show_setup_form({"base": "connection_error"}) return self._show_setup_form({"base": "connection_error"})
except IPPParseError:
_LOGGER.exception("IPP Parse Error")
return self.async_abort(reason="parse_error")
user_input[CONF_UUID] = info[CONF_UUID] user_input[CONF_UUID] = info[CONF_UUID]
await self.async_set_unique_id(user_input[CONF_UUID]) await self.async_set_unique_id(user_input[CONF_UUID])
@ -100,8 +110,11 @@ class IPPFlowHandler(ConfigFlow, domain=DOMAIN):
info = await validate_input(self.hass, self.discovery_info) info = await validate_input(self.hass, self.discovery_info)
except IPPConnectionUpgradeRequired: except IPPConnectionUpgradeRequired:
return self.async_abort(reason="connection_upgrade") return self.async_abort(reason="connection_upgrade")
except IPPConnectionError: except (IPPConnectionError, IPPResponseError):
return self.async_abort(reason="connection_error") return self.async_abort(reason="connection_error")
except IPPParseError:
_LOGGER.exception("IPP Parse Error")
return self.async_abort(reason="parse_error")
self.discovery_info[CONF_UUID] = info[CONF_UUID] self.discovery_info[CONF_UUID] = info[CONF_UUID]

View file

@ -2,7 +2,7 @@
"domain": "ipp", "domain": "ipp",
"name": "Internet Printing Protocol (IPP)", "name": "Internet Printing Protocol (IPP)",
"documentation": "https://www.home-assistant.io/integrations/ipp", "documentation": "https://www.home-assistant.io/integrations/ipp",
"requirements": ["pyipp==0.8.3"], "requirements": ["pyipp==0.9.0"],
"codeowners": ["@ctalkington"], "codeowners": ["@ctalkington"],
"config_flow": true, "config_flow": true,
"quality_scale": "platinum", "quality_scale": "platinum",

View file

@ -26,7 +26,8 @@
"abort": { "abort": {
"already_configured": "This printer is already configured.", "already_configured": "This printer is already configured.",
"connection_error": "Failed to connect to printer.", "connection_error": "Failed to connect to printer.",
"connection_upgrade": "Failed to connect to printer due to connection upgrade being required." "connection_upgrade": "Failed to connect to printer due to connection upgrade being required.",
"parse_error": "Failed to parse response from printer."
} }
} }
} }

View file

@ -1341,7 +1341,7 @@ pyintesishome==1.7.1
pyipma==2.0.5 pyipma==2.0.5
# homeassistant.components.ipp # homeassistant.components.ipp
pyipp==0.8.3 pyipp==0.9.0
# homeassistant.components.iqvia # homeassistant.components.iqvia
pyiqvia==0.2.1 pyiqvia==0.2.1

View file

@ -524,7 +524,7 @@ pyicloud==0.9.6.1
pyipma==2.0.5 pyipma==2.0.5
# homeassistant.components.ipp # homeassistant.components.ipp
pyipp==0.8.3 pyipp==0.9.0
# homeassistant.components.iqvia # homeassistant.components.iqvia
pyiqvia==0.2.1 pyiqvia==0.2.1

View file

@ -134,6 +134,44 @@ async def test_zeroconf_connection_upgrade_required(
assert result["reason"] == "connection_upgrade" assert result["reason"] == "connection_upgrade"
async def test_user_parse_error(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""Test we abort user flow on IPP parse error."""
aioclient_mock.post(
"http://192.168.1.31:631/ipp/print",
content="BAD",
headers={"Content-Type": "application/ipp"},
)
user_input = MOCK_USER_INPUT.copy()
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_USER}, data=user_input,
)
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "parse_error"
async def test_zeroconf_parse_error(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None:
"""Test we abort zeroconf flow on IPP parse error."""
aioclient_mock.post(
"http://192.168.1.31:631/ipp/print",
content="BAD",
headers={"Content-Type": "application/ipp"},
)
discovery_info = MOCK_ZEROCONF_IPP_SERVICE_INFO.copy()
result = await hass.config_entries.flow.async_init(
DOMAIN, context={"source": SOURCE_ZEROCONF}, data=discovery_info,
)
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "parse_error"
async def test_user_device_exists_abort( async def test_user_device_exists_abort(
hass: HomeAssistant, aioclient_mock: AiohttpClientMocker hass: HomeAssistant, aioclient_mock: AiohttpClientMocker
) -> None: ) -> None: