Source code for camcops_server.cc_modules.tests.cc_taskschedule_tests

"""
camcops_server/cc_modules/tests/cc_taskschedule_tests.py

===============================================================================

    Copyright (C) 2012, University of Cambridge, Department of Psychiatry.
    Created by Rudolf Cardinal (rnc1001@cam.ac.uk).

    This file is part of CamCOPS.

    CamCOPS is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    CamCOPS is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with CamCOPS. If not, see <https://www.gnu.org/licenses/>.

===============================================================================

"""

from urllib.parse import parse_qs, urlsplit

from pendulum import Duration

from camcops_server.cc_modules.cc_email import Email
from camcops_server.cc_modules.cc_pyramid import Routes
from camcops_server.cc_modules.cc_taskschedule import (
    PatientTaskSchedule,
    PatientTaskScheduleEmail,
    TaskScheduleItem,
)
from camcops_server.cc_modules.cc_testfactories import (
    EmailFactory,
    PatientTaskScheduleEmailFactory,
    PatientTaskScheduleFactory,
    ServerCreatedPatientFactory,
    TaskScheduleFactory,
    TaskScheduleItemFactory,
)
from camcops_server.cc_modules.cc_unittest import DemoRequestTestCase


# =============================================================================
# Unit tests
# =============================================================================


