"""
camcops_server/cc_modules/tests/cc_task_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/>.
===============================================================================
"""
import logging
import os
from pathlib import Path
from cardinal_pythonlib.logs import BraceStyleAdapter
from pendulum import Date, DateTime as Pendulum
from camcops_server.cc_modules.cc_dummy_database import DummyDataInserter
from camcops_server.cc_modules.cc_task import Task
from camcops_server.cc_modules.cc_testfactories import UserFactory
from camcops_server.cc_modules.cc_unittest import DemoDatabaseTestCase
from camcops_server.cc_modules.cc_validators import validate_task_tablename
log = BraceStyleAdapter(logging.getLogger(__name__))
# =============================================================================
# Unit testing
# =============================================================================
[docs]class TaskTests(DemoDatabaseTestCase):
def test_query_phq9(self) -> None:
self.announce("test_query_phq9")
from camcops_server.tasks import Phq9
phq9_query = self.dbsession.query(Phq9)
results = phq9_query.all()
log.info("{}", results)
def test_all_tasks(self) -> None:
self.announce("test_all_tasks")
from datetime import date
import hl7
from sqlalchemy.sql.schema import Column
from camcops_server.cc_modules.cc_ctvinfo import CtvInfo
from camcops_server.cc_modules.cc_patient import Patient
from camcops_server.cc_modules.cc_simpleobjects import IdNumReference
from camcops_server.cc_modules.cc_snomed import (
SnomedExpression,
)
from camcops_server.cc_modules.cc_string import APPSTRING_TASKNAME
from camcops_server.cc_modules.cc_summaryelement import SummaryElement
from camcops_server.cc_modules.cc_trackerhelpers import (
TrackerInfo,
)
from camcops_server.cc_modules.cc_spreadsheet import (
SpreadsheetPage,
)
from camcops_server.cc_modules.cc_xml import XmlElement
user = UserFactory()
subclasses = Task.all_subclasses_by_tablename()
tables = [cls.tablename for cls in subclasses]
log.info("Actual task table names: {!r} (n={})", tables, len(tables))
req = self.req
recipdef = self.recipdef
dummy_data_factory = DummyDataInserter()
task_doc_root = os.path.join(
Path(__file__).resolve().parents[4], "docs", "source", "tasks"
)
for cls in subclasses:
log.info("Testing {}", cls)
assert cls.extrastring_taskname != APPSTRING_TASKNAME
q = self.dbsession.query(cls)
t = q.first() # type: Task
self.assertIsNotNone(t, "Missing task!")
# Name validity
validate_task_tablename(t.tablename)
# Core functions
self.assertIsInstance(t.is_complete(), bool)
self.assertIsInstance(t.get_task_html(req), str)
for trackerinfo in t.get_trackers(req):
self.assertIsInstance(trackerinfo, TrackerInfo)
ctvlist = t.get_clinical_text(req)
if ctvlist is not None:
for ctvinfo in ctvlist:
self.assertIsInstance(ctvinfo, CtvInfo)
for est in t.get_all_summary_tables(req):
self.assertIsInstance(
est.get_spreadsheet_page(), SpreadsheetPage
)
self.assertIsInstance(est.get_xml_element(), XmlElement)
self.assertIsInstance(t.has_patient, bool)
self.assertIsInstance(t.is_anonymous, bool)
self.assertIsInstance(t.has_clinician, bool)
self.assertIsInstance(t.has_respondent, bool)
self.assertIsInstance(t.tablename, str)
for fn in t.get_fieldnames():
self.assertIsInstance(fn, str)
self.assertIsInstance(t.field_contents_valid(), bool)
for msg in t.field_contents_invalid_because():
self.assertIsInstance(msg, str)
for fn in t.get_blob_fields():
self.assertIsInstance(fn, str)
self.assertIsInstance(t.pk, int) # all our examples do have PKs
self.assertIsInstance(t.is_preserved(), bool)
self.assertIsInstance(t.was_forcibly_preserved(), bool)
self.assertIsInstanceOrNone(t.get_creation_datetime(), Pendulum)
self.assertIsInstanceOrNone(
t.get_creation_datetime_utc(), Pendulum
)
self.assertIsInstanceOrNone(
t.get_seconds_from_creation_to_first_finish(), float
)
self.assertIsInstance(t.get_adding_user_id(), int)
self.assertIsInstance(t.get_adding_user_username(), str)
self.assertIsInstance(t.get_removing_user_username(), str)
self.assertIsInstance(t.get_preserving_user_username(), str)
self.assertIsInstance(t.get_manually_erasing_user_username(), str)
# Summaries
for se in t.standard_task_summary_fields():
self.assertIsInstance(se, SummaryElement)
# SNOMED-CT
if req.snomed_supported:
for snomed_code in t.get_snomed_codes(req):
self.assertIsInstance(snomed_code, SnomedExpression)
# Clinician
self.assertIsInstance(t.get_clinician_name(), str)
# Respondent
self.assertIsInstance(t.is_respondent_complete(), bool)
# Patient
self.assertIsInstanceOrNone(t.patient, Patient)
self.assertIsInstance(t.is_female(), bool)
self.assertIsInstance(t.is_male(), bool)
self.assertIsInstanceOrNone(t.get_patient_server_pk(), int)
self.assertIsInstance(t.get_patient_forename(), str)
self.assertIsInstance(t.get_patient_surname(), str)
dob = t.get_patient_dob()
assert (
dob is None or isinstance(dob, date) or isinstance(dob, Date)
)
self.assertIsInstanceOrNone(t.get_patient_dob_first11chars(), str)
self.assertIsInstance(t.get_patient_sex(), str)
self.assertIsInstance(t.get_patient_address(), str)
for idnum in t.get_patient_idnum_objects():
self.assertIsInstance(
idnum.get_idnum_reference(), IdNumReference
)
self.assertIsInstance(idnum.is_superficially_valid(), bool)
self.assertIsInstance(idnum.description(req), str)
self.assertIsInstance(idnum.short_description(req), str)
self.assertIsInstance(idnum.get_filename_component(req), str)
# HL7 v2
pidseg = t.get_patient_hl7_pid_segment(req, recipdef)
assert isinstance(pidseg, str) or isinstance(pidseg, hl7.Segment)
for dataseg in t.get_hl7_data_segments(req, recipdef):
self.assertIsInstance(dataseg, hl7.Segment)
for dataseg in t.get_hl7_extra_data_segments(recipdef):
self.assertIsInstance(dataseg, hl7.Segment)
# FHIR
self.assertIsInstance(
t.get_fhir_bundle(req, recipdef).as_json(), dict
) # the main test is not crashing!
# Other properties
self.assertIsInstance(t.is_erased(), bool)
self.assertIsInstance(t.is_live_on_tablet(), bool)
for attrname, col in t.gen_text_filter_columns():
self.assertIsInstance(attrname, str)
self.assertIsInstance(col, Column)
# Views
for page in t.get_spreadsheet_pages(req):
self.assertIsInstance(page.get_tsv(), str)
self.assertIsInstance(t.get_xml(req), str)
self.assertIsInstance(t.get_html(req), str)
self.assertIsInstance(t.get_pdf(req), bytes)
self.assertIsInstance(t.get_pdf_html(req), str)
self.assertIsInstance(t.suggested_pdf_filename(req), str)
self.assertIsInstance(
t.get_rio_metadata(
req,
which_idnum=1,
uploading_user_id=user.id,
document_type="some_doc_type",
),
str,
)
# Help
help_file = f"{t.help_url_basename()}.rst"
task_help_file = os.path.join(task_doc_root, help_file)
self.assertTrue(
os.path.exists(task_help_file),
msg=f"Task help not found at {task_help_file}",
)
# Special operations
t.apply_special_note(
req, "Debug: Special note! (1)", from_console=True
)
t.apply_special_note(
req, "Debug: Special note! (2)", from_console=False
)
self.assertIsInstance(t.special_notes, list)
t.cancel_from_export_log(req, from_console=True)
t.cancel_from_export_log(req, from_console=False)
# Insert random data and check it doesn't crash.
dummy_data_factory.fill_in_task_fields(t)
self.assertIsInstance(t.get_html(req), str)
# Destructive special operations
self.assertFalse(t.is_erased())
t.manually_erase(req)
self.assertTrue(t.is_erased())
t.delete_entirely(req)