Skip to content

Commit

Permalink
add tests and validation for filterset (#2588)
Browse files Browse the repository at this point in the history
add tests and validation for filterset (#2588)
  • Loading branch information
DraKen0009 authored Nov 25, 2024
1 parent fbc6157 commit 3ab5d90
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 13 deletions.
40 changes: 27 additions & 13 deletions care/facility/api/viewsets/patient.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from django.conf import settings
from django.contrib.postgres.search import TrigramSimilarity
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.db.models import (
Case,
Expand Down Expand Up @@ -76,7 +77,7 @@
NewDischargeReasonEnum,
)
from care.facility.models.patient_consultation import PatientConsultation
from care.users.models import User
from care.users.models import GENDER_CHOICES, User
from care.utils.cache.cache_allowed_facilities import get_accessible_facilities
from care.utils.exports.mixins import CSVExportViewSetMixin
from care.utils.filters.choicefilter import CareChoiceFilter
Expand Down Expand Up @@ -107,14 +108,22 @@ class PatientFilterSet(filters.FilterSet):
phone_number = filters.CharFilter(field_name="phone_number")
emergency_phone_number = filters.CharFilter(field_name="emergency_phone_number")
allow_transfer = filters.BooleanFilter(field_name="allow_transfer")
name = filters.CharFilter(field_name="name", lookup_expr="icontains")
name = filters.CharFilter(
field_name="name", lookup_expr="icontains", max_length=200
)
patient_no = filters.CharFilter(
field_name=f"{last_consultation_field}__patient_no", lookup_expr="iexact"
field_name=f"{last_consultation_field}__patient_no",
lookup_expr="iexact",
max_length=100,
)
gender = filters.ChoiceFilter(field_name="gender", choices=GENDER_CHOICES)
age = filters.NumberFilter(field_name="age", validators=[MinValueValidator(0)])
age_min = filters.NumberFilter(
field_name="age", lookup_expr="gte", validators=[MinValueValidator(0)]
)
age_max = filters.NumberFilter(
field_name="age", lookup_expr="lte", validators=[MinValueValidator(0)]
)
gender = filters.NumberFilter(field_name="gender")
age = filters.NumberFilter(field_name="age")
age_min = filters.NumberFilter(field_name="age", lookup_expr="gte")
age_max = filters.NumberFilter(field_name="age", lookup_expr="lte")
deprecated_covid_category = filters.ChoiceFilter(
field_name=f"{last_consultation_field}__deprecated_covid_category",
choices=COVID_CATEGORY_CHOICES,
Expand All @@ -141,7 +150,7 @@ def filter_by_category(self, queryset, name, value):

created_date = filters.DateFromToRangeFilter(field_name="created_date")
modified_date = filters.DateFromToRangeFilter(field_name="modified_date")
srf_id = filters.CharFilter(field_name="srf_id")
srf_id = filters.CharFilter(field_name="srf_id", max_length=200)
is_declared_positive = filters.BooleanFilter(field_name="is_declared_positive")
date_declared_positive = filters.DateFromToRangeFilter(
field_name="date_declared_positive"
Expand All @@ -159,14 +168,16 @@ def filter_by_category(self, queryset, name, value):
# Location Based Filtering
district = filters.NumberFilter(field_name="district__id")
district_name = filters.CharFilter(
field_name="district__name", lookup_expr="icontains"
field_name="district__name", lookup_expr="icontains", max_length=255
)
local_body = filters.NumberFilter(field_name="local_body__id")
local_body_name = filters.CharFilter(
field_name="local_body__name", lookup_expr="icontains"
field_name="local_body__name", lookup_expr="icontains", max_length=255
)
state = filters.NumberFilter(field_name="state__id")
state_name = filters.CharFilter(field_name="state__name", lookup_expr="icontains")
state_name = filters.CharFilter(
field_name="state__name", lookup_expr="icontains", max_length=255
)
# Consultation Fields
is_kasp = filters.BooleanFilter(field_name=f"{last_consultation_field}__is_kasp")
last_consultation_kasp_enabled_date = filters.DateFromToRangeFilter(
Expand Down Expand Up @@ -225,9 +236,12 @@ def filter_by_bed_type(self, queryset, name, value):
)

# Vaccination Filters
covin_id = filters.CharFilter(field_name="covin_id")
covin_id = filters.CharFilter(field_name="covin_id", max_length=15)
is_vaccinated = filters.BooleanFilter(field_name="is_vaccinated")
number_of_doses = filters.NumberFilter(field_name="number_of_doses")
number_of_doses = filters.NumberFilter(
field_name="number_of_doses",
validators=[MinValueValidator(0), MaxValueValidator(3)],
)
# Permission Filters
assigned_to = filters.NumberFilter(field_name="assigned_to")
# Other Filters
Expand Down
129 changes: 129 additions & 0 deletions care/facility/tests/test_patient_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,135 @@ def test_filter_by_has_consents(self):
self.assertEqual(res.status_code, status.HTTP_200_OK)
self.assertEqual(res.json()["count"], 3)

def test_filter_by_invalid_params(self):
self.client.force_authenticate(user=self.user)

# name length > 200 words
invalid_name_param = "a" * 201
res = self.client.get(self.get_base_url() + f"?name={invalid_name_param}")
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn(
"Ensure this value has at most 200 characters (it has 201).",
res.json()["name"],
)

# invalid gender choice
invalid_gender = 4
res = self.client.get(self.get_base_url() + f"?gender={invalid_gender}")
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn(
"Select a valid choice. 4 is not one of the available choices.",
res.json()["gender"],
)

# invalid value for age, age max , age min filter (i.e <0)
invalid_age = -2
res = self.client.get(self.get_base_url() + f"?age={invalid_age}")
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn(
"Ensure this value is greater than or equal to 0.", res.json()["age"]
)

invalid_min_age = -2
res = self.client.get(self.get_base_url() + f"?age_min={invalid_min_age}")
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn(
"Ensure this value is greater than or equal to 0.", res.json()["age_min"]
)

invalid_max_age = -2
res = self.client.get(self.get_base_url() + f"?age_max={invalid_max_age}")
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn(
"Ensure this value is greater than or equal to 0.", res.json()["age_max"]
)

# invalid number_of_doses param >3 or <0
invalid_number_of_doses = -2
res = self.client.get(
self.get_base_url() + f"?number_of_doses={invalid_number_of_doses}"
)
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn(
"Ensure this value is greater than or equal to 0.",
res.json()["number_of_doses"],
)

invalid_number_of_doses = 4
res = self.client.get(
self.get_base_url() + f"?number_of_doses={invalid_number_of_doses}"
)
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn(
"Ensure this value is less than or equal to 3.",
res.json()["number_of_doses"],
)

# invalid srf id length > 200 words
invalid_srf_param = "a" * 201
res = self.client.get(self.get_base_url() + f"?srf_id={invalid_srf_param}")
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn(
"Ensure this value has at most 200 characters (it has 201).",
res.json()["srf_id"],
)

# invalid district_name length > 255 words
invalid_district_name_param = "a" * 256
res = self.client.get(
self.get_base_url() + f"?district_name={invalid_district_name_param}"
)
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn(
"Ensure this value has at most 255 characters (it has 256).",
res.json()["district_name"],
)

# invalid local_body_name length > 255 words
invalid_local_body_name_param = "a" * 256
res = self.client.get(
self.get_base_url() + f"?local_body_name={invalid_local_body_name_param}"
)
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn(
"Ensure this value has at most 255 characters (it has 256).",
res.json()["local_body_name"],
)

# invalid state_name length > 255 words
invalid_state_name_param = "a" * 256
res = self.client.get(
self.get_base_url() + f"?state_name={invalid_state_name_param}"
)
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn(
"Ensure this value has at most 255 characters (it has 256).",
res.json()["state_name"],
)

# invalid patient no value > 100
invalid_patient_no_param = "A" * 101
res = self.client.get(
self.get_base_url() + f"?patient_no={invalid_patient_no_param}"
)
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn(
"Ensure this value has at most 100 characters (it has 101).",
res.json()["patient_no"],
)

def test_invalid_covin_id_param(self):
self.client.force_authenticate(user=self.user)

# Test invalid covin_id length > 15 characters
invalid_covin_id = "A" * 16
res = self.client.get(self.get_base_url() + f"?covin_id={invalid_covin_id}")
self.assertEqual(res.status_code, status.HTTP_400_BAD_REQUEST)
self.assertIn(
"Ensure this value has at most 15 characters (it has 16).",
res.json()["covin_id"],
)


class DischargePatientFilterTestCase(TestUtils, APITestCase):
@classmethod
Expand Down

0 comments on commit 3ab5d90

Please sign in to comment.