Skip to content

Commit

Permalink
Merge branch 'release/0.3.63'
Browse files Browse the repository at this point in the history
  • Loading branch information
JonathanWillitts committed Nov 6, 2023
2 parents 9a6697a + 68c2618 commit ff8019a
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 7 deletions.
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ repos:
- "-x *test*.py"

- repo: https://github.com/psf/black
rev: 23.9.1
rev: 23.10.1
hooks:
- id: black
language_version: python3.11
Expand All @@ -28,7 +28,7 @@ repos:
- id: isort

- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.5.0
hooks:
- id: requirements-txt-fixer
files: requirements/.*\.txt$
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
from typing import Any, Optional
from __future__ import annotations

from typing import TYPE_CHECKING, Any, Optional
from zoneinfo import ZoneInfo

from django import forms
Expand All @@ -8,6 +10,9 @@
from edc_form_validators.base_form_validator import INVALID_ERROR
from edc_utils import convert_php_dateformat

if TYPE_CHECKING:
from datetime import date


class DeathReportFormValidatorMixin:

Expand All @@ -23,6 +28,13 @@ def cause_of_death_model_cls(self):
def clean(self: Any) -> None:
self.validate_study_day_with_death_report_date()

self.date_is_after_or_raise(
field="report_datetime",
reference_value=self.death_report_date,
inclusive=True,
extra_msg="(on or after date of death)",
)

cause_of_death = self.cause_of_death_model_cls.objects.get(name=OTHER)

self.validate_other_specify(
Expand All @@ -36,7 +48,7 @@ def clean(self: Any) -> None:
)

@property
def death_report_date(self: Any) -> None:
def death_report_date(self: Any) -> date:
try:
return self.cleaned_data.get(self.death_report_date_field).date()
except AttributeError:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
from edc_model.models import HistoricalRecords
from edc_model.validators import date_not_future, datetime_not_future
from edc_model_fields.fields.other_charfield import OtherCharField
from edc_protocol.validators import datetime_not_before_study_start
from edc_protocol.validators import (
date_not_before_study_start,
datetime_not_before_study_start,
)
from edc_sites.models import SiteModelMixin
from edc_utils import get_utcnow

Expand Down Expand Up @@ -39,14 +42,14 @@ class DeathReportModelMixin(
)

death_datetime = models.DateTimeField(
validators=[datetime_not_future],
validators=[datetime_not_before_study_start, datetime_not_future],
verbose_name="Date and Time of Death",
null=True,
blank=False,
)

death_date = models.DateField(
validators=[date_not_future],
validators=[date_not_before_study_start, date_not_future],
verbose_name="Date of Death",
null=True,
blank=False,
Expand Down
134 changes: 134 additions & 0 deletions edc_adverse_event/tests/tests/test_death_report_form_validator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
from dateutil.relativedelta import relativedelta
from django import forms
from django.test import TestCase
from edc_constants.constants import OTHER, UNKNOWN
from edc_constants.disease_constants import BACTERAEMIA
from edc_form_validators import FormValidatorTestCaseMixin
from edc_form_validators.tests.mixins import FormValidatorTestMixin
from edc_utils import get_utcnow

from edc_adverse_event.form_validators import DeathReportFormValidator as Base


class DeathReportFormValidator(FormValidatorTestMixin, Base):
pass


class TestHospitalizationFormValidation(FormValidatorTestCaseMixin, TestCase):
@staticmethod
def get_cleaned_data() -> dict:
report_datetime = get_utcnow()
return {
"report_datetime": report_datetime,
"death_datetime": report_datetime - relativedelta(days=3),
"cause_of_death": BACTERAEMIA,
"cause_of_death_other": "",
"narrative": "Narrative around death",
}

def test_cleaned_data_ok(self):
cleaned_data = self.get_cleaned_data()
form_validator = DeathReportFormValidator(cleaned_data=cleaned_data)
try:
form_validator.validate()
except forms.ValidationError as e:
self.fail(f"ValidationError unexpectedly raised. Got {e}")

def test_death_datetime_after_report_datetime_raises(self):
for death_report_date_field in ["death_date", "death_datetime"]:
for days_after in [1, 3, 14]:
with self.subTest(
death_report_date_field=death_report_date_field, days_after=days_after
):
report_datetime = get_utcnow()
death_datetime = report_datetime + relativedelta(days=days_after)
cleaned_data = {
"report_datetime": get_utcnow(),
death_report_date_field: (
death_datetime
if death_report_date_field == "death_datetime"
else death_datetime.date()
),
}
form_validator = DeathReportFormValidator(cleaned_data=cleaned_data)
form_validator.death_report_date_field = death_report_date_field
with self.assertRaises(forms.ValidationError) as cm:
form_validator.validate()
self.assertIn("report_datetime", cm.exception.error_dict)
self.assertIn(
"Invalid. Expected a date on or after",
str(cm.exception.error_dict.get("report_datetime")),
)
self.assertIn(
"(on or after date of death)",
str(cm.exception.error_dict.get("report_datetime")),
)

def test_death_datetime_on_or_before_report_datetime_datetime_ok(self):
for death_report_date_field in ["death_date", "death_datetime"]:
for days_before in [0, 1, 2, 14]:
with self.subTest(
death_report_date_field=death_report_date_field, days_before=days_before
):
report_datetime = get_utcnow()
death_datetime = report_datetime - relativedelta(days=days_before)
cleaned_data = {
"report_datetime": report_datetime,
death_report_date_field: death_datetime
if death_report_date_field == "death_datetime"
else death_datetime.date(),
}
form_validator = DeathReportFormValidator(cleaned_data=cleaned_data)
form_validator.death_report_date_field = death_report_date_field
try:
form_validator.validate()
except forms.ValidationError as e:
self.fail(f"ValidationError unexpectedly raised. Got {e}")

def test_cause_of_death_other_required_if_cause_of_death_other(self):
cleaned_data = self.get_cleaned_data()
cleaned_data.update(
{
"cause_of_death": OTHER,
"cause_of_death_other": "",
}
)
form_validator = DeathReportFormValidator(cleaned_data=cleaned_data)
with self.assertRaises(forms.ValidationError) as cm:
form_validator.validate()
self.assertIn("cause_of_death_other", cm.exception.error_dict)
self.assertIn(
"This field is required.",
str(cm.exception.error_dict.get("cause_of_death_other")),
)

cleaned_data.update({"cause_of_death_other": "Some other cause of death..."})
form_validator = DeathReportFormValidator(cleaned_data=cleaned_data)
try:
form_validator.validate()
except forms.ValidationError as e:
self.fail(f"ValidationError unexpectedly raised. Got {e}")

def test_cause_of_death_other_not_required_if_cause_of_death_not_other(self):
cleaned_data = self.get_cleaned_data()
cleaned_data.update(
{
"cause_of_death": UNKNOWN,
"cause_of_death_other": "Some other cause of death",
}
)
form_validator = DeathReportFormValidator(cleaned_data=cleaned_data)
with self.assertRaises(forms.ValidationError) as cm:
form_validator.validate()
self.assertIn("cause_of_death_other", cm.exception.error_dict)
self.assertIn(
"This field is not required.",
str(cm.exception.error_dict.get("cause_of_death_other")),
)

cleaned_data.update({"cause_of_death_other": ""})
form_validator = DeathReportFormValidator(cleaned_data=cleaned_data)
try:
form_validator.validate()
except forms.ValidationError as e:
self.fail(f"ValidationError unexpectedly raised. Got {e}")

0 comments on commit ff8019a

Please sign in to comment.