Risco code review follow ups (#39143)
parent
45401d4308
commit
e3ce699d75
|
@ -4,19 +4,14 @@ import logging
|
|||
from homeassistant.components.alarm_control_panel import AlarmControlPanelEntity
|
||||
from homeassistant.components.alarm_control_panel.const import (
|
||||
SUPPORT_ALARM_ARM_AWAY,
|
||||
SUPPORT_ALARM_ARM_CUSTOM_BYPASS,
|
||||
SUPPORT_ALARM_ARM_HOME,
|
||||
SUPPORT_ALARM_ARM_NIGHT,
|
||||
)
|
||||
from homeassistant.const import (
|
||||
STATE_ALARM_ARMED_AWAY,
|
||||
STATE_ALARM_ARMED_CUSTOM_BYPASS,
|
||||
STATE_ALARM_ARMED_HOME,
|
||||
STATE_ALARM_ARMED_NIGHT,
|
||||
STATE_ALARM_ARMING,
|
||||
STATE_ALARM_DISARMED,
|
||||
STATE_ALARM_TRIGGERED,
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
|
||||
from .const import DATA_COORDINATOR, DOMAIN
|
||||
|
@ -27,8 +22,6 @@ SUPPORTED_STATES = [
|
|||
STATE_ALARM_DISARMED,
|
||||
STATE_ALARM_ARMED_AWAY,
|
||||
STATE_ALARM_ARMED_HOME,
|
||||
STATE_ALARM_ARMED_NIGHT,
|
||||
STATE_ALARM_ARMED_CUSTOM_BYPASS,
|
||||
STATE_ALARM_TRIGGERED,
|
||||
]
|
||||
|
||||
|
@ -37,8 +30,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
"""Set up the Risco alarm control panel."""
|
||||
coordinator = hass.data[DOMAIN][config_entry.entry_id][DATA_COORDINATOR]
|
||||
entities = [
|
||||
RiscoAlarm(hass, coordinator, partition_id)
|
||||
for partition_id in coordinator.data.partitions.keys()
|
||||
RiscoAlarm(coordinator, partition_id)
|
||||
for partition_id in coordinator.data.partitions
|
||||
]
|
||||
|
||||
async_add_entities(entities, False)
|
||||
|
@ -47,9 +40,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
|||
class RiscoAlarm(AlarmControlPanelEntity):
|
||||
"""Representation of a Risco partition."""
|
||||
|
||||
def __init__(self, hass, coordinator, partition_id):
|
||||
def __init__(self, coordinator, partition_id):
|
||||
"""Init the partition."""
|
||||
self._hass = hass
|
||||
self._coordinator = coordinator
|
||||
self._partition_id = partition_id
|
||||
self._partition = self._coordinator.data.partitions[self._partition_id]
|
||||
|
@ -112,17 +104,12 @@ class RiscoAlarm(AlarmControlPanelEntity):
|
|||
if self._partition.disarmed:
|
||||
return STATE_ALARM_DISARMED
|
||||
|
||||
return STATE_UNKNOWN
|
||||
return None
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
"""Return the list of supported features."""
|
||||
return (
|
||||
SUPPORT_ALARM_ARM_HOME
|
||||
| SUPPORT_ALARM_ARM_AWAY
|
||||
| SUPPORT_ALARM_ARM_NIGHT
|
||||
| SUPPORT_ALARM_ARM_CUSTOM_BYPASS
|
||||
)
|
||||
return SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY
|
||||
|
||||
@property
|
||||
def code_arm_required(self):
|
||||
|
@ -137,14 +124,6 @@ class RiscoAlarm(AlarmControlPanelEntity):
|
|||
"""Send arm home command."""
|
||||
await self._call_alarm_method("partial_arm")
|
||||
|
||||
async def async_alarm_arm_night(self, code=None):
|
||||
"""Send arm night command."""
|
||||
await self._call_alarm_method("partial_arm")
|
||||
|
||||
async def async_alarm_arm_custom_bypass(self, code=None):
|
||||
"""Send arm custom bypass command."""
|
||||
await self._call_alarm_method("partial_arm")
|
||||
|
||||
async def async_alarm_arm_away(self, code=None):
|
||||
"""Send arm away command."""
|
||||
await self._call_alarm_method("arm")
|
||||
|
|
|
@ -41,10 +41,11 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
"""Handle the initial step."""
|
||||
errors = {}
|
||||
if user_input is not None:
|
||||
await self.async_set_unique_id(user_input[CONF_USERNAME])
|
||||
self._abort_if_unique_id_configured()
|
||||
|
||||
try:
|
||||
info = await validate_input(self.hass, user_input)
|
||||
|
||||
return self.async_create_entry(title=info["title"], data=user_input)
|
||||
except CannotConnectError:
|
||||
errors["base"] = "cannot_connect"
|
||||
except UnauthorizedError:
|
||||
|
@ -52,6 +53,8 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception("Unexpected exception")
|
||||
errors["base"] = "unknown"
|
||||
else:
|
||||
return self.async_create_entry(title=info["title"], data=user_input)
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="user", data_schema=DATA_SCHEMA, errors=errors
|
||||
|
|
|
@ -9,9 +9,7 @@ from homeassistant.const import (
|
|||
CONF_PIN,
|
||||
CONF_USERNAME,
|
||||
SERVICE_ALARM_ARM_AWAY,
|
||||
SERVICE_ALARM_ARM_CUSTOM_BYPASS,
|
||||
SERVICE_ALARM_ARM_HOME,
|
||||
SERVICE_ALARM_ARM_NIGHT,
|
||||
SERVICE_ALARM_DISARM,
|
||||
STATE_ALARM_ARMED_AWAY,
|
||||
STATE_ALARM_ARMED_HOME,
|
||||
|
@ -22,7 +20,7 @@ from homeassistant.const import (
|
|||
)
|
||||
from homeassistant.helpers.entity_component import async_update_entity
|
||||
|
||||
from tests.async_mock import AsyncMock, MagicMock, PropertyMock, patch
|
||||
from tests.async_mock import MagicMock, PropertyMock, patch
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
TEST_CONFIG = {
|
||||
|
@ -60,14 +58,15 @@ def two_part_alarm():
|
|||
"partitions",
|
||||
new_callable=PropertyMock(return_value=partition_mocks),
|
||||
), patch(
|
||||
"homeassistant.components.risco.RiscoAPI.get_state",
|
||||
AsyncMock(return_value=alarm_mock),
|
||||
"homeassistant.components.risco.RiscoAPI.get_state", return_value=alarm_mock,
|
||||
):
|
||||
yield alarm_mock
|
||||
|
||||
|
||||
async def _setup_risco(hass, alarm=MagicMock()):
|
||||
config_entry = MockConfigEntry(domain=DOMAIN, data=TEST_CONFIG)
|
||||
config_entry.add_to_hass(hass)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.risco.RiscoAPI.login", return_value=True,
|
||||
), patch(
|
||||
|
@ -77,9 +76,8 @@ async def _setup_risco(hass, alarm=MagicMock()):
|
|||
"homeassistant.components.risco.RiscoAPI.site_name",
|
||||
new_callable=PropertyMock(return_value=TEST_SITE_NAME),
|
||||
), patch(
|
||||
"homeassistant.components.risco.RiscoAPI.close", AsyncMock()
|
||||
"homeassistant.components.risco.RiscoAPI.close"
|
||||
):
|
||||
config_entry.add_to_hass(hass)
|
||||
await hass.config_entries.async_setup(config_entry.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
|
@ -194,9 +192,7 @@ async def test_states(hass, two_part_alarm):
|
|||
|
||||
|
||||
async def _test_servie_call(hass, service, method, entity_id, partition_id):
|
||||
with patch(
|
||||
"homeassistant.components.risco.RiscoAPI." + method, AsyncMock()
|
||||
) as set_mock:
|
||||
with patch("homeassistant.components.risco.RiscoAPI." + method) as set_mock:
|
||||
await _call_alarm_service(hass, service, entity_id)
|
||||
set_mock.assert_awaited_once_with(partition_id)
|
||||
|
||||
|
@ -223,15 +219,3 @@ async def test_sets(hass, two_part_alarm):
|
|||
await _test_servie_call(
|
||||
hass, SERVICE_ALARM_ARM_HOME, "partial_arm", SECOND_ENTITY_ID, 1
|
||||
)
|
||||
await _test_servie_call(
|
||||
hass, SERVICE_ALARM_ARM_NIGHT, "partial_arm", FIRST_ENTITY_ID, 0
|
||||
)
|
||||
await _test_servie_call(
|
||||
hass, SERVICE_ALARM_ARM_NIGHT, "partial_arm", SECOND_ENTITY_ID, 1
|
||||
)
|
||||
await _test_servie_call(
|
||||
hass, SERVICE_ALARM_ARM_CUSTOM_BYPASS, "partial_arm", FIRST_ENTITY_ID, 0
|
||||
)
|
||||
await _test_servie_call(
|
||||
hass, SERVICE_ALARM_ARM_CUSTOM_BYPASS, "partial_arm", SECOND_ENTITY_ID, 1
|
||||
)
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
"""Test the Risco config flow."""
|
||||
from homeassistant import config_entries, setup
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.components.risco.config_flow import (
|
||||
CannotConnectError,
|
||||
UnauthorizedError,
|
||||
)
|
||||
from homeassistant.components.risco.const import DOMAIN
|
||||
|
||||
from tests.async_mock import AsyncMock, PropertyMock, patch
|
||||
from tests.async_mock import PropertyMock, patch
|
||||
from tests.common import MockConfigEntry
|
||||
|
||||
TEST_SITE_NAME = "test-site-name"
|
||||
TEST_DATA = {
|
||||
|
@ -18,7 +19,6 @@ TEST_DATA = {
|
|||
|
||||
async def test_form(hass):
|
||||
"""Test we get the form."""
|
||||
await setup.async_setup_component(hass, "persistent_notification", {})
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
|
@ -31,7 +31,7 @@ async def test_form(hass):
|
|||
"homeassistant.components.risco.config_flow.RiscoAPI.site_name",
|
||||
new_callable=PropertyMock(return_value=TEST_SITE_NAME),
|
||||
), patch(
|
||||
"homeassistant.components.risco.config_flow.RiscoAPI.close", AsyncMock()
|
||||
"homeassistant.components.risco.config_flow.RiscoAPI.close"
|
||||
) as mock_close, patch(
|
||||
"homeassistant.components.risco.async_setup", return_value=True
|
||||
) as mock_setup, patch(
|
||||
|
@ -59,9 +59,7 @@ async def test_form_invalid_auth(hass):
|
|||
with patch(
|
||||
"homeassistant.components.risco.config_flow.RiscoAPI.login",
|
||||
side_effect=UnauthorizedError,
|
||||
), patch(
|
||||
"homeassistant.components.risco.config_flow.RiscoAPI.close", AsyncMock()
|
||||
) as mock_close:
|
||||
), patch("homeassistant.components.risco.config_flow.RiscoAPI.close") as mock_close:
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], TEST_DATA
|
||||
)
|
||||
|
@ -80,9 +78,7 @@ async def test_form_cannot_connect(hass):
|
|||
with patch(
|
||||
"homeassistant.components.risco.config_flow.RiscoAPI.login",
|
||||
side_effect=CannotConnectError,
|
||||
), patch(
|
||||
"homeassistant.components.risco.config_flow.RiscoAPI.close", AsyncMock()
|
||||
) as mock_close:
|
||||
), patch("homeassistant.components.risco.config_flow.RiscoAPI.close") as mock_close:
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], TEST_DATA
|
||||
)
|
||||
|
@ -101,9 +97,7 @@ async def test_form_exception(hass):
|
|||
with patch(
|
||||
"homeassistant.components.risco.config_flow.RiscoAPI.login",
|
||||
side_effect=Exception,
|
||||
), patch(
|
||||
"homeassistant.components.risco.config_flow.RiscoAPI.close", AsyncMock()
|
||||
) as mock_close:
|
||||
), patch("homeassistant.components.risco.config_flow.RiscoAPI.close") as mock_close:
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], TEST_DATA
|
||||
)
|
||||
|
@ -111,3 +105,24 @@ async def test_form_exception(hass):
|
|||
assert result2["type"] == "form"
|
||||
assert result2["errors"] == {"base": "unknown"}
|
||||
mock_close.assert_awaited_once()
|
||||
|
||||
|
||||
async def test_form_already_exists(hass):
|
||||
"""Test that a flow with an existing username aborts."""
|
||||
entry = MockConfigEntry(
|
||||
domain=DOMAIN, unique_id=TEST_DATA["username"], data=TEST_DATA,
|
||||
)
|
||||
|
||||
entry.add_to_hass(hass)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
result = await hass.config_entries.flow.async_init(
|
||||
DOMAIN, context={"source": config_entries.SOURCE_USER}
|
||||
)
|
||||
|
||||
result2 = await hass.config_entries.flow.async_configure(
|
||||
result["flow_id"], TEST_DATA
|
||||
)
|
||||
|
||||
assert result2["type"] == "abort"
|
||||
assert result2["reason"] == "already_configured"
|
||||
|
|
Loading…
Reference in New Issue