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", "integration_type": "hub",
"iot_class": "local_push", "iot_class": "local_push",
"loggers": ["uiprotect", "unifi_discovery"], "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": [ "ssdp": [
{ {
"manufacturer": "Ubiquiti Networks", "manufacturer": "Ubiquiti Networks",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -75,7 +75,7 @@ async def test_doorbell_ring(
api=ufp.api, api=ufp.api,
) )
new_camera = doorbell.copy() new_camera = doorbell.model_copy()
new_camera.last_ring_event_id = "test_event_id" new_camera.last_ring_event_id = "test_event_id"
ufp.api.bootstrap.cameras = {new_camera.id: new_camera} ufp.api.bootstrap.cameras = {new_camera.id: new_camera}
ufp.api.bootstrap.events = {event.id: event} ufp.api.bootstrap.events = {event.id: event}
@ -107,7 +107,7 @@ async def test_doorbell_ring(
api=ufp.api, api=ufp.api,
) )
new_camera = doorbell.copy() new_camera = doorbell.model_copy()
ufp.api.bootstrap.cameras = {new_camera.id: new_camera} ufp.api.bootstrap.cameras = {new_camera.id: new_camera}
ufp.api.bootstrap.events = {event.id: event} ufp.api.bootstrap.events = {event.id: event}
@ -137,7 +137,7 @@ async def test_doorbell_ring(
api=ufp.api, api=ufp.api,
) )
new_camera = doorbell.copy() new_camera = doorbell.model_copy()
ufp.api.bootstrap.cameras = {new_camera.id: new_camera} ufp.api.bootstrap.cameras = {new_camera.id: new_camera}
ufp.api.bootstrap.events = {event.id: event} 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"}}, 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" new_camera.last_nfc_card_scanned_event_id = "test_event_id"
ufp.api.bootstrap.cameras = {new_camera.id: new_camera} ufp.api.bootstrap.cameras = {new_camera.id: new_camera}
ufp.api.bootstrap.events = {event.id: event} ufp.api.bootstrap.events = {event.id: event}
@ -248,7 +248,7 @@ async def test_doorbell_fingerprint_identified(
metadata={"fingerprint": {"ulp_id": "test_ulp_id"}}, 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" new_camera.last_fingerprint_identified_event_id = "test_event_id"
ufp.api.bootstrap.cameras = {new_camera.id: new_camera} ufp.api.bootstrap.cameras = {new_camera.id: new_camera}
ufp.api.bootstrap.events = {event.id: event} ufp.api.bootstrap.events = {event.id: event}
@ -306,7 +306,7 @@ async def test_doorbell_fingerprint_not_identified(
metadata={"fingerprint": {}}, metadata={"fingerprint": {}},
) )
new_camera = doorbell.copy() new_camera = doorbell.model_copy()
new_camera.last_fingerprint_identified_event_id = "test_event_id" new_camera.last_fingerprint_identified_event_id = "test_event_id"
ufp.api.bootstrap.cameras = {new_camera.id: new_camera} ufp.api.bootstrap.cameras = {new_camera.id: new_camera}
ufp.api.bootstrap.events = {event.id: event} ufp.api.bootstrap.events = {event.id: event}

View File

@ -118,7 +118,7 @@ async def test_setup_too_old(
) -> None: ) -> None:
"""Test setup of unifiprotect entry with too old of version of UniFi Protect.""" """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 old_bootstrap.nvr = old_nvr
ufp.api.update.return_value = old_bootstrap ufp.api.update.return_value = old_bootstrap
ufp.api.bootstrap = 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]) await init_entry(hass, ufp, [light, unadopted_light])
assert_entity_counts(hass, Platform.LIGHT, 1, 1) 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.is_light_on = True
new_light.light_device_settings.led_level = LEDLevel(3) 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) assert_entity_counts(hass, Platform.LIGHT, 1, 1)
entity_id = "light.test_light" 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() light.set_light = AsyncMock()
await hass.services.async_call( await hass.services.async_call(
@ -123,7 +123,7 @@ async def test_light_turn_off(
assert_entity_counts(hass, Platform.LIGHT, 1, 1) assert_entity_counts(hass, Platform.LIGHT, 1, 1)
entity_id = "light.test_light" 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() light.set_light = AsyncMock()
await hass.services.async_call( await hass.services.async_call(

View File

@ -75,7 +75,7 @@ async def test_lock_locked(
await init_entry(hass, ufp, [doorlock, unadopted_doorlock]) await init_entry(hass, ufp, [doorlock, unadopted_doorlock])
assert_entity_counts(hass, Platform.LOCK, 1, 1) assert_entity_counts(hass, Platform.LOCK, 1, 1)
new_lock = doorlock.copy() new_lock = doorlock.model_copy()
new_lock.lock_status = LockStatusType.CLOSED new_lock.lock_status = LockStatusType.CLOSED
mock_msg = Mock() mock_msg = Mock()
@ -102,7 +102,7 @@ async def test_lock_unlocking(
await init_entry(hass, ufp, [doorlock, unadopted_doorlock]) await init_entry(hass, ufp, [doorlock, unadopted_doorlock])
assert_entity_counts(hass, Platform.LOCK, 1, 1) assert_entity_counts(hass, Platform.LOCK, 1, 1)
new_lock = doorlock.copy() new_lock = doorlock.model_copy()
new_lock.lock_status = LockStatusType.OPENING new_lock.lock_status = LockStatusType.OPENING
mock_msg = Mock() mock_msg = Mock()
@ -129,7 +129,7 @@ async def test_lock_locking(
await init_entry(hass, ufp, [doorlock, unadopted_doorlock]) await init_entry(hass, ufp, [doorlock, unadopted_doorlock])
assert_entity_counts(hass, Platform.LOCK, 1, 1) assert_entity_counts(hass, Platform.LOCK, 1, 1)
new_lock = doorlock.copy() new_lock = doorlock.model_copy()
new_lock.lock_status = LockStatusType.CLOSING new_lock.lock_status = LockStatusType.CLOSING
mock_msg = Mock() mock_msg = Mock()
@ -156,7 +156,7 @@ async def test_lock_jammed(
await init_entry(hass, ufp, [doorlock, unadopted_doorlock]) await init_entry(hass, ufp, [doorlock, unadopted_doorlock])
assert_entity_counts(hass, Platform.LOCK, 1, 1) 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 new_lock.lock_status = LockStatusType.JAMMED_WHILE_CLOSING
mock_msg = Mock() mock_msg = Mock()
@ -183,7 +183,7 @@ async def test_lock_unavailable(
await init_entry(hass, ufp, [doorlock, unadopted_doorlock]) await init_entry(hass, ufp, [doorlock, unadopted_doorlock])
assert_entity_counts(hass, Platform.LOCK, 1, 1) assert_entity_counts(hass, Platform.LOCK, 1, 1)
new_lock = doorlock.copy() new_lock = doorlock.model_copy()
new_lock.lock_status = LockStatusType.NOT_CALIBRATED new_lock.lock_status = LockStatusType.NOT_CALIBRATED
mock_msg = Mock() mock_msg = Mock()
@ -210,7 +210,7 @@ async def test_lock_do_lock(
await init_entry(hass, ufp, [doorlock, unadopted_doorlock]) await init_entry(hass, ufp, [doorlock, unadopted_doorlock])
assert_entity_counts(hass, Platform.LOCK, 1, 1) 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() doorlock.close_lock = AsyncMock()
await hass.services.async_call( await hass.services.async_call(
@ -234,7 +234,7 @@ async def test_lock_do_unlock(
await init_entry(hass, ufp, [doorlock, unadopted_doorlock]) await init_entry(hass, ufp, [doorlock, unadopted_doorlock])
assert_entity_counts(hass, Platform.LOCK, 1, 1) assert_entity_counts(hass, Platform.LOCK, 1, 1)
new_lock = doorlock.copy() new_lock = doorlock.model_copy()
new_lock.lock_status = LockStatusType.CLOSED new_lock.lock_status = LockStatusType.CLOSED
mock_msg = Mock() mock_msg = Mock()
@ -245,7 +245,7 @@ async def test_lock_do_unlock(
ufp.ws_msg(mock_msg) ufp.ws_msg(mock_msg)
await hass.async_block_till_done() 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() new_lock.open_lock = AsyncMock()
await hass.services.async_call( 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]) await init_entry(hass, ufp, [doorbell, unadopted_camera])
assert_entity_counts(hass, Platform.MEDIA_PLAYER, 1, 1) 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 = Mock()
new_camera.talkback_stream.is_running = True 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]) await init_entry(hass, ufp, [doorbell, unadopted_camera])
assert_entity_counts(hass, Platform.MEDIA_PLAYER, 1, 1) 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() doorbell.set_speaker_volume = AsyncMock()
await hass.services.async_call( await hass.services.async_call(
@ -140,7 +140,7 @@ async def test_media_player_stop(
await init_entry(hass, ufp, [doorbell, unadopted_camera]) await init_entry(hass, ufp, [doorbell, unadopted_camera])
assert_entity_counts(hass, Platform.MEDIA_PLAYER, 1, 1) 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 = AsyncMock()
new_camera.talkback_stream.is_running = True 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]) await init_entry(hass, ufp, [doorbell, unadopted_camera])
assert_entity_counts(hass, Platform.MEDIA_PLAYER, 1, 1) assert_entity_counts(hass, Platform.MEDIA_PLAYER, 1, 1)
doorbell.__fields__["stop_audio"] = Mock(final=False) doorbell.__pydantic_fields__["stop_audio"] = Mock(final=False, frozen=False)
doorbell.__fields__["play_audio"] = Mock(final=False) doorbell.__pydantic_fields__["play_audio"] = Mock(final=False, frozen=False)
doorbell.__fields__["wait_until_audio_completes"] = Mock(final=False) doorbell.__pydantic_fields__["wait_until_audio_completes"] = Mock(
final=False, frozen=False
)
doorbell.stop_audio = AsyncMock() doorbell.stop_audio = AsyncMock()
doorbell.play_audio = AsyncMock() doorbell.play_audio = AsyncMock()
doorbell.wait_until_audio_completes = 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]) await init_entry(hass, ufp, [doorbell, unadopted_camera])
assert_entity_counts(hass, Platform.MEDIA_PLAYER, 1, 1) assert_entity_counts(hass, Platform.MEDIA_PLAYER, 1, 1)
doorbell.__fields__["stop_audio"] = Mock(final=False) doorbell.__pydantic_fields__["stop_audio"] = Mock(final=False, frozen=False)
doorbell.__fields__["play_audio"] = Mock(final=False) doorbell.__pydantic_fields__["play_audio"] = Mock(final=False, frozen=False)
doorbell.__fields__["wait_until_audio_completes"] = Mock(final=False) doorbell.__pydantic_fields__["wait_until_audio_completes"] = Mock(
final=False, frozen=False
)
doorbell.stop_audio = AsyncMock() doorbell.stop_audio = AsyncMock()
doorbell.play_audio = AsyncMock() doorbell.play_audio = AsyncMock()
doorbell.wait_until_audio_completes = 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]) await init_entry(hass, ufp, [doorbell, unadopted_camera])
assert_entity_counts(hass, Platform.MEDIA_PLAYER, 1, 1) 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() doorbell.play_audio = AsyncMock()
with pytest.raises(HomeAssistantError): with pytest.raises(HomeAssistantError):
@ -276,8 +280,10 @@ async def test_media_player_play_error(
await init_entry(hass, ufp, [doorbell, unadopted_camera]) await init_entry(hass, ufp, [doorbell, unadopted_camera])
assert_entity_counts(hass, Platform.MEDIA_PLAYER, 1, 1) 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.__fields__["wait_until_audio_completes"] = Mock(final=False) doorbell.__pydantic_fields__["wait_until_audio_completes"] = Mock(
final=False, frozen=False
)
doorbell.play_audio = AsyncMock(side_effect=StreamError) doorbell.play_audio = AsyncMock(side_effect=StreamError)
doorbell.wait_until_audio_completes = AsyncMock() 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.config_entries.async_setup(ufp.entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()
bootstrap2 = bootstrap.copy() bootstrap2 = bootstrap.model_copy()
bootstrap2._has_media = True bootstrap2._has_media = True
bootstrap2.nvr = bootstrap.nvr.copy() bootstrap2.nvr = bootstrap.nvr.model_copy()
bootstrap2.nvr.id = "test_id2" bootstrap2.nvr.id = "test_id2"
bootstrap2.nvr.mac = "A2E00C826924" bootstrap2.nvr.mac = "A2E00C826924"
bootstrap2.nvr.name = "UnifiProtect2" 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.config_entries.async_setup(ufp.entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()
bootstrap2 = bootstrap.copy() bootstrap2 = bootstrap.model_copy()
bootstrap2._has_media = False bootstrap2._has_media = False
bootstrap2.nvr = bootstrap.nvr.copy() bootstrap2.nvr = bootstrap.nvr.model_copy()
bootstrap2.nvr.id = "test_id2" bootstrap2.nvr.id = "test_id2"
bootstrap2.nvr.mac = "A2E00C826924" bootstrap2.nvr.mac = "A2E00C826924"
bootstrap2.nvr.name = "UnifiProtect2" bootstrap2.nvr.name = "UnifiProtect2"

View File

@ -162,7 +162,7 @@ async def test_number_light_sensitivity(
description = LIGHT_NUMBERS[0] description = LIGHT_NUMBERS[0]
assert description.ufp_set_method is not None 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() light.set_sensitivity = AsyncMock()
_, entity_id = ids_from_device_description(Platform.NUMBER, light, description) _, entity_id = ids_from_device_description(Platform.NUMBER, light, description)
@ -184,7 +184,7 @@ async def test_number_light_duration(
description = LIGHT_NUMBERS[1] 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() light.set_duration = AsyncMock()
_, entity_id = ids_from_device_description(Platform.NUMBER, light, description) _, 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 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()) setattr(camera, description.ufp_set_method, AsyncMock())
_, entity_id = ids_from_device_description(Platform.NUMBER, camera, description) _, 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] 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() doorlock.set_auto_close_time = AsyncMock()
_, entity_id = ids_from_device_description(Platform.NUMBER, doorlock, description) _, 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, camera_id=doorbell.id,
) )
new_camera = doorbell.copy() new_camera = doorbell.model_copy()
new_camera.is_motion_detected = True new_camera.is_motion_detected = True
new_camera.last_motion_event_id = event.id new_camera.last_motion_event_id = event.id

View File

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

View File

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

View File

@ -56,7 +56,9 @@ async def test_global_service_bad_device(
"""Test global service, invalid device ID.""" """Test global service, invalid device ID."""
nvr = ufp.api.bootstrap.nvr 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() nvr.add_custom_doorbell_message = AsyncMock()
with pytest.raises(HomeAssistantError): with pytest.raises(HomeAssistantError):
@ -75,7 +77,9 @@ async def test_global_service_exception(
"""Test global service, unexpected error.""" """Test global service, unexpected error."""
nvr = ufp.api.bootstrap.nvr 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) nvr.add_custom_doorbell_message = AsyncMock(side_effect=BadRequest)
with pytest.raises(HomeAssistantError): with pytest.raises(HomeAssistantError):
@ -94,7 +98,9 @@ async def test_add_doorbell_text(
"""Test add_doorbell_text service.""" """Test add_doorbell_text service."""
nvr = ufp.api.bootstrap.nvr 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() nvr.add_custom_doorbell_message = AsyncMock()
await hass.services.async_call( await hass.services.async_call(
@ -112,7 +118,9 @@ async def test_remove_doorbell_text(
"""Test remove_doorbell_text service.""" """Test remove_doorbell_text service."""
nvr = ufp.api.bootstrap.nvr 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() nvr.remove_custom_doorbell_message = AsyncMock()
await hass.services.async_call( await hass.services.async_call(
@ -129,7 +137,9 @@ async def test_add_doorbell_text_disabled_config_entry(
) -> None: ) -> None:
"""Test add_doorbell_text service.""" """Test add_doorbell_text service."""
nvr = ufp.api.bootstrap.nvr 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() nvr.add_custom_doorbell_message = AsyncMock()
await hass.config_entries.async_set_disabled_by( await hass.config_entries.async_set_disabled_by(
@ -158,10 +168,10 @@ async def test_set_chime_paired_doorbells(
ufp.api.update_device = AsyncMock() ufp.api.update_device = AsyncMock()
camera1 = doorbell.copy() camera1 = doorbell.model_copy()
camera1.name = "Test Camera 1" camera1.name = "Test Camera 1"
camera2 = doorbell.copy() camera2 = doorbell.model_copy()
camera2.name = "Test Camera 2" camera2.name = "Test Camera 2"
await init_entry(hass, ufp, [camera1, camera2, chime]) 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) assert_entity_counts(hass, Platform.SWITCH, 2, 2)
nvr = ufp.api.bootstrap.nvr 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() nvr.set_insights = AsyncMock()
entity_id = "switch.unifiprotect_insights_enabled" entity_id = "switch.unifiprotect_insights_enabled"
@ -272,7 +272,7 @@ async def test_switch_light_status(
description = LIGHT_SWITCHES[1] 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() light.set_status_light = AsyncMock()
_, entity_id = ids_from_device_description(Platform.SWITCH, light, description) _, entity_id = ids_from_device_description(Platform.SWITCH, light, description)
@ -300,7 +300,7 @@ async def test_switch_camera_ssh(
description = CAMERA_SWITCHES[0] 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() doorbell.set_ssh = AsyncMock()
_, entity_id = ids_from_device_description(Platform.SWITCH, doorbell, description) _, 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 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()) setattr(doorbell, description.ufp_set_method, AsyncMock())
set_method = getattr(doorbell, description.ufp_set_method) set_method = getattr(doorbell, description.ufp_set_method)
@ -362,7 +364,7 @@ async def test_switch_camera_highfps(
description = CAMERA_SWITCHES[3] 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() doorbell.set_video_mode = AsyncMock()
_, entity_id = ids_from_device_description(Platform.SWITCH, doorbell, description) _, entity_id = ids_from_device_description(Platform.SWITCH, doorbell, description)
@ -393,7 +395,7 @@ async def test_switch_camera_privacy(
description = PRIVACY_MODE_SWITCH 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() doorbell.set_privacy = AsyncMock()
_, entity_id = ids_from_device_description(Platform.SWITCH, doorbell, description) _, 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) 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.add_privacy_zone()
new_doorbell.mic_volume = 0 new_doorbell.mic_volume = 0
new_doorbell.recording_settings.mode = RecordingMode.NEVER new_doorbell.recording_settings.mode = RecordingMode.NEVER
@ -445,7 +447,7 @@ async def test_switch_camera_privacy_already_on(
description = PRIVACY_MODE_SWITCH 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() doorbell.set_privacy = AsyncMock()
_, entity_id = ids_from_device_description(Platform.SWITCH, doorbell, description) _, 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 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() doorbell.set_lcd_text = AsyncMock()
await hass.services.async_call( await hass.services.async_call(