# coding=utf-8 import datetime import json import logging from django.contrib.auth.models import User from django.test import Client from django.test import TestCase from django.urls import reverse from web.api_views.subject import get_subjects_order, get_subjects_filtered, serialize_subject from web.models import StudySubject, Appointment, Study from web.models.constants import GLOBAL_STUDY_ID, SUBJECT_TYPE_CHOICES_PATIENT, SUBJECT_TYPE_CHOICES_CONTROL from web.models.study_subject_list import SUBJECT_LIST_GENERIC, SUBJECT_LIST_NO_VISIT, SUBJECT_LIST_REQUIRE_CONTACT, \ StudySubjectList from web.tests.functions import create_study_subject, create_worker, create_get_suffix, create_visit, \ create_appointment, create_empty_study_columns, create_contact_attempt, create_flying_team from web.views.notifications import get_today_midnight_date logger = logging.getLogger(__name__) class TestApi(TestCase): def setUp(self): self.study_subject = create_study_subject() self.client = Client() username = 'piotr' password = 'top_secret' self.user = User.objects.create_user( username=username, email='jacob@bla', password=password) self.worker = create_worker(self.user) self.client.login(username=username, password=password) def test_cities(self): city_name = "some city" response = self.client.get(reverse('web.api.cities')) self.assertEqual(response.status_code, 200) cities = json.loads(response.content)['cities'] self.assertFalse(city_name in cities) self.study_subject.subject.city = city_name self.study_subject.subject.save() response = self.client.get(reverse('web.api.cities')) cities = json.loads(response.content)['cities'] self.assertTrue(city_name in cities) def test_get_columns(self): response = self.client.get( reverse('web.api.subjects.columns', kwargs={'subject_list_type': SUBJECT_LIST_GENERIC})) self.assertEqual(response.status_code, 200) columns = json.loads(response.content)['columns'] self.assertTrue(len(columns) >= 20) def test_get_columns_for_require_contact(self): response = self.client.get( reverse('web.api.subjects.columns', kwargs={'subject_list_type': SUBJECT_LIST_REQUIRE_CONTACT})) self.assertEqual(response.status_code, 200) columns = json.loads(response.content)['columns'] visible_columns = 0 for column in columns: if column["visible"]: visible_columns += 1 self.assertTrue(visible_columns < 20) def test_get_columns_when_no_list_is_available(self): StudySubjectList.objects.all().delete() response = self.client.get( reverse('web.api.subjects.columns', kwargs={'subject_list_type': SUBJECT_LIST_GENERIC})) self.assertEqual(response.status_code, 200) columns = json.loads(response.content)['columns'] self.assertTrue(len(columns) > 0) def test_get_columns_when_study_has_no_data_columns(self): study = Study.objects.filter(id=GLOBAL_STUDY_ID)[0] study.columns = create_empty_study_columns() study.save() response = self.client.get( reverse('web.api.subjects.columns', kwargs={'subject_list_type': SUBJECT_LIST_GENERIC})) self.assertEqual(response.status_code, 200) columns = json.loads(response.content)['columns'] self.assertTrue(len(columns) < 20) def test_referrals(self): referral_name = "some referral" response = self.client.get(reverse('web.api.referrals')) self.assertEqual(response.status_code, 200) referrals = json.loads(response.content)['referrals'] self.assertFalse(referral_name in referrals) self.study_subject.referral = referral_name self.study_subject.save() response = self.client.get(reverse('web.api.referrals')) referrals = json.loads(response.content)['referrals'] self.assertTrue(referral_name in referrals) def test_subjects_general(self): response = self.client.get(reverse('web.api.subjects', kwargs={'type': SUBJECT_LIST_GENERIC})) self.assertEqual(response.status_code, 200) def test_subjects_no_visit(self): response = self.client.get(reverse('web.api.subjects', kwargs={'type': SUBJECT_LIST_NO_VISIT})) self.assertEqual(response.status_code, 200) def test_subjects_require_contact(self): response = self.client.get(reverse('web.api.subjects', kwargs={'type': SUBJECT_LIST_REQUIRE_CONTACT})) self.assertEqual(response.status_code, 200) def test_subjects_invalid(self): response = self.client.get(reverse('web.api.subjects', kwargs={'type': "bla"})) self.assertEqual(response.status_code, 500) def test_subjects_general_search(self): name = "Piotrek" self.study_subject.subject.first_name = name self.study_subject.subject.save() params = { "columns[0][search][value]": "another_name", "columns[0][data]": "first_name" } url = ("%s" + create_get_suffix(params)) % reverse('web.api.subjects', kwargs={'type': SUBJECT_LIST_GENERIC}) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertFalse(name in response.content) params["columns[0][search][value]"] = name url = ("%s" + create_get_suffix(params)) % reverse('web.api.subjects', kwargs={'type': SUBJECT_LIST_GENERIC}) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertTrue(name in response.content) def check_subject_filtered(self, filters, result): subjects = get_subjects_filtered(StudySubject.objects.all(), filters) self.assertEqual(len(result), subjects.count()) for index in range(len(result)): self.assertEqual(result[index], subjects[index]) def check_subject_ordered(self, order, result): subjects = get_subjects_order(StudySubject.objects.all(), order, "asc") self.assertEqual(len(result), subjects.count()) for index in range(len(result)): self.assertEqual(result[index], subjects[index]) subjects = get_subjects_order(StudySubject.objects.all(), order, "desc") length = len(result) self.assertEqual(length, subjects.count()) for index in range(length): self.assertEqual(result[length - index - 1], subjects[index]) def test_subjects_sort_nd_number(self): subject = self.study_subject subject.nd_number = "PPP" subject.save() subject2 = create_study_subject(2) subject2.nd_number = "QQQ" subject2.save() self.check_subject_ordered("nd_number", [subject, subject2]) def test_subjects_sort_id(self): subject = self.study_subject subject2 = create_study_subject(2) self.check_subject_ordered("id", [subject, subject2]) def test_subjects_sort_date_born(self): subject = self.study_subject subject.subject.date_born = get_today_midnight_date() subject.subject.save() subject2 = create_study_subject(2) subject2.subject.date_born = get_today_midnight_date() + datetime.timedelta(days=1) subject2.subject.save() self.check_subject_ordered("date_born", [subject, subject2]) def test_subjects_sort_contact_on(self): subject = self.study_subject subject.datetime_contact_reminder = get_today_midnight_date() subject.save() subject2 = create_study_subject(2) subject2.datetime_contact_reminder = get_today_midnight_date() + datetime.timedelta(days=1) subject2.save() self.check_subject_ordered("datetime_contact_reminder", [subject, subject2]) def test_subjects_sort_default_location(self): subject = self.study_subject self.check_subject_ordered("default_location", [subject]) def test_subjects_sort_flying_team(self): subject = self.study_subject subject.flying_team = create_flying_team() subject.save() self.check_subject_ordered("flying_team", [subject]) def test_subjects_sort_screening_number(self): subject = self.study_subject subject.screening_number = "PPP" subject.save() subject2 = create_study_subject(2) subject2.screening_number = "QQQ" subject2.save() self.check_subject_ordered("screening_number", [subject, subject2]) def test_subjects_sort_last_name(self): subject = self.study_subject subject.subject.last_name = "XXX" subject.subject.save() subject2 = create_study_subject(2) subject2.subject.last_name = "YYY" subject2.subject.save() self.check_subject_ordered("last_name", [subject, subject2]) def test_subjects_sort_referral(self): subject = self.study_subject subject.referral = "XXX" subject.save() subject2 = create_study_subject(2) subject2.referral = "YYY" subject2.save() self.check_subject_ordered("referral", [subject, subject2]) def test_subjects_sort_dead(self): study_subject = self.study_subject study_subject.subject.dead = True study_subject.subject.save() study_subject2 = create_study_subject(2) study_subject2.subject.dead = False study_subject2.subject.save() self.check_subject_ordered("dead", [study_subject2, study_subject]) def test_subjects_sort_resigned(self): subject = self.study_subject subject.resigned = True subject.save() subject2 = create_study_subject(2) subject2.resigned = False subject2.save() self.check_subject_ordered("resigned", [subject2, subject]) def test_subjects_sort_postponed(self): subject = self.study_subject subject.postponed = True subject.save() subject2 = create_study_subject(2) subject2.postponed = False subject2.save() self.check_subject_ordered("postponed", [subject2, subject]) def test_subjects_filter_dead(self): subject = self.study_subject.subject subject.dead = True subject.save() study_subject2 = create_study_subject(2) study_subject2.subject.dead = False study_subject2.subject.save() self.check_subject_filtered([["dead", "true"]], [self.study_subject]) self.check_subject_filtered([["dead", "false"]], [study_subject2]) def test_subjects_filter_nd_number(self): subject = self.study_subject subject.nd_number = "PPP" subject.save() subject2 = create_study_subject(2) subject2.nd_number = "QQQ" subject2.save() self.check_subject_filtered([["nd_number", "P"]], [subject]) def test_subjects_filter_screening_number(self): subject = self.study_subject subject.screening_number = "PPP" subject.save() subject2 = create_study_subject(2) subject2.screening_number = "QQQ" subject2.save() self.check_subject_filtered([["screening_number", "Q"]], [subject2]) def test_subjects_filter_last_name(self): subject = self.study_subject subject.subject.last_name = "XXX" subject.subject.save() subject2 = create_study_subject(2) subject2.subject.last_name = "YYY" subject2.subject.save() self.check_subject_filtered([["last_name", "Q"]], []) def test_subjects_filter_resigned(self): subject = self.study_subject subject.resigned = True subject.save() subject2 = create_study_subject(2) subject2.resigned = False subject2.save() self.check_subject_filtered([["resigned", "true"]], [subject]) self.check_subject_filtered([["resigned", "false"]], [subject2]) def test_subjects_filter_postponed(self): subject = self.study_subject subject.postponed = True subject.save() subject2 = create_study_subject(2) subject2.postponed = False subject2.save() self.check_subject_filtered([["postponed", "true"]], [subject]) self.check_subject_filtered([["postponed", "false"]], [subject2]) def test_subjects_filter_default_location(self): subject = self.study_subject self.check_subject_filtered([["default_location", str(subject.default_location.id)]], [subject]) self.check_subject_filtered([["default_location", "-1"]], []) def test_subjects_filter_flying_team(self): subject = self.study_subject subject.flying_team = create_flying_team() subject.save() self.check_subject_filtered([["flying_team", str(subject.flying_team.id)]], [subject]) self.check_subject_filtered([["flying_team", "-1"]], []) def test_subjects_filter_information_sent(self): subject = self.study_subject subject.information_sent = True subject.save() self.check_subject_filtered([["information_sent", "true"]], [subject]) self.check_subject_filtered([["information_sent", "false"]], []) def test_subjects_filter_referral(self): subject = self.study_subject subject.referral = "xyz" subject.save() self.check_subject_filtered([["referral", "xyz"]], [subject]) self.check_subject_filtered([["referral", "false"]], []) def test_subjects_filter_type(self): subject = self.study_subject subject.type = SUBJECT_TYPE_CHOICES_PATIENT subject.save() self.check_subject_filtered([["type", SUBJECT_TYPE_CHOICES_PATIENT]], [subject]) self.check_subject_filtered([["type", SUBJECT_TYPE_CHOICES_CONTROL]], []) def test_subjects_filter_unknown(self): subject = self.study_subject self.check_subject_filtered([["some_unknown", "unknown data"]], [subject]) self.check_subject_filtered([["", ""]], [subject]) self.check_subject_filtered([["", None]], [subject]) def test_serialize_subject(self): study_subject = self.study_subject study_subject.subject.dead = True study_subject.flying_team = create_flying_team() study_subject.datetime_contact_reminder = get_today_midnight_date() create_contact_attempt(subject=study_subject) create_visit(subject=study_subject) subject_json = serialize_subject(study_subject) self.assertEqual("YES", subject_json["dead"]) def test_subjects_filter_visit_1_DONE(self): subject = self.study_subject visit = create_visit(subject) appointment = create_appointment(visit) appointment.status = Appointment.APPOINTMENT_STATUS_FINISHED appointment.save() visit.mark_as_finished() self.check_subject_filtered([["visit_1", "DONE"]], [subject]) self.check_subject_filtered([["visit_2", "DONE"]], []) self.check_subject_filtered([["visit_1", "MISSED"]], []) self.check_subject_filtered([["visit_1", "EXCEED"]], []) self.check_subject_filtered([["visit_1", "IN_PROGRESS"]], []) self.check_subject_filtered([["visit_1", "SHOULD_BE_IN_PROGRESS"]], []) self.check_subject_filtered([["visit_1", "UPCOMING"]], []) def test_subjects_filter_visit_1_MISSED(self): subject = self.study_subject visit = create_visit(subject) appointment = create_appointment(visit) appointment.status = Appointment.APPOINTMENT_STATUS_CANCELLED appointment.save() visit.mark_as_finished() self.check_subject_filtered([["visit_1", "MISSED"]], [subject]) self.check_subject_filtered([["visit_2", "MISSED"]], []) self.check_subject_filtered([["visit_1", "DONE"]], []) self.check_subject_filtered([["visit_1", "EXCEED"]], []) self.check_subject_filtered([["visit_1", "IN_PROGRESS"]], []) self.check_subject_filtered([["visit_1", "SHOULD_BE_IN_PROGRESS"]], []) self.check_subject_filtered([["visit_1", "UPCOMING"]], []) def test_subjects_filter_visit_1_EXCEED(self): subject = self.study_subject visit = create_visit(subject) visit.datetime_begin = get_today_midnight_date() + datetime.timedelta(days=-365 * 2) visit.datetime_end = get_today_midnight_date() + datetime.timedelta(days=-365 * 1) visit.save() self.check_subject_filtered([["visit_1", "EXCEED"]], [subject]) self.check_subject_filtered([["visit_2", "EXCEED"]], []) self.check_subject_filtered([["visit_1", "DONE"]], []) self.check_subject_filtered([["visit_1", "MISSED"]], []) self.check_subject_filtered([["visit_1", "IN_PROGRESS"]], []) self.check_subject_filtered([["visit_1", "SHOULD_BE_IN_PROGRESS"]], []) self.check_subject_filtered([["visit_1", "UPCOMING"]], []) def test_subjects_filter_visit_1_IN_PROGRESS(self): subject = self.study_subject visit = create_visit(subject) appointment = create_appointment(visit) appointment.status = Appointment.APPOINTMENT_STATUS_SCHEDULED appointment.save() self.check_subject_filtered([["visit_1", "IN_PROGRESS"]], [subject]) self.check_subject_filtered([["visit_2", "IN_PROGRESS"]], []) self.check_subject_filtered([["visit_1", "DONE"]], []) self.check_subject_filtered([["visit_1", "MISSED"]], []) self.check_subject_filtered([["visit_1", "EXCEED"]], []) self.check_subject_filtered([["visit_1", "SHOULD_BE_IN_PROGRESS"]], []) self.check_subject_filtered([["visit_1", "UPCOMING"]], []) def test_subjects_filter_visit_1_SHOULD_BE_IN_PROGRESS(self): subject = self.study_subject create_visit(subject) self.check_subject_filtered([["visit_1", "SHOULD_BE_IN_PROGRESS"]], [subject]) self.check_subject_filtered([["visit_2", "SHOULD_BE_IN_PROGRESS"]], []) self.check_subject_filtered([["visit_1", "DONE"]], []) self.check_subject_filtered([["visit_1", "MISSED"]], []) self.check_subject_filtered([["visit_1", "EXCEED"]], []) self.check_subject_filtered([["visit_1", "IN_PROGRESS"]], []) self.check_subject_filtered([["visit_1", "UPCOMING"]], []) def test_subjects_filter_visit_1_UPCOMING(self): subject = self.study_subject visit = create_visit(subject) visit.datetime_begin = get_today_midnight_date() + datetime.timedelta(days=2) visit.datetime_end = get_today_midnight_date() + datetime.timedelta(days=20) visit.save() self.check_subject_filtered([["visit_1", "UPCOMING"]], [subject]) self.check_subject_filtered([["visit_2", "UPCOMING"]], []) self.check_subject_filtered([["visit_1", "DONE"]], []) self.check_subject_filtered([["visit_1", "MISSED"]], []) self.check_subject_filtered([["visit_1", "EXCEED"]], []) self.check_subject_filtered([["visit_1", "IN_PROGRESS"]], []) self.check_subject_filtered([["visit_1", "SHOULD_BE_IN_PROGRESS"]], []) def test_subjects_filter_visit_1_visit_2_combined(self): subject = self.study_subject visit = create_visit(subject) appointment = create_appointment(visit) appointment.status = Appointment.APPOINTMENT_STATUS_FINISHED appointment.save() visit.mark_as_finished() self.check_subject_filtered([["visit_1", "DONE"]], [subject]) self.check_subject_filtered([["visit_2", "UPCOMING"]], [subject]) self.check_subject_filtered([["visit_1", "DONE"], ["visit_2", "UPCOMING"]], [subject]) self.check_subject_filtered([["visit_1", "UPCOMING"], ["visit_2", "DONE"]], []) def test_subjects_ordered_by_visit_1(self): subject = self.study_subject subject2 = create_study_subject(2) visit = create_visit(subject) appointment = create_appointment(visit) appointment.status = Appointment.APPOINTMENT_STATUS_FINISHED appointment.save() self.check_subject_ordered("visit_1", [subject, subject2]) def test_invalid_order(self): self.check_subject_ordered(None, [self.study_subject]) def test_subjects_ordered_by_contact_attempt(self): subject = self.study_subject subject2 = create_study_subject(2) create_contact_attempt(subject=subject) self.check_subject_ordered("last_contact_attempt", [subject, subject2])