Axis improve coverage binary tests (#111758)
* Parametrize binary sensor tests * Add test coverage to the different *guard apps * Add object analytics testspull/111800/head
parent
224f6dbdbb
commit
458391ee2b
|
@ -21,6 +21,8 @@ from homeassistant.const import (
|
|||
|
||||
from .const import (
|
||||
API_DISCOVERY_RESPONSE,
|
||||
APP_AOA_RESPONSE,
|
||||
APP_VMD4_RESPONSE,
|
||||
APPLICATIONS_LIST_RESPONSE,
|
||||
BASIC_DEVICE_INFO_RESPONSE,
|
||||
BRAND_RESPONSE,
|
||||
|
@ -36,7 +38,6 @@ from .const import (
|
|||
PTZ_RESPONSE,
|
||||
STREAM_PROFILES_RESPONSE,
|
||||
VIEW_AREAS_RESPONSE,
|
||||
VMD4_RESPONSE,
|
||||
)
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
|
@ -105,88 +106,90 @@ def default_request_fixture(
|
|||
"""Mock default Vapix requests responses."""
|
||||
|
||||
def __mock_default_requests(host):
|
||||
path = f"http://{host}:80"
|
||||
respx_mock(base_url=f"http://{host}:80")
|
||||
|
||||
if host != DEFAULT_HOST:
|
||||
respx.post(f"{path}/axis-cgi/apidiscovery.cgi").respond(
|
||||
respx.post("/axis-cgi/apidiscovery.cgi").respond(
|
||||
json=API_DISCOVERY_RESPONSE,
|
||||
)
|
||||
respx.post(f"{path}/axis-cgi/basicdeviceinfo.cgi").respond(
|
||||
respx.post("/axis-cgi/basicdeviceinfo.cgi").respond(
|
||||
json=BASIC_DEVICE_INFO_RESPONSE,
|
||||
)
|
||||
respx.post(f"{path}/axis-cgi/io/portmanagement.cgi").respond(
|
||||
respx.post("/axis-cgi/io/portmanagement.cgi").respond(
|
||||
json=port_management_payload,
|
||||
)
|
||||
respx.post(f"{path}/axis-cgi/mqtt/client.cgi").respond(
|
||||
respx.post("/axis-cgi/mqtt/client.cgi").respond(
|
||||
json=MQTT_CLIENT_RESPONSE,
|
||||
)
|
||||
respx.post(f"{path}/axis-cgi/streamprofile.cgi").respond(
|
||||
respx.post("/axis-cgi/streamprofile.cgi").respond(
|
||||
json=STREAM_PROFILES_RESPONSE,
|
||||
)
|
||||
respx.post(f"{path}/axis-cgi/viewarea/info.cgi").respond(
|
||||
json=VIEW_AREAS_RESPONSE
|
||||
)
|
||||
respx.post("/axis-cgi/viewarea/info.cgi").respond(json=VIEW_AREAS_RESPONSE)
|
||||
respx.post(
|
||||
f"{path}/axis-cgi/param.cgi",
|
||||
"/axis-cgi/param.cgi",
|
||||
data={"action": "list", "group": "root.Brand"},
|
||||
).respond(
|
||||
text=BRAND_RESPONSE,
|
||||
headers={"Content-Type": "text/plain"},
|
||||
)
|
||||
respx.post(
|
||||
f"{path}/axis-cgi/param.cgi",
|
||||
"/axis-cgi/param.cgi",
|
||||
data={"action": "list", "group": "root.Image"},
|
||||
).respond(
|
||||
text=IMAGE_RESPONSE,
|
||||
headers={"Content-Type": "text/plain"},
|
||||
)
|
||||
respx.post(
|
||||
f"{path}/axis-cgi/param.cgi",
|
||||
"/axis-cgi/param.cgi",
|
||||
data={"action": "list", "group": "root.Input"},
|
||||
).respond(
|
||||
text=PORTS_RESPONSE,
|
||||
headers={"Content-Type": "text/plain"},
|
||||
)
|
||||
respx.post(
|
||||
f"{path}/axis-cgi/param.cgi",
|
||||
"/axis-cgi/param.cgi",
|
||||
data={"action": "list", "group": "root.IOPort"},
|
||||
).respond(
|
||||
text=param_ports_payload,
|
||||
headers={"Content-Type": "text/plain"},
|
||||
)
|
||||
respx.post(
|
||||
f"{path}/axis-cgi/param.cgi",
|
||||
"/axis-cgi/param.cgi",
|
||||
data={"action": "list", "group": "root.Output"},
|
||||
).respond(
|
||||
text=PORTS_RESPONSE,
|
||||
headers={"Content-Type": "text/plain"},
|
||||
)
|
||||
respx.post(
|
||||
f"{path}/axis-cgi/param.cgi",
|
||||
"/axis-cgi/param.cgi",
|
||||
data={"action": "list", "group": "root.Properties"},
|
||||
).respond(
|
||||
text=param_properties_payload,
|
||||
headers={"Content-Type": "text/plain"},
|
||||
)
|
||||
respx.post(
|
||||
f"{path}/axis-cgi/param.cgi",
|
||||
"/axis-cgi/param.cgi",
|
||||
data={"action": "list", "group": "root.PTZ"},
|
||||
).respond(
|
||||
text=PTZ_RESPONSE,
|
||||
headers={"Content-Type": "text/plain"},
|
||||
)
|
||||
respx.post(
|
||||
f"{path}/axis-cgi/param.cgi",
|
||||
"/axis-cgi/param.cgi",
|
||||
data={"action": "list", "group": "root.StreamProfile"},
|
||||
).respond(
|
||||
text=STREAM_PROFILES_RESPONSE,
|
||||
headers={"Content-Type": "text/plain"},
|
||||
)
|
||||
respx.post(f"{path}/axis-cgi/applications/list.cgi").respond(
|
||||
respx.post("/axis-cgi/applications/list.cgi").respond(
|
||||
text=APPLICATIONS_LIST_RESPONSE,
|
||||
headers={"Content-Type": "text/xml"},
|
||||
)
|
||||
respx.post(f"{path}/local/vmd/control.cgi").respond(json=VMD4_RESPONSE)
|
||||
respx.post("/local/fenceguard/control.cgi").respond(json=APP_VMD4_RESPONSE)
|
||||
respx.post("/local/loiteringguard/control.cgi").respond(json=APP_VMD4_RESPONSE)
|
||||
respx.post("/local/motionguard/control.cgi").respond(json=APP_VMD4_RESPONSE)
|
||||
respx.post("/local/vmd/control.cgi").respond(json=APP_VMD4_RESPONSE)
|
||||
respx.post("/local/objectanalytics/control.cgi").respond(json=APP_AOA_RESPONSE)
|
||||
|
||||
return __mock_default_requests
|
||||
|
||||
|
|
|
@ -35,7 +35,11 @@ API_DISCOVERY_PORT_MANAGEMENT = {
|
|||
}
|
||||
|
||||
APPLICATIONS_LIST_RESPONSE = """<reply result="ok">
|
||||
<application Name="fenceguard" NiceName="AXIS Fence Guard" Vendor="Axis Communications" Version="2.2-6" ApplicationID="47775" License="None" Status="Running" ConfigurationPage="local/fenceguard/config.html" VendorHomePage="http://www.axis.com" LicenseName="Proprietary" />
|
||||
<application Name="loiteringguard" NiceName="AXIS Loitering Guard" Vendor="Axis Communications" Version="2.2-6" ApplicationID="46775" License="None" Status="Running" ConfigurationPage="local/loiteringguard/config.html" VendorHomePage="http://www.axis.com" LicenseName="Proprietary" />
|
||||
<application Name="motionguard" NiceName="AXIS Motion Guard" Vendor="Axis Communications" Version="2.2-6" ApplicationID="48170" License="None" Status="Running" ConfigurationPage="local/motionguard/config.html" VendorHomePage="http://www.axis.com" LicenseName="Proprietary" />
|
||||
<application Name="vmd" NiceName="AXIS Video Motion Detection" Vendor="Axis Communications" Version="4.2-0" ApplicationID="143440" License="None" Status="Running" ConfigurationPage="local/vmd/config.html" VendorHomePage="http://www.axis.com" />
|
||||
<application Name="objectanalytics" NiceName="AXIS Object Analytics" Vendor="Axis Communications" Version="1.0-0" ApplicationID="143440" License="None" Status="Running" ConfigurationPage="local/vmd/config.html" VendorHomePage="http://www.axis.com" />
|
||||
</reply>"""
|
||||
|
||||
BASIC_DEVICE_INFO_RESPONSE = {
|
||||
|
@ -95,7 +99,7 @@ PORT_MANAGEMENT_RESPONSE = {
|
|||
},
|
||||
}
|
||||
|
||||
VMD4_RESPONSE = {
|
||||
APP_VMD4_RESPONSE = {
|
||||
"apiVersion": "1.4",
|
||||
"method": "getConfiguration",
|
||||
"context": CONTEXT,
|
||||
|
@ -108,6 +112,46 @@ VMD4_RESPONSE = {
|
|||
},
|
||||
}
|
||||
|
||||
APP_AOA_RESPONSE = {
|
||||
"apiVersion": "1.0",
|
||||
"context": "Axis library",
|
||||
"data": {
|
||||
"devices": [{"id": 1, "rotation": 180, "type": "camera"}],
|
||||
"metadataOverlay": [],
|
||||
"perspectives": [],
|
||||
"scenarios": [
|
||||
{
|
||||
"devices": [{"id": 1}],
|
||||
"filters": [
|
||||
{"distance": 5, "type": "distanceSwayingObject"},
|
||||
{"time": 1, "type": "timeShortLivedLimit"},
|
||||
{"height": 3, "type": "sizePercentage", "width": 3},
|
||||
],
|
||||
"id": 1,
|
||||
"name": "Scenario 1",
|
||||
"objectClassifications": [],
|
||||
"perspectives": [],
|
||||
"presets": [],
|
||||
"triggers": [
|
||||
{
|
||||
"type": "includeArea",
|
||||
"vertices": [
|
||||
[-0.97, -0.97],
|
||||
[-0.97, 0.97],
|
||||
[0.97, 0.97],
|
||||
[0.97, -0.97],
|
||||
],
|
||||
}
|
||||
],
|
||||
"type": "motion",
|
||||
},
|
||||
],
|
||||
"status": {},
|
||||
},
|
||||
"method": "getConfiguration",
|
||||
}
|
||||
|
||||
|
||||
BRAND_RESPONSE = """root.Brand.Brand=AXIS
|
||||
root.Brand.ProdFullName=AXIS M1065-LW Network Camera
|
||||
root.Brand.ProdNbr=M1065-LW
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
"""Axis binary sensor platform tests."""
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.axis.const import DOMAIN as AXIS_DOMAIN
|
||||
from homeassistant.components.binary_sensor import (
|
||||
DOMAIN as BINARY_SENSOR_DOMAIN,
|
||||
|
@ -30,23 +32,10 @@ async def test_no_binary_sensors(hass: HomeAssistant, setup_config_entry) -> Non
|
|||
assert not hass.states.async_entity_ids(BINARY_SENSOR_DOMAIN)
|
||||
|
||||
|
||||
async def test_binary_sensors(
|
||||
async def test_unsupported_binary_sensors(
|
||||
hass: HomeAssistant, setup_config_entry, mock_rtsp_event
|
||||
) -> None:
|
||||
"""Test that sensors are loaded properly."""
|
||||
mock_rtsp_event(
|
||||
topic="tns1:Device/tnsaxis:Sensor/PIR",
|
||||
data_type="state",
|
||||
data_value="0",
|
||||
source_name="sensor",
|
||||
source_idx="0",
|
||||
)
|
||||
mock_rtsp_event(
|
||||
topic="tnsaxis:CameraApplicationPlatform/VMD/Camera1Profile1",
|
||||
data_type="active",
|
||||
data_value="1",
|
||||
)
|
||||
# Unsupported event
|
||||
"""Test that unsupported sensors are not loaded."""
|
||||
mock_rtsp_event(
|
||||
topic="tns1:PTZController/tnsaxis:PTZPresets/Channel_1",
|
||||
data_type="on_preset",
|
||||
|
@ -56,14 +45,104 @@ async def test_binary_sensors(
|
|||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(hass.states.async_entity_ids(BINARY_SENSOR_DOMAIN)) == 2
|
||||
assert len(hass.states.async_entity_ids(BINARY_SENSOR_DOMAIN)) == 0
|
||||
|
||||
pir = hass.states.get(f"{BINARY_SENSOR_DOMAIN}.{NAME}_pir_0")
|
||||
assert pir.state == STATE_OFF
|
||||
assert pir.name == f"{NAME} PIR 0"
|
||||
assert pir.attributes["device_class"] == BinarySensorDeviceClass.MOTION
|
||||
|
||||
vmd4 = hass.states.get(f"{BINARY_SENSOR_DOMAIN}.{NAME}_vmd4_profile_1")
|
||||
assert vmd4.state == STATE_ON
|
||||
assert vmd4.name == f"{NAME} VMD4 Profile 1"
|
||||
assert vmd4.attributes["device_class"] == BinarySensorDeviceClass.MOTION
|
||||
@pytest.mark.parametrize(
|
||||
("event", "entity"),
|
||||
[
|
||||
(
|
||||
{
|
||||
"topic": "tns1:Device/tnsaxis:Sensor/PIR",
|
||||
"data_type": "state",
|
||||
"data_value": "0",
|
||||
"source_name": "sensor",
|
||||
"source_idx": "0",
|
||||
},
|
||||
{
|
||||
"id": f"{BINARY_SENSOR_DOMAIN}.{NAME}_pir_0",
|
||||
"state": STATE_OFF,
|
||||
"name": f"{NAME} PIR 0",
|
||||
"device_class": BinarySensorDeviceClass.MOTION,
|
||||
},
|
||||
),
|
||||
(
|
||||
{
|
||||
"topic": "tnsaxis:CameraApplicationPlatform/FenceGuard/Camera1Profile1",
|
||||
"data_type": "active",
|
||||
"data_value": "1",
|
||||
},
|
||||
{
|
||||
"id": f"{BINARY_SENSOR_DOMAIN}.{NAME}_fence_guard_profile_1",
|
||||
"state": STATE_ON,
|
||||
"name": f"{NAME} Fence Guard Profile 1",
|
||||
"device_class": BinarySensorDeviceClass.MOTION,
|
||||
},
|
||||
),
|
||||
(
|
||||
{
|
||||
"topic": "tnsaxis:CameraApplicationPlatform/MotionGuard/Camera1Profile1",
|
||||
"data_type": "active",
|
||||
"data_value": "1",
|
||||
},
|
||||
{
|
||||
"id": f"{BINARY_SENSOR_DOMAIN}.{NAME}_motion_guard_profile_1",
|
||||
"state": STATE_ON,
|
||||
"name": f"{NAME} Motion Guard Profile 1",
|
||||
"device_class": BinarySensorDeviceClass.MOTION,
|
||||
},
|
||||
),
|
||||
(
|
||||
{
|
||||
"topic": "tnsaxis:CameraApplicationPlatform/LoiteringGuard/Camera1Profile1",
|
||||
"data_type": "active",
|
||||
"data_value": "1",
|
||||
},
|
||||
{
|
||||
"id": f"{BINARY_SENSOR_DOMAIN}.{NAME}_loitering_guard_profile_1",
|
||||
"state": STATE_ON,
|
||||
"name": f"{NAME} Loitering Guard Profile 1",
|
||||
"device_class": BinarySensorDeviceClass.MOTION,
|
||||
},
|
||||
),
|
||||
(
|
||||
{
|
||||
"topic": "tnsaxis:CameraApplicationPlatform/VMD/Camera1Profile1",
|
||||
"data_type": "active",
|
||||
"data_value": "1",
|
||||
},
|
||||
{
|
||||
"id": f"{BINARY_SENSOR_DOMAIN}.{NAME}_vmd4_profile_1",
|
||||
"state": STATE_ON,
|
||||
"name": f"{NAME} VMD4 Profile 1",
|
||||
"device_class": BinarySensorDeviceClass.MOTION,
|
||||
},
|
||||
),
|
||||
(
|
||||
{
|
||||
"topic": "tnsaxis:CameraApplicationPlatform/ObjectAnalytics/Device1Scenario1",
|
||||
"data_type": "active",
|
||||
"data_value": "1",
|
||||
},
|
||||
{
|
||||
"id": f"{BINARY_SENSOR_DOMAIN}.{NAME}_object_analytics_scenario_1",
|
||||
"state": STATE_ON,
|
||||
"name": f"{NAME} Object Analytics Scenario 1",
|
||||
"device_class": BinarySensorDeviceClass.MOTION,
|
||||
},
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_binary_sensors(
|
||||
hass: HomeAssistant, setup_config_entry, mock_rtsp_event, event, entity
|
||||
) -> None:
|
||||
"""Test that sensors are loaded properly."""
|
||||
mock_rtsp_event(**event)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(hass.states.async_entity_ids(BINARY_SENSOR_DOMAIN)) == 1
|
||||
|
||||
state = hass.states.get(entity["id"])
|
||||
assert state.state == entity["state"]
|
||||
assert state.name == entity["name"]
|
||||
assert state.attributes["device_class"] == entity["device_class"]
|
||||
|
|
Loading…
Reference in New Issue