import datetime import logging from dateutil.relativedelta import relativedelta from django.test import TestCase from web.models import Visit, Study from web.models.constants import SUBJECT_TYPE_CHOICES_PATIENT, GLOBAL_STUDY_ID from web.tests.functions import create_study_subject, create_visit from web.utils import get_today_midnight_date logger = logging.getLogger(__name__) class VisitModelTests(TestCase): def test_so_called_no_concurrency(self): subject = create_study_subject() Visit.objects.filter(subject=subject).all().delete() visit1 = create_visit(subject=subject) visit1.datetime_end = get_today_midnight_date() + datetime.timedelta(days=1) visit1.save() self.assertEqual(1, visit1.visit_number) visit2 = create_visit(subject=subject) visit2.datetime_end = get_today_midnight_date() + datetime.timedelta(days=2) visit2.save() visit2.refresh_from_db() self.assertEqual(2, visit2.visit_number) def test_socalled_concurrency(self): subject = create_study_subject() Visit.objects.filter(subject=subject).all().delete() visit1 = create_visit(subject=subject) #post save will be raised visit2 = create_visit(subject=subject) #post save will be raised visit1.datetime_end = get_today_midnight_date() + datetime.timedelta(days=1) visit2.datetime_end = get_today_midnight_date() + datetime.timedelta(days=2) visit1.save() #post save will be raised visit2.save() #post save will be raised visit1.refresh_from_db() visit2.refresh_from_db() self.assertEqual(1, visit1.visit_number) self.assertEqual(2, visit2.visit_number) datetime_begin = get_today_midnight_date() - datetime.timedelta(days=60) datetime_end = get_today_midnight_date() - datetime.timedelta(days=55) visit3 = create_visit(subject=subject, datetime_begin=datetime_begin, datetime_end=datetime_end) #post save will be raised visit1.refresh_from_db() visit2.refresh_from_db() visit3.refresh_from_db() self.assertEqual(1, visit3.visit_number) self.assertEqual(2, visit1.visit_number) self.assertEqual(3, visit2.visit_number) def test_visit_numbers(self): subject = create_study_subject() Visit.objects.filter(subject=subject).all().delete() visit1 = create_visit(subject=subject, datetime_begin = get_today_midnight_date() - datetime.timedelta(days=15), datetime_end = get_today_midnight_date() - datetime.timedelta(days=14)) #post save will be raised visit2 = create_visit(subject=subject, datetime_begin = get_today_midnight_date(), datetime_end = get_today_midnight_date() + datetime.timedelta(days=2)) #post save will be raised visit3 = create_visit(subject=subject, datetime_begin = get_today_midnight_date() + datetime.timedelta(days=5), datetime_end = get_today_midnight_date() + datetime.timedelta(days=10)) #post save will be raised # order should be [V1, V2, V3] visit1.refresh_from_db() visit2.refresh_from_db() visit3.refresh_from_db() self.assertEqual(1, visit1.visit_number) self.assertEqual(2, visit2.visit_number) self.assertEqual(3, visit3.visit_number) #NOW, move V3 between V1 and V2 visit3.datetime_begin = get_today_midnight_date() - datetime.timedelta(days=11) visit3.datetime_end = get_today_midnight_date() - datetime.timedelta(days=10) visit3.save() #post save will be raised and V1, V2 and V3 should change their visits numbers #order now should be [V1, V3, V2] visit1.refresh_from_db() visit2.refresh_from_db() visit3.refresh_from_db() self.assertEqual(1, visit1.visit_number) self.assertEqual(3, visit2.visit_number) #<= change self.assertEqual(2, visit3.visit_number) #<= change #NOW, move V1 after V2 and V3 visit1.datetime_begin = get_today_midnight_date() + datetime.timedelta(days=110) visit1.datetime_end = get_today_midnight_date() + datetime.timedelta(days=111) visit1.save() #post save will be raised and V1, V2 and V3 should change their visits numbers #order now should be [V3, V2, V1] visit1.refresh_from_db() visit2.refresh_from_db() visit3.refresh_from_db() self.assertEqual(3, visit1.visit_number) #<= change self.assertEqual(2, visit2.visit_number) #<= change self.assertEqual(1, visit3.visit_number) #<= change def test_mark_as_finished_for_global_study(self): subject = create_study_subject() visit = create_visit(subject) subject.study = Study.objects.get(pk=GLOBAL_STUDY_ID) subject.save() visit.mark_as_finished() visit_count = Visit.objects.filter(subject=subject).count() self.assertEqual(2, visit_count) def test_mark_as_finished(self): subject = create_study_subject() visit = create_visit(subject) visit.mark_as_finished() visit_count = Visit.objects.filter(subject=subject).count() self.assertEqual(2, visit_count) def test_future_visits(self): subject = create_study_subject() visit = create_visit(subject) visit.mark_as_finished() #assumes auto follow up visit visit_count = Visit.objects.filter(subject=subject).count() self.assertEqual(2, visit_count) for fv in visit.future_visits: self.assertGreater(fv.visit_number, visit.visit_number) def test_next_visit(self): subject = create_study_subject() visit = create_visit(subject) visit.mark_as_finished() #assumes auto follow up visit visit_count = Visit.objects.filter(subject=subject).count() self.assertEqual(2, visit_count) nv = Visit.objects.filter(subject=subject).order_by('datetime_begin','datetime_end').last() self.assertEqual(visit.next_visit.id, nv.id) def test_unfinish_visit(self): subject = create_study_subject() visit = create_visit(subject) visit.mark_as_finished() #assumes auto follow up visit visit_count = Visit.objects.filter(subject=subject).count() self.assertEqual(2, visit_count) visit.unfinish() visit_count = Visit.objects.filter(subject=subject).count() self.assertEqual(1, visit_count) def test_mark_as_finished_2(self): study_subject = create_study_subject() visit = create_visit(study_subject) study_subject.subject.dead = True study_subject.subject.save() visit.mark_as_finished() visit_count = Visit.objects.filter(subject=study_subject).count() self.assertEqual(1, visit_count) def test_mark_as_finished_3(self): subject = create_study_subject() visit = create_visit(subject) subject.resigned = True subject.save() visit.mark_as_finished() visit_count = Visit.objects.filter(subject=subject).count() self.assertEqual(1, visit_count) def test_mark_as_finished_4(self): subject = create_study_subject() visit = create_visit(subject) subject.endpoint_reached = True subject.save() visit.mark_as_finished() visit_count = Visit.objects.filter(subject=subject).count() self.assertEqual(1, visit_count) def test_mark_as_finished_for_follow_up_visit(self): subject = create_study_subject() subject.type = SUBJECT_TYPE_CHOICES_PATIENT subject.save() visit = create_visit(subject) visit.mark_as_finished() visit_number=2 follow_up_visit = Visit.objects.filter(subject=subject).filter(visit_number=visit_number)[0] follow_up_visit.datetime_begin = visit.datetime_begin + datetime.timedelta(days=133) follow_up_visit.datetime_end = visit.datetime_begin + datetime.timedelta(days=170) follow_up_visit.save() follow_up_visit.mark_as_finished() visit_count = Visit.objects.filter(subject=subject).count() self.assertEqual(3, visit_count) visit_number=3 new_follow_up = Visit.objects.filter(subject=subject).filter(visit_number=visit_number)[0] # check if follow up date is based on the first visit date study = visit.subject.study args = {study.default_delta_time_for_follow_up_units: study.default_delta_time_for_patient_follow_up} #patient time_to_next_visit = relativedelta(**args) * (visit_number - 1) #calculated from first visit self.assertTrue(visit.datetime_begin + time_to_next_visit - datetime.timedelta(days=1) < new_follow_up.datetime_begin) def test_visit_to_string(self): visit = create_visit(create_study_subject()) self.assertIsNotNone(str(visit)) def test_visit_to_unicode(self): visit = create_visit(create_study_subject()) self.assertIsNotNone(str(visit)) def test_visit_numbers_with_the_same_dates(self): subject = create_study_subject() visit1 = create_visit(subject=subject, datetime_begin=get_today_midnight_date() - datetime.timedelta(days=1), datetime_end=get_today_midnight_date() + datetime.timedelta(days=4)) visit2 = create_visit(subject=subject, datetime_begin=get_today_midnight_date() - datetime.timedelta(days=1), datetime_end=get_today_midnight_date() + datetime.timedelta(days=3)) visit3 = create_visit(subject=subject, datetime_begin=get_today_midnight_date() + datetime.timedelta(days=1), datetime_end=get_today_midnight_date() + datetime.timedelta(days=2)) visit3.is_finished = True visit3.save() visit2.mark_as_finished() visit1.is_finished = True visit1.save() self.assertEqual(4, Visit.objects.filter(subject=subject).count()) # order should be [V1, V2, V3] visit1.refresh_from_db() visit2.refresh_from_db() visit3.refresh_from_db() self.assertEqual(1, visit1.visit_number) self.assertEqual(2, visit2.visit_number) self.assertEqual(3, visit3.visit_number)