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

73 statements  

« prev     ^ index     » next       coverage.py v7.6.10, created at 2025-01-30 13:48 +0000

1""" 

2camcops_server/tasks/tests/core10_tests.py 

3 

4=============================================================================== 

5 

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

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

8 

9 This file is part of CamCOPS. 

10 

11 CamCOPS is free software: you can redistribute it and/or modify 

12 it under the terms of the GNU General Public License as published by 

13 the Free Software Foundation, either version 3 of the License, or 

14 (at your option) any later version. 

15 

16 CamCOPS is distributed in the hope that it will be useful, 

17 but WITHOUT ANY WARRANTY; without even the implied warranty of 

18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

19 GNU General Public License for more details. 

20 

21 You should have received a copy of the GNU General Public License 

22 along with CamCOPS. If not, see <https://www.gnu.org/licenses/>. 

23 

24=============================================================================== 

25 

26""" 

27 

28import pendulum 

29 

30from camcops_server.cc_modules.cc_testfactories import ( 

31 PatientFactory, 

32 UserFactory, 

33) 

34from camcops_server.cc_modules.cc_unittest import DemoRequestTestCase 

35from camcops_server.tasks.core10 import Core10, Core10Report 

36from camcops_server.tasks.tests.factories import Core10Factory 

37 

38 

39class Core10ReportTestCase(DemoRequestTestCase): 

40 def setUp(self) -> None: 

41 super().setUp() 

42 

43 self.report = self.create_report() 

44 self.req._debugging_user = UserFactory(superuser=True) 

45 

46 def create_report(self) -> Core10Report: 

47 return Core10Report(via_index=False) 

48 

49 

50class Core10ReportTotalsTests(Core10ReportTestCase): 

51 def setUp(self) -> None: 

52 super().setUp() 

53 

54 patient_1 = PatientFactory() 

55 patient_2 = PatientFactory() 

56 patient_3 = PatientFactory() 

57 

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

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

60 

61 Core10Factory( 

62 patient=patient_1, 

63 q1=4, 

64 q2=4, 

65 when_created=pendulum.parse("2018-06-01"), 

66 ) # Score 8 

67 Core10Factory( 

68 patient=patient_1, 

69 q7=1, 

70 q8=1, 

71 when_created=pendulum.parse("2018-10-04"), 

72 ) # Score 2 

73 

74 Core10Factory( 

75 patient=patient_2, 

76 q3=3, 

77 q4=3, 

78 when_created=pendulum.parse("2018-05-02"), 

79 ) # Score 6 

80 Core10Factory( 

81 patient=patient_2, 

82 q3=2, 

83 q4=1, 

84 when_created=pendulum.parse("2018-10-03"), 

85 ) # Score 3 

86 

87 Core10Factory( 

88 patient=patient_3, 

89 q5=2, 

90 q6=2, 

91 when_created=pendulum.parse("2018-01-10"), 

92 ) # Score 4 

93 Core10Factory( 

94 patient=patient_3, 

95 q9=1, 

96 q10=3, 

97 when_created=pendulum.parse("2018-10-01"), 

98 ) # Score 4 

99 

100 def test_row_has_totals_and_averages(self) -> None: 

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

102 expected_rows = [ 

103 [ 

104 3, # n initial 

105 3, # n latest 

106 6.0, # Initial average 

107 3.0, # Latest average 

108 3.0, # Average progress 

109 ] 

110 ] 

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

112 

113 

114class Core10ReportEmptyTests(Core10ReportTestCase): 

115 def test_no_rows_when_no_data(self) -> None: 

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

117 no_data = self.report.no_data_value() 

118 expected_rows = [[0, 0, no_data, no_data, no_data]] 

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

120 

121 

122class Core10ReportDoubleCountingTests(Core10ReportTestCase): 

123 def setUp(self) -> None: 

124 super().setUp() 

125 

126 patient_1 = PatientFactory() 

127 patient_2 = PatientFactory() 

128 patient_3 = PatientFactory() 

129 

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

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

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

133 

134 Core10Factory( 

135 patient=patient_1, 

136 q1=4, 

137 q2=4, 

138 when_created=pendulum.parse("2018-06-01"), 

139 ) # Score 8 

140 

141 Core10Factory( 

142 patient=patient_2, 

143 q3=3, 

144 q4=3, 

145 when_created=pendulum.parse("2018-05-02"), 

146 ) # Score 6 

