Bump uiprotect to 7.0.2 (#132975)

pull/133188/head
J. Nick Koston 2024-12-13 21:05:41 -05:00 committed by GitHub
parent 1aabbec3dd
commit 165ca5140c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
20 changed files with 152 additions and 126 deletions

View File

@ -40,7 +40,7 @@
"integration_type": "hub",
"iot_class": "local_push",
"loggers": ["uiprotect", "unifi_discovery"],
"requirements": ["uiprotect==6.8.0", "unifi-discovery==1.2.0"],
"requirements": ["uiprotect==7.0.2", "unifi-discovery==1.2.0"],
"ssdp": [
{
"manufacturer": "Ubiquiti Networks",

View File

@ -5,7 +5,7 @@ from __future__ import annotations
import asyncio
from typing import Any, cast
from pydantic.v1 import ValidationError
from pydantic import ValidationError
from uiprotect.api import ProtectApiClient
from uiprotect.data import Camera, Chime
from uiprotect.exceptions import ClientError

View File

@ -2905,7 +2905,7 @@ typedmonarchmoney==0.3.1
uasiren==0.0.1
# homeassistant.components.unifiprotect
uiprotect==6.8.0
uiprotect==7.0.2
# homeassistant.components.landisgyr_heat_meter
ultraheat-api==0.5.7

View File

@ -2324,7 +2324,7 @@ typedmonarchmoney==0.3.1
uasiren==0.0.1
# homeassistant.components.unifiprotect
uiprotect==6.8.0
uiprotect==7.0.2
# homeassistant.components.landisgyr_heat_meter
ultraheat-api==0.5.7

View File

@ -51,11 +51,11 @@ def mock_nvr():
nvr = NVR.from_unifi_dict(**data)
# disable pydantic validation so mocking can happen
NVR.__config__.validate_assignment = False
NVR.model_config["validate_assignment"] = False
yield nvr
NVR.__config__.validate_assignment = True
NVR.model_config["validate_assignment"] = True
@pytest.fixture(name="ufp_config_entry")
@ -120,7 +120,11 @@ def mock_ufp_client(bootstrap: Bootstrap):
client.base_url = "https://127.0.0.1"
client.connection_host = IPv4Address("127.0.0.1")
client.get_nvr = AsyncMock(return_value=nvr)
async def get_nvr(*args: Any, **kwargs: Any) -> NVR:
return client.bootstrap.nvr
client.get_nvr = get_nvr
client.get_bootstrap = AsyncMock(return_value=bootstrap)
client.update = AsyncMock(return_value=bootstrap)
client.async_disconnect_ws = AsyncMock()
@ -173,7 +177,7 @@ def camera_fixture(fixed_now: datetime):
"""Mock UniFi Protect Camera device."""
# disable pydantic validation so mocking can happen
Camera.__config__.validate_assignment = False
Camera.model_config["validate_assignment"] = False
data = json.loads(load_fixture("sample_camera.json", integration=DOMAIN))
camera = Camera.from_unifi_dict(**data)
@ -181,23 +185,23 @@ def camera_fixture(fixed_now: datetime):
yield camera
Camera.__config__.validate_assignment = True
Camera.model_config["validate_assignment"] = True
@pytest.fixture(name="camera_all")
def camera_all_fixture(camera: Camera):
"""Mock UniFi Protect Camera device."""
all_camera = camera.copy()
all_camera.channels = [all_camera.channels[0].copy()]
all_camera = camera.model_copy()
all_camera.channels = [all_camera.channels[0].model_copy()]
medium_channel = all_camera.channels[0].copy()
medium_channel = all_camera.channels[0].model_copy()
medium_channel.name = "Medium"
medium_channel.id = 1
medium_channel.rtsp_alias = "test_medium_alias"
all_camera.channels.append(medium_channel)
low_channel = all_camera.channels[0].copy()
low_channel = all_camera.channels[0].model_copy()
low_channel.name = "Low"
low_channel.id = 2
low_channel.rtsp_alias = "test_medium_alias"
@ -210,10 +214,10 @@ def camera_all_fixture(camera: Camera):
def doorbell_fixture(camera: Camera, fixed_now: datetime):
"""Mock UniFi Protect Camera device (with chime)."""
doorbell = camera.copy()
doorbell.channels = [c.copy() for c in doorbell.channels]
doorbell = camera.model_copy()
doorbell.channels = [c.model_copy() for c in doorbell.channels]
package_channel = doorbell.channels[0].copy()
package_channel = doorbell.channels[0].model_copy()
package_channel.name = "Package Camera"
package_channel.id = 3
package_channel.fps = 2
@ -247,8 +251,8 @@ def doorbell_fixture(camera: Camera, fixed_now: datetime):
def unadopted_camera(camera: Camera):
"""Mock UniFi Protect Camera device (unadopted)."""
no_camera = camera.copy()
no_camera.channels = [c.copy() for c in no_camera.channels]
no_camera = camera.model_copy()
no_camera.channels = [c.model_copy() for c in no_camera.channels]
no_camera.name = "Unadopted Camera"
no_camera.is_adopted = False
return no_camera
@ -259,19 +263,19 @@ def light_fixture():
"""Mock UniFi Protect Light device."""
# disable pydantic validation so mocking can happen
Light.__config__.validate_assignment = False
Light.model_config["validate_assignment"] = False
data = json.loads(load_fixture("sample_light.json", integration=DOMAIN))
yield Light.from_unifi_dict(**data)
Light.__config__.validate_assignment = True
Light.model_config["validate_assignment"] = True
@pytest.fixture
def unadopted_light(light: Light):
"""Mock UniFi Protect Light device (unadopted)."""
no_light = light.copy()
no_light = light.model_copy()
no_light.name = "Unadopted Light"
no_light.is_adopted = False
return no_light
@ -282,12 +286,12 @@ def viewer():
"""Mock UniFi Protect Viewport device."""
# disable pydantic validation so mocking can happen
Viewer.__config__.validate_assignment = False
Viewer.model_config["validate_assignment"] = False
data = json.loads(load_fixture("sample_viewport.json", integration=DOMAIN))
yield Viewer.from_unifi_dict(**data)
Viewer.__config__.validate_assignment = True
Viewer.model_config["validate_assignment"] = True
@pytest.fixture(name="sensor")
@ -295,7 +299,7 @@ def sensor_fixture(fixed_now: datetime):
"""Mock UniFi Protect Sensor device."""
# disable pydantic validation so mocking can happen
Sensor.__config__.validate_assignment = False
Sensor.model_config["validate_assignment"] = False
data = json.loads(load_fixture("sample_sensor.json", integration=DOMAIN))
sensor: Sensor = Sensor.from_unifi_dict(**data)
@ -304,14 +308,14 @@ def sensor_fixture(fixed_now: datetime):
sensor.alarm_triggered_at = fixed_now - timedelta(hours=1)
yield sensor
Sensor.__config__.validate_assignment = True
Sensor.model_config["validate_assignment"] = True
@pytest.fixture(name="sensor_all")
def csensor_all_fixture(sensor: Sensor):
"""Mock UniFi Protect Sensor device."""
all_sensor = sensor.copy()
all_sensor = sensor.model_copy()
all_sensor.light_settings.is_enabled = True
all_sensor.humidity_settings.is_enabled = True
all_sensor.temperature_settings.is_enabled = True
@ -327,19 +331,19 @@ def doorlock_fixture():
"""Mock UniFi Protect Doorlock device."""
# disable pydantic validation so mocking can happen
Doorlock.__config__.validate_assignment = False
Doorlock.model_config["validate_assignment"] = False
data = json.loads(load_fixture("sample_doorlock.json", integration=DOMAIN))
yield Doorlock.from_unifi_dict(**data)
Doorlock.__config__.validate_assignment = True
Doorlock.model_config["validate_assignment"] = True
@pytest.fixture
def unadopted_doorlock(doorlock: Doorlock):
"""Mock UniFi Protect Light device (unadopted)."""
no_doorlock = doorlock.copy()
no_doorlock = doorlock.model_copy()
no_doorlock.name = "Unadopted Lock"
no_doorlock.is_adopted = False
return no_doorlock
@ -350,12 +354,12 @@ def chime():
"""Mock UniFi Protect Chime device."""
# disable pydantic validation so mocking can happen
Chime.__config__.validate_assignment = False
Chime.model_config["validate_assignment"] = False
data = json.loads(load_fixture("sample_chime.json", integration=DOMAIN))
yield Chime.from_unifi_dict(**data)
Chime.__config__.validate_assignment = True
Chime.model_config["validate_assignment"] = True
@pytest.fixture(name="fixed_now")

View File

@ -305,7 +305,7 @@ async def test_binary_sensor_update_motion(
api=ufp.api,
)
new_camera = doorbell.copy()
new_camera = doorbell.model_copy()
new_camera.is_motion_detected = True
new_camera.last_motion_event_id = event.id
@ -352,7 +352,7 @@ async def test_binary_sensor_update_light_motion(
api=ufp.api,
)
new_light = light.copy()
new_light = light.model_copy()
new_light.is_pir_motion_detected = True
new_light.last_motion_event_id = event.id
@ -386,7 +386,7 @@ async def test_binary_sensor_update_mount_type_window(
assert state
assert state.attributes[ATTR_DEVICE_CLASS] == BinarySensorDeviceClass.DOOR.value
new_sensor = sensor_all.copy()
new_sensor = sensor_all.model_copy()
new_sensor.mount_type = MountType.WINDOW
mock_msg = Mock()
@ -418,7 +418,7 @@ async def test_binary_sensor_update_mount_type_garage(
assert state
assert state.attributes[ATTR_DEVICE_CLASS] == BinarySensorDeviceClass.DOOR.value
new_sensor = sensor_all.copy()
new_sensor = sensor_all.model_copy()
new_sensor.mount_type = MountType.GARAGE
mock_msg = Mock()
@ -468,7 +468,7 @@ async def test_binary_sensor_package_detected(
api=ufp.api,
)
new_camera = doorbell.copy()
new_camera = doorbell.model_copy()
new_camera.is_smart_detected = True
new_camera.last_smart_detect_event_ids[SmartDetectObjectType.PACKAGE] = event.id
@ -501,7 +501,7 @@ async def test_binary_sensor_package_detected(
api=ufp.api,
)
new_camera = doorbell.copy()
new_camera = doorbell.model_copy()
new_camera.is_smart_detected = True
new_camera.last_smart_detect_event_ids[SmartDetectObjectType.PACKAGE] = event.id
@ -534,7 +534,7 @@ async def test_binary_sensor_package_detected(
api=ufp.api,
)
new_camera = doorbell.copy()
new_camera = doorbell.model_copy()
new_camera.is_smart_detected = True
new_camera.last_smart_detect_event_ids[SmartDetectObjectType.PACKAGE] = event.id
@ -611,7 +611,7 @@ async def test_binary_sensor_person_detected(
api=ufp.api,
)
new_camera = doorbell.copy()
new_camera = doorbell.model_copy()
new_camera.is_smart_detected = True
ufp.api.bootstrap.cameras = {new_camera.id: new_camera}
@ -641,7 +641,7 @@ async def test_binary_sensor_person_detected(
api=ufp.api,
)
new_camera = doorbell.copy()
new_camera = doorbell.model_copy()
new_camera.is_smart_detected = True
new_camera.last_smart_detect_event_ids[SmartDetectObjectType.PERSON] = event.id
@ -680,7 +680,7 @@ async def test_binary_sensor_person_detected(
api=ufp.api,
)
new_camera = doorbell.copy()
new_camera = doorbell.model_copy()
new_camera.is_smart_detected = True
new_camera.last_smart_detect_event_ids[SmartDetectObjectType.PERSON] = event.id

View File

@ -236,15 +236,15 @@ async def test_basic_setup(
) -> None:
"""Test working setup of unifiprotect entry."""
camera_high_only = camera_all.copy()
camera_high_only.channels = [c.copy() for c in camera_all.channels]
camera_high_only = camera_all.model_copy()
camera_high_only.channels = [c.model_copy() for c in camera_all.channels]
camera_high_only.name = "Test Camera 1"
camera_high_only.channels[0].is_rtsp_enabled = True
camera_high_only.channels[1].is_rtsp_enabled = False
camera_high_only.channels[2].is_rtsp_enabled = False
camera_medium_only = camera_all.copy()
camera_medium_only.channels = [c.copy() for c in camera_all.channels]
camera_medium_only = camera_all.model_copy()
camera_medium_only.channels = [c.model_copy() for c in camera_all.channels]
camera_medium_only.name = "Test Camera 2"
camera_medium_only.channels[0].is_rtsp_enabled = False
camera_medium_only.channels[1].is_rtsp_enabled = True
@ -252,8 +252,8 @@ async def test_basic_setup(
camera_all.name = "Test Camera 3"
camera_no_channels = camera_all.copy()
camera_no_channels.channels = [c.copy() for c in camera_all.channels]
camera_no_channels = camera_all.model_copy()
camera_no_channels.channels = [c.model_copy() for c in camera_all.channels]
camera_no_channels.name = "Test Camera 4"
camera_no_channels.channels[0].is_rtsp_enabled = False
camera_no_channels.channels[1].is_rtsp_enabled = False
@ -337,8 +337,8 @@ async def test_webrtc_support(
camera_all: ProtectCamera,
) -> None:
"""Test webrtc support is available."""
camera_high_only = camera_all.copy()
camera_high_only.channels = [c.copy() for c in camera_all.channels]
camera_high_only = camera_all.model_copy()
camera_high_only.channels = [c.model_copy() for c in camera_all.channels]
camera_high_only.name = "Test Camera 1"
camera_high_only.channels[0].is_rtsp_enabled = True
camera_high_only.channels[1].is_rtsp_enabled = False
@ -355,7 +355,7 @@ async def test_adopt(
) -> None:
"""Test setting up camera with no camera channels."""
camera1 = camera.copy()
camera1 = camera.model_copy()
camera1.channels = []
await init_entry(hass, ufp, [camera1])
@ -450,7 +450,7 @@ async def test_camera_interval_update(
state = hass.states.get(entity_id)
assert state and state.state == "idle"
new_camera = camera.copy()
new_camera = camera.model_copy()
new_camera.is_recording = True
ufp.api.bootstrap.cameras = {new_camera.id: new_camera}
@ -527,10 +527,10 @@ async def test_camera_ws_update(
state = hass.states.get(entity_id)
assert state and state.state == "idle"
new_camera = camera.copy()
new_camera = camera.model_copy()
new_camera.is_recording = True
no_camera = camera.copy()
no_camera = camera.model_copy()
no_camera.is_adopted = False
ufp.api.bootstrap.cameras = {new_camera.id: new_camera}
@ -563,7 +563,7 @@ async def test_camera_ws_update_offline(
assert state and state.state == "idle"
# camera goes offline
new_camera = camera.copy()
new_camera = camera.model_copy()
new_camera.state = StateType.DISCONNECTED
mock_msg = Mock()
@ -601,7 +601,7 @@ async def test_camera_enable_motion(
assert_entity_counts(hass, Platform.CAMERA, 2, 1)
entity_id = "camera.test_camera_high_resolution_channel"
camera.__fields__["set_motion_detection"] = Mock(final=False)
camera.__pydantic_fields__["set_motion_detection"] = Mock(final=False, frozen=False)
camera.set_motion_detection = AsyncMock()
await hass.services.async_call(
@ -623,7 +623,7 @@ async def test_camera_disable_motion(
assert_entity_counts(hass, Platform.CAMERA, 2, 1)
entity_id = "camera.test_camera_high_resolution_channel"
camera.__fields__["set_motion_detection"] = Mock(final=False)
camera.__pydantic_fields__["set_motion_detection"] = Mock(final=False, frozen=False)
camera.set_motion_detection = AsyncMock()
await hass.services.async_call(

View File

@ -75,7 +75,7 @@ async def test_doorbell_ring(
api=ufp.api,
)
new_camera = doorbell.copy()
new_camera = doorbell.model_copy()
new_camera.last_ring_event_id = "test_event_id"
ufp.api.bootstrap.cameras = {new_camera.id: new_camera}
ufp.api.bootstrap.events = {event.id: event}
@ -107,7 +107,7 @@ async def test_doorbell_ring(
api=ufp.api,
)
new_camera = doorbell.copy()
new_camera = doorbell.model_copy()
ufp.api.bootstrap.cameras = {new_camera.id: new_camera}
ufp.api.bootstrap.events = {event.id: event}
@ -137,7 +137,7 @@ async def test_doorbell_ring(
api=ufp.api,
)
new_camera = doorbell.copy()
new_camera = doorbell.model_copy()
ufp.api.bootstrap.cameras = {new_camera.id: new_camera}
ufp.api.bootstrap.events = {event.id: event}
@ -190,7 +190,7 @@ async def test_doorbell_nfc_scanned(
metadata={"nfc": {"nfc_id": "test_nfc_id", "user_id": "test_user_id"}},
)
new_camera = doorbell.copy()
new_camera = doorbell.model_copy()
new_camera.last_nfc_card_scanned_event_id = "test_event_id"
ufp.api.bootstrap.cameras = {new_camera.id: new_camera}
ufp.api.bootstrap.events = {event.id: event}
@ -248,7 +248,7 @@ async def test_doorbell_fingerprint_identified(
metadata={"fingerprint": {"ulp_id": "test_ulp_id"}},
)
new_camera = doorbell.copy()
new_camera = doorbell.model_copy()
new_camera.last_fingerprint_identified_event_id = "test_event_id"
ufp.api.bootstrap.cameras = {new_camera.id: new_camera}
ufp.api.bootstrap.events = {event.id: event}
@ -306,7 +306,7 @@ async def test_doorbell_fingerprint_not_identified(
metadata={"fingerprint": {}},
)
new_camera = doorbell.copy()
new_camera = doorbell.model_copy()
new_camera.last_fingerprint_identified_event_id = "test_event_id"
ufp.api.bootstrap.cameras = {new_camera.id: new_camera}
ufp.api.bootstrap.events = {event.id: event}

View File

@ -118,7 +118,7 @@ async def test_setup_too_old(
) -> None:
"""Test setup of unifiprotect entry with too old of version of UniFi Protect."""
old_bootstrap = ufp.api.bootstrap.copy()
old_bootstrap = ufp.api.bootstrap.model_copy()
old_bootstrap.nvr = old_nvr
ufp.api.update.return_value = old_bootstrap
ufp.api.bootstrap = old_bootstrap

View File

@ -74,7 +74,7 @@ async def test_light_update(
await init_entry(hass, ufp, [light, unadopted_light])
assert_entity_counts(hass, Platform.LIGHT, 1, 1)
new_light = light.copy()
new_light = light.model_copy()
new_light.is_light_on = True
new_light.light_device_settings.led_level = LEDLevel(3)
@ -101,7 +101,7 @@ async def test_light_turn_on(
assert_entity_counts(hass, Platform.LIGHT, 1, 1)
entity_id = "light.test_light"
light.__fields__["set_light"] = Mock(final=False)
light.__pydantic_fields__["set_light"] = Mock(final=False, frozen=False)
light.set_light = AsyncMock()
await hass.services.async_call(
@ -123,7 +123,7 @@ async def test_light_turn_off(
assert_entity_counts(hass, Platform.LIGHT, 1, 1)
entity_id = "light.test_light"
light.__fields__["set_light"] = Mock(final=False)
light.__pydantic_fields__["set_light"] = Mock(final=False, frozen=False)
light.set_light = AsyncMock()
await hass.services.async_call(

View File

@ -75,7 +75,7 @@ async def test_lock_locked(
await init_entry(hass, ufp, [doorlock, unadopted_doorlock])
assert_entity_counts(hass, Platform.LOCK, 1, 1)
new_lock = doorlock.copy()
new_lock = doorlock.model_copy()
new_lock.lock_status = LockStatusType.CLOSED
mock_msg = Mock()
@ -102,7 +102,7 @@ async def test_lock_unlocking(
await init_entry(hass, ufp, [doorlock, unadopted_doorlock])
assert_entity_counts(hass, Platform.LOCK, 1, 1)
new_lock = doorlock.copy()
new_lock = doorlock.model_copy()
new_lock.lock_status = LockStatusType.OPENING
mock_msg = Mock()
@ -129,7 +129,7 @@ async def test_lock_locking(
await init_entry(hass, ufp, [doorlock, unadopted_doorlock])
assert_entity_counts(hass, Platform.LOCK, 1, 1)
new_lock = doorlock.copy()
new_lock = doorlock.model_copy()
new_lock.lock_status = LockStatusType.CLOSING
mock_msg = Mock()
@ -156,7 +156,7 @@ async def test_lock_jammed(
await init_entry(hass, ufp, [doorlock, unadopted_doorlock])
assert_entity_counts(hass, Platform.LOCK, 1, 1)
new_lock = doorlock.copy()
new_lock = doorlock.model_copy()
new_lock.lock_status = LockStatusType.JAMMED_WHILE_CLOSING
mock_msg = Mock()
@ -183,7 +183,7 @@ async def test_lock_unavailable(
await init_entry(hass, ufp, [doorlock, unadopted_doorlock])
assert_entity_counts(hass, Platform.LOCK, 1, 1)
new_lock = doorlock.copy()
new_lock = doorlock.model_copy()
new_lock.lock_status = LockStatusType.NOT_CALIBRATED
mock_msg = Mock()
@ -210,7 +210,7 @@ async def test_lock_do_lock(
await init_entry(hass, ufp, [doorlock, unadopted_doorlock])
assert_entity_counts(hass, Platform.LOCK, 1, 1)
doorlock.__fields__["close_lock"] = Mock(final=False)
doorlock.__pydantic_fields__["close_lock"] = Mock(final=False, frozen=False)
doorlock.close_lock = AsyncMock()
await hass.services.async_call(
@ -234,7 +234,7 @@ async def test_lock_do_unlock(
await init_entry(hass, ufp, [doorlock, unadopted_doorlock])
assert_entity_counts(hass, Platform.LOCK, 1, 1)
new_lock = doorlock.copy()
new_lock = doorlock.model_copy()
new_lock.lock_status = LockStatusType.CLOSED
mock_msg = Mock()
@ -245,7 +245,7 @@ async def test_lock_do_unlock(
ufp.ws_msg(mock_msg)
await hass.async_block_till_done()
new_lock.__fields__["open_lock"] = Mock(final=False)
doorlock.__pydantic_fields__["open_lock"] = Mock(final=False, frozen=False)
new_lock.open_lock = AsyncMock()
await hass.services.async_call(

View File

@ -88,7 +88,7 @@ async def test_media_player_update(
await init_entry(hass, ufp, [doorbell, unadopted_camera])
assert_entity_counts(hass, Platform.MEDIA_PLAYER, 1, 1)
new_camera = doorbell.copy()
new_camera = doorbell.model_copy()
new_camera.talkback_stream = Mock()
new_camera.talkback_stream.is_running = True
@ -116,7 +116,7 @@ async def test_media_player_set_volume(
await init_entry(hass, ufp, [doorbell, unadopted_camera])
assert_entity_counts(hass, Platform.MEDIA_PLAYER, 1, 1)
doorbell.__fields__["set_speaker_volume"] = Mock(final=False)
doorbell.__pydantic_fields__["set_speaker_volume"] = Mock(final=False, frozen=False)
doorbell.set_speaker_volume = AsyncMock()
await hass.services.async_call(
@ -140,7 +140,7 @@ async def test_media_player_stop(
await init_entry(hass, ufp, [doorbell, unadopted_camera])
assert_entity_counts(hass, Platform.MEDIA_PLAYER, 1, 1)
new_camera = doorbell.copy()
new_camera = doorbell.model_copy()
new_camera.talkback_stream = AsyncMock()
new_camera.talkback_stream.is_running = True
@ -173,9 +173,11 @@ async def test_media_player_play(
await init_entry(hass, ufp, [doorbell, unadopted_camera])
assert_entity_counts(hass, Platform.MEDIA_PLAYER, 1, 1)
doorbell.__fields__["stop_audio"] = Mock(final=False)
doorbell.__fields__["play_audio"] = Mock(final=False)
doorbell.__fields__["wait_until_audio_completes"] = Mock(final=False)
doorbell.__pydantic_fields__["stop_audio"] = Mock(final=False, frozen=False)
doorbell.__pydantic_fields__["play_audio"] = Mock(final=False, frozen=False)
doorbell.__pydantic_fields__["wait_until_audio_completes"] = Mock(
final=False, frozen=False
)
doorbell.stop_audio = AsyncMock()
doorbell.play_audio = AsyncMock()
doorbell.wait_until_audio_completes = AsyncMock()
@ -208,9 +210,11 @@ async def test_media_player_play_media_source(
await init_entry(hass, ufp, [doorbell, unadopted_camera])
assert_entity_counts(hass, Platform.MEDIA_PLAYER, 1, 1)
doorbell.__fields__["stop_audio"] = Mock(final=False)
doorbell.__fields__["play_audio"] = Mock(final=False)
doorbell.__fields__["wait_until_audio_completes"] = Mock(final=False)
doorbell.__pydantic_fields__["stop_audio"] = Mock(final=False, frozen=False)
doorbell.__pydantic_fields__["play_audio"] = Mock(final=False, frozen=False)
doorbell.__pydantic_fields__["wait_until_audio_completes"] = Mock(
final=False, frozen=False
)
doorbell.stop_audio = AsyncMock()
doorbell.play_audio = AsyncMock()
doorbell.wait_until_audio_completes = AsyncMock()
@ -247,7 +251,7 @@ async def test_media_player_play_invalid(
await init_entry(hass, ufp, [doorbell, unadopted_camera])
assert_entity_counts(hass, Platform.MEDIA_PLAYER, 1, 1)
doorbell.__fields__["play_audio"] = Mock(final=False)
doorbell.__pydantic_fields__["play_audio"] = Mock(final=False, frozen=False)
doorbell.play_audio = AsyncMock()
with pytest.raises(HomeAssistantError):
@ -276,8 +280,10 @@ async def test_media_player_play_error(
await init_entry(hass, ufp, [doorbell, unadopted_camera])
assert_entity_counts(hass, Platform.MEDIA_PLAYER, 1, 1)
doorbell.__fields__["play_audio"] = Mock(final=False)
doorbell.__fields__["wait_until_audio_completes"] = Mock(final=False)
doorbell.__pydantic_fields__["play_audio"] = Mock(final=False, frozen=False)
doorbell.__pydantic_fields__["wait_until_audio_completes"] = Mock(
final=False, frozen=False
)
doorbell.play_audio = AsyncMock(side_effect=StreamError)
doorbell.wait_until_audio_completes = AsyncMock()

View File

@ -204,9 +204,9 @@ async def test_browse_media_root_multiple_consoles(
await hass.config_entries.async_setup(ufp.entry.entry_id)
await hass.async_block_till_done()
bootstrap2 = bootstrap.copy()
bootstrap2 = bootstrap.model_copy()
bootstrap2._has_media = True
bootstrap2.nvr = bootstrap.nvr.copy()
bootstrap2.nvr = bootstrap.nvr.model_copy()
bootstrap2.nvr.id = "test_id2"
bootstrap2.nvr.mac = "A2E00C826924"
bootstrap2.nvr.name = "UnifiProtect2"
@ -270,9 +270,9 @@ async def test_browse_media_root_multiple_consoles_only_one_media(
await hass.config_entries.async_setup(ufp.entry.entry_id)
await hass.async_block_till_done()
bootstrap2 = bootstrap.copy()
bootstrap2 = bootstrap.model_copy()
bootstrap2._has_media = False
bootstrap2.nvr = bootstrap.nvr.copy()
bootstrap2.nvr = bootstrap.nvr.model_copy()
bootstrap2.nvr.id = "test_id2"
bootstrap2.nvr.mac = "A2E00C826924"
bootstrap2.nvr.name = "UnifiProtect2"

View File

@ -162,7 +162,7 @@ async def test_number_light_sensitivity(
description = LIGHT_NUMBERS[0]
assert description.ufp_set_method is not None
light.__fields__["set_sensitivity"] = Mock(final=False)
light.__pydantic_fields__["set_sensitivity"] = Mock(final=False, frozen=False)
light.set_sensitivity = AsyncMock()
_, entity_id = ids_from_device_description(Platform.NUMBER, light, description)
@ -184,7 +184,7 @@ async def test_number_light_duration(
description = LIGHT_NUMBERS[1]
light.__fields__["set_duration"] = Mock(final=False)
light.__pydantic_fields__["set_duration"] = Mock(final=False, frozen=False)
light.set_duration = AsyncMock()
_, entity_id = ids_from_device_description(Platform.NUMBER, light, description)
@ -210,7 +210,9 @@ async def test_number_camera_simple(
assert description.ufp_set_method is not None
camera.__fields__[description.ufp_set_method] = Mock(final=False)
camera.__pydantic_fields__[description.ufp_set_method] = Mock(
final=False, frozen=False
)
setattr(camera, description.ufp_set_method, AsyncMock())
_, entity_id = ids_from_device_description(Platform.NUMBER, camera, description)
@ -230,7 +232,9 @@ async def test_number_lock_auto_close(
description = DOORLOCK_NUMBERS[0]
doorlock.__fields__["set_auto_close_time"] = Mock(final=False)
doorlock.__pydantic_fields__["set_auto_close_time"] = Mock(
final=False, frozen=False
)
doorlock.set_auto_close_time = AsyncMock()
_, entity_id = ids_from_device_description(Platform.NUMBER, doorlock, description)

View File

@ -51,7 +51,7 @@ async def test_exclude_attributes(
camera_id=doorbell.id,
)
new_camera = doorbell.copy()
new_camera = doorbell.model_copy()
new_camera.is_motion_detected = True
new_camera.last_motion_event_id = event.id

View File

@ -262,7 +262,7 @@ async def test_select_update_doorbell_settings(
expected_length += 1
new_nvr = copy(ufp.api.bootstrap.nvr)
new_nvr.__fields__["update_all_messages"] = Mock(final=False)
new_nvr.__pydantic_fields__["update_all_messages"] = Mock(final=False, frozen=False)
new_nvr.update_all_messages = Mock()
new_nvr.doorbell_settings.all_messages = [
@ -304,7 +304,7 @@ async def test_select_update_doorbell_message(
assert state
assert state.state == "Default Message (Welcome)"
new_camera = doorbell.copy()
new_camera = doorbell.model_copy()
new_camera.lcd_message = LCDMessage(
type=DoorbellMessageType.CUSTOM_MESSAGE, text="Test"
)
@ -332,7 +332,7 @@ async def test_select_set_option_light_motion(
_, entity_id = ids_from_device_description(Platform.SELECT, light, LIGHT_SELECTS[0])
light.__fields__["set_light_settings"] = Mock(final=False)
light.__pydantic_fields__["set_light_settings"] = Mock(final=False, frozen=False)
light.set_light_settings = AsyncMock()
await hass.services.async_call(
@ -357,7 +357,7 @@ async def test_select_set_option_light_camera(
_, entity_id = ids_from_device_description(Platform.SELECT, light, LIGHT_SELECTS[1])
light.__fields__["set_paired_camera"] = Mock(final=False)
light.__pydantic_fields__["set_paired_camera"] = Mock(final=False, frozen=False)
light.set_paired_camera = AsyncMock()
camera = list(light.api.bootstrap.cameras.values())[0]
@ -393,7 +393,7 @@ async def test_select_set_option_camera_recording(
Platform.SELECT, doorbell, CAMERA_SELECTS[0]
)
doorbell.__fields__["set_recording_mode"] = Mock(final=False)
doorbell.__pydantic_fields__["set_recording_mode"] = Mock(final=False, frozen=False)
doorbell.set_recording_mode = AsyncMock()
await hass.services.async_call(
@ -418,7 +418,7 @@ async def test_select_set_option_camera_ir(
Platform.SELECT, doorbell, CAMERA_SELECTS[1]
)
doorbell.__fields__["set_ir_led_model"] = Mock(final=False)
doorbell.__pydantic_fields__["set_ir_led_model"] = Mock(final=False, frozen=False)
doorbell.set_ir_led_model = AsyncMock()
await hass.services.async_call(
@ -443,7 +443,7 @@ async def test_select_set_option_camera_doorbell_custom(
Platform.SELECT, doorbell, CAMERA_SELECTS[2]
)
doorbell.__fields__["set_lcd_text"] = Mock(final=False)
doorbell.__pydantic_fields__["set_lcd_text"] = Mock(final=False, frozen=False)
doorbell.set_lcd_text = AsyncMock()
await hass.services.async_call(
@ -470,7 +470,7 @@ async def test_select_set_option_camera_doorbell_unifi(
Platform.SELECT, doorbell, CAMERA_SELECTS[2]
)
doorbell.__fields__["set_lcd_text"] = Mock(final=False)
doorbell.__pydantic_fields__["set_lcd_text"] = Mock(final=False, frozen=False)
doorbell.set_lcd_text = AsyncMock()
await hass.services.async_call(
@ -512,7 +512,7 @@ async def test_select_set_option_camera_doorbell_default(
Platform.SELECT, doorbell, CAMERA_SELECTS[2]
)
doorbell.__fields__["set_lcd_text"] = Mock(final=False)
doorbell.__pydantic_fields__["set_lcd_text"] = Mock(final=False, frozen=False)
doorbell.set_lcd_text = AsyncMock()
await hass.services.async_call(
@ -541,7 +541,7 @@ async def test_select_set_option_viewer(
Platform.SELECT, viewer, VIEWER_SELECTS[0]
)
viewer.__fields__["set_liveview"] = Mock(final=False)
viewer.__pydantic_fields__["set_liveview"] = Mock(final=False, frozen=False)
viewer.set_liveview = AsyncMock()
liveview = list(viewer.api.bootstrap.liveviews.values())[0]

View File

@ -464,7 +464,7 @@ async def test_sensor_update_alarm(
api=ufp.api,
)
new_sensor = sensor_all.copy()
new_sensor = sensor_all.model_copy()
new_sensor.set_alarm_timeout()
new_sensor.last_alarm_event_id = event.id
@ -548,7 +548,7 @@ async def test_camera_update_license_plate(
api=ufp.api,
)
new_camera = camera.copy()
new_camera = camera.model_copy()
new_camera.is_smart_detected = True
new_camera.last_smart_detect_event_ids[SmartDetectObjectType.LICENSE_PLATE] = (
event.id
@ -663,7 +663,7 @@ async def test_camera_update_license_plate_changes_number_during_detect(
api=ufp.api,
)
new_camera = camera.copy()
new_camera = camera.model_copy()
new_camera.is_smart_detected = True
new_camera.last_smart_detect_event_ids[SmartDetectObjectType.LICENSE_PLATE] = (
event.id
@ -750,7 +750,7 @@ async def test_camera_update_license_plate_multiple_updates(
api=ufp.api,
)
new_camera = camera.copy()
new_camera = camera.model_copy()
new_camera.is_smart_detected = True
new_camera.last_smart_detect_event_ids[SmartDetectObjectType.LICENSE_PLATE] = (
event.id
@ -873,7 +873,7 @@ async def test_camera_update_license_no_dupes(
api=ufp.api,
)
new_camera = camera.copy()
new_camera = camera.model_copy()
new_camera.is_smart_detected = True
new_camera.last_smart_detect_event_ids[SmartDetectObjectType.LICENSE_PLATE] = (
event.id

View File

@ -56,7 +56,9 @@ async def test_global_service_bad_device(
"""Test global service, invalid device ID."""
nvr = ufp.api.bootstrap.nvr
nvr.__fields__["add_custom_doorbell_message"] = Mock(final=False)
nvr.__pydantic_fields__["add_custom_doorbell_message"] = Mock(
final=False, frozen=False
)
nvr.add_custom_doorbell_message = AsyncMock()
with pytest.raises(HomeAssistantError):
@ -75,7 +77,9 @@ async def test_global_service_exception(
"""Test global service, unexpected error."""
nvr = ufp.api.bootstrap.nvr
nvr.__fields__["add_custom_doorbell_message"] = Mock(final=False)
nvr.__pydantic_fields__["add_custom_doorbell_message"] = Mock(
final=False, frozen=False
)
nvr.add_custom_doorbell_message = AsyncMock(side_effect=BadRequest)
with pytest.raises(HomeAssistantError):
@ -94,7 +98,9 @@ async def test_add_doorbell_text(
"""Test add_doorbell_text service."""
nvr = ufp.api.bootstrap.nvr
nvr.__fields__["add_custom_doorbell_message"] = Mock(final=False)
nvr.__pydantic_fields__["add_custom_doorbell_message"] = Mock(
final=False, frozen=False
)
nvr.add_custom_doorbell_message = AsyncMock()
await hass.services.async_call(
@ -112,7 +118,9 @@ async def test_remove_doorbell_text(
"""Test remove_doorbell_text service."""
nvr = ufp.api.bootstrap.nvr
nvr.__fields__["remove_custom_doorbell_message"] = Mock(final=False)
nvr.__pydantic_fields__["remove_custom_doorbell_message"] = Mock(
final=False, frozen=False
)
nvr.remove_custom_doorbell_message = AsyncMock()
await hass.services.async_call(
@ -129,7 +137,9 @@ async def test_add_doorbell_text_disabled_config_entry(
) -> None:
"""Test add_doorbell_text service."""
nvr = ufp.api.bootstrap.nvr
nvr.__fields__["add_custom_doorbell_message"] = Mock(final=False)
nvr.__pydantic_fields__["add_custom_doorbell_message"] = Mock(
final=False, frozen=False
)
nvr.add_custom_doorbell_message = AsyncMock()
await hass.config_entries.async_set_disabled_by(
@ -158,10 +168,10 @@ async def test_set_chime_paired_doorbells(
ufp.api.update_device = AsyncMock()
camera1 = doorbell.copy()
camera1 = doorbell.model_copy()
camera1.name = "Test Camera 1"
camera2 = doorbell.copy()
camera2 = doorbell.model_copy()
camera2.name = "Test Camera 2"
await init_entry(hass, ufp, [camera1, camera2, chime])

View File

@ -89,7 +89,7 @@ async def test_switch_nvr(hass: HomeAssistant, ufp: MockUFPFixture) -> None:
assert_entity_counts(hass, Platform.SWITCH, 2, 2)
nvr = ufp.api.bootstrap.nvr
nvr.__fields__["set_insights"] = Mock(final=False)
nvr.__pydantic_fields__["set_insights"] = Mock(final=False, frozen=False)
nvr.set_insights = AsyncMock()
entity_id = "switch.unifiprotect_insights_enabled"
@ -272,7 +272,7 @@ async def test_switch_light_status(
description = LIGHT_SWITCHES[1]
light.__fields__["set_status_light"] = Mock(final=False)
light.__pydantic_fields__["set_status_light"] = Mock(final=False, frozen=False)
light.set_status_light = AsyncMock()
_, entity_id = ids_from_device_description(Platform.SWITCH, light, description)
@ -300,7 +300,7 @@ async def test_switch_camera_ssh(
description = CAMERA_SWITCHES[0]
doorbell.__fields__["set_ssh"] = Mock(final=False)
doorbell.__pydantic_fields__["set_ssh"] = Mock(final=False, frozen=False)
doorbell.set_ssh = AsyncMock()
_, entity_id = ids_from_device_description(Platform.SWITCH, doorbell, description)
@ -333,7 +333,9 @@ async def test_switch_camera_simple(
assert description.ufp_set_method is not None
doorbell.__fields__[description.ufp_set_method] = Mock(final=False)
doorbell.__pydantic_fields__[description.ufp_set_method] = Mock(
final=False, frozen=False
)
setattr(doorbell, description.ufp_set_method, AsyncMock())
set_method = getattr(doorbell, description.ufp_set_method)
@ -362,7 +364,7 @@ async def test_switch_camera_highfps(
description = CAMERA_SWITCHES[3]
doorbell.__fields__["set_video_mode"] = Mock(final=False)
doorbell.__pydantic_fields__["set_video_mode"] = Mock(final=False, frozen=False)
doorbell.set_video_mode = AsyncMock()
_, entity_id = ids_from_device_description(Platform.SWITCH, doorbell, description)
@ -393,7 +395,7 @@ async def test_switch_camera_privacy(
description = PRIVACY_MODE_SWITCH
doorbell.__fields__["set_privacy"] = Mock(final=False)
doorbell.__pydantic_fields__["set_privacy"] = Mock(final=False, frozen=False)
doorbell.set_privacy = AsyncMock()
_, entity_id = ids_from_device_description(Platform.SWITCH, doorbell, description)
@ -409,7 +411,7 @@ async def test_switch_camera_privacy(
doorbell.set_privacy.assert_called_with(True, 0, RecordingMode.NEVER)
new_doorbell = doorbell.copy()
new_doorbell = doorbell.model_copy()
new_doorbell.add_privacy_zone()
new_doorbell.mic_volume = 0
new_doorbell.recording_settings.mode = RecordingMode.NEVER
@ -445,7 +447,7 @@ async def test_switch_camera_privacy_already_on(
description = PRIVACY_MODE_SWITCH
doorbell.__fields__["set_privacy"] = Mock(final=False)
doorbell.__pydantic_fields__["set_privacy"] = Mock(final=False, frozen=False)
doorbell.set_privacy = AsyncMock()
_, entity_id = ids_from_device_description(Platform.SWITCH, doorbell, description)

View File

@ -78,7 +78,7 @@ async def test_text_camera_set(
Platform.TEXT, doorbell, description
)
doorbell.__fields__["set_lcd_text"] = Mock(final=False)
doorbell.__pydantic_fields__["set_lcd_text"] = Mock(final=False, frozen=False)
doorbell.set_lcd_text = AsyncMock()
await hass.services.async_call(