mirror of
https://github.com/Electric-Special/ha-core.git
synced 2026-03-21 04:05:20 +01:00
Add bad code attempt event to manual alarm control panel (#146315)
Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
@@ -408,6 +408,20 @@ class ManualAlarm(AlarmControlPanelEntity, RestoreEntity):
|
||||
if not alarm_code or code == alarm_code:
|
||||
return
|
||||
|
||||
current_context = (
|
||||
self._context if hasattr(self, "_context") and self._context else None
|
||||
)
|
||||
user_id_from_context = current_context.user_id if current_context else None
|
||||
|
||||
self.hass.bus.async_fire(
|
||||
"manual_alarm_bad_code_attempt",
|
||||
{
|
||||
"entity_id": self.entity_id,
|
||||
"user_id": user_id_from_context,
|
||||
"target_state": state,
|
||||
},
|
||||
)
|
||||
|
||||
raise ServiceValidationError(
|
||||
"Invalid alarm code provided",
|
||||
translation_domain=DOMAIN,
|
||||
|
||||
@@ -6,8 +6,10 @@ from unittest.mock import MagicMock, patch
|
||||
from freezegun import freeze_time
|
||||
import pytest
|
||||
|
||||
from homeassistant.auth.models import User
|
||||
from homeassistant.components import alarm_control_panel
|
||||
from homeassistant.components.alarm_control_panel import (
|
||||
DOMAIN as ALARM_DOMAIN,
|
||||
AlarmControlPanelEntityFeature,
|
||||
AlarmControlPanelState,
|
||||
)
|
||||
@@ -25,7 +27,7 @@ from homeassistant.const import (
|
||||
SERVICE_ALARM_ARM_NIGHT,
|
||||
SERVICE_ALARM_ARM_VACATION,
|
||||
)
|
||||
from homeassistant.core import CoreState, HomeAssistant, State
|
||||
from homeassistant.core import Context, CoreState, HomeAssistant, State, callback
|
||||
from homeassistant.exceptions import ServiceValidationError
|
||||
from homeassistant.setup import async_setup_component
|
||||
from homeassistant.util import dt as dt_util
|
||||
@@ -1123,6 +1125,80 @@ async def test_disarm_during_trigger_with_invalid_code(hass: HomeAssistant) -> N
|
||||
assert state.state == AlarmControlPanelState.TRIGGERED
|
||||
|
||||
|
||||
async def test_bad_code_attempt_event_fired(hass: HomeAssistant) -> None:
|
||||
"""Test that manual_alarm_bad_code_attempt event is fired on bad code."""
|
||||
|
||||
entity_id = "alarm_control_panel.test_alarm"
|
||||
config = {
|
||||
ALARM_DOMAIN: {
|
||||
"platform": "manual",
|
||||
"name": "Test Alarm",
|
||||
"code": "1234",
|
||||
"delay_time": 0,
|
||||
"arming_time": 0,
|
||||
"trigger_time": 0,
|
||||
}
|
||||
}
|
||||
assert await async_setup_component(hass, ALARM_DOMAIN, config)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
alarm_entity = hass.states.get(entity_id)
|
||||
assert alarm_entity is not None
|
||||
|
||||
await hass.services.async_call(
|
||||
ALARM_DOMAIN,
|
||||
"alarm_arm_away",
|
||||
{"entity_id": entity_id, "code": "1234"},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
assert hass.states.get(entity_id).state == AlarmControlPanelState.ARMED_AWAY
|
||||
|
||||
bad_code = "0000"
|
||||
|
||||
mock_user_id = "test_user_id_123"
|
||||
test_context = Context(user_id=mock_user_id)
|
||||
|
||||
events = []
|
||||
|
||||
@callback
|
||||
def event_listener(event):
|
||||
events.append(event.data)
|
||||
|
||||
hass.bus.async_listen("manual_alarm_bad_code_attempt", event_listener)
|
||||
|
||||
await hass.services.async_call(
|
||||
ALARM_DOMAIN,
|
||||
"alarm_disarm",
|
||||
{"entity_id": entity_id, "code": "1234"},
|
||||
blocking=True,
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(events) == 0
|
||||
|
||||
with patch("homeassistant.auth.AuthManager.async_get_user") as mock_get_user:
|
||||
mock_user = MagicMock(spec=User)
|
||||
mock_user.id = mock_user_id
|
||||
mock_get_user.return_value = mock_user
|
||||
|
||||
with pytest.raises(ServiceValidationError):
|
||||
await hass.services.async_call(
|
||||
ALARM_DOMAIN,
|
||||
"alarm_disarm",
|
||||
{"entity_id": entity_id, "code": bad_code},
|
||||
blocking=True,
|
||||
context=test_context,
|
||||
)
|
||||
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert len(events) == 1
|
||||
assert events[0].get("entity_id") == entity_id
|
||||
assert events[0].get("target_state") == AlarmControlPanelState.DISARMED
|
||||
assert events[0].get("user_id") == mock_user_id
|
||||
|
||||
|
||||
async def test_disarm_with_template_code(hass: HomeAssistant) -> None:
|
||||
"""Attempt to disarm with a valid or invalid template-based code."""
|
||||
assert await async_setup_component(
|
||||
|
||||
Reference in New Issue
Block a user