147 Core10Factory( 

148 patient=patient_2, 

149 q3=2, 

150 q4=1, 

151 when_created=pendulum.parse("2018-10-03"), 

152 ) # Score 3 

153 

154 Core10Factory( 

155 patient=patient_3, 

156 q5=2, 

157 q6=2, 

158 when_created=pendulum.parse("2018-01-10"), 

159 ) # Score 4 

160 Core10Factory( 

161 patient=patient_3, 

162 q9=1, 

163 q10=2, 

164 when_created=pendulum.parse("2018-10-01"), 

165 ) # Score 3 

166 

167 def test_record_does_not_appear_in_first_and_latest(self) -> None: 

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

169 expected_rows = [ 

170 [ 

171 3, # n initial 

172 2, # n latest 

173 6.0, # Initial average 

174 3.0, # Latest average 

175 2.0, # Average progress 

176 ] 

177 ] 

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

179 

180 

181class Core10ReportDateRangeTests(Core10ReportTestCase): 

182 """ 

183 Test code: 

184 

185 .. code-block:: sql 

186 

187 -- 2019-10-21 

188 -- For SQLite: 

189 

190 CREATE TABLE core10 

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

192 

193 .schema core10 

194 

195 INSERT INTO core10 

196 (_pk,patient_id,when_created,_current) 

197 VALUES 

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

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

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

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

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

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

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

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

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

207 

208 SELECT * from core10; 

209 

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

211 -- ... gives e.g. 

212 -- 2018-06-01 00:00:00.000 

213 

214 SELECT * 

215 FROM core10 

216 WHERE core10._current = 1 

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

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

219 

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

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

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

223 

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

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

226 

227 See 

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

229 

230 """ # noqa 

231 

232 def setUp(self) -> None: 

233 super().setUp() 

234 

235 patient_1 = PatientFactory() 

236 patient_2 = PatientFactory() 

237 patient_3 = PatientFactory() 

238 

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

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

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

242 

243 Core10Factory( 

244 patient=patient_1, 

245 q1=4, 

246 q2=4, 

247 when_created=pendulum.parse("2018-06-01"), 

248 ) # Score 8 

249 Core10Factory( 

250 patient=patient_1, 

251 q7=3, 

252 q8=1, 

253 when_created=pendulum.parse("2018-08-01"), 

254 ) # Score 4 

255 Core10Factory( 

256 patient=patient_1, 

257 q7=1, 

258 q8=1, 

259 when_created=pendulum.parse("2018-10-01"), 

260 ) # Score 2 

261 

262 Core10Factory( 

263 patient=patient_2, 

264 q3=3, 

265 q4=3, 

266 when_created=pendulum.parse("2018-06-01"), 

267 ) # Score 6 

268 Core10Factory( 

269 patient=patient_2, 

270 q3=2, 

271 q4=2, 

272 when_created=pendulum.parse("2018-08-01"), 

273 ) # Score 4 

274 Core10Factory( 

275 patient=patient_2, 

276 q3=1, 

277 q4=2, 

278 when_created=pendulum.parse("2018-10-01"), 

279 ) # Score 3 

280 

281 Core10Factory( 

282 patient=patient_3, 

283 q5=2, 

284 q6=2, 

285 when_created=pendulum.parse("2018-06-01"), 

286 ) # Score 4 

287 Core10Factory( 

288 patient=patient_3, 

289 q9=1, 

290 q10=3, 

291 when_created=pendulum.parse("2018-08-01"), 

292 ) # Score 4 

293 Core10Factory( 

294 patient=patient_3, 

295 q9=1, 

296 q10=3, 

297 when_created=pendulum.parse("2018-10-01"), 

298 ) # Score 4 

299 

300 self.dump_table( 

301 Core10.__tablename__, 

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

303 ) 

304 

305 def test_report_filtered_by_date_range(self) -> None: 

306 self.report.start_datetime = "2018-06-01T00:00:00.000000+00:00" 

307 self.report.end_datetime = "2018-09-01T00:00:00.000000+00:00" 

308 

309 self.set_echo(True) 

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

311 self.set_echo(False) 

312 expected_rows = [ 

313 [ 

314 3, # n initial 

315 3, # n latest 

316 6.0, # Initial average 

317 4.0, # Latest average 

318 2.0, # Average progress 

319 ] 

320 ] 

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