Coverage for tasks/tests/apeq_cpft_perinatal_tests.py: 23%

106 statements  

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

1""" 

2camcops_server/tasks/tests/apeq_cpft_perinatal_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_unittest import DemoRequestTestCase 

31from camcops_server.tasks.apeq_cpft_perinatal import ( 

32 APEQCPFTPerinatalReport, 

33) 

34from camcops_server.tasks.tests.factories import APEQCPFTPerinatalFactory 

35 

36# ============================================================================= 

37# Unit tests 

38# ============================================================================= 

39 

40 

41class APEQCPFTPerinatalReportTestCase(DemoRequestTestCase): 

42 COL_Q = 0 

43 COL_TOTAL = 1 

44 COL_RESPONSE_START = 2 

45 

46 COL_FF_WHY = 1 

47 

48 def setUp(self) -> None: 

49 super().setUp() 

50 

51 self.report = APEQCPFTPerinatalReport() 

52 

53 # Really only needed for tests 

54 self.report.start_datetime = None 

55 self.report.end_datetime = None 

56 

57 

58class APEQCPFTPerinatalReportTests(APEQCPFTPerinatalReportTestCase): 

59 def setUp(self) -> None: 

60 """ 

61 Creates 20 tasks. 

62 Should give us: 

63 

64 .. code-block:: none 

65 

66 q1: 0 - 50%, 

67 1 - 25% 

68 2 - 25% 

69 q2: 1 - 100% 

70 q3: 0 - 5% 

71 1 - 20% 

72 2 - 75% 

73 q4: 0 - 10% 

74 1 - 40% 

75 2 - 50% 

76 q5: 0 - 15% 

77 1 - 55% 

78 2 - 30% 

79 q6: 1 - 50% 

80 2 - 50% 

81 ff: 0 - 25% 

82 1 - 10% 

83 2 - 15% 

84 3 - 10% 

85 4 - 5% 

86 5 - 35% 

87 

