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

131 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/apeq_cpft_perinatal_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 

30from typing import Generator, Optional 

31 

32import pendulum 

33 

34from camcops_server.cc_modules.cc_unittest import BasicDatabaseTestCase 

35from camcops_server.tasks.apeq_cpft_perinatal import ( 

36 APEQCPFTPerinatal, 

37 APEQCPFTPerinatalReport, 

38) 

39 

40 

41# ============================================================================= 

42# Unit tests 

43# ============================================================================= 

44 

45 

46class APEQCPFTPerinatalReportTestCase(BasicDatabaseTestCase): 

47 COL_Q = 0 

48 COL_TOTAL = 1 

49 COL_RESPONSE_START = 2 

50 

51 COL_FF_WHY = 1 

52 

53 def __init__(self, *args, **kwargs) -> None: 

54 super().__init__(*args, **kwargs) 

55 self.id_sequence = self.get_id() 

56 

57 def setUp(self) -> None: 

58 super().setUp() 

59 

60 self.report = APEQCPFTPerinatalReport() 

61 

62 # Really only needed for tests 

63 self.report.start_datetime = None 

64 self.report.end_datetime = None 

65 

66 @staticmethod 

67 def get_id() -> Generator[int, None, None]: 

68 i = 1 

69 

70 while True: 

71 yield i 

72 i += 1 

73 

74 def create_task( 

75 self, 

76 q1: Optional[int], 

77 q2: Optional[int], 

78 q3: Optional[int], 

79 q4: Optional[int], 

80 q5: Optional[int], 

81 q6: Optional[int], 

82 ff_rating: int, 

83 ff_why: str = None, 

84 comments: str = None, 

85 era: str = None, 

86 ) -> None: 

87 task = APEQCPFTPerinatal() 

88 self.apply_standard_task_fields(task) 

89 task.id = next(self.id_sequence) 

90 task.q1 = q1 

91 task.q2 = q2 

92 task.q3 = q3 

93 task.q4 = q4 

94 task.q5 = q5 

95 task.q6 = q6 

96 task.ff_rating = ff_rating 

97 task.ff_why = ff_why 

98 task.comments = comments 

99 

100 if era is not None: 

101 task.when_created = pendulum.parse(era) 

102 

103 self.dbsession.add(task) 

104 

105 

106class APEQCPFTPerinatalReportTests(APEQCPFTPerinatalReportTestCase): 

107 def create_tasks(self) -> None: 

108 """ 

109 Creates 20 tasks. 

110 Should give us: 

111 

112 .. code-block:: none 

113 

114 q1: 0 - 50%, 

115 1 - 25% 

116 2 - 25% 

117 q2: 1 - 100% 

118 q3: 0 - 5% 

119 1 - 20% 

120 2 - 75% 

121 q4: 0 - 10% 

122 1 - 40% 

123 2 - 50% 

124 q5: 0 - 15% 

125 1 - 55% 

126 2 - 30% 

127 q6: 1 - 50% 

128 2 - 50% 

129 ff: 0 - 25% 

130 1 - 10% 

131 2 - 15% 

132 3 - 10% 

133 4 - 5% 

134 5 - 35% 

135 

136 """ 

137 # q1 q2 q3 q4 q5 q6 ff 

138 self.create_task(0, 1, 0, 0, 2, 2, 5, ff_why="ff_5_1") 

139 self.create_task( 

140 0, 1, 1, 0, 2, 2, 5, ff_why="ff_5_2", comments="comments_2" 

141 ) 

142 self.create_task(0, 1, 1, 1, 2, 2, 5) 

143 self.create_task(0, 1, 1, 1, 2, 2, 5) 

144 self.create_task(0, 1, 1, 1, 2, 2, 5, comments="comments_5") 

145 

146 self.create_task(0, 1, 2, 1, 2, 2, 5) 

147 self.create_task(0, 1, 2, 1, 1, 2, 5) 

148 self.create_task(0, 1, 2, 1, 1, 2, 4, ff_why="ff_4_1") 

149 self.create_task(0, 1, 2, 1, 1, 2, 3) 

150 self.create_task(0, 1, 2, 1, 1, 1, 3, ff_why="ff_3_1") 

151 

152 self.create_task(1, 1, 2, 2, 1, 1, 2, ff_why="ff_2_1") 

153 self.create_task(1, 1, 2, 2, 1, 1, 2) 

154 self.create_task(1, 1, 2, 2, 1, 1, 2, ff_why="ff_2_2") 

155 self.create_task(1, 1, 2, 2, 1, 1, 1, ff_why="ff_1_1") 

