Coverage for tasks/tests/core10_tests.py: 22%

87 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/tasks/tests/core10_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 pendulum 

31 

32from camcops_server.cc_modules.cc_patient import Patient 

33from camcops_server.cc_modules.tests.cc_report_tests import ( 

34 AverageScoreReportTestCase, 

35) 

36from camcops_server.tasks.core10 import Core10, Core10Report 

37 

38 

39class Core10ReportTestCase(AverageScoreReportTestCase): 

40 def create_report(self) -> Core10Report: 

41 return Core10Report(via_index=False) 

42 

43 def create_task( 

44 self, 

45 patient: Patient, 

46 q1: int = 0, 

47 q2: int = 0, 

48 q3: int = 0, 

49 q4: int = 0, 

50 q5: int = 0, 

51 q6: int = 0, 

52 q7: int = 0, 

53 q8: int = 0, 

54 q9: int = 0, 

55 q10: int = 0, 

56 era: str = None, 

57 ) -> None: 

58 task = Core10() 

59 self.apply_standard_task_fields(task) 

60 task.id = next(self.task_id_sequence) 

61 

62 task.patient_id = patient.id 

63 

64 task.q1 = q1 

65 task.q2 = q2 

66 task.q3 = q3 

67 task.q4 = q4 

68 task.q5 = q5 

69 task.q6 = q6 

70 task.q7 = q7 

71 task.q8 = q8 

72 task.q9 = q9 

73 task.q10 = q10 

74 

75 if era is not None: 

76 task.when_created = pendulum.parse(era) 

77 # log.info(f"Creating task, when_created = {task.when_created}") 

78 

79 self.dbsession.add(task) 

80 

81 

82class Core10ReportTests(Core10ReportTestCase): 

83 def create_tasks(self) -> None: 

84 self.patient_1 = self.create_patient(idnum_value=333) 

85 self.patient_2 = self.create_patient(idnum_value=444) 

86 self.patient_3 = self.create_patient(idnum_value=555) 

87 

88 # Initial average score = (8 + 6 + 4) / 3 = 6 

89 # Latest average score = (2 + 3 + 4) / 3 = 3 

90 

91 self.create_task( 

92 patient=self.patient_1, q1=4, q2=4, era="2018-06-01" 

93 ) # Score 8 

94 self.create_task( 

95 patient=self.patient_1, q7=1, q8=1, era="2018-10-04" 

96 ) # Score 2 

97 

98 self.create_task( 

99 patient=self.patient_2, q3=3, q4=3, era="2018-05-02" 

100 ) # Score 6 

101 self.create_task( 

102 patient=self.patient_2, q3=2, q4=1, era="2018-10-03" 

103 ) # Score 3 

104 

105 self.create_task( 

106 patient=self.patient_3, q5=2, q6=2, era="2018-01-10" 

107 ) # Score 4 

108 self.create_task( 

109 patient=self.patient_3, q9=1, q10=3, era="2018-10-01" 

110 ) # Score 4 

111 self.dbsession.commit() 

112 

113 def test_row_has_totals_and_averages(self) -> None: 

114 pages = self.report.get_spreadsheet_pages(req=self.req) 

115 expected_rows = [ 

116 [ 

117 3, # n initial 

118 3, # n latest 

119 6.0, # Initial average 

120 3.0, # Latest average 

121 3.0, # Average progress 

122 ] 

123 ] 

124 self.assertEqual(pages[0].plainrows, expected_rows) 

125 

126 

127class Core10ReportEmptyTests(Core10ReportTestCase): 

128 def test_no_rows_when_no_data(self) -> None: 

129 pages = self.report.get_spreadsheet_pages(req=self.req) 

130 no_data = self.report.no_data_value() 

131 expected_rows = [[0, 0, no_data, no_data, no_data]] 

132 self.assertEqual(pages[0].plainrows, expected_rows) 

133 

134 

135class Core10ReportDoubleCountingTests(Core10ReportTestCase): 

136 def create_tasks(self) -> None: 

137 self.patient_1 = self.create_patient(idnum_value=333) 

138 self.patient_2 = self.create_patient(idnum_value=444) 

139 self.patient_3 = self.create_patient(idnum_value=555) 

140 

141 # Initial average score = (8 + 6 + 4) / 3 = 6 

142 # Latest average score = ( 3 + 3) / 2 = 3 

143 # Progress avg score = ( 3 + 1) / 2 = 2 ... NOT 3. 

144 self.create_task( 

145 patient=self.patient_1, q1=4, q2=4, era="2018-06-01" 

146 ) # Score 8 

147 

148 self.create_task( 

149 patient=self.patient_2, q3=3, q4=3, era="2018-05-02" 

150 ) # Score 6 

151 self.create_task( 

152 patient=self.patient_2, q3=2, q4=1, era="2018-10-03" 

153 ) # Score 3 

154 

155 self.create_task( 

156 patient=self.patient_3, q5=2, q6=2, era="2018-01-10" 

157 ) # Score 4 

158 self.create_task( 

159 patient=self.patient_3, q9=1, q10=2, era="2018-10-01" 

160 ) # Score 3 

161 self.dbsession.commit() 

162 

163 def test_record_does_not_appear_in_first_and_latest(self) -> None: 

164 pages = self.report.get_spreadsheet_pages(req=self.req) 

165 expected_rows = [ 

166 [ 

167 3, # n initial 

168 2, # n latest 

169 6.0, # Initial average 

170 3.0, # Latest average 

171 2.0, # Average progress 

172 ] 

173 ] 

