Coverage for cc_modules/tests/cc_task_tests.py: 11%
153 statements
« prev ^ index » next coverage.py v6.5.0, created at 2022-11-08 23:14 +0000
« prev ^ index » next coverage.py v6.5.0, created at 2022-11-08 23:14 +0000
1#!/usr/bin/env python
3"""
4camcops_server/cc_modules/tests/cc_task_tests.py
6===============================================================================
8 Copyright (C) 2012, University of Cambridge, Department of Psychiatry.
9 Created by Rudolf Cardinal (rnc1001@cam.ac.uk).
11 This file is part of CamCOPS.
13 CamCOPS is free software: you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
18 CamCOPS is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
23 You should have received a copy of the GNU General Public License
24 along with CamCOPS. If not, see <https://www.gnu.org/licenses/>.
26===============================================================================
28"""
30import logging
31from time import sleep
32import urllib.error
33import urllib.request
35from cardinal_pythonlib.httpconst import HttpStatus
36from cardinal_pythonlib.logs import BraceStyleAdapter
37from pendulum import Date, DateTime as Pendulum
39from camcops_server.cc_modules.cc_dummy_database import DummyDataInserter
40from camcops_server.cc_modules.cc_task import Task
41from camcops_server.cc_modules.cc_unittest import DemoDatabaseTestCase
42from camcops_server.cc_modules.cc_validators import validate_task_tablename
44log = BraceStyleAdapter(logging.getLogger(__name__))
47# =============================================================================
48# Unit testing
49# =============================================================================
52class TaskTests(DemoDatabaseTestCase):
53 """
54 Unit tests.
55 """
57 def open_url(self, url: str) -> int:
58 num_tries = 0
59 response = None
60 delay = 10
62 while response is None:
63 try:
64 response = urllib.request.urlopen(url)
65 except urllib.error.URLError:
66 num_tries += 1
67 if num_tries == 5:
68 raise
69 sleep(delay)
70 delay = delay * 2
72 return response.getcode()
74 def test_query_phq9(self) -> None:
75 self.announce("test_query_phq9")
76 from camcops_server.tasks import Phq9
78 phq9_query = self.dbsession.query(Phq9)
79 results = phq9_query.all()
80 log.info("{}", results)
82 def test_all_tasks(self) -> None:
83 self.announce("test_all_tasks")
84 from datetime import date
85 import hl7
86 from sqlalchemy.sql.schema import Column
87 from camcops_server.cc_modules.cc_ctvinfo import CtvInfo # noqa: F811
88 from camcops_server.cc_modules.cc_patient import Patient # noqa: F811
89 from camcops_server.cc_modules.cc_simpleobjects import IdNumReference
90 from camcops_server.cc_modules.cc_snomed import ( # noqa: F811
91 SnomedExpression,
92 )
93 from camcops_server.cc_modules.cc_string import APPSTRING_TASKNAME
94 from camcops_server.cc_modules.cc_summaryelement import SummaryElement
95 from camcops_server.cc_modules.cc_trackerhelpers import ( # noqa: F811
96 TrackerInfo,
97 )
98 from camcops_server.cc_modules.cc_spreadsheet import ( # noqa: F811
99 SpreadsheetPage,
100 )
101 from camcops_server.cc_modules.cc_xml import XmlElement
103 subclasses = Task.all_subclasses_by_tablename()
104 tables = [cls.tablename for cls in subclasses]
105 log.info("Actual task table names: {!r} (n={})", tables, len(tables))
106 req = self.req
107 recipdef = self.recipdef
108 dummy_data_factory = DummyDataInserter()
109 for cls in subclasses:
110 log.info("Testing {}", cls)
111 assert cls.extrastring_taskname != APPSTRING_TASKNAME
112 q = self.dbsession.query(cls)
113 t = q.first() # type: Task
115 self.assertIsNotNone(t, "Missing task!")
117 # Name validity
118 validate_task_tablename(t.tablename)
120 # Core functions
121 self.assertIsInstance(t.is_complete(), bool)
122 self.assertIsInstance(t.get_task_html(req), str)
123 for trackerinfo in t.get_trackers(req):
124 self.assertIsInstance(trackerinfo, TrackerInfo)
125 ctvlist = t.get_clinical_text(req)
126 if ctvlist is not None:
127 for ctvinfo in ctvlist:
128 self.assertIsInstance(ctvinfo, CtvInfo)
129 for est in t.get_all_summary_tables(req):
130 self.assertIsInstance(
131 est.get_spreadsheet_page(), SpreadsheetPage
132 )
133 self.assertIsInstance(est.get_xml_element(), XmlElement)
135 self.assertIsInstance(t.has_patient, bool)
136 self.assertIsInstance(t.is_anonymous, bool)
137 self.assertIsInstance(t.has_clinician, bool)
138 self.assertIsInstance(t.has_respondent, bool)
139 self.assertIsInstance(t.tablename, str)
140 for fn in t.get_fieldnames():
141 self.assertIsInstance(fn, str)
142 self.assertIsInstance(t.field_contents_valid(), bool)
143 for msg in t.field_contents_invalid_because():
144 self.assertIsInstance(msg, str)
145 for fn in t.get_blob_fields():
146 self.assertIsInstance(fn, str)
148 self.assertIsInstance(
149 t.pk, int
150 ) # all our examples do have PKs # noqa
151 self.assertIsInstance(t.is_preserved(), bool)
152 self.assertIsInstance(t.was_forcibly_preserved(), bool)
153 self.assertIsInstanceOrNone(t.get_creation_datetime(), Pendulum)
154 self.assertIsInstanceOrNone(
155 t.get_creation_datetime_utc(), Pendulum
156 )
157 self.assertIsInstanceOrNone(
158 t.get_seconds_from_creation_to_first_finish(), float
159 )
161 self.assertIsInstance(t.get_adding_user_id(), int)
162 self.assertIsInstance(t.get_adding_user_username(), str)
163 self.assertIsInstance(t.get_removing_user_username(), str)
164 self.assertIsInstance(t.get_preserving_user_username(), str)
165 self.assertIsInstance(t.get_manually_erasing_user_username(), str)
167 # Summaries
168 for se in t.standard_task_summary_fields():
169 self.assertIsInstance(se, SummaryElement)
171 # SNOMED-CT
172 if req.snomed_supported:
173 for snomed_code in t.get_snomed_codes(req):
174 self.assertIsInstance(snomed_code, SnomedExpression)
176 # Clinician
177 self.assertIsInstance(t.get_clinician_name(), str)
179 # Respondent
180 self.assertIsInstance(t.is_respondent_complete(), bool)
182 # Patient
183 self.assertIsInstanceOrNone(t.patient, Patient)
184 self.assertIsInstance(t.is_female(), bool)
185 self.assertIsInstance(t.is_male(), bool)
186 self.assertIsInstanceOrNone(t.get_patient_server_pk(), int)
187 self.assertIsInstance(t.get_patient_forename(), str)
188 self.assertIsInstance(t.get_patient_surname(), str)
189 dob = t.get_patient_dob()
190 assert (
191 dob is None or isinstance(dob, date) or isinstance(dob, Date)
192 )
193 self.assertIsInstanceOrNone(t.get_patient_dob_first11chars(), str)
194 self.assertIsInstance(t.get_patient_sex(), str)
195 self.assertIsInstance(t.get_patient_address(), str)
196 for idnum in t.get_patient_idnum_objects():
197 self.assertIsInstance(
198 idnum.get_idnum_reference(), IdNumReference
199 )
200 self.assertIsInstance(idnum.is_superficially_valid(), bool)
201 self.assertIsInstance(idnum.description(req), str)
202 self.assertIsInstance(idnum.short_description(req), str)
203 self.assertIsInstance(idnum.get_filename_component(req), str)
205 # HL7 v2
206 pidseg = t.get_patient_hl7_pid_segment(req, recipdef)
207 assert isinstance(pidseg, str) or isinstance(pidseg, hl7.Segment)
208 for dataseg in t.get_hl7_data_segments(req, recipdef):
209 self.assertIsInstance(dataseg, hl7.Segment)
210 for dataseg in t.get_hl7_extra_data_segments(recipdef):
211 self.assertIsInstance(dataseg, hl7.Segment)
213 # FHIR
214 self.assertIsInstance(
215 t.get_fhir_bundle(req, recipdef).as_json(), dict
216 ) # the main test is not crashing!
218 # Other properties
219 self.assertIsInstance(t.is_erased(), bool)
220 self.assertIsInstance(t.is_live_on_tablet(), bool)
221 for attrname, col in t.gen_text_filter_columns():
222 self.assertIsInstance(attrname, str)
223 self.assertIsInstance(col, Column)
225 # Views
226 for page in t.get_spreadsheet_pages(req):
227 self.assertIsInstance(page.get_tsv(), str)
228 self.assertIsInstance(t.get_xml(req), str)
229 self.assertIsInstance(t.get_html(req), str)
230 self.assertIsInstance(t.get_pdf(req), bytes)
231 self.assertIsInstance(t.get_pdf_html(req), str)
232 self.assertIsInstance(t.suggested_pdf_filename(req), str)
233 self.assertIsInstance(
234 t.get_rio_metadata(
235 req,
236 which_idnum=1,
237 uploading_user_id=self.user.id,
238 document_type="some_doc_type",
239 ),
240 str,
241 )
243 # Help
244 help_url = t.help_url()
245 status = self.open_url(help_url)
246 self.assertEqual(
247 status,
248 HttpStatus.OK,
249 msg=f"Task help not found at {help_url}",
250 )
252 # Special operations
253 t.apply_special_note(
254 req, "Debug: Special note! (1)", from_console=True
255 )
256 t.apply_special_note(
257 req, "Debug: Special note! (2)", from_console=False
258 )
259 self.assertIsInstance(t.special_notes, list)
260 t.cancel_from_export_log(req, from_console=True)
261 t.cancel_from_export_log(req, from_console=False)
263 # Insert random data and check it doesn't crash.
264 dummy_data_factory.fill_in_task_fields(t)
265 self.assertIsInstance(t.get_html(req), str)
267 # Destructive special operations
268 self.assertFalse(t.is_erased())
269 t.manually_erase(req)
270 self.assertTrue(t.is_erased())
271 t.delete_entirely(req)