Add XML support to RESTful binary sensor (#110062)

* Add XML support to RESTful binary sensor

* Add test for binary sensor with XML input data

* Address mypy validation results by handling None returns

* Use proper incorrect XML instead of blank

* Change failure condition to match the behavior of the library method

* Change error handling for bad XML to expect ExpatError

* Parametrize bad XML test to catch both empty and invalid XML

* Move exception handling out of the shared method

---------

Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
Oleg Kurapov 2024-05-30 16:29:50 +02:00 committed by GitHub
parent 4b95ea864f
commit 2cc38b426a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 107 additions and 18 deletions

View file

@ -362,6 +362,77 @@ async def test_setup_get_on(hass: HomeAssistant) -> None:
assert state.state == STATE_ON
@respx.mock
async def test_setup_get_xml(hass: HomeAssistant) -> None:
"""Test setup with valid xml configuration."""
respx.get("http://localhost").respond(
status_code=HTTPStatus.OK,
headers={"content-type": "text/xml"},
content="<dog>1</dog>",
)
assert await async_setup_component(
hass,
BINARY_SENSOR_DOMAIN,
{
BINARY_SENSOR_DOMAIN: {
"platform": DOMAIN,
"resource": "http://localhost",
"method": "GET",
"value_template": "{{ value_json.dog }}",
"name": "foo",
"verify_ssl": "true",
"timeout": 30,
}
},
)
await hass.async_block_till_done()
assert len(hass.states.async_all(BINARY_SENSOR_DOMAIN)) == 1
state = hass.states.get("binary_sensor.foo")
assert state.state == STATE_ON
@respx.mock
@pytest.mark.parametrize(
("content"),
[
(""),
("<open></close>"),
],
)
async def test_setup_get_bad_xml(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture, content: str
) -> None:
"""Test attributes get extracted from a XML result with bad xml."""
respx.get("http://localhost").respond(
status_code=HTTPStatus.OK,
headers={"content-type": "text/xml"},
content=content,
)
assert await async_setup_component(
hass,
BINARY_SENSOR_DOMAIN,
{
BINARY_SENSOR_DOMAIN: {
"platform": DOMAIN,
"resource": "http://localhost",
"method": "GET",
"value_template": "{{ value_json.toplevel.master_value }}",
"name": "foo",
"verify_ssl": "true",
"timeout": 30,
}
},
)
await hass.async_block_till_done()
assert len(hass.states.async_all(BINARY_SENSOR_DOMAIN)) == 1
state = hass.states.get("binary_sensor.foo")
assert state.state == STATE_OFF
assert "REST xml result could not be parsed" in caplog.text
@respx.mock
async def test_setup_with_exception(hass: HomeAssistant) -> None:
"""Test setup with exception."""

View file

@ -868,15 +868,25 @@ async def test_update_with_application_xml_convert_json_attrs_with_jsonattr_temp
@respx.mock
@pytest.mark.parametrize(
("content", "error_message"),
[
("", "Empty reply"),
("<open></close>", "Erroneous JSON"),
],
)
async def test_update_with_xml_convert_bad_xml(
hass: HomeAssistant, caplog: pytest.LogCaptureFixture
hass: HomeAssistant,
caplog: pytest.LogCaptureFixture,
content: str,
error_message: str,
) -> None:
"""Test attributes get extracted from a XML result with bad xml."""
respx.get("http://localhost").respond(
status_code=HTTPStatus.OK,
headers={"content-type": "text/xml"},
content="",
content=content,
)
assert await async_setup_component(
hass,
@ -901,7 +911,7 @@ async def test_update_with_xml_convert_bad_xml(
assert state.state == STATE_UNKNOWN
assert "REST xml result could not be parsed" in caplog.text
assert "Empty reply" in caplog.text
assert error_message in caplog.text
@respx.mock