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 list and detail serializer patient external serializer #1539

Closed
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
112 changes: 112 additions & 0 deletions care/facility/api/serializers/patient_external_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@


class PatientExternalTestSerializer(serializers.ModelSerializer):
# TODO: Remove when #5492 is completed and merged
ward_object = WardSerializer(source="ward", read_only=True)
local_body_object = LocalBodySerializer(source="local_body", read_only=True)
district_object = DistrictSerializer(source="district", read_only=True)
Comment on lines 14 to 18
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this serializer

Expand Down Expand Up @@ -130,3 +131,114 @@
)

return super().update(instance, validated_data)


class PatientExternalListSerializer(serializers.ModelSerializer):
result_date = serializers.DateField(input_formats=["%Y-%m-%d"], required=False)

class Meta:
model = PatientExternalTest
fields = [
"id",
"name",
"age",
"age_in",
"test_type",
"result",
"patient_created",
"result_date",
]


class PatientExternalDetailSerializer(serializers.ModelSerializer):
ward_object = WardSerializer(source="ward", read_only=True)
local_body_object = LocalBodySerializer(source="local_body", read_only=True)
district_object = DistrictSerializer(source="district", read_only=True)

local_body_type = serializers.CharField(required=False, write_only=True)

sample_collection_date = serializers.DateField(
input_formats=["%Y-%m-%d"], required=False
)
result_date = serializers.DateField(input_formats=["%Y-%m-%d"], required=False)

def validate_empty_values(self, data, *args, **kwargs):
# if "is_repeat" in data:
# is_repeat = data["is_repeat"]
# if is_repeat.lower() == "yes":
# data["is_repeat"] = True
# else:
# data["is_repeat"] = False
district_obj = None

Check warning on line 172 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L172

Added line #L172 was not covered by tests
if "district" in data:
district = data["district"]
district_obj = District.objects.filter(name__icontains=district).first()

Check warning on line 175 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L174-L175

Added lines #L174 - L175 were not covered by tests
if district_obj:
data["district"] = district_obj.id

Check warning on line 177 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L177

Added line #L177 was not covered by tests
else:
raise ValidationError({"district": ["District Does not Exist"]})

Check warning on line 179 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L179

Added line #L179 was not covered by tests
else:
raise ValidationError({"district": ["District Not Present in Data"]})

Check warning on line 181 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L181

Added line #L181 was not covered by tests

if "local_body_type" not in data:
raise ValidationError(

Check warning on line 184 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L184

Added line #L184 was not covered by tests
{"local_body_type": ["local_body_type is not present in data"]}
)

if not data["local_body_type"]:
raise ValidationError(

Check warning on line 189 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L189

Added line #L189 was not covered by tests
{"local_body_type": ["local_body_type cannot be empty"]}
)

if data["local_body_type"].lower() not in REVERSE_LOCAL_BODY_CHOICES:
raise ValidationError({"local_body_type": ["Invalid Local Body Type"]})

Check warning on line 194 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L194

Added line #L194 was not covered by tests

local_body_type = REVERSE_LOCAL_BODY_CHOICES[data["local_body_type"].lower()]

Check warning on line 196 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L196

Added line #L196 was not covered by tests

local_body_obj = None

Check warning on line 198 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L198

Added line #L198 was not covered by tests
if "local_body" in data and district_obj:
if not data["local_body"]:
raise ValidationError({"local_body": ["Local Body Cannot Be Empty"]})
local_body = data["local_body"]
local_body_obj = LocalBody.objects.filter(

Check warning on line 203 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L201-L203

Added lines #L201 - L203 were not covered by tests
name__icontains=local_body,
district=district_obj,
body_type=local_body_type,
).first()
if local_body_obj:
data["local_body"] = local_body_obj.id

Check warning on line 209 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L209

Added line #L209 was not covered by tests
else:
raise ValidationError({"local_body": ["Local Body Does not Exist"]})

Check warning on line 211 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L211

Added line #L211 was not covered by tests
else:
raise ValidationError({"local_body": ["Local Body Not Present in Data"]})

Check warning on line 213 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L213

Added line #L213 was not covered by tests

if "ward" in data and local_body_obj:
try:
int(data["ward"])
except Exception:
raise ValidationError({"ward": ["Ward must be an integer value"]})

Check warning on line 219 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L216-L219

Added lines #L216 - L219 were not covered by tests
if data["ward"]:
ward_obj = Ward.objects.filter(

Check warning on line 221 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L221

Added line #L221 was not covered by tests
number=data["ward"], local_body=local_body_obj
).first()
if ward_obj:
data["ward"] = ward_obj.id

Check warning on line 225 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L225

Added line #L225 was not covered by tests
else:
raise ValidationError({"ward": ["Ward Does not Exist"]})

Check warning on line 227 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L227

Added line #L227 was not covered by tests

del data["local_body_type"]

Check warning on line 229 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L229

Added line #L229 was not covered by tests

return super().validate_empty_values(data, *args, **kwargs)

Check warning on line 231 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L231

Added line #L231 was not covered by tests

def create(self, validated_data):
if "srf_id" in validated_data:
if PatientRegistration.objects.filter(
srf_id__iexact=validated_data["srf_id"]
).exists():
validated_data["patient_created"] = True
return super().create(validated_data)

