Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
test_visit.py 7.15 KiB
import datetime
from dateutil.relativedelta import relativedelta
from django.test import TestCase

from web.models import Visit
from web.models.constants import SUBJECT_TYPE_CHOICES_PATIENT
from web.tests.functions import create_study_subject, create_visit
from web.utils import get_today_midnight_date

import logging
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.assertEquals(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.assertEquals(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.assertEquals(1, visit1.visit_number)
        self.assertEquals(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.assertEquals(1, visit3.visit_number)
        self.assertEquals(2, visit1.visit_number)
        self.assertEquals(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.assertEquals(1, visit1.visit_number)
        self.assertEquals(2, visit2.visit_number)
        self.assertEquals(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.assertEquals(1, visit1.visit_number)
        self.assertEquals(3, visit2.visit_number) #<= change
        self.assertEquals(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.assertEquals(3, visit1.visit_number) #<= change        
        self.assertEquals(2, visit2.visit_number) #<= change
        self.assertEquals(1, visit3.visit_number) #<= change        

    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.assertEquals(2, 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.assertEquals(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.assertEquals(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.assertEquals(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(unicode(visit))