Skip to content

Commit

Permalink
fix query bugs while resolving asset hostname (#2099)
Browse files Browse the repository at this point in the history
Co-authored-by: Vignesh Hari <[email protected]>
  • Loading branch information
sainak and vigneshhari authored Apr 18, 2024
1 parent 338b510 commit 2c023e1
Show file tree
Hide file tree
Showing 5 changed files with 327 additions and 18 deletions.
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
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

0 comments on commit 2c023e1

Please sign in to comment.