156 self.create_task(1, 1, 2, 2, 1, 1, 1, ff_why="ff_1_2") 

157 

158 self.create_task(2, 1, 2, 2, 1, 1, 0) 

159 self.create_task(2, 1, 2, 2, 1, 1, 0) 

160 self.create_task(2, 1, 2, 2, 0, None, 0) 

161 self.create_task(2, 1, 2, 2, 0, None, 0) 

162 self.create_task(2, 1, 2, 2, 0, 1, 0, comments="comments_20") 

163 

164 self.dbsession.commit() 

165 

166 def test_main_rows_contain_percentages(self) -> None: 

167 expected_percentages = [ 

168 [20, 50, 25, 25], # q1 

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

170 [20, 5, 20, 75], # q3 

171 [20, 10, 40, 50], # q4 

172 [20, 15, 55, 30], # q5 

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

174 ] 

175 

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

177 

178 # MySQL does floating point division 

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

180 percentages = [] 

181 

182 for p in row[1:]: 

183 if p != "": 

184 p = int(float(p)) 

185 

186 percentages.append(p) 

187 

188 self.assertEqual(percentages, expected) 

189 

190 def test_main_rows_formatted(self) -> None: 

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

192 

193 main_rows = self.report._get_main_rows( 

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

195 ) 

196 

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

198 

199 def test_ff_rows_contain_percentages(self) -> None: 

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

201 

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

203 

204 # MySQL does floating point division 

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

206 

207 self.assertEqual(percentages, expected_ff) 

208 

209 def test_ff_rows_formatted(self) -> None: 

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

211 

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

213 

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

215 

216 def test_ff_why_rows_contain_reasons(self) -> None: 

217 expected_reasons = [ 

218 ["Extremely unlikely", "ff_1_1"], 

219 ["Extremely unlikely", "ff_1_2"], 

220 ["Unlikely", "ff_2_1"], 

221 ["Unlikely", "ff_2_2"], 

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

223 ["Likely", "ff_4_1"], 

224 ["Extremely likely", "ff_5_1"], 

225 ["Extremely likely", "ff_5_2"], 

226 ] 

227 

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

229 

230 self.assertEqual(ff_why_rows, expected_reasons) 

231 

232 def test_comments(self) -> None: 

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

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

235 self.assertEqual(comments, expected_comments) 

236 

237 

238class APEQCPFTPerinatalReportDateRangeTests(APEQCPFTPerinatalReportTestCase): 

239 def create_tasks(self) -> None: 

240 self.create_task( 

241 1, 

242 0, 

243 0, 

244 0, 

245 0, 

246 0, 

247 0, 

248 ff_why="ff why 1", 

249 comments="comments 1", 

250 era="2018-10-01T00:00:00.000000+00:00", 

251 ) 

252 self.create_task( 

253 0, 

254 0, 

255 0, 

256 0, 

257 0, 

258 0, 

259 2, 

260 ff_why="ff why 2", 

261 comments="comments 2", 

262 era="2018-10-02T00:00:00.000000+00:00", 

263 ) 

264 self.create_task( 

265 0, 

266 0, 

267 0, 

268 0, 

269 0, 

270 0, 

271 2, 

272 ff_why="ff why 3", 

273 comments="comments 3", 

274 era="2018-10-03T00:00:00.000000+00:00", 

275 ) 

276 self.create_task( 

277 0, 

278 0, 

279 0, 

280 0, 

281 0, 

282 0, 

283 2, 

284 ff_why="ff why 4", 

285 comments="comments 4", 

286 era="2018-10-04T00:00:00.000000+00:00", 

287 ) 

288 self.create_task( 

289 1, 

290 0, 

291 0, 

292 0, 

293 0, 

294 0, 

295 0, 

296 ff_why="ff why 5", 

297 comments="comments 5", 

298 era="2018-10-05T00:00:00.000000+00:00", 

299 ) 

300 self.dbsession.commit() 

301 

302 def test_main_rows_filtered_by_date(self) -> None: 

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

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

305 

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

307 q1_row = rows[0] 

308 

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

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

311 

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

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

314 # 60% 

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

316 

317 def test_ff_rows_filtered_by_date(self) -> None: 

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

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

320 

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

322 ff_row = rows[0] 

323 

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

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

326 

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

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

329 # 60% 

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

331 

332 def test_ff_why_row_filtered_by_date(self) -> None: 

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

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

335 

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

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

338 

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

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

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

342 

343 def test_comments_filtered_by_date(self) -> None: 

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

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

346 

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

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

349 

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

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

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