Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Lock asset & Patient privacy & Boundary based validation #1757

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
122 commits
Select commit Hold shift + click to select a range
eacf4e6
rlative move validation
JahnabDutta Jul 9, 2023
2250c4c
camera boundary minor changes
JahnabDutta Jul 11, 2023
565e29d
Merge branch 'master' into add-boundary-preset
JahnabDutta Jul 11, 2023
4f0f3d6
move Boundary based validation from AssetViewset to OnvifAsset
JahnabDutta Jul 14, 2023
3926591
Merge branch 'master' into add-boundary-preset
JahnabDutta Jul 14, 2023
d4c39c5
Merge branch 'coronasafe:master' into add-boundary-preset
JahnabDutta Jul 17, 2023
f8d3d00
add test for operate_asset for onvif assets
JahnabDutta Jul 17, 2023
be69d00
add test skeletons for other assets
JahnabDutta Jul 17, 2023
cf29b9b
Merge branch 'master' into add-boundary-preset
JahnabDutta Jul 19, 2023
fcb38fe
Merge branch 'coronasafe:master' into add-boundary-preset
JahnabDutta Jul 21, 2023
addfd1c
initial commit
JahnabDutta Jul 21, 2023
91783b0
add locking mechanism to asset
JahnabDutta Jul 21, 2023
04fa29f
verify locking only for movement actions
JahnabDutta Jul 22, 2023
3708d12
Merge branch 'coronasafe:master' into add-boundary-preset
JahnabDutta Jul 29, 2023
fef448d
Merge branch 'coronasafe:master' into lock-asset-feature
JahnabDutta Jul 29, 2023
11b772a
add lock action
JahnabDutta Jul 29, 2023
63961a2
Merge branch 'lock-asset-feature' of https://github.com/JahnabDutta/c…
JahnabDutta Jul 29, 2023
6b3b501
add privacy field in consultationbed model and toggle_patient_privacy…
JahnabDutta Aug 7, 2023
b16e4fc
merge conflicts
JahnabDutta Aug 7, 2023
745c99a
change privacy toggle privildeges
JahnabDutta Aug 8, 2023
6635b94
Merge branch 'coronasafe:master' into add-boundary-preset
JahnabDutta Aug 9, 2023
e2422bd
Merge branch 'coronasafe:master' into lock-asset-feature
JahnabDutta Aug 9, 2023
4973918
Merge branch 'coronasafe:master' into patient-privacy-feature
JahnabDutta Aug 9, 2023
a6763e2
Merge branch 'patient-privacy-feature' of https://github.com/JahnabDu…
JahnabDutta Aug 9, 2023
3211244
patient privacy tests
JahnabDutta Aug 10, 2023
b077553
change functions for lock/unlock asset
JahnabDutta Aug 13, 2023
abb0c3f
add push notification
JahnabDutta Aug 13, 2023
eab6aaf
add asset_unlock in notification event type
JahnabDutta Aug 13, 2023
2f000fd
use send_webpush instead of new class
JahnabDutta Aug 15, 2023
2ee66d3
send current asset occupier information to user
JahnabDutta Aug 21, 2023
0bc2fb4
Merge branch 'coronasafe:master' into add-boundary-preset
JahnabDutta Aug 21, 2023
9f8a05d
Merge branch 'coronasafe:master' into patient-privacy-feature
JahnabDutta Aug 21, 2023
1b17b1d
Merge branch 'coronasafe:master' into lock-asset-feature
JahnabDutta Aug 21, 2023
9093bdf
Merge branch 'lock-asset-feature' of https://github.com/JahnabDutta/c…
JahnabDutta Aug 21, 2023
88934c9
add lock asset test
JahnabDutta Aug 22, 2023
95f20d6
Merge branch 'master' into add-boundary-preset
JahnabDutta Aug 23, 2023
7289938
replace boolean result with validation error
JahnabDutta Aug 23, 2023
60b6478
Merge branch 'add-boundary-preset' of https://github.com/JahnabDutta/…
JahnabDutta Aug 23, 2023
521606d
Merge branch 'coronasafe:master' into patient-privacy-feature
JahnabDutta Aug 23, 2023
f255045
Merge branch 'add-boundary-preset' into patient-privacy-feature
JahnabDutta Aug 23, 2023
4215840
raise permission error in validate action
JahnabDutta Aug 23, 2023
862cebc
add request asset feature
JahnabDutta Aug 25, 2023
dade5ee
Merge branch 'master' into lock-asset-feature
JahnabDutta Aug 25, 2023
1964c5a
add migration
JahnabDutta Aug 27, 2023
c7f0104
Merge branch 'coronasafe:master' into patient-privacy-feature
JahnabDutta Aug 27, 2023
1db44cc
Merge branch 'coronasafe:master' into add-boundary-preset
JahnabDutta Aug 27, 2023
bb8f55a
Merge branch 'coronasafe:master' into add-boundary-preset
JahnabDutta Aug 29, 2023
d2bacf3
Merge branch 'coronasafe:master' into lock-asset-feature
JahnabDutta Aug 29, 2023
727bdc5
Merge branch 'coronasafe:master' into patient-privacy-feature
JahnabDutta Aug 29, 2023
9f305ee
Merge branch 'master' into add-boundary-preset
khavinshankar Nov 14, 2023
5b029d2
revert unwanted changes
khavinshankar Nov 14, 2023
48dabf1
Refactor test_asset_operate_api.py to use
khavinshankar Nov 15, 2023
270462c
Fix setUp method in AssetViewSetTestCase
khavinshankar Nov 15, 2023
c89bac7
Refactor test_asset_operate_api.py to remove
khavinshankar Nov 15, 2023
bf289a8
trigger tests
khavinshankar Nov 15, 2023
38bb043
Refactor AssetViewSetTestCase in
khavinshankar Nov 15, 2023
e9c4d38
trigger tests
khavinshankar Nov 15, 2023
91e53d0
fix asset operate test
khavinshankar Nov 15, 2023
901c54d
Merge branch 'master' into patient-privacy-feature
khavinshankar Nov 22, 2023
9610e8b
revert unwanted changes
khavinshankar Nov 22, 2023
ecc2cbc
fix tests
khavinshankar Nov 22, 2023
71843cc
trigger tests
khavinshankar Nov 22, 2023
2ee67bc
Merge branch 'master' into lock-asset-feature
khavinshankar Nov 22, 2023
a09898a
revert unwanted changes
khavinshankar Nov 22, 2023
01be9b4
fix tests
khavinshankar Nov 22, 2023
d616e38
Merge branch 'master' into patient-privacy-feature
sainak Nov 23, 2023
cc60a1f
squash migrations
sainak Nov 23, 2023
fd08f11
Merge branch 'janab-patient-privacy-feature' into feature/lock-asset-…
Pranshu1902 Dec 8, 2023
e933489
Merge branch 'pr/JahnabDutta/1453' into feature/lock-asset-and-privacy
Pranshu1902 Dec 8, 2023
d8c0c8a
Merge branch 'pr/JahnabDutta/1467' into feature/lock-asset-and-privacy
Pranshu1902 Dec 8, 2023
ccf784f
mock middleware tests
Pranshu1902 Dec 8, 2023
12ce4c5
Merge branch 'master' into feature/lock-asset-and-privacy
Pranshu1902 Dec 11, 2023
d84d9a7
Merge branch 'master' into feature/lock-asset-and-privacy
Pranshu1902 Dec 26, 2023
e89674b
merge migration
Pranshu1902 Dec 29, 2023
5624fa9
Merge branch 'master' into feature/lock-asset-and-privacy
Pranshu1902 Jan 31, 2024
d8999bc
Merge branch 'master' into feature/lock-asset-and-privacy
Pranshu1902 Feb 12, 2024
cb8f420
cache operate_asset requests
Pranshu1902 Feb 12, 2024
e922a26
update migrations
Pranshu1902 Feb 12, 2024
c7692ff
fix migrations
Pranshu1902 Feb 12, 2024
b8233ff
refactor permissions and send privacy in response
Pranshu1902 Feb 12, 2024
075169a
refactor
Pranshu1902 Feb 12, 2024
3dada9b
Merge branch 'master' into feature/lock-asset-and-privacy
Pranshu1902 Feb 12, 2024
b0a3975
pass privacy
Pranshu1902 Feb 12, 2024
1440fdb
update migrations
Pranshu1902 Feb 13, 2024
3be027e
move permissions logic to separate permission class for toggle privacy
Pranshu1902 Feb 13, 2024
863e4c5
Merge branch 'master' into feature/lock-asset-and-privacy
sainak Feb 13, 2024
64e6d3a
update migrations to new merge
Pranshu1902 Feb 13, 2024
4c0c665
move cache logic to handle_action
Pranshu1902 Feb 17, 2024
8b3d250
refactor using kwargs
Pranshu1902 Feb 17, 2024
adfdf88
refactor error response body
Pranshu1902 Feb 17, 2024
be3697b
Merge branch 'master' into feature/lock-asset-and-privacy
Pranshu1902 Feb 17, 2024
150956a
add DRY permissions check
Pranshu1902 Feb 17, 2024
7b346fd
Update care/utils/assetintegration/hl7monitor.py
Pranshu1902 Feb 17, 2024
33d84c4
Update care/utils/assetintegration/onvif.py
Pranshu1902 Feb 17, 2024
9ddad1e
Update care/facility/api/viewsets/asset.py
Pranshu1902 Feb 17, 2024
ec72029
import cache
Pranshu1902 Feb 17, 2024
6e543fe
update migrations
Pranshu1902 Feb 17, 2024
197c26a
update permissions and fix tests
Pranshu1902 Feb 18, 2024
4811ab3
add separate routes for toggle and update permissions
Pranshu1902 Feb 20, 2024
8670bd8
custom permissions and cover tests
Pranshu1902 Feb 20, 2024
f32c1b3
store locking users data in meta and add tests for that
Pranshu1902 Feb 20, 2024
8ecd1f0
refactor
Pranshu1902 Feb 20, 2024
5032b89
add custom permissions
Pranshu1902 Feb 21, 2024
1c8c042
restrict other users
Pranshu1902 Feb 21, 2024
7083f82
refactor
Pranshu1902 Feb 21, 2024
8263730
move cache handle logic
Pranshu1902 Feb 22, 2024
d359ff9
add requested chages
Pranshu1902 Feb 22, 2024
aa0ea2f
check privacy mode before view preset
Pranshu1902 Feb 22, 2024
68d4f7f
check if consultationbed exists
Pranshu1902 Feb 23, 2024
ece92f7
handle case without consultationbed
Pranshu1902 Feb 23, 2024
25b7012
cache only for move actions and send locking user details
Pranshu1902 Feb 24, 2024
9f008e7
update consultation check query
Pranshu1902 Feb 24, 2024
5c3f13c
refactor to requested changes
Pranshu1902 Feb 27, 2024
e7c14cb
refactor permissions method
Pranshu1902 Feb 28, 2024
f0a11eb
add cache key prefix
Pranshu1902 Feb 28, 2024
7a4426e
update permissions
Pranshu1902 Feb 28, 2024
bf9495a
Apply suggestions from code review
sainak Mar 1, 2024
ef89303
Merge branch 'master' into feature/lock-asset-and-privacy
sainak Mar 1, 2024
4fa4c39
added validation error and handle_action method
Pranshu1902 Mar 4, 2024
e47ae9e
fix validate_action method
Pranshu1902 Mar 5, 2024
21b20e4
Merge branch 'master' into feature/lock-asset-and-privacy
Pranshu1902 Mar 11, 2024
bf3f9cf
update migrations
Pranshu1902 Mar 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 42 additions & 3 deletions care/facility/api/viewsets/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from rest_framework import filters as drf_filters
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.exceptions import APIException, ValidationError
from rest_framework.exceptions import APIException, PermissionDenied, ValidationError
from rest_framework.mixins import (
CreateModelMixin,
DestroyModelMixin,
Expand Down Expand Up @@ -371,6 +371,7 @@
"""
try:
action = request.data["action"]
action["user"] = request.user.username

Check warning on line 374 in care/facility/api/viewsets/asset.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/viewsets/asset.py#L374

Added line #L374 was not covered by tests
asset: Asset = self.get_object()
middleware_hostname = (
asset.meta.get(
Expand All @@ -385,15 +386,53 @@
"middleware_hostname": middleware_hostname,
}
)
result = asset_class.handle_action(action)
asset_class.validate_action(action)

Check warning on line 389 in care/facility/api/viewsets/asset.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/viewsets/asset.py#L389

Added line #L389 was not covered by tests

# cache the move camera actions for 3 seconds
if action["type"] == "relative_move" or action["type"] == "absolute_move":
cacheId = f"asset_move: {str(asset.external_id)}"

Check warning on line 393 in care/facility/api/viewsets/asset.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/viewsets/asset.py#L393

Added line #L393 was not covered by tests
if cache.get(cacheId):
return Response(

Check warning on line 395 in care/facility/api/viewsets/asset.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/viewsets/asset.py#L395

Added line #L395 was not covered by tests
{"status": "failure", "message": "Camera is still moving"},
status=status.HTTP_403_FORBIDDEN,
)
cache.set(cacheId, True, 3)

Check warning on line 399 in care/facility/api/viewsets/asset.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/viewsets/asset.py#L399

Added line #L399 was not covered by tests

result = asset_class.handle_action(

Check warning on line 401 in care/facility/api/viewsets/asset.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/viewsets/asset.py#L401

Added line #L401 was not covered by tests
action,
username=request.user.username,
asset_id=asset.external_id,
)
return Response({"result": result}, status=status.HTTP_200_OK)

except PermissionDenied as e:
user: User = User.objects.get(

Check warning on line 409 in care/facility/api/viewsets/asset.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/viewsets/asset.py#L409

Added line #L409 was not covered by tests
username=cache.get(f"asset_lock_{asset.external_id}")
)
return Response(

Check warning on line 412 in care/facility/api/viewsets/asset.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/viewsets/asset.py#L412

Added line #L412 was not covered by tests
{
"message": e.detail.get("message", None),
Pranshu1902 marked this conversation as resolved.
Show resolved Hide resolved
"username": user.username,
"firstName": user.first_name,
"lastName": user.last_name,
"role": User.REVERSE_TYPE_MAP[user.user_type],
"homeFacility": user.home_facility,
},
status=status.HTTP_409_CONFLICT,
)
except ValidationError as e:
return Response({"detail": e.detail}, status=status.HTTP_400_BAD_REQUEST)

except KeyError as e:
return Response(
{"message": {key: "is required" for key in e.args}},
{
"message": {key: "is required" for key in e.args},
"username": e.detail.get("username", None),
"firstName": e.detail.get("firstName", None),
"lastName": e.detail.get("lastName", None),
"role": e.detail.get("role", None),
"homeFacility": e.detail.get("homeFacility", None),
},
status=status.HTTP_400_BAD_REQUEST,
)

Expand Down
53 changes: 53 additions & 0 deletions care/facility/api/viewsets/bed.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
from django.db.models import Exists, OuterRef, Subquery
from django_filters import rest_framework as filters
from drf_spectacular.utils import extend_schema, extend_schema_view
from dry_rest_permissions.generics import DRYPermissions
from rest_framework import filters as drf_filters
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.exceptions import PermissionDenied
from rest_framework.exceptions import ValidationError as DRFValidationError
from rest_framework.fields import get_error_detail
Expand Down Expand Up @@ -235,6 +237,10 @@
filter_backends = (filters.DjangoFilterBackend,)
filterset_class = ConsultationBedFilter
lookup_field = "external_id"
permission_classes = (
IsAuthenticated,
DRYPermissions,
)

def get_queryset(self):
user = self.request.user
Expand All @@ -249,3 +255,50 @@
allowed_facilities = get_accessible_facilities(user)
queryset = queryset.filter(bed__facility__id__in=allowed_facilities)
return queryset

@extend_schema(
description="Toggle patient privacy",
responses={status.HTTP_200_OK: None},
Pranshu1902 marked this conversation as resolved.
Show resolved Hide resolved
request=None,
tags=["consultationbed"],
)
@action(detail=True, methods=["POST"])
def patient_privacy(self, request, **kwargs):
instance = self.get_object()
if instance.privacy:
return Response(
{
"status": "failed",
"message": "Asset already locked",
"locked_by": instance.meta["locked_by"],
},
status=status.HTTP_409_CONFLICT,
)

instance.privacy = True
instance.meta["locked_by"] = request.user.username
instance.save()
return Response(
{"status": "success"},
status=status.HTTP_200_OK,
)

@patient_privacy.mapping.delete
def disable_patient_privacy(self, request, **kwargs):
instance = self.get_object()
if not instance.privacy:
return Response(
{"status": "failure", "message": "Asset not locked"},
status=status.HTTP_409_CONFLICT,
)

if instance.meta["locked_by"] != request.user.username:
raise PermissionDenied("You do not have permission to unlock this asset")

Check warning on line 296 in care/facility/api/viewsets/bed.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/viewsets/bed.py#L296

Added line #L296 was not covered by tests

instance.privacy = False
del instance.meta["locked_by"]
instance.save()
return Response(
{"status": "success", "privacy": instance.privacy},
status=status.HTTP_200_OK,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Generated by Django 4.2.10 on 2024-03-11 16:01

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("facility", "0419_alter_patientconsultation_patient_no"),
]

operations = [
migrations.AddField(
model_name="consultationbed",
name="privacy",
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name="notification",
name="event",
field=models.IntegerField(
choices=[
(0, "MESSAGE"),
(10, "ASSET_UNLOCKED"),
(20, "PATIENT_CREATED"),
(30, "PATIENT_UPDATED"),
(40, "PATIENT_DELETED"),
(50, "PATIENT_CONSULTATION_CREATED"),
(60, "PATIENT_CONSULTATION_UPDATED"),
(70, "PATIENT_CONSULTATION_DELETED"),
(80, "INVESTIGATION_SESSION_CREATED"),
(90, "INVESTIGATION_UPDATED"),
(100, "PATIENT_FILE_UPLOAD_CREATED"),
(110, "CONSULTATION_FILE_UPLOAD_CREATED"),
(120, "PATIENT_CONSULTATION_UPDATE_CREATED"),
(130, "PATIENT_CONSULTATION_UPDATE_UPDATED"),
(140, "PATIENT_CONSULTATION_ASSIGNMENT"),
(200, "SHIFTING_UPDATED"),
(210, "PATIENT_NOTE_ADDED"),
(220, "PUSH_MESSAGE"),
],
default=0,
),
),
]
27 changes: 26 additions & 1 deletion care/facility/models/bed.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@

from care.facility.models.asset import Asset, AssetLocation
from care.facility.models.facility import Facility
from care.facility.models.mixins.permissions.patient import (
ConsultationRelatedPermissionMixin,
)
from care.facility.models.patient_base import BedType, BedTypeChoices
from care.facility.models.patient_consultation import PatientConsultation
from care.users.models import User
from care.utils.models.base import BaseModel


Expand Down Expand Up @@ -71,18 +75,39 @@
return f"{self.asset.name} - {self.bed.name}"


class ConsultationBed(BaseModel):
class ConsultationBed(BaseModel, ConsultationRelatedPermissionMixin):
consultation = models.ForeignKey(
PatientConsultation, on_delete=models.PROTECT, null=False, blank=False
)
bed = models.ForeignKey(Bed, on_delete=models.PROTECT, null=False, blank=False)
start_date = models.DateTimeField(null=False, blank=False)
end_date = models.DateTimeField(null=True, blank=True, default=None)
privacy = models.BooleanField(default=False)
Pranshu1902 marked this conversation as resolved.
Show resolved Hide resolved
meta = JSONField(default=dict, blank=True)
assets = models.ManyToManyField(
Asset, through="ConsultationBedAsset", related_name="assigned_consultation_beds"
)

@staticmethod
def has_patient_privacy_permission(request, **kwargs):
permission_mixin = ConsultationRelatedPermissionMixin()
return permission_mixin.has_write_permission(request)

def has_object_patient_privacy_permission(self, request, **kwargs):
if super().has_object_update_permission(request, **kwargs):
if request.user.user_type >= User.TYPE_VALUE_MAP["DistrictAdmin"]:
return True
return self.consultation.facility_id == request.user.home_facility_id
return False

Check warning on line 101 in care/facility/models/bed.py

View check run for this annotation

Codecov / codecov/patch

care/facility/models/bed.py#L101

Added line #L101 was not covered by tests

@staticmethod
def has_disable_patient_privacy_permission(request, **kwargs):
permission_mixin = ConsultationRelatedPermissionMixin()
return permission_mixin.has_write_permission(request)

def has_object_disable_patient_privacy_permission(self, request, **kwargs):
return self.has_object_patient_privacy_permission(request, **kwargs)


class ConsultationBedAsset(BaseModel):
consultation_bed = models.ForeignKey(
Expand Down
1 change: 1 addition & 0 deletions care/facility/models/notification.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class Medium(enum.Enum):

class Event(enum.Enum):
MESSAGE = 0
ASSET_UNLOCKED = 10
PATIENT_CREATED = 20
PATIENT_UPDATED = 30
PATIENT_DELETED = 40
Expand Down
142 changes: 142 additions & 0 deletions care/facility/tests/test_asset_operate_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
from unittest.mock import MagicMock, patch

from rest_framework import status
from rest_framework.response import Response
from rest_framework.test import APITestCase

from care.facility.models import AssetBed
from care.utils.tests.test_utils import TestUtils


class AssetViewSetTestCase(TestUtils, APITestCase):
@classmethod
def setUpTestData(cls):
cls.state = cls.create_state()
cls.district = cls.create_district(state=cls.state)
cls.local_body = cls.create_local_body(cls.district)
cls.user = cls.create_user(district=cls.district, username="test user")
cls.facility = cls.create_facility(
district=cls.district, local_body=cls.local_body, user=cls.user
)
cls.asset1_location = cls.create_asset_location(facility=cls.facility)

# depends upon the operational dev camera config
cls.onvif_meta = {
"asset_type": "CAMERA",
"local_ip_address": "192.168.1.64",
"camera_access_key": "remote_user:2jCkrCRSeahzKEU:d5694af2-21e2-4a39-9bad-2fb98d9818bd",
"middleware_hostname": "mock_middleware",
}
cls.hl7monitor_meta = {}
cls.ventilator_meta = {}
cls.bed = cls.create_bed(
facility=cls.facility, location=cls.asset1_location, meta={}
)
cls.asset = cls.create_asset(location=cls.asset1_location)

@patch("care.facility.api.viewsets.asset.AssetViewSet.operate_assets")
def test_onvif_relative_move(self, mock_asset):
# Set up your mock Asset instance
asset_instance = MagicMock()
asset_instance.meta = {"middleware_hostname": "mock_hostname"}
asset_instance.current_location.middleware_address = "mock_middleware_address"
mock_asset.objects.get.return_value = asset_instance

def validate_action(data):
boundary_range = boundary_asset_bed.meta.get("range", None)
camera_state = data["action"]["data"]["camera_state"]
action_data = data["action"]["data"]

if (
(camera_state["x"] + action_data["x"] < boundary_range["min_x"])
or (camera_state["x"] + action_data["x"] > boundary_range["max_x"])
or (camera_state["y"] + action_data["y"] < boundary_range["min_y"])
or (camera_state["y"] + action_data["y"] > boundary_range["max_y"])
):
mock_asset.return_value = Response(
{
"result": "mock_result",
"message": {"action": {"code": "invalid"}},
},
status=status.HTTP_400_BAD_REQUEST,
)
else:
mock_asset.return_value = Response(
{"result": "mock_result"}, status=status.HTTP_200_OK
)

self.asset.asset_class = "ONVIF"
self.asset.meta = self.onvif_meta
self.asset.save()
boundary_asset_bed = AssetBed.objects.create(
asset=self.asset,
bed=self.bed,
meta={
"range": {
"max_x": 2,
"min_x": -2,
"max_y": 2,
"min_y": -2,
}
},
)

sample_data = {
"action": {
"type": "relative_move",
"data": {
"x": 0.1,
"y": 0.1,
"zoom": 0.1,
"camera_state": {"x": 1.5, "y": 1.5, "zoom": 0},
"id": boundary_asset_bed.external_id,
},
}
}

validate_action(sample_data)
response = self.client.post(
f"/api/v1/asset/{self.asset.external_id}/operate_assets/",
sample_data,
format="json",
)

self.assertEqual(response.status_code, status.HTTP_200_OK)

sample_data_invald = {
"action": {
"type": "relative_move",
"data": {
"x": 0.6,
"y": 0.1,
"zoom": 0.1,
"camera_state": {"x": 1.5, "y": 1.5, "zoom": 0},
"id": boundary_asset_bed.external_id,
},
}
}

validate_action(sample_data_invald)
response_invalid = self.client.post(
f"/api/v1/asset/{self.asset.external_id}/operate_assets/",
sample_data_invald,
"json",
)

self.assertEqual(response_invalid.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(
response_invalid.data.get("message", {}).get("action", {})["code"],
"invalid",
)

def test_hl7monitor(self):
self.asset.asset_class = "HL7MONITOR"
self.asset.meta = self.hl7monitor_meta
self.asset.save()
pass

def test_ventilator(self):
self.asset.asset_class = "VENTILATOR"
self.asset.meta = self.ventilator_meta
self.asset.save()
pass
Loading
Loading