Check warning on line 239 in care/facility/api/serializers/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/serializers/patient_external_test.py#L238-L239

Added lines #L238 - L239 were not covered by tests

class Meta:
model = PatientExternalTest
fields = "__all__"
read_only_fields = ("patient_created",)
9 changes: 6 additions & 3 deletions care/facility/api/viewsets/patient_external_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
from rest_framework.viewsets import GenericViewSet

from care.facility.api.serializers.patient_external_test import (
PatientExternalTestSerializer,
PatientExternalDetailSerializer,
PatientExternalListSerializer,
PatientExternalTestUpdateSerializer,
)
from care.facility.models import PatientExternalTest
Expand Down Expand Up @@ -71,7 +72,7 @@
DestroyModelMixin,
GenericViewSet,
):
serializer_class = PatientExternalTestSerializer
serializer_class = PatientExternalDetailSerializer
queryset = (
PatientExternalTest.objects.select_related("ward", "local_body", "district")
.all()
Expand Down Expand Up @@ -100,6 +101,8 @@
return queryset

def get_serializer_class(self):
if self.action == "list":
return PatientExternalListSerializer
if self.action == "update" or self.action == "partial_update":
return PatientExternalTestUpdateSerializer
return super().get_serializer_class()
Expand Down Expand Up @@ -149,7 +152,7 @@
invalid = False
for sample in request.data["sample_tests"]:
counter += 1
serialiser_obj = PatientExternalTestSerializer(data=sample)
serialiser_obj = PatientExternalDetailSerializer(data=sample)

Check warning on line 155 in care/facility/api/viewsets/patient_external_test.py

View check run for this annotation

Codecov / codecov/patch

care/facility/api/viewsets/patient_external_test.py#L155

Added line #L155 was not covered by tests
valid = serialiser_obj.is_valid()
current_error = prettyerrors(serialiser_obj._errors)
if current_error and (not valid):
Expand Down
124 changes: 124 additions & 0 deletions care/facility/tests/test_facility_patient_external_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
from enum import Enum

from rest_framework import status
from rest_framework.test import APITestCase
from rest_framework_simplejwt.tokens import RefreshToken

from care.utils.tests.test_utils import TestUtils


class ExpectedPatientExternalTestListKeys(Enum):
id = "id"
name = "name"
age = "age"
age_in = "age_in"
test_type = "test_type"
result = "result"
patient_created = "patient_created"
result_date = "result_date"


class ExpectedPatientExternalTestRetrieveKeys(Enum):
id = "id"
ward_object = "ward_object"
local_body_object = "local_body_object"
district_object = "district_object"
sample_collection_date = "sample_collection_date"
result_date = "result_date"
external_id = "external_id"
created_date = "created_date"
modified_date = "modified_date"
deleted = "deleted"
srf_id = "srf_id"
name = "name"
age = "age"
age_in = "age_in"
gender = "gender"
address = "address"
mobile_number = "mobile_number"
is_repeat = "is_repeat"
patient_status = "patient_status"
source = "source"
patient_category = "patient_category"
lab_name = "lab_name"
test_type = "test_type"
sample_type = "sample_type"
result = "result"
patient_created = "patient_created"
ward = "ward"
local_body = "local_body"
district = "district"


class WardKeys(Enum):
ID = "id"
NAME = "name"
NUMBER = "number"
LOCAL_BODY = "local_body"


class LocalBodyKeys(Enum):
ID = "id"
NAME = "name"
BODY_TYPE = "body_type"
LOCALBODY_CODE = "localbody_code"
DISTRICT = "district"


class DistrictKeys(Enum):
ID = "id"
NAME = "name"
STATE = "state"


class PatientExternalTestViewSetTestCase(TestUtils, APITestCase):
@classmethod
def setUpTestData(cls) -> None:
cls.state = cls.create_state()
cls.district = cls.create_district(cls.state)
cls.super_user = cls.create_super_user(username="su2", district=cls.district)
cls.local_body = cls.create_local_body(cls.district)
cls.ward = cls.create_ward(cls.local_body)
cls.patient_external = cls.create_patient_external_test(
district=cls.district, local_body=cls.local_body, ward=cls.ward
)

def setUp(self) -> None:
refresh_token = RefreshToken.for_user(self.super_user)
self.client.credentials(
HTTP_AUTHORIZATION=f"Bearer {refresh_token.access_token}"
)

def test_list_patient_external_test(self):
response = self.client.get("/api/v1/external_result/")

self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertIsInstance(response.json()["results"], list)

# Ensure only necessary data is being sent and no extra data
expected_keys = [key.value for key in ExpectedPatientExternalTestListKeys]
data = response.json()["results"][0]
self.assertCountEqual(data.keys(), expected_keys)

def test_retrieve_patient_external_test(self):
response = self.client.get(
f"/api/v1/external_result/{self.patient_external.id}/"
)

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

expected_keys = [key.value for key in ExpectedPatientExternalTestRetrieveKeys]

data = response.json()

self.assertCountEqual(data.keys(), expected_keys)

self.assertCountEqual(
data["ward_object"].keys(), [key.value for key in WardKeys]
)
self.assertCountEqual(
data["local_body_object"].keys(), [key.value for key in LocalBodyKeys]
)
self.assertCountEqual(
data["district_object"].keys(), [key.value for key in DistrictKeys]
)
Loading