Axis - Remove manual configuration and legacy config file import (#30365)

* Remove manual configuration and legacy config file import

* Remove unused imports in tests after rebase
This commit is contained in:
Robert Svensson 2020-01-03 21:25:31 +01:00 committed by Andrew Sayre
parent 6387a50697
commit bb55606d29
4 changed files with 24 additions and 233 deletions

View File

@ -1,43 +1,18 @@
"""Support for Axis devices."""
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.const import (
CONF_DEVICE,
CONF_MAC,
CONF_NAME,
CONF_TRIGGER_TIME,
EVENT_HOMEASSISTANT_STOP,
)
from homeassistant.helpers import config_validation as cv
from .config_flow import DEVICE_SCHEMA
from .const import CONF_CAMERA, CONF_EVENTS, DEFAULT_TRIGGER_TIME, DOMAIN
from .device import AxisNetworkDevice, get_device
CONFIG_SCHEMA = vol.Schema(
{DOMAIN: cv.schema_with_slug_keys(DEVICE_SCHEMA)}, extra=vol.ALLOW_EXTRA
)
async def async_setup(hass, config):
"""Set up for Axis devices."""
if not hass.config_entries.async_entries(DOMAIN) and DOMAIN in config:
for device_name, device_config in config[DOMAIN].items():
if CONF_NAME not in device_config:
device_config[CONF_NAME] = device_name
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data=device_config,
)
)
"""Old way to set up Axis devices."""
return True

View File

