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

Adding tests for questionnaire and few minor changes #2745

Merged
merged 9 commits into from
Jan 21, 2025
14 changes: 5 additions & 9 deletions care/emr/api/viewsets/questionnaire.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class QuestionnaireViewSet(EMRModelViewSet):
def permissions_controller(self, request):
if self.action in ["list", "retrieve", "get_organizations"]:
return AuthorizationController.call("can_read_questionnaire", request.user)
if self.action in ["create", "update", "set_organizations", "set_tags"]:
if self.action in ["create", "set_organizations", "set_tags"]:
return AuthorizationController.call("can_write_questionnaire", request.user)

return request.user.is_authenticated
Expand Down Expand Up @@ -147,14 +147,10 @@ def submit(self, request, *args, **kwargs):
raise PermissionDenied(
"Permission Denied to submit patient questionnaire"
)
else:
patient = get_object_or_404(Patient, external_id=request_params.patient)
if not AuthorizationController.call(
"can_submit_questionnaire_patient_obj", request.user, patient
):
raise PermissionDenied(
"Permission Denied to submit patient questionnaire"
)
elif not AuthorizationController.call(
"can_submit_questionnaire_patient_obj", request.user, patient
):
raise PermissionDenied("Permission Denied to submit patient questionnaire")
with transaction.atomic():
response = handle_response(questionnaire, request_params, request.user)
return Response(QuestionnaireResponseReadSpec.serialize(response).to_json())
Expand Down
27 changes: 23 additions & 4 deletions care/emr/resources/questionnaire/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import uuid
from datetime import datetime
from urllib.parse import urlparse

from dateutil import parser
from django.utils import timezone
from rest_framework.exceptions import ValidationError

Expand All @@ -27,7 +27,19 @@ def check_required(questionnaire, questionnaire_ref):
return False


def validate_data(values, value_type, questionnaire_ref):
def get_valid_choices(question):
"""
Extracts valid choices from a choice question dictionary.
"""
answer_options = question.get("answer_option", [])
if not answer_options:
error = f"No 'answer_option' found in question with id {question.get('id')}."
raise ValueError(error)

return [option["value"] for option in answer_options if "value" in option]


def validate_data(values, value_type, questionnaire_ref): # noqa PLR0912
"""
Validate the type of the value based on the question type.
Args:
Expand All @@ -51,11 +63,18 @@ def validate_data(values, value_type, questionnaire_ref):
if value.value.lower() not in ["true", "false", "1", "0"]:
errors.append(f"Invalid boolean value: {value.value}")
elif value_type == QuestionType.date.value:
parser.parse(value.value).date()
datetime.strptime(value.value, "%Y-%m-%d").date() # noqa DTZ007
elif value_type == QuestionType.datetime.value:
parser.parse(value.value)
datetime.strptime(value.value, "%Y-%m-%dT%H:%M:%S") # noqa DTZ007
elif value_type == QuestionType.time.value:
datetime.strptime(value.value, "%H:%M:%S") # noqa DTZ007
elif value_type == QuestionType.choice.value:
if value.value not in get_valid_choices(questionnaire_ref):
errors.append(f"Invalid {value_type}")
elif value_type == QuestionType.url.value:
parsed = urlparse(value.value)
if not all([parsed.scheme, parsed.netloc]):
errors.append(f"Invalid {value_type}")
except ValueError:
errors.append(f"Invalid {value_type}")
except Exception:
Expand Down
Loading
Loading