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

Merge develop to staging v24.16.0 #2100

Merged
merged 2 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
14 changes: 5 additions & 9 deletions care/facility/api/serializers/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
from django.core.cache import cache
from django.db import models, transaction
from django.db.models import F, Value
from django.db.models.functions import Cast, Coalesce, NullIf
from django.db.models.fields.json import KT
from django.db.models.functions import Coalesce, NullIf
from django.shortcuts import get_object_or_404
from django.utils.timezone import now
from drf_spectacular.utils import extend_schema_field
Expand Down Expand Up @@ -214,8 +215,8 @@ def validate(self, attrs):
raise ValidationError({"asset_class": "Cannot change asset class"})

if meta := attrs.get("meta"):
current_location = attrs.get(
"current_location", self.instance.current_location
current_location = (
attrs.get("current_location") or self.instance.current_location
)
ip_address = meta.get("local_ip_address")
middleware_hostname = (
Expand All @@ -227,12 +228,7 @@ def validate(self, attrs):
asset_using_ip = (
Asset.objects.annotate(
resolved_middleware_hostname=Coalesce(
NullIf(
Cast(
F("meta__middleware_hostname"), models.CharField()
),
Value('""'),
),
NullIf(KT("meta__middleware_hostname"), Value("")),
NullIf(
F("current_location__middleware_address"), Value("")
),
Expand Down
8 changes: 3 additions & 5 deletions care/facility/api/viewsets/asset.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
from django.conf import settings
from django.core.cache import cache
from django.db.models import CharField, Exists, F, OuterRef, Q, Subquery, Value
from django.db.models.functions import Cast, Coalesce, NullIf
from django.db.models.fields.json import KT
from django.db.models.functions import Coalesce, NullIf
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.http import Http404
Expand Down Expand Up @@ -464,10 +465,7 @@ def list(self, request, *args, **kwargs):
)
.annotate(
resolved_middleware_hostname=Coalesce(
NullIf(
Cast(F("meta__middleware_hostname"), CharField()),
Value('""'),
),
NullIf(KT("meta__middleware_hostname"), Value("")),
NullIf(F("current_location__middleware_address"), Value("")),
F("current_location__facility__middleware_address"),
output_field=CharField(),
Expand Down
3 changes: 2 additions & 1 deletion care/facility/api/viewsets/patient.py
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,7 @@ def filter_queryset(self, request, queryset, view):
q_filters = Q(facility__id__in=allowed_facilities)
if view.action == "retrieve":
q_filters |= Q(consultations__facility__id__in=allowed_facilities)
queryset = queryset.distinct("id")
q_filters |= Q(last_consultation__assigned_to=request.user)
q_filters |= Q(assigned_to=request.user)
queryset = queryset.filter(q_filters)
Expand Down Expand Up @@ -340,7 +341,7 @@ def filter_queryset(self, request, queryset, view):
)
).order_by(ordering)

return queryset.distinct(ordering.lstrip("-") if ordering else "id")
return queryset


@extend_schema_view(history=extend_schema(tags=["patient"]))
Expand Down
183 changes: 180 additions & 3 deletions care/facility/tests/test_asset_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from rest_framework.test import APITestCase

from care.facility.models import Asset, Bed
from care.utils.assetintegration.asset_classes import AssetClasses
from care.utils.tests.test_utils import TestUtils


Expand Down Expand Up @@ -31,7 +32,6 @@ def test_list_assets(self):
def test_create_asset(self):
sample_data = {
"name": "Test Asset",
"current_location": self.asset_location.pk,
"asset_type": 50,
"location": self.asset_location.external_id,
}
Expand All @@ -41,7 +41,6 @@ def test_create_asset(self):
def test_create_asset_with_warranty_past(self):
sample_data = {
"name": "Test Asset",
"current_location": self.asset_location.pk,
"asset_type": 50,
"location": self.asset_location.external_id,
"warranty_amc_end_of_validity": "2000-04-01",
Expand All @@ -57,7 +56,6 @@ def test_retrieve_asset(self):
def test_update_asset(self):
sample_data = {
"name": "Updated Test Asset",
"current_location": self.asset_location.pk,
"asset_type": 50,
"location": self.asset_location.external_id,
}
Expand Down Expand Up @@ -166,3 +164,182 @@ def test_asset_filter_warranty_amc_end_of_validity(self):
self.assertNotIn(
str(asset1.external_id), [asset["id"] for asset in response.data["results"]]
)


class AssetConfigValidationTestCase(TestUtils, APITestCase):
@classmethod
def setUpTestData(cls) -> None:
cls.state = cls.create_state()
cls.district = cls.create_district(cls.state)
cls.local_body = cls.create_local_body(cls.district)
cls.super_user = cls.create_super_user("su", cls.district)
cls.hostname = "test-middleware.com"
cls.facility = cls.create_facility(
cls.super_user,
cls.district,
cls.local_body,
middleware_address=cls.hostname,
)
cls.asset_location = cls.create_asset_location(cls.facility)
cls.user = cls.create_user("staff", cls.district, home_facility=cls.facility)

def test_create_asset_with_unique_ip(self):
sample_data = {
"name": "Test Asset",
"asset_type": 50,
"location": self.asset_location.external_id,
"asset_class": AssetClasses.HL7MONITOR.name,
"meta": {"local_ip_address": "192.168.1.14"},
}
response = self.client.post("/api/v1/asset/", sample_data, format="json")
self.assertEqual(response.status_code, status.HTTP_201_CREATED)

def test_create_asset_with_duplicate_ip(self):
self.create_asset(
self.asset_location,
name="I was here first",
asset_class=AssetClasses.HL7MONITOR.name,
meta={"local_ip_address": "192.168.1.14"},
)
sample_data = {
"name": "Test Asset",
"asset_type": 50,
"location": self.asset_location.external_id,
"asset_class": AssetClasses.HL7MONITOR.name,
"meta": {"local_ip_address": "192.168.1.14"},
}
response = self.client.post("/api/v1/asset/", sample_data, format="json")
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn("I was here first", response.json()["non_field_errors"][0])

def test_create_asset_with_duplicate_ip_same_hostname_on_location(self):
test_location = self.create_asset_location(
self.facility, middleware_address=self.hostname
)
self.create_asset(
test_location,
name="I was here first",
asset_class=AssetClasses.HL7MONITOR.name,
meta={"local_ip_address": "192.168.1.14"},
)
sample_data = {
"name": "Test Asset",
"asset_type": 50,
"location": test_location.external_id,
"asset_class": AssetClasses.HL7MONITOR.name,
"meta": {"local_ip_address": "192.168.1.14"},
}
response = self.client.post("/api/v1/asset/", sample_data, format="json")
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn("I was here first", response.json()["non_field_errors"][0])

def test_create_asset_with_duplicate_ip_same_hostname_on_asset(self):
self.create_asset(
self.asset_location,
name="I was here first",
asset_class=AssetClasses.HL7MONITOR.name,
meta={
"local_ip_address": "192.168.1.14",
"middleware_hostname": self.hostname,
},
)
sample_data = {
"name": "Test Asset",
"asset_type": 50,
"location": self.asset_location.external_id,
"asset_class": AssetClasses.HL7MONITOR.name,
"meta": {"local_ip_address": "192.168.1.14"},
}
response = self.client.post("/api/v1/asset/", sample_data, format="json")
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn("I was here first", response.json()["non_field_errors"][0])

def test_create_asset_with_duplicate_ip_same_hostname_on_location_asset(self):
test_location = self.create_asset_location(
self.facility, middleware_address=self.hostname
)
self.create_asset(
test_location,
name="I was here first",
asset_class=AssetClasses.HL7MONITOR.name,
meta={
"local_ip_address": "192.168.1.14",
"middleware_hostname": self.hostname,
},
)
sample_data = {
"name": "Test Asset",
"asset_type": 50,
"location": test_location.external_id,
"asset_class": AssetClasses.HL7MONITOR.name,
"meta": {"local_ip_address": "192.168.1.14"},
}
response = self.client.post("/api/v1/asset/", sample_data, format="json")
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn("I was here first", response.json()["non_field_errors"][0])

def test_create_asset_with_duplicate_ip_different_hostname_on_location(self):
test_location = self.create_asset_location(
self.facility, middleware_address="not-test-middleware.com"
)
self.create_asset(
self.asset_location,
name="I was here first",
asset_class=AssetClasses.HL7MONITOR.name,
meta={"local_ip_address": "192.168.1.14"},
)
sample_data = {
"name": "Test Asset",
"asset_type": 50,
"location": test_location.external_id,
"asset_class": AssetClasses.HL7MONITOR.name,
"meta": {"local_ip_address": "192.168.1.14"},
}
response = self.client.post("/api/v1/asset/", sample_data, format="json")
self.assertEqual(response.status_code, status.HTTP_201_CREATED)

def test_create_asset_with_duplicate_ip_different_hostname_on_asset(self):
self.create_asset(
self.asset_location,
name="I was here first",
asset_class=AssetClasses.HL7MONITOR.name,
meta={"local_ip_address": "192.168.1.14"},
)
sample_data = {
"name": "Test Asset",
"asset_type": 50,
"location": self.asset_location.external_id,
"asset_class": AssetClasses.HL7MONITOR.name,
"meta": {
"local_ip_address": "192.168.1.14",
"middleware_hostname": "not-test-middleware.com",
},
}
response = self.client.post("/api/v1/asset/", sample_data, format="json")
self.assertEqual(response.status_code, status.HTTP_201_CREATED)

def test_create_asset_with_duplicate_ip_different_hostname_on_location_asset(self):
test_location = self.create_asset_location(
self.facility, middleware_address="not-test-middleware.com"
)
self.create_asset(
test_location,
name="I was here first",
asset_class=AssetClasses.HL7MONITOR.name,
meta={
"local_ip_address": "192.168.1.14",
"middleware_hostname": self.hostname,
},
)
sample_data = {
"name": "Test Asset",
"asset_type": 50,
"location": test_location.external_id,
"asset_class": AssetClasses.HL7MONITOR.name,
"meta": {
"local_ip_address": "192.168.1.14",
"middleware_hostname": "not-test-middleware.com",
},
}
response = self.client.post("/api/v1/asset/", sample_data, format="json")
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
Loading
Loading