Coverage for cc_modules/tests/cc_patient_tests.py: 17%

155 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_patient_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 hl7 

31import pendulum 

32 

33from camcops_server.cc_modules.cc_simpleobjects import BarePatientInfo 

34from camcops_server.cc_modules.cc_patient import Patient 

35from camcops_server.cc_modules.cc_patientidnum import PatientIdNum 

36from camcops_server.cc_modules.cc_simpleobjects import IdNumReference 

37from camcops_server.cc_modules.cc_taskschedule import ( 

38 PatientTaskSchedule, 

39 TaskSchedule, 

40 TaskScheduleItem, 

41) 

42from camcops_server.cc_modules.cc_spreadsheet import SpreadsheetPage 

43from camcops_server.cc_modules.cc_unittest import ( 

44 BasicDatabaseTestCase, 

45 DemoDatabaseTestCase, 

46) 

47from camcops_server.cc_modules.cc_xml import XmlElement 

48 

49 

50# ============================================================================= 

51# Unit tests 

52# ============================================================================= 

53 

54 

55class PatientTests(DemoDatabaseTestCase): 

56 """ 

57 Unit tests. 

58 """ 

59 

60 def test_patient(self) -> None: 

61 self.announce("test_patient") 

62 from camcops_server.cc_modules.cc_group import Group 

63 

64 req = self.req 

65 q = self.dbsession.query(Patient) 

66 p = q.first() # type: Patient 

67 assert p, "Missing Patient in demo database!" 

68 

69 for pidnum in p.get_idnum_objects(): 

70 self.assertIsInstance(pidnum, PatientIdNum) 

71 for idref in p.get_idnum_references(): 

72 self.assertIsInstance(idref, IdNumReference) 

73 for idnum in p.get_idnum_raw_values_only(): 

74 self.assertIsInstance(idnum, int) 

75 self.assertIsInstance(p.get_xml_root(req), XmlElement) 

76 self.assertIsInstance(p.get_spreadsheet_page(req), SpreadsheetPage) 

77 self.assertIsInstance(p.get_bare_ptinfo(), BarePatientInfo) 

78 self.assertIsInstanceOrNone(p.group, Group) 

79 self.assertIsInstance(p.satisfies_upload_id_policy(), bool) 

80 self.assertIsInstance(p.satisfies_finalize_id_policy(), bool) 

81 self.assertIsInstance(p.get_surname(), str) 

82 self.assertIsInstance(p.get_forename(), str) 

83 self.assertIsInstance(p.get_surname_forename_upper(), str) 

84 for longform in (True, False): 

85 self.assertIsInstance(p.get_dob_html(req, longform), str) 

86 age_str_int = p.get_age(req) 

87 assert isinstance(age_str_int, str) or isinstance(age_str_int, int) 

88 self.assertIsInstanceOrNone(p.get_dob(), pendulum.Date) 

89 self.assertIsInstanceOrNone(p.get_dob_str(), str) 

90 age_at_str_int = p.get_age_at(req.now) 

91 assert isinstance(age_at_str_int, str) or isinstance( 

92 age_at_str_int, int 

93 ) 

94 self.assertIsInstance(p.is_female(), bool) 

95 self.assertIsInstance(p.is_male(), bool) 

96 self.assertIsInstance(p.get_sex(), str) 

97 self.assertIsInstance(p.get_sex_verbose(), str) 

98 self.assertIsInstance(p.get_address(), str) 

99 self.assertIsInstance(p.get_email(), str) 

100 self.assertIsInstance( 

101 p.get_hl7_pid_segment(req, self.recipdef), hl7.Segment 

102 ) 

103 self.assertIsInstanceOrNone( 

104 p.get_idnum_object(which_idnum=1), PatientIdNum 

105 ) 

106 self.assertIsInstanceOrNone(p.get_idnum_value(which_idnum=1), int) 

107 self.assertIsInstance(p.get_iddesc(req, which_idnum=1), str) 

108 self.assertIsInstance(p.get_idshortdesc(req, which_idnum=1), str) 

109 self.assertIsInstance(p.is_preserved(), bool) 

110 self.assertIsInstance(p.is_finalized(), bool) 

111 self.assertIsInstance(p.user_may_edit(req), bool) 

112 

113 def test_surname_forename_upper(self) -> None: 

114 patient = Patient() 

115 patient.forename = "Forename" 

116 patient.surname = "Surname" 

117 

118 self.assertEqual( 

119 patient.get_surname_forename_upper(), "SURNAME, FORENAME" 

120 ) 

121 

122 def test_surname_forename_upper_no_forename(self) -> None: 

123 patient = Patient() 

124 patient.surname = "Surname" 

125 

126 self.assertEqual( 

127 patient.get_surname_forename_upper(), "SURNAME, (UNKNOWN)" 

128 ) 

129 

130 def test_surname_forename_upper_no_surname(self) -> None: 

131 patient = Patient() 

132 patient.forename = "Forename" 

133 

134 self.assertEqual( 

135 patient.get_surname_forename_upper(), "(UNKNOWN), FORENAME" 

136 ) 

137 

138 

139class LineageTests(DemoDatabaseTestCase): 

140 def create_tasks(self) -> None: 

141 # Actually not creating any tasks but we don't want the patients 

142 # created by default in the baseclass 

143 

144 # First record for patient 1 

145 self.set_era("2020-01-01") 

146 

147 self.patient_1 = Patient() 

148 self.patient_1.id = 1 

149 self.apply_standard_db_fields(self.patient_1) 

150 self.dbsession.add(self.patient_1) 

151 

152 # First ID number record for patient 1 

