Add test coverage for doorbird events (#122617)
This commit is contained in:
parent
850703824b
commit
5bb6272dfa
6 changed files with 91 additions and 14 deletions
|
@ -25,19 +25,12 @@ class DoorBirdRequestView(HomeAssistantView):
|
||||||
"""Respond to requests from the device."""
|
"""Respond to requests from the device."""
|
||||||
hass = request.app[KEY_HASS]
|
hass = request.app[KEY_HASS]
|
||||||
token: str | None = request.query.get("token")
|
token: str | None = request.query.get("token")
|
||||||
if (
|
if not token or not (door_station := get_door_station_by_token(hass, token)):
|
||||||
token is None
|
|
||||||
or (door_station := get_door_station_by_token(hass, token)) is None
|
|
||||||
):
|
|
||||||
return web.Response(
|
return web.Response(
|
||||||
status=HTTPStatus.UNAUTHORIZED, text="Invalid token provided."
|
status=HTTPStatus.UNAUTHORIZED, text="Invalid token provided."
|
||||||
)
|
)
|
||||||
|
|
||||||
if door_station:
|
event_data = door_station.get_event_data(event)
|
||||||
event_data = door_station.get_event_data(event)
|
|
||||||
else:
|
|
||||||
event_data = {}
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# This integration uses a multiple different events.
|
# This integration uses a multiple different events.
|
||||||
# It would be a major breaking change to change this to
|
# It would be a major breaking change to change this to
|
||||||
|
|
|
@ -6,7 +6,15 @@ from unittest.mock import AsyncMock, MagicMock, Mock
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from doorbirdpy import DoorBird, DoorBirdScheduleEntry
|
from doorbirdpy import DoorBird, DoorBirdScheduleEntry
|
||||||
|
|
||||||
from homeassistant.const import CONF_HOST, CONF_NAME, CONF_PASSWORD, CONF_USERNAME
|
from homeassistant import config_entries
|
||||||
|
from homeassistant.components.doorbird.const import API_URL
|
||||||
|
from homeassistant.const import (
|
||||||
|
CONF_HOST,
|
||||||
|
CONF_NAME,
|
||||||
|
CONF_PASSWORD,
|
||||||
|
CONF_TOKEN,
|
||||||
|
CONF_USERNAME,
|
||||||
|
)
|
||||||
|
|
||||||
VALID_CONFIG = {
|
VALID_CONFIG = {
|
||||||
CONF_HOST: "1.2.3.4",
|
CONF_HOST: "1.2.3.4",
|
||||||
|
@ -39,6 +47,7 @@ def get_mock_doorbird_api(
|
||||||
info: dict[str, Any] | None = None,
|
info: dict[str, Any] | None = None,
|
||||||
info_side_effect: Exception | None = None,
|
info_side_effect: Exception | None = None,
|
||||||
schedule: list[DoorBirdScheduleEntry] | None = None,
|
schedule: list[DoorBirdScheduleEntry] | None = None,
|
||||||
|
favorites: dict[str, dict[str, Any]] | None = None,
|
||||||
favorites_side_effect: Exception | None = None,
|
favorites_side_effect: Exception | None = None,
|
||||||
) -> DoorBird:
|
) -> DoorBird:
|
||||||
"""Return a mock DoorBirdAPI object with return values."""
|
"""Return a mock DoorBirdAPI object with return values."""
|
||||||
|
@ -48,9 +57,10 @@ def get_mock_doorbird_api(
|
||||||
)
|
)
|
||||||
type(doorbirdapi_mock).favorites = AsyncMock(
|
type(doorbirdapi_mock).favorites = AsyncMock(
|
||||||
side_effect=favorites_side_effect,
|
side_effect=favorites_side_effect,
|
||||||
return_value={"http": {"x": {"value": "http://webhook"}}},
|
return_value=favorites,
|
||||||
)
|
)
|
||||||
type(doorbirdapi_mock).change_favorite = AsyncMock(return_value=True)
|
type(doorbirdapi_mock).change_favorite = AsyncMock(return_value=True)
|
||||||
|
type(doorbirdapi_mock).change_schedule = AsyncMock(return_value=(True, 200))
|
||||||
type(doorbirdapi_mock).schedule = AsyncMock(return_value=schedule)
|
type(doorbirdapi_mock).schedule = AsyncMock(return_value=schedule)
|
||||||
type(doorbirdapi_mock).energize_relay = AsyncMock(return_value=True)
|
type(doorbirdapi_mock).energize_relay = AsyncMock(return_value=True)
|
||||||
type(doorbirdapi_mock).turn_light_on = AsyncMock(return_value=True)
|
type(doorbirdapi_mock).turn_light_on = AsyncMock(return_value=True)
|
||||||
|
@ -59,3 +69,14 @@ def get_mock_doorbird_api(
|
||||||
side_effect=mock_unauthorized_exception()
|
side_effect=mock_unauthorized_exception()
|
||||||
)
|
)
|
||||||
return doorbirdapi_mock
|
return doorbirdapi_mock
|
||||||
|
|
||||||
|
|
||||||
|
async def mock_webhook_call(
|
||||||
|
config_entry: config_entries.ConfigEntry,
|
||||||
|
aiohttp_client: aiohttp.ClientSession,
|
||||||
|
event: str,
|
||||||
|
) -> None:
|
||||||
|
"""Mock the webhook call."""
|
||||||
|
token = config_entry.data.get(CONF_TOKEN, config_entry.entry_id)
|
||||||
|
response = await aiohttp_client.get(f"{API_URL}/{event}?token={token}")
|
||||||
|
response.raise_for_status()
|
||||||
|
|
|
@ -9,7 +9,12 @@ from unittest.mock import MagicMock, patch
|
||||||
from doorbirdpy import DoorBird, DoorBirdScheduleEntry
|
from doorbirdpy import DoorBird, DoorBirdScheduleEntry
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.doorbird.const import CONF_EVENTS, DOMAIN
|
from homeassistant.components.doorbird.const import (
|
||||||
|
CONF_EVENTS,
|
||||||
|
DEFAULT_DOORBELL_EVENT,
|
||||||
|
DEFAULT_MOTION_EVENT,
|
||||||
|
DOMAIN,
|
||||||
|
)
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
from . import VALID_CONFIG, get_mock_doorbird_api
|
from . import VALID_CONFIG, get_mock_doorbird_api
|
||||||
|
@ -41,6 +46,12 @@ def doorbird_schedule() -> list[DoorBirdScheduleEntry]:
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session")
|
||||||
|
def doorbird_favorites() -> dict[str, dict[str, Any]]:
|
||||||
|
"""Return a loaded DoorBird favorites fixture."""
|
||||||
|
return load_json_value_fixture("favorites.json", "doorbird")
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def doorbird_api(
|
def doorbird_api(
|
||||||
doorbird_info: dict[str, Any], doorbird_schedule: dict[str, Any]
|
doorbird_info: dict[str, Any], doorbird_schedule: dict[str, Any]
|
||||||
|
@ -72,6 +83,7 @@ async def doorbird_mocker(
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
doorbird_info: dict[str, Any],
|
doorbird_info: dict[str, Any],
|
||||||
doorbird_schedule: dict[str, Any],
|
doorbird_schedule: dict[str, Any],
|
||||||
|
doorbird_favorites: dict[str, dict[str, Any]],
|
||||||
) -> DoorbirdMockerType:
|
) -> DoorbirdMockerType:
|
||||||
"""Create a MockDoorbirdEntry."""
|
"""Create a MockDoorbirdEntry."""
|
||||||
|
|
||||||
|
@ -81,6 +93,7 @@ async def doorbird_mocker(
|
||||||
info: dict[str, Any] | None = None,
|
info: dict[str, Any] | None = None,
|
||||||
info_side_effect: Exception | None = None,
|
info_side_effect: Exception | None = None,
|
||||||
schedule: list[DoorBirdScheduleEntry] | None = None,
|
schedule: list[DoorBirdScheduleEntry] | None = None,
|
||||||
|
favorites: dict[str, dict[str, Any]] | None = None,
|
||||||
favorites_side_effect: Exception | None = None,
|
favorites_side_effect: Exception | None = None,
|
||||||
) -> MockDoorbirdEntry:
|
) -> MockDoorbirdEntry:
|
||||||
"""Create a MockDoorbirdEntry from defaults or specific values."""
|
"""Create a MockDoorbirdEntry from defaults or specific values."""
|
||||||
|
@ -88,12 +101,13 @@ async def doorbird_mocker(
|
||||||
domain=DOMAIN,
|
domain=DOMAIN,
|
||||||
unique_id="1CCAE3AAAAAA",
|
unique_id="1CCAE3AAAAAA",
|
||||||
data=VALID_CONFIG,
|
data=VALID_CONFIG,
|
||||||
options={CONF_EVENTS: ["event1", "event2", "event3"]},
|
options={CONF_EVENTS: [DEFAULT_DOORBELL_EVENT, DEFAULT_MOTION_EVENT]},
|
||||||
)
|
)
|
||||||
api = api or get_mock_doorbird_api(
|
api = api or get_mock_doorbird_api(
|
||||||
info=info or doorbird_info,
|
info=info or doorbird_info,
|
||||||
info_side_effect=info_side_effect,
|
info_side_effect=info_side_effect,
|
||||||
schedule=schedule or doorbird_schedule,
|
schedule=schedule or doorbird_schedule,
|
||||||
|
favorites=favorites or doorbird_favorites,
|
||||||
favorites_side_effect=favorites_side_effect,
|
favorites_side_effect=favorites_side_effect,
|
||||||
)
|
)
|
||||||
entry.add_to_hass(hass)
|
entry.add_to_hass(hass)
|
||||||
|
|
12
tests/components/doorbird/fixtures/favorites.json
Normal file
12
tests/components/doorbird/fixtures/favorites.json
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"http": {
|
||||||
|
"0": {
|
||||||
|
"title": "Home Assistant (mydoorbird_doorbell)",
|
||||||
|
"value": "http://127.0.0.1:8123/api/doorbird/mydoorbird_doorbell?token=01J2F4B97Y7P1SARXEJ6W07EKD"
|
||||||
|
},
|
||||||
|
"1": {
|
||||||
|
"title": "Home Assistant (mydoorbird_motion)",
|
||||||
|
"value": "http://127.0.0.1:8123/api/doorbird/mydoorbird_motion?token=01J2F4B97Y7P1SARXEJ6W07EKD"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -49,4 +49,4 @@ async def test_reset_favorites_button(
|
||||||
DOMAIN, SERVICE_PRESS, {ATTR_ENTITY_ID: reset_entity_id}, blocking=True
|
DOMAIN, SERVICE_PRESS, {ATTR_ENTITY_ID: reset_entity_id}, blocking=True
|
||||||
)
|
)
|
||||||
assert hass.states.get(reset_entity_id).state != STATE_UNKNOWN
|
assert hass.states.get(reset_entity_id).state != STATE_UNKNOWN
|
||||||
assert doorbird_entry.api.delete_favorite.call_count == 1
|
assert doorbird_entry.api.delete_favorite.call_count == 2
|
||||||
|
|
37
tests/components/doorbird/test_event.py
Normal file
37
tests/components/doorbird/test_event.py
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
"""Test DoorBird events."""
|
||||||
|
|
||||||
|
from homeassistant.const import STATE_UNKNOWN
|
||||||
|
from homeassistant.core import HomeAssistant
|
||||||
|
|
||||||
|
from . import mock_webhook_call
|
||||||
|
from .conftest import DoorbirdMockerType
|
||||||
|
|
||||||
|
from tests.typing import ClientSessionGenerator
|
||||||
|
|
||||||
|
|
||||||
|
async def test_doorbell_ring_event(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
hass_client: ClientSessionGenerator,
|
||||||
|
doorbird_mocker: DoorbirdMockerType,
|
||||||
|
) -> None:
|
||||||
|
"""Test a doorbell ring event."""
|
||||||
|
doorbird_entry = await doorbird_mocker()
|
||||||
|
relay_1_entity_id = "event.mydoorbird_doorbell"
|
||||||
|
assert hass.states.get(relay_1_entity_id).state == STATE_UNKNOWN
|
||||||
|
client = await hass_client()
|
||||||
|
await mock_webhook_call(doorbird_entry.entry, client, "mydoorbird_doorbell")
|
||||||
|
assert hass.states.get(relay_1_entity_id).state != STATE_UNKNOWN
|
||||||
|
|
||||||
|
|
||||||
|
async def test_motion_event(
|
||||||
|
hass: HomeAssistant,
|
||||||
|
hass_client: ClientSessionGenerator,
|
||||||
|
doorbird_mocker: DoorbirdMockerType,
|
||||||
|
) -> None:
|
||||||
|
"""Test a doorbell motion event."""
|
||||||
|
doorbird_entry = await doorbird_mocker()
|
||||||
|
relay_1_entity_id = "event.mydoorbird_motion"
|
||||||
|
assert hass.states.get(relay_1_entity_id).state == STATE_UNKNOWN
|
||||||
|
client = await hass_client()
|
||||||
|
await mock_webhook_call(doorbird_entry.entry, client, "mydoorbird_motion")
|
||||||
|
assert hass.states.get(relay_1_entity_id).state != STATE_UNKNOWN
|
Loading…
Add table
Add a link
Reference in a new issue