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

Add boundary based validation #1453

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 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
3708d12
Merge branch 'coronasafe:master' into add-boundary-preset
JahnabDutta Jul 29, 2023
6635b94
Merge branch 'coronasafe:master' into add-boundary-preset
JahnabDutta Aug 9, 2023
0bc2fb4
Merge branch 'coronasafe:master' into add-boundary-preset
JahnabDutta Aug 21, 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
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
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
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
3 changes: 2 additions & 1 deletion care/facility/api/viewsets/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,9 +334,10 @@ def operate_assets(self, request, *args, **kwargs):
"middleware_hostname": middleware_hostname,
}
)

asset_class.validate_action(action)
result = asset_class.handle_action(action)
return Response({"result": result}, status=status.HTTP_200_OK)

except ValidationError as e:
return Response({"message": e.detail}, status=status.HTTP_400_BAD_REQUEST)

Expand Down
103 changes: 103 additions & 0 deletions care/facility/tests/test_asset_operate_api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
from rest_framework import status
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": "dev_middleware.coronasafe.live",
}
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)

def test_onvif_relative_move(self):
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,
},
}
}
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,
},
}
}
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
3 changes: 3 additions & 0 deletions care/utils/assetintegration/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,6 @@
return response
except json.decoder.JSONDecodeError:
return {"error": "Invalid Response"}

def validate_action(self, action):
pass

Check warning on line 57 in care/utils/assetintegration/base.py

View check run for this annotation

Codecov / codecov/patch

care/utils/assetintegration/base.py#L57

Added line #L57 was not covered by tests
43 changes: 42 additions & 1 deletion care/utils/assetintegration/onvif.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@
def handle_action(self, action):
action_type = action["type"]
action_data = action.get("data", {})

allowed_action_data = ["x", "y", "zoom"]
action_data = {
key: action_data[key] for key in action_data if key in allowed_action_data
}
request_body = {
"hostname": self.host,
"port": 80,
Expand All @@ -55,3 +58,41 @@
return self.api_post(self.get_url("relativeMove"), request_body)

raise ValidationError({"action": "invalid action type"})

def validate_action(self, action):
khavinshankar marked this conversation as resolved.
Show resolved Hide resolved
from care.facility.models.bed import AssetBed

action_type = action["type"]
action_data = action.get("data", {})
boundary_preset_id = action_data.get("id", None)

if (
not boundary_preset_id
or action_type != self.OnvifActions.RELATIVE_MOVE.value
):
return

Check warning on line 73 in care/utils/assetintegration/onvif.py

View check run for this annotation

Codecov / codecov/patch

care/utils/assetintegration/onvif.py#L73

Added line #L73 was not covered by tests

boundary_preset = AssetBed.objects.filter(
external_id=boundary_preset_id
).first()

if (
not boundary_preset
or not action_data.get("camera_state", None)
or not action_data["camera_state"].get("x", None)
or not action_data["camera_state"].get("y", None)
):
raise ValidationError({"action": "invalid action type"})

Check warning on line 85 in care/utils/assetintegration/onvif.py

View check run for this annotation

Codecov / codecov/patch

care/utils/assetintegration/onvif.py#L85

Added line #L85 was not covered by tests

boundary_range = boundary_preset.meta.get("range", None)
camera_state = action_data["camera_state"]

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"])
):
raise ValidationError({"action": "invalid action type"})

return