core/tests/components/axis/test_device.py

238 lines
7.1 KiB
Python

"""Test Axis device."""
from unittest.mock import Mock, patch
import pytest
from homeassistant.components.axis import device, errors
from homeassistant.components.axis.camera import AxisCamera
from tests.common import MockConfigEntry, mock_coro
DEVICE_DATA = {
device.CONF_HOST: "1.2.3.4",
device.CONF_USERNAME: "username",
device.CONF_PASSWORD: "password",
device.CONF_PORT: 1234,
}
ENTRY_OPTIONS = {device.CONF_CAMERA: True, device.CONF_EVENTS: True}
ENTRY_CONFIG = {
device.CONF_DEVICE: DEVICE_DATA,
device.CONF_MAC: "mac",
device.CONF_MODEL: "model",
device.CONF_NAME: "name",
}
async def test_device_setup():
"""Successful setup."""
hass = Mock()
entry = Mock()
entry.data = ENTRY_CONFIG
entry.options = ENTRY_OPTIONS
api = Mock()
axis_device = device.AxisNetworkDevice(hass, entry)
axis_device.start = Mock()
assert axis_device.host == DEVICE_DATA[device.CONF_HOST]
assert axis_device.model == ENTRY_CONFIG[device.CONF_MODEL]
assert axis_device.name == ENTRY_CONFIG[device.CONF_NAME]
assert axis_device.serial == ENTRY_CONFIG[device.CONF_MAC]
with patch.object(device, "get_device", return_value=mock_coro(api)):
assert await axis_device.async_setup() is True
assert axis_device.api is api
assert len(hass.config_entries.async_forward_entry_setup.mock_calls) == 3
assert hass.config_entries.async_forward_entry_setup.mock_calls[0][1] == (
entry,
"camera",
)
assert hass.config_entries.async_forward_entry_setup.mock_calls[1][1] == (
entry,
"binary_sensor",
)
assert hass.config_entries.async_forward_entry_setup.mock_calls[2][1] == (
entry,
"switch",
)
async def test_device_signal_new_address(hass):
"""Successful setup."""
entry = MockConfigEntry(
domain=device.DOMAIN, data=ENTRY_CONFIG, options=ENTRY_OPTIONS
)
api = Mock()
api.vapix.get_param.return_value = "1234"
axis_device = device.AxisNetworkDevice(hass, entry)
hass.data[device.DOMAIN] = {axis_device.serial: axis_device}
with patch.object(device, "get_device", return_value=mock_coro(api)), patch.object(
AxisCamera, "_new_address"
) as new_address_mock:
await axis_device.async_setup()
await hass.async_block_till_done()
assert len(hass.states.async_all()) == 1
assert len(axis_device.listeners) == 2
entry.data[device.CONF_DEVICE][device.CONF_HOST] = "2.3.4.5"
hass.config_entries.async_update_entry(entry, data=entry.data)
await hass.async_block_till_done()
assert axis_device.host == "2.3.4.5"
assert axis_device.api.config.host == "2.3.4.5"
assert len(new_address_mock.mock_calls) == 1
async def test_device_unavailable(hass):
"""Successful setup."""
entry = MockConfigEntry(
domain=device.DOMAIN, data=ENTRY_CONFIG, options=ENTRY_OPTIONS
)
api = Mock()
api.vapix.get_param.return_value = "1234"
axis_device = device.AxisNetworkDevice(hass, entry)
hass.data[device.DOMAIN] = {axis_device.serial: axis_device}
with patch.object(device, "get_device", return_value=mock_coro(api)), patch.object(
device, "async_dispatcher_send"
) as mock_dispatcher:
await axis_device.async_setup()
await hass.async_block_till_done()
axis_device.async_connection_status_callback(status=False)
assert not axis_device.available
assert len(mock_dispatcher.mock_calls) == 1
async def test_device_reset(hass):
"""Successfully reset device."""
entry = MockConfigEntry(
domain=device.DOMAIN, data=ENTRY_CONFIG, options=ENTRY_OPTIONS
)
api = Mock()
api.vapix.get_param.return_value = "1234"
axis_device = device.AxisNetworkDevice(hass, entry)
hass.data[device.DOMAIN] = {axis_device.serial: axis_device}
with patch.object(device, "get_device", return_value=mock_coro(api)):
await axis_device.async_setup()
await hass.async_block_till_done()
await axis_device.async_reset()
assert len(api.stop.mock_calls) == 1
assert len(hass.states.async_all()) == 0
assert len(axis_device.listeners) == 0
async def test_device_not_accessible():
"""Failed setup schedules a retry of setup."""
hass = Mock()
hass.data = dict()
entry = Mock()
entry.data = ENTRY_CONFIG
entry.options = ENTRY_OPTIONS
axis_device = device.AxisNetworkDevice(hass, entry)
with patch.object(
device, "get_device", side_effect=errors.CannotConnect
), pytest.raises(device.ConfigEntryNotReady):
await axis_device.async_setup()
assert not hass.helpers.event.async_call_later.mock_calls
async def test_device_unknown_error():
"""Unknown errors are handled."""
hass = Mock()
entry = Mock()
entry.data = ENTRY_CONFIG
entry.options = ENTRY_OPTIONS
axis_device = device.AxisNetworkDevice(hass, entry)
with patch.object(device, "get_device", side_effect=Exception):
assert await axis_device.async_setup() is False
assert not hass.helpers.event.async_call_later.mock_calls
async def test_new_event_sends_signal(hass):
"""Make sure that new event send signal."""
entry = Mock()
entry.data = ENTRY_CONFIG
axis_device = device.AxisNetworkDevice(hass, entry)
with patch.object(device, "async_dispatcher_send") as mock_dispatch_send:
axis_device.async_event_callback(action="add", event_id="event")
await hass.async_block_till_done()
assert len(mock_dispatch_send.mock_calls) == 1
assert len(mock_dispatch_send.mock_calls[0]) == 3
async def test_shutdown():
"""Successful shutdown."""
hass = Mock()
entry = Mock()
entry.data = ENTRY_CONFIG
axis_device = device.AxisNetworkDevice(hass, entry)
axis_device.api = Mock()
axis_device.shutdown(None)
assert len(axis_device.api.stop.mock_calls) == 1
async def test_get_device(hass):
"""Successful call."""
with patch("axis.param_cgi.Params.update_brand", return_value=mock_coro()), patch(
"axis.param_cgi.Params.update_properties", return_value=mock_coro()
), patch("axis.port_cgi.Ports.update", return_value=mock_coro()):
assert await device.get_device(hass, DEVICE_DATA)
async def test_get_device_fails(hass):
"""Device unauthorized yields authentication required error."""
import axis
with patch(
"axis.param_cgi.Params.update_brand", side_effect=axis.Unauthorized
), pytest.raises(errors.AuthenticationRequired):
await device.get_device(hass, DEVICE_DATA)
async def test_get_device_device_unavailable(hass):
"""Device unavailable yields cannot connect error."""
import axis
with patch(
"axis.param_cgi.Params.update_brand", side_effect=axis.RequestError
), pytest.raises(errors.CannotConnect):
await device.get_device(hass, DEVICE_DATA)
async def test_get_device_unknown_error(hass):
"""Device yield unknown error."""
import axis
with patch(
"axis.param_cgi.Params.update_brand", side_effect=axis.AxisException
), pytest.raises(errors.AuthenticationRequired):
await device.get_device(hass, DEVICE_DATA)