88 """ 

89 super().setUp() 

90 

91 APEQCPFTPerinatalFactory( 

92 q1=0, q2=1, q3=0, q4=0, q5=2, q6=2, ff_rating=5, ff_why="ff_5_1" 

93 ) 

94 APEQCPFTPerinatalFactory( 

95 q1=0, 

96 q2=1, 

97 q3=1, 

98 q4=0, 

99 q5=2, 

100 q6=2, 

101 ff_rating=5, 

102 ff_why="ff_5_2", 

103 comments="comments_2", 

104 ) 

105 APEQCPFTPerinatalFactory( 

106 q1=0, q2=1, q3=1, q4=1, q5=2, q6=2, ff_rating=5 

107 ) 

108 APEQCPFTPerinatalFactory( 

109 q1=0, q2=1, q3=1, q4=1, q5=2, q6=2, ff_rating=5 

110 ) 

111 APEQCPFTPerinatalFactory( 

112 q1=0, 

113 q2=1, 

114 q3=1, 

115 q4=1, 

116 q5=2, 

117 q6=2, 

118 ff_rating=5, 

119 comments="comments_5", 

120 ) 

121 

122 APEQCPFTPerinatalFactory( 

123 q1=0, q2=1, q3=2, q4=1, q5=2, q6=2, ff_rating=5 

124 ) 

125 APEQCPFTPerinatalFactory( 

126 q1=0, q2=1, q3=2, q4=1, q5=1, q6=2, ff_rating=5 

127 ) 

128 APEQCPFTPerinatalFactory( 

129 q1=0, q2=1, q3=2, q4=1, q5=1, q6=2, ff_rating=4, ff_why="ff_4_1" 

130 ) 

131 APEQCPFTPerinatalFactory( 

132 q1=0, q2=1, q3=2, q4=1, q5=1, q6=2, ff_rating=3 

133 ) 

134 APEQCPFTPerinatalFactory( 

135 q1=0, q2=1, q3=2, q4=1, q5=1, q6=1, ff_rating=3, ff_why="ff_3_1" 

136 ) 

137 

138 APEQCPFTPerinatalFactory( 

139 q1=1, q2=1, q3=2, q4=2, q5=1, q6=1, ff_rating=2, ff_why="ff_2_1" 

140 ) 

141 APEQCPFTPerinatalFactory( 

142 q1=1, q2=1, q3=2, q4=2, q5=1, q6=1, ff_rating=2 

143 ) 

144 APEQCPFTPerinatalFactory( 

145 q1=1, q2=1, q3=2, q4=2, q5=1, q6=1, ff_rating=2, ff_why="ff_2_2" 

146 ) 

147 APEQCPFTPerinatalFactory( 

148 q1=1, q2=1, q3=2, q4=2, q5=1, q6=1, ff_rating=1, ff_why="ff_1_1" 

149 ) 

150 APEQCPFTPerinatalFactory( 

151 q1=1, q2=1, q3=2, q4=2, q5=1, q6=1, ff_rating=1, ff_why="ff_1_2" 

152 ) 

153 

154 APEQCPFTPerinatalFactory( 

155 q1=2, q2=1, q3=2, q4=2, q5=1, q6=1, ff_rating=0 

156 ) 

157 APEQCPFTPerinatalFactory( 

158 q1=2, q2=1, q3=2, q4=2, q5=1, q6=1, ff_rating=0 

159 ) 

160 APEQCPFTPerinatalFactory( 

161 q1=2, q2=1, q3=2, q4=2, q5=0, q6=None, ff_rating=0 

162 ) 

163 APEQCPFTPerinatalFactory( 

164 q1=2, q2=1, q3=2, q4=2, q5=0, q6=None, ff_rating=0 

165 ) 

166 APEQCPFTPerinatalFactory( 

167 q1=2, 

168 q2=1, 

169 q3=2, 

170 q4=2, 

171 q5=0, 

172 q6=1, 

173 ff_rating=0, 

174 comments="comments_20", 

175 ) 

176 

177 def test_main_rows_contain_percentages(self) -> None: 

178 expected_percentages = [ 

179 ["20", "50", "25", "25"], # q1 

180 ["20", "", "100", ""], # q2 

181 ["20", "5", "20", "75"], # q3 

182 ["20", "10", "40", "50"], # q4 

183 ["20", "15", "55", "30"], # q5 

184 ["18", "", "50", "50"], # q6 

185 ] 

186 

187 main_rows = self.report._get_main_rows(self.req) 

188 

189 # MySQL does floating point division 

190 for row, expected in zip(main_rows, expected_percentages): 

191 percentages = [] 

192 

193 for p in row[1:]: 

194 if p != "": 

195 p = str(int(float(p))) 

196 

197 percentages.append(p) 

198 

199 self.assertEqual(percentages, expected) 

200 

201 def test_main_rows_formatted(self) -> None: 

202 expected_q1 = [20, "50.0%", "25.0%", "25.0%"] 

203 

204 main_rows = self.report._get_main_rows( 

205 self.req, cell_format="{0:.1f}%" 

206 ) 

207 

208 self.assertEqual(main_rows[0][1:], expected_q1) 

209 

210 def test_ff_rows_contain_percentages(self) -> None: 

211 expected_ff = [20, 25, 10, 15, 10, 5, 35] 

212 

213 ff_rows = self.report._get_ff_rows(self.req) 

214 

215 # MySQL does floating point division 

216 percentages = [int(float(p)) for p in ff_rows[0][1:]] 

217 

218 self.assertEqual(percentages, expected_ff) 

219 

220 def test_ff_rows_formatted(self) -> None: 

221 expected_ff = [20, "25.0%", "10.0%", "15.0%", "10.0%", "5.0%", "35.0%"] 

222 

223 ff_rows = self.report._get_ff_rows(self.req, cell_format="{0:.1f}%") 

224 

225 self.assertEqual(ff_rows[0][1:], expected_ff) 

226 

227 def test_ff_why_rows_contain_reasons(self) -> None: 

228 expected_reasons = [ 

229 ["Extremely unlikely", "ff_1_1"], 

230 ["Extremely unlikely", "ff_1_2"], 

231 ["Unlikely", "ff_2_1"], 

232 ["Unlikely", "ff_2_2"], 

233 ["Neither likely nor unlikely", "ff_3_1"], 

234 ["Likely", "ff_4_1"], 

235 ["Extremely likely", "ff_5_1"], 

236 ["Extremely likely", "ff_5_2"], 

237 ] 

238 

239 ff_why_rows = self.report._get_ff_why_rows(self.req) 

240 

241 self.assertEqual(ff_why_rows, expected_reasons) 

242 

243 def test_comments(self) -> None: 

244 expected_comments = ["comments_2", "comments_5", "comments_20"] 

245 

246 comments = self.report._get_comments(self.req) 

247 self.assertEqual(comments, expected_comments) 

248 

249 

250class APEQCPFTPerinatalReportDateRangeTests(APEQCPFTPerinatalReportTestCase): 

251 def setUp(self) -> None: 

252 super().setUp() 

253 

254 APEQCPFTPerinatalFactory( 

255 q1=1, 

256 q2=0, 

257 q3=0, 

258 q4=0, 

259 q5=0, 

260 q6=0, 

261 ff_rating=0, 

262 ff_why="ff why 1", 

263 comments="comments 1", 

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

265 ) 

266 APEQCPFTPerinatalFactory( 

267 q1=0, 

268 q2=0, 

269 q3=0, 

270 q4=0, 

271 q5=0, 

272 q6=0, 

273 ff_rating=2, 

274 ff_why="ff why 2", 

275 comments="comments 2", 

276 when_created=pendulum.parse("2018-10-02"), 

277 ) 

278 APEQCPFTPerinatalFactory( 

279 q1=0, 

280 q2=0, 

281 q3=0, 

282 q4=0, 

283 q5=0, 

284 q6=0, 

285 ff_rating=2, 

286 ff_why="ff why 3", 

287 comments="comments 3", 

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

289 ) 

290 APEQCPFTPerinatalFactory( 

291 q1=0, 

292 q2=0, 

293 q3=0, 

294 q4=0, 

295 q5=0, 

296 q6=0, 

297 ff_rating=2, 

298 ff_why="ff why 4", 

299 comments="comments 4", 

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

301 ) 

302 APEQCPFTPerinatalFactory( 

303 q1=1, 

304 q2=0, 

305 q3=0, 

306 q4=0, 

307 q5=0, 

308 q6=0, 

309 ff_rating=0, 

310 ff_why="ff why 5", 

311 comments="comments 5", 

312 when_created=pendulum.parse("2018-10-05"), 

313 ) 

314 

315 def test_main_rows_filtered_by_date(self) -> None: 

316 self.report.start_datetime = "2018-10-02T00:00:00.000000+00:00" 

317 self.report.end_datetime = "2018-10-05T00:00:00.000000+00:00" 

318 

319 rows = self.report._get_main_rows(self.req, cell_format="{0:.1f}%") 

320 q1_row = rows[0] 

321 

322 # There should be three tasks included in the calculation. 

323 self.assertEqual(q1_row[self.COL_TOTAL], 3) 

324 

325 # For question 1 all of them answered 0 so we would expect 

326 # 100%. If the results aren't being filtered we will get 

327 # 60% 

328 self.assertEqual(q1_row[self.COL_RESPONSE_START + 0], "100.0%") 

329 

330 def test_ff_rows_filtered_by_date(self) -> None: 

331 self.report.start_datetime = "2018-10-02T00:00:00.000000+00:00" 

332 self.report.end_datetime = "2018-10-05T00:00:00.000000+00:00" 

333 

334 rows = self.report._get_ff_rows(self.req, cell_format="{0:.1f}%") 

335 ff_row = rows[0] 

336 

337 # There should be three tasks included in the calculation. 

338 self.assertEqual(ff_row[self.COL_TOTAL], 3) 

339 

340 # For the ff question all of them answered 2 so we would expect 

341 # 100%. If the results aren't being filtered we will get 

342 # 60% 

343 self.assertEqual(ff_row[self.COL_RESPONSE_START + 2], "100.0%") 

344 

345 def test_ff_why_row_filtered_by_date(self) -> None: 

346 self.report.start_datetime = "2018-10-02T00:00:00.000000+00:00" 

347 self.report.end_datetime = "2018-10-05T00:00:00.000000+00:00" 

348 

349 rows = self.report._get_ff_why_rows(self.req) 

350 self.assertEqual(len(rows), 3) 

351 

352 self.assertEqual(rows[0][self.COL_FF_WHY], "ff why 2") 

353 self.assertEqual(rows[1][self.COL_FF_WHY], "ff why 3") 

354 self.assertEqual(rows[2][self.COL_FF_WHY], "ff why 4") 

355 

356 def test_comments_filtered_by_date(self) -> None: 

357 self.report.start_datetime = "2018-10-02T00:00:00.000000+00:00" 

358 self.report.end_datetime = "2018-10-05T00:00:00.000000+00:00" 

359 

360 comments = self.report._get_comments(self.req) 

361 self.assertEqual(len(comments), 3) 

362 

363 self.assertEqual(comments[0], "comments 2") 

364 self.assertEqual(comments[1], "comments 3") 

365 self.assertEqual(comments[2], "comments 4")