Add coverage for fixing missing params in the doorbird schedule (#122745)

This commit is contained in:
J. Nick Koston 2024-07-29 04:36:44 -05:00 committed by GitHub
parent fa61ad072d
commit ca430f0e7b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 144 additions and 4 deletions

View file

@ -103,9 +103,8 @@ class ConfiguredDoorBird:
async def async_register_events(self) -> None:
"""Register events on device."""
if not self.door_station_events:
# User may not have permission to get the favorites
# The config entry might not have any events configured yet
return
http_fav = await self._async_register_events()
event_config = await self._async_get_event_config(http_fav)
_LOGGER.debug("%s: Event config: %s", self.name, event_config)

View file

@ -49,6 +49,7 @@ def get_mock_doorbird_api(
schedule: list[DoorBirdScheduleEntry] | None = None,
favorites: dict[str, dict[str, Any]] | None = None,
favorites_side_effect: Exception | None = None,
change_schedule: tuple[bool, int] | None = None,
) -> DoorBird:
"""Return a mock DoorBirdAPI object with return values."""
doorbirdapi_mock = MagicMock(spec_set=DoorBird)
@ -60,7 +61,9 @@ def get_mock_doorbird_api(
return_value=favorites,
)
type(doorbirdapi_mock).change_favorite = AsyncMock(return_value=True)
type(doorbirdapi_mock).change_schedule = AsyncMock(return_value=(True, 200))
type(doorbirdapi_mock).change_schedule = AsyncMock(
return_value=change_schedule or (True, 200)
)
type(doorbirdapi_mock).schedule = AsyncMock(return_value=schedule)
type(doorbirdapi_mock).energize_relay = AsyncMock(return_value=True)
type(doorbirdapi_mock).turn_light_on = AsyncMock(return_value=True)

View file

@ -46,6 +46,14 @@ def doorbird_schedule() -> list[DoorBirdScheduleEntry]:
)
@pytest.fixture(scope="session")
def doorbird_schedule_wrong_param() -> list[DoorBirdScheduleEntry]:
"""Return a loaded DoorBird schedule fixture with an incorrect param."""
return DoorBirdScheduleEntry.parse_all(
load_json_value_fixture("schedule_wrong_param.json", "doorbird")
)
@pytest.fixture(scope="session")
def doorbird_favorites() -> dict[str, dict[str, Any]]:
"""Return a loaded DoorBird favorites fixture."""
@ -90,18 +98,21 @@ async def doorbird_mocker(
async def _async_mock(
entry: MockConfigEntry | None = None,
api: DoorBird | None = None,
change_schedule: tuple[bool, int] | None = None,
info: dict[str, Any] | None = None,
info_side_effect: Exception | None = None,
schedule: list[DoorBirdScheduleEntry] | None = None,
favorites: dict[str, dict[str, Any]] | None = None,
favorites_side_effect: Exception | None = None,
options: dict[str, Any] | None = None,
) -> MockDoorbirdEntry:
"""Create a MockDoorbirdEntry from defaults or specific values."""
entry = entry or MockConfigEntry(
domain=DOMAIN,
unique_id="1CCAE3AAAAAA",
data=VALID_CONFIG,
options={CONF_EVENTS: [DEFAULT_DOORBELL_EVENT, DEFAULT_MOTION_EVENT]},
options=options
or {CONF_EVENTS: [DEFAULT_DOORBELL_EVENT, DEFAULT_MOTION_EVENT]},
)
api = api or get_mock_doorbird_api(
info=info or doorbird_info,
@ -109,6 +120,7 @@ async def doorbird_mocker(
schedule=schedule or doorbird_schedule,
favorites=favorites or doorbird_favorites,
favorites_side_effect=favorites_side_effect,
change_schedule=change_schedule,
)
entry.add_to_hass(hass)
with patch_doorbird_api_entry_points(api):

View file

@ -0,0 +1,67 @@
[
{
"input": "doorbell",
"param": "99",
"output": [
{
"event": "notify",
"param": "",
"schedule": {
"weekdays": [
{
"to": "107999",
"from": "108000"
}
]
}
},
{
"event": "http",
"param": "0",
"schedule": {
"weekdays": [
{
"to": "107999",
"from": "108000"
}
]
}
}
]
},
{
"input": "motion",
"param": "",
"output": [
{
"event": "notify",
"param": "",
"schedule": {
"weekdays": [
{
"to": "107999",
"from": "108000"
}
]
}
},
{
"event": "http",
"param": "5",
"schedule": {
"weekdays": [
{
"to": "107999",
"from": "108000"
}
]
}
}
]
},
{
"input": "relay",
"param": "1",
"output": []
}
]

View file

@ -0,0 +1,59 @@
"""Test DoorBird device."""
from copy import deepcopy
from http import HTTPStatus
from doorbirdpy import DoorBirdScheduleEntry
import pytest
from homeassistant.components.doorbird.const import CONF_EVENTS
from homeassistant.core import HomeAssistant
from .conftest import DoorbirdMockerType
async def test_no_configured_events(
hass: HomeAssistant,
doorbird_mocker: DoorbirdMockerType,
) -> None:
"""Test a doorbird with no events configured."""
await doorbird_mocker(options={CONF_EVENTS: []})
assert not hass.states.async_all("event")
async def test_change_schedule_success(
doorbird_mocker: DoorbirdMockerType,
doorbird_schedule_wrong_param: list[DoorBirdScheduleEntry],
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test a doorbird when change_schedule fails."""
schedule_copy = deepcopy(doorbird_schedule_wrong_param)
mock_doorbird = await doorbird_mocker(schedule=schedule_copy)
assert "Unable to update schedule entry mydoorbird" not in caplog.text
assert mock_doorbird.api.change_schedule.call_count == 1
new_schedule: list[DoorBirdScheduleEntry] = (
mock_doorbird.api.change_schedule.call_args[0]
)
# Ensure the attempt to update the schedule to fix the incorrect
# param is made
assert new_schedule[-1].output[-1].param == "1"
async def test_change_schedule_fails(
doorbird_mocker: DoorbirdMockerType,
doorbird_schedule_wrong_param: list[DoorBirdScheduleEntry],
caplog: pytest.LogCaptureFixture,
) -> None:
"""Test a doorbird when change_schedule fails."""
schedule_copy = deepcopy(doorbird_schedule_wrong_param)
mock_doorbird = await doorbird_mocker(
schedule=schedule_copy, change_schedule=(False, HTTPStatus.UNAUTHORIZED)
)
assert "Unable to update schedule entry mydoorbird" in caplog.text
assert mock_doorbird.api.change_schedule.call_count == 1
new_schedule: list[DoorBirdScheduleEntry] = (
mock_doorbird.api.change_schedule.call_args[0]
)
# Ensure the attempt to update the schedule to fix the incorrect
# param is made
assert new_schedule[-1].output[-1].param == "1"