[docs]class TaskScheduleTests(DemoRequestTestCase): def test_deleting_deletes_related_objects(self) -> None: patient = ServerCreatedPatientFactory() schedule = TaskScheduleFactory(group=patient._group) item = TaskScheduleItemFactory( task_schedule=schedule, task_table_name="ace3", ) pts = PatientTaskScheduleFactory( task_schedule=schedule, patient=patient, ) pts_email = PatientTaskScheduleEmailFactory( patient_task_schedule=pts, ) self.assertIsNotNone( self.dbsession.query(TaskScheduleItem) .filter(TaskScheduleItem.id == item.id) .one_or_none() ) self.assertIsNotNone( self.dbsession.query(PatientTaskSchedule) .filter(PatientTaskSchedule.id == pts.id) .one_or_none() ) self.assertIsNotNone( self.dbsession.query(PatientTaskScheduleEmail) .filter( PatientTaskScheduleEmail.patient_task_schedule_id == pts.id ) .one_or_none() ) self.assertIsNotNone( self.dbsession.query(Email) .filter(Email.id == pts_email.email.id) .one_or_none() ) self.dbsession.delete(schedule) self.dbsession.commit() self.assertIsNone( self.dbsession.query(TaskScheduleItem) .filter(TaskScheduleItem.id == item.id) .one_or_none() ) self.assertIsNone( self.dbsession.query(PatientTaskSchedule) .filter(PatientTaskSchedule.id == pts.id) .one_or_none() ) self.assertIsNone( self.dbsession.query(PatientTaskScheduleEmail) .filter( PatientTaskScheduleEmail.patient_task_schedule_id == pts.id ) .one_or_none() ) self.assertIsNone( self.dbsession.query(Email) .filter(Email.id == pts_email.email.id) .one_or_none() )
[docs]class TaskScheduleItemTests(DemoRequestTestCase): def test_description_shows_shortname_and_number_of_days(self) -> None: item = TaskScheduleItemFactory( task_table_name="bmi", due_from=Duration(days=30), ) self.assertEqual(item.description(self.req), "BMI @ 30 days") def test_description_with_no_durations(self) -> None: item = TaskScheduleItemFactory(task_table_name="bmi") self.assertEqual(item.description(self.req), "BMI @ ? days") def test_due_within_calculated_from_due_by_and_due_from(self) -> None: item = TaskScheduleItemFactory( due_from=Duration(days=30), due_by=Duration(days=50), ) self.assertEqual(item.due_within.in_days(), 20) def test_due_within_is_none_when_missing_due_by(self) -> None: item = TaskScheduleItemFactory(due_from=Duration(days=30)) self.assertIsNone(item.due_within) def test_due_within_calculated_when_missing_due_from(self) -> None: item = TaskScheduleItemFactory(due_by=Duration(days=30)) self.assertEqual(item.due_within.in_days(), 30)
[docs]class PatientTaskScheduleTests(DemoRequestTestCase): def test_email_body_contains_access_key(self) -> None: schedule = TaskScheduleFactory(email_template="{access_key}") pts = PatientTaskScheduleFactory(task_schedule=schedule) self.assertIn( f"{pts.patient.uuid_as_proquint}", pts.email_body(self.req) ) def test_email_body_contains_server_url(self) -> None: schedule = TaskScheduleFactory(email_template="{server_url}") pts = PatientTaskScheduleFactory(task_schedule=schedule) expected_url = self.req.route_url(Routes.CLIENT_API) self.assertIn(f"{expected_url}", pts.email_body(self.req)) def test_email_body_contains_patient_forename(self) -> None: schedule = TaskScheduleFactory(email_template="{forename}") pts = PatientTaskScheduleFactory(task_schedule=schedule) self.assertIn(f"{pts.patient.forename}", pts.email_body(self.req)) def test_email_body_contains_patient_surname(self) -> None: schedule = TaskScheduleFactory(email_template="{surname}") pts = PatientTaskScheduleFactory(task_schedule=schedule) self.assertIn(f"{pts.patient.surname}", pts.email_body(self.req)) def test_email_body_contains_android_launch_url(self) -> None: schedule = TaskScheduleFactory(email_template="{android_launch_url}") pts = PatientTaskScheduleFactory(task_schedule=schedule) url = pts.email_body(self.req) (scheme, netloc, path, query, fragment) = urlsplit(url) self.assertEqual(scheme, "https") self.assertEqual(netloc, "ucam-department-of-psychiatry.github.io") self.assertEqual(path, "/camcops/register") query_dict = parse_qs(query) self.assertEqual(query_dict["default_single_user_mode"], ["true"]) self.assertEqual( query_dict["default_server_location"], [self.req.route_url(Routes.CLIENT_API)], ) self.assertEqual( query_dict["default_access_key"], [pts.patient.uuid_as_proquint] ) def test_email_body_contains_ios_launch_url(self) -> None: schedule = TaskScheduleFactory(email_template="{ios_launch_url}") pts = PatientTaskScheduleFactory(task_schedule=schedule) url = pts.email_body(self.req) (scheme, netloc, path, query, fragment) = urlsplit(url) self.assertEqual(scheme, "camcops") self.assertEqual(netloc, "ucam-department-of-psychiatry.github.io") self.assertEqual(path, "/camcops/register") query_dict = parse_qs(query) self.assertEqual(query_dict["default_single_user_mode"], ["true"]) self.assertEqual( query_dict["default_server_location"], [self.req.route_url(Routes.CLIENT_API)], ) self.assertEqual( query_dict["default_access_key"], [pts.patient.uuid_as_proquint] ) def test_email_body_disallows_invalid_template(self) -> None: schedule = TaskScheduleFactory(email_template="{foobar}") pts = PatientTaskScheduleFactory(task_schedule=schedule) with self.assertRaises(KeyError): pts.email_body(self.req) def test_email_body_disallows_accessing_properties(self) -> None: schedule = TaskScheduleFactory(email_template="{server_url.__class__}") pts = PatientTaskScheduleFactory(task_schedule=schedule) with self.assertRaises(KeyError): pts.email_body(self.req) def test_email_sent_false_for_no_emails(self) -> None: pts = PatientTaskScheduleFactory() self.assertFalse(pts.email_sent) def test_email_sent_false_for_one_unsent_email(self) -> None: email1 = EmailFactory(sent=False) pts_email1 = PatientTaskScheduleEmailFactory(email=email1) self.assertFalse(pts_email1.patient_task_schedule.email_sent) def test_email_sent_true_for_one_sent_email(self) -> None: email1 = EmailFactory(sent=True) pts_email1 = PatientTaskScheduleEmailFactory(email=email1) self.assertTrue(pts_email1.patient_task_schedule.email_sent)