def test_history(self): SubjectConsent.objects.create( subject_identifier=self.subject_identifier, consent_datetime=get_utcnow() - relativedelta(years=3), ) OnSchedule.objects.create( subject_identifier=self.subject_identifier, onschedule_datetime=get_utcnow() - relativedelta(years=3), ) OffSchedule.objects.create( subject_identifier=self.subject_identifier, offschedule_datetime=get_utcnow(), ) obj = SubjectScheduleHistory.objects.get( subject_identifier=self.subject_identifier) self.assertEqual( obj.natural_key(), (obj.subject_identifier, obj.visit_schedule_name, obj.schedule_name), ) self.assertEqual( SubjectScheduleHistory.objects.get_by_natural_key( obj.subject_identifier, obj.visit_schedule_name, obj.schedule_name), obj, )
def test_crf(self): """Assert can enter a CRF.""" SubjectConsent.objects.create( subject_identifier=self.subject_identifier, consent_datetime=get_utcnow() - relativedelta(years=3), ) OnSchedule.objects.create( subject_identifier=self.subject_identifier, onschedule_datetime=get_utcnow() - relativedelta(years=3), ) appointments = Appointment.objects.all() self.assertEqual(appointments.count(), 4) appointment = Appointment.objects.all().order_by( "appt_datetime").first() subject_visit = SubjectVisit.objects.create( appointment=appointment, report_datetime=appointment.appt_datetime, subject_identifier=self.subject_identifier, reason=SCHEDULED, ) CrfOne.objects.create(subject_visit=subject_visit, report_datetime=appointment.appt_datetime) OffSchedule.objects.create( subject_identifier=self.subject_identifier, offschedule_datetime=appointment.appt_datetime, ) self.assertEqual(Appointment.objects.all().count(), 1)
def test_date_validators(self): future_datetime = get_utcnow() + relativedelta(days=10) form = DateForm(data={"datetime_not_future": future_datetime}) self.assertFalse(form.is_valid()) self.assertEqual( form.errors.get("datetime_not_future"), ["Cannot be a future date/time"] ) future_date = (get_utcnow() + relativedelta(days=10)).date() form = DateForm(data={"date_not_future": future_date}) self.assertFalse(form.is_valid()) self.assertEqual( form.errors.get("date_not_future"), ["Cannot be a future date"] ) past_datetime = get_utcnow() - relativedelta(days=10) form = DateForm(data={"datetime_is_future": past_datetime}) self.assertFalse(form.is_valid()) self.assertEqual( form.errors.get("datetime_is_future"), ["Expected a future date/time"] ) past_date = (get_utcnow() - relativedelta(days=10)).date() form = DateForm(data={"date_is_future": past_date}) self.assertFalse(form.is_valid()) self.assertEqual(form.errors.get("date_is_future"), ["Expected a future date"])
def test_bmi_calculator(self): dob = get_utcnow() - relativedelta(years=25) self.assertRaises(CalculatorError, BMI, weight_kg=56, height_cm=None) try: calculate_bmi(weight_kg=56, height_cm=None, dob=dob) except CalculatorError: self.fail("CalculatorError unexpectedly raised ") for func in [BMI, calculate_bmi]: with self.subTest(func=func): self.assertRaises( CalculatorError, func, weight_kg=56, height_cm=1.50, dob=dob, report_datetime=get_utcnow(), ) try: bmi = func(weight_kg=56, height_cm=150, dob=dob, report_datetime=get_utcnow()) except CalculatorError as e: self.fail(f"CalculatorError unexpectedly raises. Got {e}") else: self.assertEqual(round(bmi.value, 2), 24.89)
def test_haemoglobin(self): reportables = site_reportables.get("my_reference_list") haemoglobin = reportables.get("haemoglobin") normal = haemoglobin.get_normal( value=15.0, units="g/dL", gender=MALE, dob=get_utcnow() - relativedelta(years=25), ) self.assertIsNotNone(normal) self.assertIn("13.5<=15.0<=17.5", normal.description) grade = haemoglobin.get_grade( value=8, units="g/dL", gender=MALE, dob=get_utcnow() - relativedelta(years=25), ) self.assertIn("7.0<=8.0<9.0", grade.description) grade = haemoglobin.get_grade( value=15, units="g/dL", gender=MALE, dob=get_utcnow() - relativedelta(years=25), ) self.assertIsNone(grade)
def setUp(self): self.subject_identifier = "12345" RegisteredSubject.objects.create( subject_identifier="12345", dob=get_utcnow() - relativedelta(years=25), gender=FEMALE, ) self.medication = Medication.objects.create(name="Flucytosine", ) self.formulation = Formulation.objects.create( medication=self.medication, strength=500, units=Units.objects.get(name="mg"), route=Route.objects.get(display_name="Oral"), formulation_type=FormulationType.objects.get( display_name__iexact="Tablet"), ) self.dosage_guideline = DosageGuideline.objects.create( medication=self.medication, dose_per_kg=100, dose_units=Units.objects.get(name="mg"), frequency=1, frequency_units=FrequencyUnits.objects.get(name="day"), ) self.rx = Rx.objects.create( subject_identifier=self.subject_identifier, weight_in_kgs=40, report_datetime=get_utcnow(), medication=self.medication, )
def test_requires_previous_visit_thru_model2(self): appointments = Appointment.objects.all().order_by( "timepoint", "visit_code_sequence") opts = appointments[1].__dict__ opts.pop("_state") opts.pop("id") opts.pop("created") opts.pop("modified") opts["visit_code_sequence"] = 1 Appointment.objects.create(**opts) opts["visit_code_sequence"] = 2 SubjectVisit.objects.create( appointment=appointments[0], report_datetime=get_utcnow() - relativedelta(months=10), reason=SCHEDULED, ) self.assertRaises( PreviousVisitError, SubjectVisit.objects.create, appointment=appointments[2], report_datetime=get_utcnow() - relativedelta(months=8), )
def setUp(self): site_visit_schedules._registry = {} site_visit_schedules.register(visit_schedule) self.lab_helper.setup_site_labs() class RequisitionForm(RequisitionFormMixin, FormValidatorMixin, forms.ModelForm): form_validator_cls = RequisitionFormValidator class Meta: fields = "__all__" model = SubjectRequisition self.form_cls = RequisitionForm self.subject_identifier = "12345" SubjectConsent.objects.create( subject_identifier=self.subject_identifier, consent_datetime=get_utcnow(), identity="1111111", confirm_identity="1111111", visit_schedule_name="visit_schedule", schedule_name="schedule", ) appointment = Appointment.objects.get(visit_code="1000") self.subject_visit = SubjectVisit.objects.create( appointment=appointment, report_datetime=get_utcnow(), reason=SCHEDULED)
def test_numbers(self): IntegratedCareClinicRegistration.objects.create(date_opened=get_utcnow().date()) data = { "site": Site.objects.get_current(), "log_date": get_utcnow(), "clinic_services": INTEGRATED, "selection_method": SEQUENTIAL, "attended": 10, "approached": 10, "agreed_to_screen": 10, } form = DailyClosingLogForm(data=data) form.is_valid() self.assertDictEqual({}, form._errors) data.update(approached=11) form = DailyClosingLogForm(data=data) form.is_valid() self.assertIn("approached", form._errors) data.update(approached=10, agreed_to_screen=11) form = DailyClosingLogForm(data=data) form.is_valid() self.assertIn("agreed_to_screen", form._errors)
def test_model_notification_mail_subject(self): site_notifications._registry = {} site_notifications.update_notification_list() @register() class DeathNotification(ModelNotification): name = "death" model = "edc_notification.death" update_fields = ["report_datetime"] site_notifications.update_notification_list() death = Death.objects.create(subject_identifier="1", cause="A") self.assertNotIn("UPDATE*", mail.outbox[0].subject) self.assertNotIn("DELETED*", mail.outbox[0].subject) death.report_datetime = get_utcnow() - timedelta(days=1) death.save() self.assertIn("UPDATE*", mail.outbox[1].subject) death.report_datetime = get_utcnow() death.save() self.assertIn("UPDATE*", mail.outbox[2].subject) death.delete() self.assertIn("DELETED*", mail.outbox[3].subject)
def test_requires_previous_visit_thru_model(self): """Asserts requires previous visit to exist on create.""" appointments = Appointment.objects.all().order_by( "timepoint", "visit_code_sequence") SubjectVisit.objects.create( appointment=appointments[0], report_datetime=get_utcnow() - relativedelta(months=10), reason=SCHEDULED, ) self.assertRaises( PreviousVisitError, SubjectVisit.objects.create, appointment=appointments[2], report_datetime=get_utcnow() - relativedelta(months=8), reason=SCHEDULED, ) SubjectVisit.objects.create( appointment=appointments[1], report_datetime=get_utcnow() - relativedelta(months=10), reason=SCHEDULED, ) self.assertRaises( PreviousVisitError, SubjectVisit.objects.create, appointment=appointments[3], report_datetime=get_utcnow() - relativedelta(months=8), reason=SCHEDULED, )
def to_outgoing_transaction(self, using, created=None, deleted=None): """ Serialize the model instance to an AES encrypted json object and saves the json object to the OutgoingTransaction model. """ outgoing_transaction_model_cls = django_apps.get_model( "django_collect_offline", "OutgoingTransaction") created = True if created is None else created action = INSERT if created else UPDATE timestamp_datetime = (self.instance.created if created else self.instance.modified) if not timestamp_datetime: timestamp_datetime = get_utcnow() if deleted: timestamp_datetime = get_utcnow() action = DELETE outgoing_transaction = None if self.is_serialized: hostname = socket.gethostname() outgoing_transaction = outgoing_transaction_model_cls.objects.using( using).create( tx_name=self.instance._meta.label_lower, tx_pk=getattr(self.instance, self.primary_key_field.name), tx=self.encrypted_json(), timestamp=timestamp_datetime.strftime("%Y%m%d%H%M%S%f"), producer=f"{hostname}-{using}", action=action, using=using, ) return outgoing_transaction
def test_pregnancy(self): data = copy(self.female_data) options = [ (NO, None, NO, "preg_test_date"), (NO, None, YES, "preg_test_date"), (YES, None, YES, None), (NO, get_utcnow().date(), NO, None), (YES, get_utcnow().date(), NO, None), (YES, get_utcnow().date(), YES, None), (YES, get_utcnow().date(), NOT_APPLICABLE, None), (NOT_APPLICABLE, get_utcnow().date(), NOT_APPLICABLE, "preg_test_date"), (NOT_APPLICABLE, None, NOT_APPLICABLE, None), ] for pregnancy, preg_test_date, breast_feeding, error_key in options: with self.subTest( pregnancy=pregnancy, preg_test_date=preg_test_date, breast_feeding=breast_feeding, error_key=error_key, ): data.update( pregnancy=pregnancy, preg_test_date=preg_test_date, breast_feeding=breast_feeding, ) form = SubjectScreeningForm(data=data) form.is_valid() if error_key: self.assertIn(error_key, form.errors) else: self.assertFalse(form.errors)
def test_subject_has_current_consent(self): subject_identifier = "123456789" identity = "987654321" baker.make_recipe( "edc_consent.subjectconsent", subject_identifier=subject_identifier, identity=identity, confirm_identity=identity, consent_datetime=self.study_open_datetime + timedelta(days=1), dob=get_utcnow() + relativedelta(years=25), ) subject_consent = SubjectConsent.consent.consent_for_period( "123456789", self.study_open_datetime + timedelta(days=1)) self.assertEqual(subject_consent.version, "1.0") baker.make_recipe( "edc_consent.subjectconsent", subject_identifier=subject_identifier, identity=identity, confirm_identity=identity, consent_datetime=self.study_open_datetime + timedelta(days=60), dob=get_utcnow() + relativedelta(years=25), ) subject_consent = SubjectConsent.consent.consent_for_period( "123456789", self.study_open_datetime + timedelta(days=60)) self.assertEqual(subject_consent.version, "2.0")
def test_included_in_error_reason_narrative_provided(self): """ Asserts included_in_error_date when termination reason is included_in_error. """ subject_identifier = self.create_subject() cleaned_data = { "subject_identifier": subject_identifier, "termination_reason": "included_in_error", "included_in_error_date": get_utcnow(), "included_in_error": None, } form_validator = StudyTerminationConclusionFormValidator( cleaned_data=cleaned_data) self.assertRaises(ValidationError, form_validator.validate) self.assertIn("included_in_error", form_validator._errors) cleaned_data = { "subject_identifier": subject_identifier, "termination_reason": "included_in_error", "included_in_error_date": get_utcnow(), "included_in_error": "blah blah blah blah", } form_validator = StudyTerminationConclusionFormValidator( cleaned_data=cleaned_data) try: form_validator.validate() except forms.ValidationError as e: self.fail(f"ValidationError unexpectedly raised. Got{e}")
def test_model_updates(self): subject_identifier = "123456789" identity = "987654321" consent = baker.make_recipe( "edc_consent.subjectconsent", subject_identifier=subject_identifier, identity=identity, confirm_identity=identity, consent_datetime=self.study_open_datetime, dob=get_utcnow() + relativedelta(years=25), ) self.assertEqual(consent.version, "1.0") consent = baker.make_recipe( "edc_consent.subjectconsent", subject_identifier=subject_identifier, identity=identity, confirm_identity=identity, consent_datetime=self.study_open_datetime + timedelta(days=51), dob=get_utcnow() + relativedelta(years=25), ) self.assertEqual(consent.version, "2.0") consent = baker.make_recipe( "edc_consent.subjectconsent", subject_identifier=subject_identifier, identity=identity, confirm_identity=identity, consent_datetime=self.study_open_datetime + timedelta(days=101), dob=get_utcnow() + relativedelta(years=25), ) self.assertEqual(consent.version, "3.0")
def prepare(self): self.subject_screening = self.get_subject_screening( report_datetime=get_utcnow(), clinic_type=HIV_CLINIC ) self.subject_consent = self.get_subject_consent( subject_screening=self.subject_screening, clinic_type=HIV_CLINIC, ) self.subject_visit = self.get_subject_visit( subject_screening=self.subject_screening, subject_consent=self.subject_consent, ) baker.make( "inte_subject.clinicalreviewbaseline", subject_visit=self.subject_visit, hiv_test=YES, hiv_dx=YES, hiv_test_ago="5y", ) baker.make( "inte_subject.hivinitialreview", subject_visit=self.subject_visit, dx_date=get_utcnow() - relativedelta(years=5), arv_initiation_ago="4y", )
def setUp(self): super().setUp() self.eligibility_datetime = get_utcnow() - relativedelta(days=1) # yesterday self.subject_screening = self.get_subject_screening( report_datetime=get_utcnow(), eligibility_datetime=self.eligibility_datetime ) self.screening_identifier = self.subject_screening.screening_identifier
def test_model_notification3(self): site_notifications._registry = {} site_notifications.update_notification_list() @register() class DeathNotification(ModelNotification): name = "death" model = "edc_notification.death" update_fields = ["report_datetime"] model_operations = [UPDATE] site_notifications.update_notification_list() death = Death.objects.create(subject_identifier="1", cause="A") self.assertEqual(len(mail.outbox), 0) death.save() self.assertEqual(len(mail.outbox), 0) death.report_datetime = get_utcnow() - timedelta(days=1) death.save() self.assertEqual(len(mail.outbox), 1) death.save() self.assertEqual(len(mail.outbox), 1) death.report_datetime = get_utcnow() death.save() self.assertEqual(len(mail.outbox), 2) death.delete() self.assertEqual(len(mail.outbox), 2)
def test_next_appointment_integrated_raises(self): self.prepare() IntegratedCareClinicRegistration.objects.create( report_datetime=get_utcnow(), date_opened=get_utcnow(), ) cleaned_data = { "subject_visit": self.subject_visit, "hiv_clinic_appt_date": None, "htn_clinic_appt_date": None, "dm_clinic_appt_date": None, "integrated_clinic_appt_date": None, "report_datetime": self.subject_visit.report_datetime, "crf_status": INCOMPLETE, } form_validator = NextAppointmentFormValidator( cleaned_data=cleaned_data) try: form_validator.validate() except ValidationError: self.assertIn("integrated_clinic_appt_date", form_validator._errors) self.assertNotIn("hiv_clinic_appt_date", form_validator._errors) self.assertNotIn("htn_clinic_appt_date", form_validator._errors) self.assertNotIn("dm_clinic_appt_date", form_validator._errors) else: self.fail("ValidationError unexpectedly NOT raised.")
def setUp(self): year = get_utcnow().year subject_screening = baker.make_recipe( "ambition_screening.subjectscreening") consent = baker.make_recipe( "ambition_subject.subjectconsent", screening_identifier=subject_screening.screening_identifier, consent_datetime=datetime(year, 12, 1, 0, 0, 0, 0, pytz.utc), user_created="erikvw", ) self.subject_identifier = consent.subject_identifier self.appointment = Appointment.objects.get( subject_identifier=self.subject_identifier, visit_code=DAY1) self.subject_visit = baker.make_recipe( "ambition_subject.subjectvisit", appointment=self.appointment, reason=SCHEDULED, ) self.data = { "clinic_verified": YES, "clinic_verified_datetime": get_utcnow(), "drawn_datetime": None, "item_type": TUBE, "panel": str(Panel.objects.get(name=wb_panel.name).pk), "reason_not_drawn": NOT_APPLICABLE, "report_datetime": get_utcnow(), "requisition_datetime": get_utcnow(), "requisition_identifier": "12345", "subject_identifier": self.subject_identifier, "subject_visit": str(self.subject_visit.pk), }
def test_clinic_start_time(self): IntegratedCareClinicRegistration.objects.create( date_opened=get_utcnow().date()) data = { "site": Site.objects.get_current(), "log_date": get_utcnow(), "clinic_services": INTEGRATED, "attended": 10, "clinic_start_time": "08:00", "clinic_end_time": "18:00", } form = DailyClosingLogRevisedForm(data=data) form.is_valid() self.assertDictEqual({}, form._errors) data.update(clinic_start_time="19:00") form = DailyClosingLogRevisedForm(data=data) form.is_valid() self.assertIn("clinic_start_time", form._errors) data.update(clinic_start_time="09:00", clinic_end_time="08:00") form = DailyClosingLogRevisedForm(data=data) form.is_valid() self.assertIn("clinic_start_time", form._errors)
def test_bmi_form_validator(self): data = dict( gender=MALE, ethnicity=BLACK, age_in_years=30, ) class BmiFormValidator(BmiFormValidatorMixin, FormValidator): pass # not enough data form_validator = BmiFormValidator(cleaned_data=data) bmi = form_validator.validate_bmi() self.assertIsNone(bmi) # calculates data.update( weight=56, height=150, dob=get_utcnow() - relativedelta(years=30), report_datetime=get_utcnow(), ) form_validator = BmiFormValidator(cleaned_data=data) bmi = form_validator.validate_bmi() self.assertEqual(bmi.value, 24.8889) # calculation error data.update( weight=56, height=1.5, dob=get_utcnow() - relativedelta(years=25), report_datetime=get_utcnow(), ) form_validator = BmiFormValidator(cleaned_data=data) self.assertRaises(forms.ValidationError, form_validator.validate_bmi)
def in_bounds_or_raise(self, age=None): self.reasons_ineligible = None dob = localtime(get_utcnow() - relativedelta(years=age)).date() age_units = "years" report_datetime = localtime(get_utcnow()) return super().in_bounds_or_raise(dob=dob, report_datetime=report_datetime, age_units=age_units)
def save_model(self, request, obj, form, change): if not change: obj.user_created = request.user.username obj.created = get_utcnow() else: obj.user_modified = request.user.username obj.modified = get_utcnow() super().save_model(request, obj, form, change)
def test_no_subject_screening_invalid(self): cleaned_data = dict( consent_datetime=get_utcnow(), dob=(get_utcnow() - relativedelta(years=20)).date(), ) form_validator = SubjectConsentFormValidator(cleaned_data=cleaned_data) self.assertRaises(forms.ValidationError, form_validator.validate) self.assertIn("missing_subject_screening", form_validator._error_codes)
def test_icc_registration_control(self): cleaned_data = { "report_datetime": get_utcnow(), "date_open": get_utcnow(), "comment": "", } form = IntegratedCareClinicRegistrationForm(data=cleaned_data) form.is_valid() self.assertIn("__all__", [k for k in form._errors.keys()])
def test_onschedules_manager(self): SubjectConsent.objects.create( subject_identifier=self.subject_identifier, consent_datetime=get_utcnow() - relativedelta(months=3), ) onschedule_datetime = get_utcnow() - relativedelta(months=3) onschedule = OnSchedule.objects.create( subject_identifier=self.subject_identifier, onschedule_datetime=onschedule_datetime, ) history = SubjectScheduleHistory.objects.onschedules( subject_identifier=self.subject_identifier) self.assertEqual([onschedule], [obj for obj in history]) onschedules = SubjectScheduleHistory.objects.onschedules( subject_identifier=self.subject_identifier, report_datetime=get_utcnow()) self.assertEqual([onschedule], [obj for obj in onschedules]) onschedules = SubjectScheduleHistory.objects.onschedules( subject_identifier=self.subject_identifier, report_datetime=onschedule_datetime - relativedelta(months=4), ) self.assertEqual(0, len(onschedules)) # add offschedule offschedule_datetime = onschedule_datetime + relativedelta(months=2) OffSchedule.objects.create( subject_identifier=self.subject_identifier, offschedule_datetime=offschedule_datetime, ) onschedules = SubjectScheduleHistory.objects.onschedules( subject_identifier=self.subject_identifier, report_datetime=offschedule_datetime + relativedelta(days=1), ) self.assertEqual(0, len(onschedules)) onschedules = SubjectScheduleHistory.objects.onschedules( subject_identifier=self.subject_identifier, report_datetime=offschedule_datetime, ) self.assertEqual([onschedule], [obj for obj in onschedules]) onschedules = SubjectScheduleHistory.objects.onschedules( subject_identifier=self.subject_identifier, report_datetime=offschedule_datetime - relativedelta(months=1), ) self.assertEqual([onschedule], [obj for obj in onschedules]) onschedules = SubjectScheduleHistory.objects.onschedules( subject_identifier=self.subject_identifier, report_datetime=offschedule_datetime + relativedelta(months=1), ) self.assertEqual(0, len(onschedules))
class TestProtocol(TestCase): @override_settings( EDC_PROTOCOL_STUDY_OPEN_DATETIME=get_utcnow() - relativedelta(years=2), EDC_PROTOCOL_STUDY_CLOSE_DATETIME=get_utcnow() + relativedelta(years=1), ) def test_protocol(self): self.assertEqual(Protocol().study_open_datetime.date(), opendte.date()) self.assertEqual(Protocol().study_close_datetime.date(), closedte.date())
def test_verify_prescription(self): obj = Rx.objects.create( subject_identifier=self.subject_identifier, report_datetime=get_utcnow(), medication=self.medication, ) obj.verified = True obj.verified = get_utcnow() obj.save() self.assertTrue(obj.verified)