153 self.patient_idnum_1_1 = PatientIdNum() 

154 self.patient_idnum_1_1.id = 3 

155 self.apply_standard_db_fields(self.patient_idnum_1_1) 

156 self.patient_idnum_1_1.patient_id = 1 

157 self.patient_idnum_1_1.which_idnum = self.nhs_iddef.which_idnum 

158 self.patient_idnum_1_1.idnum_value = 555 

159 self.dbsession.add(self.patient_idnum_1_1) 

160 

161 # Second ID number record for patient 1 

162 self.patient_idnum_1_2 = PatientIdNum() 

163 self.patient_idnum_1_2.id = 3 

164 self.apply_standard_db_fields(self.patient_idnum_1_2) 

165 # This one is not current 

166 self.patient_idnum_1_2._current = False 

167 self.patient_idnum_1_2.patient_id = 1 

168 self.patient_idnum_1_2.which_idnum = self.nhs_iddef.which_idnum 

169 self.patient_idnum_1_2.idnum_value = 555 

170 self.dbsession.add(self.patient_idnum_1_2) 

171 

172 self.dbsession.commit() 

173 

174 def test_gen_patient_idnums_even_noncurrent(self) -> None: 

175 idnums = list(self.patient_1.gen_patient_idnums_even_noncurrent()) 

176 

177 self.assertEqual(len(idnums), 2) 

178 

179 

180class PatientDeleteTests(DemoDatabaseTestCase): 

181 def test_deletes_patient_task_schedule(self) -> None: 

182 schedule = TaskSchedule() 

183 schedule.group_id = self.group.id 

184 self.dbsession.add(schedule) 

185 self.dbsession.flush() 

186 

187 item = TaskScheduleItem() 

188 item.schedule_id = schedule.id 

189 item.task_table_name = "ace3" 

190 item.due_from = pendulum.Duration(days=30) 

191 item.due_by = pendulum.Duration(days=60) 

192 self.dbsession.add(item) 

193 self.dbsession.flush() 

194 

195 patient = self.create_patient() 

196 

197 pts = PatientTaskSchedule() 

198 pts.schedule_id = schedule.id 

199 pts.patient_pk = patient.pk 

200 self.dbsession.add(pts) 

201 self.dbsession.commit() 

202 

203 self.assertIsNotNone( 

204 self.dbsession.query(TaskSchedule) 

205 .filter(TaskSchedule.id == schedule.id) 

206 .one_or_none() 

207 ) 

208 self.assertIsNotNone( 

209 self.dbsession.query(TaskScheduleItem) 

210 .filter(TaskScheduleItem.id == item.id) 

211 .one_or_none() 

212 ) 

213 self.assertIsNotNone( 

214 self.dbsession.query(PatientTaskSchedule) 

215 .filter(PatientTaskSchedule.id == pts.id) 

216 .one_or_none() 

217 ) 

218 

219 self.dbsession.delete(patient) 

220 self.dbsession.commit() 

221 

222 self.assertIsNotNone( 

223 self.dbsession.query(TaskSchedule) 

224 .filter(TaskSchedule.id == schedule.id) 

225 .one_or_none() 

226 ) 

227 self.assertIsNotNone( 

228 self.dbsession.query(TaskScheduleItem) 

229 .filter(TaskScheduleItem.id == item.id) 

230 .one_or_none() 

231 ) 

232 

233 self.assertIsNone( 

234 self.dbsession.query(PatientTaskSchedule) 

235 .filter(PatientTaskSchedule.id == pts.id) 

236 .one_or_none() 

237 ) 

238 

239 

240class PatientPermissionTests(BasicDatabaseTestCase): 

241 def test_group_administrator_may_edit_server_created(self) -> None: 

242 user = self.create_user(username="testuser") 

243 self.dbsession.flush() 

244 

245 patient = self.create_patient( 

246 _group=self.group, as_server_patient=True 

247 ) 

248 

249 self.create_membership(user, self.group, groupadmin=True) 

250 self.dbsession.commit() 

251 

252 self.req._debugging_user = user 

253 self.assertTrue(patient.user_may_edit(self.req)) 

254 

255 def test_group_administrator_may_edit_finalized(self) -> None: 

256 user = self.create_user(username="testuser") 

257 self.dbsession.flush() 

258 

259 patient = self.create_patient( 

260 _group=self.group, as_server_patient=False 

261 ) 

262 

263 self.create_membership(user, self.group, groupadmin=True) 

264 self.dbsession.commit() 

265 

266 self.req._debugging_user = user 

267 self.assertTrue(patient.user_may_edit(self.req)) 

268 

269 def test_group_member_with_permission_may_edit_server_created( 

270 self, 

271 ) -> None: 

272 user = self.create_user(username="testuser") 

273 self.dbsession.flush() 

274 

275 patient = self.create_patient( 

276 _group=self.group, as_server_patient=True 

277 ) 

278 

279 self.create_membership(user, self.group, may_manage_patients=True) 

280 self.dbsession.commit() 

281 

282 self.req._debugging_user = user 

283 self.assertTrue(patient.user_may_edit(self.req)) 

284 

285 def test_group_member_with_permission_may_not_edit_finalized(self) -> None: 

286 user = self.create_user(username="testuser") 

287 self.dbsession.flush() 

288 

289 patient = self.create_patient( 

290 _group=self.group, as_server_patient=False 

291 ) 

292 

293 self.create_membership(user, self.group, may_manage_patients=True) 

294 self.dbsession.commit() 

295 

296 self.req._debugging_user = user 

297 self.assertFalse(patient.user_may_edit(self.req))