@ -14,7 +14,6 @@ from homeassistant.const import (
)
from homeassistant.core import callback
from homeassistant.helpers import config_validation as cv
from homeassistant.util.json import load_json
from .const import CONF_MODEL, DOMAIN
from .device import get_device
@ -107,16 +106,12 @@ class AxisFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
except CannotConnect:
errors["base"] = "device_unavailable"
data = (
self.import_schema
or self.discovery_schema
or {
vol.Required(CONF_HOST): str,
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
vol.Required(CONF_PORT, default=DEFAULT_PORT): int,
}
)
data = self.discovery_schema or {
vol.Required(CONF_HOST): str,
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
vol.Required(CONF_PORT, default=DEFAULT_PORT): int,
}
return self.async_show_form(
step_id="user",
@ -130,18 +125,17 @@ class AxisFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
Generate a name to be used as a prefix for device entities.
"""
if self.name is None:
same_model = [
entry.data[CONF_NAME]
for entry in self.hass.config_entries.async_entries(DOMAIN)
if entry.data[CONF_MODEL] == self.model
]
same_model = [
entry.data[CONF_NAME]
for entry in self.hass.config_entries.async_entries(DOMAIN)
if entry.data[CONF_MODEL] == self.model
]
self.name = f"{self.model}"
for idx in range(len(same_model) + 1):
self.name = f"{self.model} {idx}"
if self.name not in same_model:
break
self.name = f"{self.model}"
for idx in range(len(same_model) + 1):
self.name = f"{self.model} {idx}"
if self.name not in same_model:
break
data = {
CONF_DEVICE: self.device_config,
@ -187,53 +181,17 @@ class AxisFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
await self._update_entry(entry, discovery_info[CONF_HOST])
return self.async_abort(reason="already_configured")
config_file = await self.hass.async_add_executor_job(
load_json, self.hass.config.path(CONFIG_FILE)
)
# pylint: disable=no-member # https://github.com/PyCQA/pylint/issues/3167
self.context["title_placeholders"] = {
"name": discovery_info["hostname"][:-7],
"host": discovery_info[CONF_HOST],
}
if serialnumber not in config_file:
self.discovery_schema = {
vol.Required(CONF_HOST, default=discovery_info[CONF_HOST]): str,
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
vol.Required(CONF_PORT, default=discovery_info[CONF_PORT]): int,
}
return await self.async_step_user()
try:
device_config = DEVICE_SCHEMA(config_file[serialnumber])
device_config[CONF_HOST] = discovery_info[CONF_HOST]
if CONF_NAME not in device_config:
device_config[CONF_NAME] = discovery_info["hostname"]
except vol.Invalid:
return self.async_abort(reason="bad_config_file")
return await self.async_step_import(device_config)
async def async_step_import(self, import_config):
"""Import a Axis device as a config entry.
This flow is triggered by `async_setup` for configured devices.
This flow is also triggered by `async_step_discovery`.
This will execute for any Axis device that contains a complete
configuration.
"""
self.name = import_config[CONF_NAME]
self.import_schema = {
vol.Required(CONF_HOST, default=import_config[CONF_HOST]): str,
vol.Required(CONF_USERNAME, default=import_config[CONF_USERNAME]): str,
vol.Required(CONF_PASSWORD, default=import_config[CONF_PASSWORD]): str,
vol.Required(CONF_PORT, default=import_config[CONF_PORT]): int,
self.discovery_schema = {
vol.Required(CONF_HOST, default=discovery_info[CONF_HOST]): str,
vol.Required(CONF_USERNAME): str,
vol.Required(CONF_PASSWORD): str,
vol.Required(CONF_PORT, default=discovery_info[CONF_PORT]): int,
}
return await self.async_step_user(user_input=import_config)
return await self.async_step_user()

View File

@ -196,52 +196,6 @@ async def test_zeroconf_flow(hass):
assert result["step_id"] == "user"
async def test_zeroconf_flow_known_device(hass):
"""Test that zeroconf discovery for known devices work.
This is legacy support from devices registered with configurator.
"""
with patch(
"homeassistant.components.axis.config_flow.load_json",
return_value={
"00408C12345": {
config_flow.CONF_HOST: "2.3.4.5",
config_flow.CONF_USERNAME: "user",
config_flow.CONF_PASSWORD: "pass",
config_flow.CONF_PORT: 80,
}
},
), patch("axis.AxisDevice") as mock_device:
def mock_constructor(loop, host, username, password, port, web_proto):
"""Fake the controller constructor."""
mock_device.loop = loop
mock_device.host = host
mock_device.username = username
mock_device.password = password
mock_device.port = port
return mock_device
mock_device.side_effect = mock_constructor
mock_device.vapix.params.system_serialnumber = "serialnumber"
mock_device.vapix.params.prodnbr = "prodnbr"
mock_device.vapix.params.prodtype = "prodtype"
mock_device.vapix.params.firmware_version = "firmware_version"
result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN,
data={
config_flow.CONF_HOST: "1.2.3.4",
config_flow.CONF_PORT: 80,
"hostname": "name",
"properties": {"macaddress": "00408C12345"},
},
context={"source": "zeroconf"},
)
assert result["type"] == "create_entry"
async def test_zeroconf_flow_already_configured(hass):
"""Test that zeroconf doesn't setup already configured devices."""
entry = MockConfigEntry(
@ -298,79 +252,3 @@ async def test_zeroconf_flow_ignore_link_local_address(hass):
assert result["type"] == "abort"
assert result["reason"] == "link_local_address"
async def test_zeroconf_flow_bad_config_file(hass):
"""Test that zeroconf discovery with bad config files abort."""
with patch(
"homeassistant.components.axis.config_flow.load_json",
return_value={
"00408C12345": {
config_flow.CONF_HOST: "2.3.4.5",
config_flow.CONF_USERNAME: "user",
config_flow.CONF_PASSWORD: "pass",
config_flow.CONF_PORT: 80,
}
},
), patch(
"homeassistant.components.axis.config_flow.DEVICE_SCHEMA",
side_effect=config_flow.vol.Invalid(""),
):
result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN,
data={
config_flow.CONF_HOST: "1.2.3.4",
"hostname": "name",
"properties": {"macaddress": "00408C12345"},
},
context={"source": "zeroconf"},
)
assert result["type"] == "abort"
assert result["reason"] == "bad_config_file"
async def test_import_flow_works(hass):
"""Test that import flow works."""
with patch("axis.AxisDevice") as mock_device:
def mock_constructor(loop, host, username, password, port, web_proto):
"""Fake the controller constructor."""
mock_device.loop = loop
mock_device.host = host
mock_device.username = username
mock_device.password = password
mock_device.port = port
return mock_device
mock_device.side_effect = mock_constructor
mock_device.vapix.params.system_serialnumber = "serialnumber"
mock_device.vapix.params.prodnbr = "prodnbr"
mock_device.vapix.params.prodtype = "prodtype"
mock_device.vapix.params.firmware_version = "firmware_version"
result = await hass.config_entries.flow.async_init(
config_flow.DOMAIN,
data={
config_flow.CONF_HOST: "1.2.3.4",
config_flow.CONF_USERNAME: "user",
config_flow.CONF_PASSWORD: "pass",
config_flow.CONF_PORT: 80,
config_flow.CONF_NAME: "name",
},
context={"source": "import"},
)
assert result["type"] == "create_entry"
assert result["title"] == "{} - {}".format("prodnbr", "serialnumber")
assert result["data"] == {
axis.CONF_DEVICE: {
config_flow.CONF_HOST: "1.2.3.4",
config_flow.CONF_USERNAME: "user",
config_flow.CONF_PASSWORD: "pass",
config_flow.CONF_PORT: 80,
},
config_flow.CONF_MAC: "serialnumber",
config_flow.CONF_MODEL: "prodnbr",
config_flow.CONF_NAME: "name",
}

View File

@ -7,26 +7,6 @@ from homeassistant.setup import async_setup_component
from tests.common import MockConfigEntry, mock_coro
async def test_setup(hass):
"""Test configured options for a device are loaded via config entry."""
with patch.object(hass.config_entries, "flow") as mock_config_flow:
assert await async_setup_component(
hass,
axis.DOMAIN,
{
axis.DOMAIN: {
"device_name": {
axis.config_flow.CONF_HOST: "1.2.3.4",
axis.config_flow.CONF_PORT: 80,
}
}
},
)
assert len(mock_config_flow.mock_calls) == 1
async def test_setup_device_already_configured(hass):
"""Test already configured device does not configure a second."""
with patch.object(hass, "config_entries") as mock_config_entries: