Improve Axis tests following late review in SSDP PR (#45489)

This commit is contained in:
Robert Svensson 2021-01-24 14:14:49 +01:00 committed by GitHub
parent 4bb6911b76
commit b69d9860b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,6 +1,7 @@
"""Test Axis config flow."""
from unittest.mock import patch
import pytest
import respx
from homeassistant import data_entry_flow
@ -249,16 +250,66 @@ async def test_reauth_flow_update_configuration(hass):
assert device.password == "pass2"
async def test_dhcp_flow(hass):
"""Test that DHCP discovery for new devices work."""
@pytest.mark.parametrize(
"source,discovery_info",
[
(
SOURCE_DHCP,
{
HOSTNAME: f"axis-{MAC}",
IP_ADDRESS: DEFAULT_HOST,
MAC_ADDRESS: MAC,
},
),
(
SOURCE_SSDP,
{
"st": "urn:axis-com:service:BasicService:1",
"usn": f"uuid:Upnp-BasicDevice-1_0-{MAC}::urn:axis-com:service:BasicService:1",
"ext": "",
"server": "Linux/4.14.173-axis8, UPnP/1.0, Portable SDK for UPnP devices/1.8.7",
"deviceType": "urn:schemas-upnp-org:device:Basic:1",
"friendlyName": f"AXIS M1065-LW - {MAC}",
"manufacturer": "AXIS",
"manufacturerURL": "http://www.axis.com/",
"modelDescription": "AXIS M1065-LW Network Camera",
"modelName": "AXIS M1065-LW",
"modelNumber": "M1065-LW",
"modelURL": "http://www.axis.com/",
"serialNumber": MAC,
"UDN": f"uuid:Upnp-BasicDevice-1_0-{MAC}",
"serviceList": {
"service": {
"serviceType": "urn:axis-com:service:BasicService:1",
"serviceId": "urn:axis-com:serviceId:BasicServiceId",
"controlURL": "/upnp/control/BasicServiceId",
"eventSubURL": "/upnp/event/BasicServiceId",
"SCPDURL": "/scpd_basic.xml",
}
},
"presentationURL": f"http://{DEFAULT_HOST}:80/",
},
),
(
SOURCE_ZEROCONF,
{
"host": DEFAULT_HOST,
"port": 80,
"hostname": f"axis-{MAC.lower()}.local.",
"type": "_axis-video._tcp.local.",
"name": f"AXIS M1065-LW - {MAC}._axis-video._tcp.local.",
"properties": {
"_raw": {"macaddress": MAC.encode()},
"macaddress": MAC,
},
},
),
],
)
async def test_discovery_flow(hass, source: str, discovery_info: dict):
"""Test the different discovery flows for new devices work."""
result = await hass.config_entries.flow.async_init(
AXIS_DOMAIN,
data={
HOSTNAME: "axis-123",
IP_ADDRESS: "1.2.3.4",
MAC_ADDRESS: MAC,
},
context={"source": SOURCE_DHCP},
AXIS_DOMAIN, data=discovery_info, context={"source": source}
)
assert result["type"] == RESULT_TYPE_FORM
@ -290,332 +341,92 @@ async def test_dhcp_flow(hass):
assert result["data"][CONF_NAME] == "M1065-LW 0"
async def test_dhcp_flow_already_configured(hass):
"""Test that DHCP doesn't setup already configured devices."""
@pytest.mark.parametrize(
"source,discovery_info",
[
(
SOURCE_DHCP,
{
HOSTNAME: f"axis-{MAC}",
IP_ADDRESS: DEFAULT_HOST,
MAC_ADDRESS: MAC,
},
),
(
SOURCE_SSDP,
{
"friendlyName": f"AXIS M1065-LW - {MAC}",
"serialNumber": MAC,
"presentationURL": f"http://{DEFAULT_HOST}:80/",
},
),
(
SOURCE_ZEROCONF,
{
CONF_HOST: DEFAULT_HOST,
CONF_PORT: 80,
"name": f"AXIS M1065-LW - {MAC}._axis-video._tcp.local.",
"properties": {"macaddress": MAC},
},
),
],
)
async def test_discovered_device_already_configured(
hass, source: str, discovery_info: dict
):
"""Test that discovery doesn't setup already configured devices."""
config_entry = await setup_axis_integration(hass)
device = hass.data[AXIS_DOMAIN][config_entry.unique_id]
assert device.host == "1.2.3.4"
assert config_entry.data[CONF_HOST] == DEFAULT_HOST
result = await hass.config_entries.flow.async_init(
AXIS_DOMAIN,
data={
HOSTNAME: "axis-123",
IP_ADDRESS: "1.2.3.4",
MAC_ADDRESS: MAC,
},
context={"source": SOURCE_DHCP},
AXIS_DOMAIN, data=discovery_info, context={"source": source}
)
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "already_configured"
assert device.host == "1.2.3.4"
assert config_entry.data[CONF_HOST] == DEFAULT_HOST
async def test_dhcp_flow_updated_configuration(hass):
"""Test that DHCP update configuration with new parameters."""
config_entry = await setup_axis_integration(hass)
device = hass.data[AXIS_DOMAIN][config_entry.unique_id]
assert device.host == "1.2.3.4"
assert device.config_entry.data == {
CONF_HOST: "1.2.3.4",
CONF_PORT: 80,
CONF_USERNAME: "root",
CONF_PASSWORD: "pass",
CONF_MODEL: MODEL,
CONF_NAME: NAME,
}
with patch(
"homeassistant.components.axis.async_setup_entry",
return_value=True,
) as mock_setup_entry, respx.mock:
mock_default_vapix_requests(respx, "2.3.4.5")
result = await hass.config_entries.flow.async_init(
AXIS_DOMAIN,
data={
HOSTNAME: "axis-123",
@pytest.mark.parametrize(
"source,discovery_info,expected_port",
[
(
SOURCE_DHCP,
{
HOSTNAME: f"axis-{MAC}",
IP_ADDRESS: "2.3.4.5",
MAC_ADDRESS: MAC,
},
context={"source": SOURCE_DHCP},
)
await hass.async_block_till_done()
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "already_configured"
assert device.config_entry.data == {
CONF_HOST: "2.3.4.5",
CONF_PORT: 80,
CONF_USERNAME: "root",
CONF_PASSWORD: "pass",
CONF_MODEL: MODEL,
CONF_NAME: NAME,
}
assert len(mock_setup_entry.mock_calls) == 1
async def test_dhcp_flow_ignore_non_axis_device(hass):
"""Test that DHCP doesn't setup devices with link local addresses."""
result = await hass.config_entries.flow.async_init(
AXIS_DOMAIN,
data={
HOSTNAME: "axis-123",
IP_ADDRESS: "169.254.3.4",
MAC_ADDRESS: "01234567890",
},
context={"source": SOURCE_DHCP},
)
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "not_axis_device"
async def test_dhcp_flow_ignore_link_local_address(hass):
"""Test that DHCP doesn't setup devices with link local addresses."""
result = await hass.config_entries.flow.async_init(
AXIS_DOMAIN,
data={HOSTNAME: "axis-123", IP_ADDRESS: "169.254.3.4", MAC_ADDRESS: MAC},
context={"source": SOURCE_DHCP},
)
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "link_local_address"
async def test_ssdp_flow(hass):
"""Test that SSDP discovery for new devices work."""
result = await hass.config_entries.flow.async_init(
AXIS_DOMAIN,
data={
"st": "urn:axis-com:service:BasicService:1",
"usn": f"uuid:Upnp-BasicDevice-1_0-{MAC}::urn:axis-com:service:BasicService:1",
"ext": "",
"server": "Linux/4.14.173-axis8, UPnP/1.0, Portable SDK for UPnP devices/1.8.7",
"deviceType": "urn:schemas-upnp-org:device:Basic:1",
"friendlyName": f"AXIS M1065-LW - {MAC}",
"manufacturer": "AXIS",
"manufacturerURL": "http://www.axis.com/",
"modelDescription": "AXIS M1065-LW Network Camera",
"modelName": "AXIS M1065-LW",
"modelNumber": "M1065-LW",
"modelURL": "http://www.axis.com/",
"serialNumber": MAC,
"UDN": f"uuid:Upnp-BasicDevice-1_0-{MAC}",
"serviceList": {
"service": {
"serviceType": "urn:axis-com:service:BasicService:1",
"serviceId": "urn:axis-com:serviceId:BasicServiceId",
"controlURL": "/upnp/control/BasicServiceId",
"eventSubURL": "/upnp/event/BasicServiceId",
"SCPDURL": "/scpd_basic.xml",
}
},
"presentationURL": f"http://{DEFAULT_HOST}:80/",
},
context={"source": SOURCE_SSDP},
)
assert result["type"] == RESULT_TYPE_FORM
assert result["step_id"] == SOURCE_USER
with respx.mock:
mock_default_vapix_requests(respx)
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_HOST: "1.2.3.4",
CONF_USERNAME: "user",
CONF_PASSWORD: "pass",
CONF_PORT: 80,
},
)
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
assert result["title"] == f"M1065-LW - {MAC}"
assert result["data"] == {
CONF_HOST: "1.2.3.4",
CONF_USERNAME: "user",
CONF_PASSWORD: "pass",
CONF_PORT: 80,
CONF_MODEL: "M1065-LW",
CONF_NAME: "M1065-LW 0",
}
assert result["data"][CONF_NAME] == "M1065-LW 0"
async def test_ssdp_flow_already_configured(hass):
"""Test that SSDP doesn't setup already configured devices."""
config_entry = await setup_axis_integration(hass)
device = hass.data[AXIS_DOMAIN][config_entry.unique_id]
assert device.host == "1.2.3.4"
result = await hass.config_entries.flow.async_init(
AXIS_DOMAIN,
data={
"friendlyName": f"AXIS M1065-LW - {MAC}",
"serialNumber": MAC,
"presentationURL": "http://1.2.3.4:80/",
},
context={"source": SOURCE_SSDP},
)
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "already_configured"
assert device.host == "1.2.3.4"
async def test_ssdp_flow_updated_configuration(hass):
"""Test that SSDP update configuration with new parameters."""
config_entry = await setup_axis_integration(hass)
device = hass.data[AXIS_DOMAIN][config_entry.unique_id]
assert device.host == "1.2.3.4"
assert device.config_entry.data == {
CONF_HOST: "1.2.3.4",
CONF_PORT: 80,
CONF_USERNAME: "root",
CONF_PASSWORD: "pass",
CONF_MODEL: MODEL,
CONF_NAME: NAME,
}
with patch(
"homeassistant.components.axis.async_setup_entry",
return_value=True,
) as mock_setup_entry, respx.mock:
mock_default_vapix_requests(respx, "2.3.4.5")
result = await hass.config_entries.flow.async_init(
AXIS_DOMAIN,
data={
80,
),
(
SOURCE_SSDP,
{
"friendlyName": f"AXIS M1065-LW - {MAC}",
"serialNumber": MAC,
"presentationURL": "http://2.3.4.5:8080/",
},
context={"source": SOURCE_SSDP},
)
await hass.async_block_till_done()
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "already_configured"
assert device.config_entry.data == {
CONF_HOST: "2.3.4.5",
CONF_PORT: 8080,
CONF_USERNAME: "root",
CONF_PASSWORD: "pass",
CONF_MODEL: MODEL,
CONF_NAME: NAME,
}
assert len(mock_setup_entry.mock_calls) == 1
async def test_ssdp_flow_ignore_non_axis_device(hass):
"""Test that SSDP doesn't setup devices with link local addresses."""
result = await hass.config_entries.flow.async_init(
AXIS_DOMAIN,
data={
"friendlyName": f"AXIS M1065-LW - {MAC}",
"serialNumber": "01234567890",
"presentationURL": "http://1.2.3.4:80/",
},
context={"source": SOURCE_SSDP},
)
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "not_axis_device"
async def test_ssdp_flow_ignore_link_local_address(hass):
"""Test that SSDP doesn't setup devices with link local addresses."""
result = await hass.config_entries.flow.async_init(
AXIS_DOMAIN,
data={
"friendlyName": f"AXIS M1065-LW - {MAC}",
"serialNumber": MAC,
"presentationURL": "http://169.254.3.4:80/",
},
context={"source": SOURCE_SSDP},
)
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "link_local_address"
async def test_zeroconf_flow(hass):
"""Test that zeroconf discovery for new devices work."""
result = await hass.config_entries.flow.async_init(
AXIS_DOMAIN,
data={
"host": "1.2.3.4",
"port": 80,
"hostname": f"axis-{MAC.lower()}.local.",
"type": "_axis-video._tcp.local.",
"name": f"AXIS M1065-L - {MAC}._axis-video._tcp.local.",
"properties": {
"_raw": {"macaddress": MAC.encode()},
"macaddress": MAC,
8080,
),
(
SOURCE_ZEROCONF,
{
CONF_HOST: "2.3.4.5",
CONF_PORT: 8080,
"name": f"AXIS M1065-LW - {MAC}._axis-video._tcp.local.",
"properties": {"macaddress": MAC},
},
},
context={"source": SOURCE_ZEROCONF},
)
assert result["type"] == RESULT_TYPE_FORM
assert result["step_id"] == SOURCE_USER
with respx.mock:
mock_default_vapix_requests(respx)
result = await hass.config_entries.flow.async_configure(
result["flow_id"],
user_input={
CONF_HOST: "1.2.3.4",
CONF_USERNAME: "user",
CONF_PASSWORD: "pass",
CONF_PORT: 80,
},
)
assert result["type"] == RESULT_TYPE_CREATE_ENTRY
assert result["title"] == f"M1065-LW - {MAC}"
assert result["data"] == {
CONF_HOST: "1.2.3.4",
CONF_USERNAME: "user",
CONF_PASSWORD: "pass",
CONF_PORT: 80,
CONF_MODEL: "M1065-LW",
CONF_NAME: "M1065-LW 0",
}
assert result["data"][CONF_NAME] == "M1065-LW 0"
async def test_zeroconf_flow_already_configured(hass):
"""Test that zeroconf doesn't setup already configured devices."""
8080,
),
],
)
async def test_discovery_flow_updated_configuration(
hass, source: str, discovery_info: dict, expected_port: int
):
"""Test that discovery flow update configuration with new parameters."""
config_entry = await setup_axis_integration(hass)
device = hass.data[AXIS_DOMAIN][config_entry.unique_id]
assert device.host == "1.2.3.4"
result = await hass.config_entries.flow.async_init(
AXIS_DOMAIN,
data={
CONF_HOST: "1.2.3.4",
CONF_PORT: 80,
"name": "name",
"properties": {"macaddress": MAC},
},
context={"source": SOURCE_ZEROCONF},
)
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "already_configured"
assert device.host == "1.2.3.4"
async def test_zeroconf_flow_updated_configuration(hass):
"""Test that zeroconf update configuration with new parameters."""
config_entry = await setup_axis_integration(hass)
device = hass.data[AXIS_DOMAIN][config_entry.unique_id]
assert device.host == "1.2.3.4"
assert device.config_entry.data == {
CONF_HOST: "1.2.3.4",
assert config_entry.data == {
CONF_HOST: DEFAULT_HOST,
CONF_PORT: 80,
CONF_USERNAME: "root",
CONF_PASSWORD: "pass",
@ -629,22 +440,15 @@ async def test_zeroconf_flow_updated_configuration(hass):
) as mock_setup_entry, respx.mock:
mock_default_vapix_requests(respx, "2.3.4.5")
result = await hass.config_entries.flow.async_init(
AXIS_DOMAIN,
data={
CONF_HOST: "2.3.4.5",
CONF_PORT: 8080,
"name": "name",
"properties": {"macaddress": MAC},
},
context={"source": SOURCE_ZEROCONF},
AXIS_DOMAIN, data=discovery_info, context={"source": source}
)
await hass.async_block_till_done()
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "already_configured"
assert device.config_entry.data == {
assert config_entry.data == {
CONF_HOST: "2.3.4.5",
CONF_PORT: 8080,
CONF_PORT: expected_port,
CONF_USERNAME: "root",
CONF_PASSWORD: "pass",
CONF_MODEL: MODEL,
@ -653,34 +457,80 @@ async def test_zeroconf_flow_updated_configuration(hass):
assert len(mock_setup_entry.mock_calls) == 1
async def test_zeroconf_flow_ignore_non_axis_device(hass):
"""Test that zeroconf doesn't setup devices with link local addresses."""
@pytest.mark.parametrize(
"source,discovery_info",
[
(
SOURCE_DHCP,
{
HOSTNAME: "",
IP_ADDRESS: "",
MAC_ADDRESS: "01234567890",
},
),
(
SOURCE_SSDP,
{
"friendlyName": "",
"serialNumber": "01234567890",
"presentationURL": "",
},
),
(
SOURCE_ZEROCONF,
{
CONF_HOST: "",
CONF_PORT: 0,
"name": "",
"properties": {"macaddress": "01234567890"},
},
),
],
)
async def test_discovery_flow_ignore_non_axis_device(
hass, source: str, discovery_info: dict
):
"""Test that discovery flow ignores devices with non Axis OUI."""
result = await hass.config_entries.flow.async_init(
AXIS_DOMAIN,
data={
CONF_HOST: "169.254.3.4",
CONF_PORT: 80,
"name": "",
"properties": {"macaddress": "01234567890"},
},
context={"source": SOURCE_ZEROCONF},
AXIS_DOMAIN, data=discovery_info, context={"source": source}
)
assert result["type"] == RESULT_TYPE_ABORT
assert result["reason"] == "not_axis_device"
async def test_zeroconf_flow_ignore_link_local_address(hass):
"""Test that zeroconf doesn't setup devices with link local addresses."""
@pytest.mark.parametrize(
"source,discovery_info",
[
(
SOURCE_DHCP,
{HOSTNAME: f"axis-{MAC}", IP_ADDRESS: "169.254.3.4", MAC_ADDRESS: MAC},
),
(
SOURCE_SSDP,
{
"friendlyName": f"AXIS M1065-LW - {MAC}",
"serialNumber": MAC,
"presentationURL": "http://169.254.3.4:80/",
},
),
(
SOURCE_ZEROCONF,
{
CONF_HOST: "169.254.3.4",
CONF_PORT: 80,
"name": f"AXIS M1065-LW - {MAC}._axis-video._tcp.local.",
"properties": {"macaddress": MAC},
},
),
],
)
async def test_discovery_flow_ignore_link_local_address(
hass, source: str, discovery_info: dict
):
"""Test that discovery flow ignores devices with link local addresses."""
result = await hass.config_entries.flow.async_init(
AXIS_DOMAIN,
data={
CONF_HOST: "169.254.3.4",
CONF_PORT: 80,
"name": "",
"properties": {"macaddress": MAC},
},
context={"source": SOURCE_ZEROCONF},
AXIS_DOMAIN, data=discovery_info, context={"source": source}
)
assert result["type"] == RESULT_TYPE_ABORT