174 self.assertEqual(pages[0].plainrows, expected_rows) 

175 

176 

177class Core10ReportDateRangeTests(Core10ReportTestCase): 

178 """ 

179 Test code: 

180 

181 .. code-block:: sql 

182 

183 -- 2019-10-21 

184 -- For SQLite: 

185 

186 CREATE TABLE core10 

187 (_pk INT, patient_id INT, when_created DATETIME, _current INT); 

188 

189 .schema core10 

190 

191 INSERT INTO core10 

192 (_pk,patient_id,when_created,_current) 

193 VALUES 

194 (1,1,'2018-06-01T00:00:00.000000+00:00',1), 

195 (2,1,'2018-08-01T00:00:00.000000+00:00',1), 

196 (3,1,'2018-10-01T00:00:00.000000+00:00',1), 

197 (4,2,'2018-06-01T00:00:00.000000+00:00',1), 

198 (5,2,'2018-08-01T00:00:00.000000+00:00',1), 

199 (6,2,'2018-10-01T00:00:00.000000+00:00',1), 

200 (7,3,'2018-06-01T00:00:00.000000+00:00',1), 

201 (8,3,'2018-08-01T00:00:00.000000+00:00',1), 

202 (9,3,'2018-10-01T00:00:00.000000+00:00',1); 

203 

204 SELECT * from core10; 

205 

206 SELECT STRFTIME('%Y-%m-%d %H:%M:%f', core10.when_created) from core10; 

207 -- ... gives e.g. 

208 -- 2018-06-01 00:00:00.000 

209 

210 SELECT * 

211 FROM core10 

212 WHERE core10._current = 1 

213 AND STRFTIME('%Y-%m-%d %H:%M:%f', core10.when_created) >= '2018-06-01 00:00:00.000000' 

214 AND STRFTIME('%Y-%m-%d %H:%M:%f', core10.when_created) < '2018-09-01 00:00:00.000000'; 

215 

216 -- That fails. Either our date/time comparison code is wrong for SQLite, or 

217 -- we are inserting text in the wrong format. 

218 -- Ah. It's the number of decimal places: 

219 

220 SELECT '2018-06-01 00:00:00.000' >= '2018-06-01 00:00:00.000000'; -- 0, false 

221 SELECT '2018-06-01 00:00:00.000' >= '2018-06-01 00:00:00.000'; -- 1, true 

222 

223 See 

224 :func:`camcops_server.cc_modules.cc_sqla_coltypes.isotzdatetime_to_utcdatetime_sqlite`. 

225 

226 """ # noqa 

227 

228 def create_tasks(self) -> None: 

229 self.patient_1 = self.create_patient(idnum_value=333) 

230 self.patient_2 = self.create_patient(idnum_value=444) 

231 self.patient_3 = self.create_patient(idnum_value=555) 

232 

233 # 2018-06 average score = (8 + 6 + 4) / 3 = 6 

234 # 2018-08 average score = (4 + 4 + 4) / 3 = 4 

235 # 2018-10 average score = (2 + 3 + 4) / 3 = 3 

236 

237 self.create_task( 

238 patient=self.patient_1, q1=4, q2=4, era="2018-06-01" 

239 ) # Score 8 

240 self.create_task( 

241 patient=self.patient_1, q7=3, q8=1, era="2018-08-01" 

242 ) # Score 4 

243 self.create_task( 

244 patient=self.patient_1, q7=1, q8=1, era="2018-10-01" 

245 ) # Score 2 

246 

247 self.create_task( 

248 patient=self.patient_2, q3=3, q4=3, era="2018-06-01" 

249 ) # Score 6 

250 self.create_task( 

251 patient=self.patient_2, q3=2, q4=2, era="2018-08-01" 

252 ) # Score 4 

253 self.create_task( 

254 patient=self.patient_2, q3=1, q4=2, era="2018-10-01" 

255 ) # Score 3 

256 

257 self.create_task( 

258 patient=self.patient_3, q5=2, q6=2, era="2018-06-01" 

259 ) # Score 4 

260 self.create_task( 

261 patient=self.patient_3, q9=1, q10=3, era="2018-08-01" 

262 ) # Score 4 

263 self.create_task( 

264 patient=self.patient_3, q9=1, q10=3, era="2018-10-01" 

265 ) # Score 4 

266 self.dbsession.commit() 

267 

268 self.dump_table( 

269 Core10.__tablename__, 

270 ["_pk", "patient_id", "when_created", "_current"], 

271 ) 

272 

273 def test_report_filtered_by_date_range(self) -> None: 

274 # self.report.start_datetime = pendulum.parse("2018-05-01T00:00:00.000000+00:00") # noqa 

275 self.report.start_datetime = pendulum.parse( 

276 "2018-06-01T00:00:00.000000+00:00" 

277 ) 

278 self.report.end_datetime = pendulum.parse( 

279 "2018-09-01T00:00:00.000000+00:00" 

280 ) 

281 

282 self.set_echo(True) 

283 pages = self.report.get_spreadsheet_pages(req=self.req) 

284 self.set_echo(False) 

285 expected_rows = [ 

286 [ 

287 3, # n initial 

288 3, # n latest 

289 6.0, # Initial average 

290 4.0, # Latest average 

291 2.0, # Average progress 

292 ] 

293 ] 

294 self.assertEqual(pages[0].plainrows, expected_rows)