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

1#!/usr/bin/env python 

2 

3""" 

4camcops_server/cc_modules/tests/cc_task_tests.py 

5 

6=============================================================================== 

7 

8 Copyright (C) 2012, University of Cambridge, Department of Psychiatry. 

9 Created by Rudolf Cardinal (rnc1001@cam.ac.uk). 

10 

11 This file is part of CamCOPS. 

12 

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. 

17 

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. 

22 

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/>. 

25 

26=============================================================================== 

27 

28""" 

29 

30import logging 

31from time import sleep 

32import urllib.error 

33import urllib.request 

34 

35from cardinal_pythonlib.httpconst import HttpStatus 

36from cardinal_pythonlib.logs import BraceStyleAdapter 

37from pendulum import Date, DateTime as Pendulum 

38 

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 

43 

44log = BraceStyleAdapter(logging.getLogger(__name__)) 

45 

46 

47# ============================================================================= 

48# Unit testing 

49# ============================================================================= 

50 

51 

52class TaskTests(DemoDatabaseTestCase): 

53 """ 

54 Unit tests. 

55 """ 

56 

57 def open_url(self, url: str) -> int: 

58 num_tries = 0 

59 response = None 

60 delay = 10 

61 

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 

71 

72 return response.getcode() 

73 

74 def test_query_phq9(self) -> None: 

75 self.announce("test_query_phq9") 

76 from camcops_server.tasks import Phq9 

77 

78 phq9_query = self.dbsession.query(Phq9) 

79 results = phq9_query.all() 

80 log.info("{}", results) 

81 

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 

102 

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 

114 

115 self.assertIsNotNone(t, "Missing task!") 

116 

117 # Name validity 

118 validate_task_tablename(t.tablename) 

119 

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) 

134 

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) 

147 

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 ) 

160 

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) 

166 

167 # Summaries 

168 for se in t.standard_task_summary_fields(): 

169 self.assertIsInstance(se, SummaryElement) 

170 

171 # SNOMED-CT 

172 if req.snomed_supported: 

173 for snomed_code in t.get_snomed_codes(req): 

174 self.assertIsInstance(snomed_code, SnomedExpression) 

175 

176 # Clinician 

177 self.assertIsInstance(t.get_clinician_name(), str) 

178 

179 # Respondent 

180 self.assertIsInstance(t.is_respondent_complete(), bool) 

181 

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) 

204 

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) 

212 

213 # FHIR 

214 self.assertIsInstance( 

215 t.get_fhir_bundle(req, recipdef).as_json(), dict 

216 ) # the main test is not crashing! 

217 

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) 

224 

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 ) 

242 

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 ) 

251 

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) 

262 

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) 

266 

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)