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
« prev ^ index » next coverage.py v6.5.0, created at 2022-11-08 23:14 +0000
1#!/usr/bin/env python
3"""
4camcops_server/tasks/tests/apeq_cpft_perinatal_tests.py
6===============================================================================
8 Copyright (C) 2012, University of Cambridge, Department of Psychiatry.
9 Created by Rudolf Cardinal (rnc1001@cam.ac.uk).
11 This file is part of CamCOPS.
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.
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.
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/>.
26===============================================================================
28"""
30from typing import Generator, Optional
32import pendulum
34from camcops_server.cc_modules.cc_unittest import BasicDatabaseTestCase
35from camcops_server.tasks.apeq_cpft_perinatal import (
36 APEQCPFTPerinatal,
37 APEQCPFTPerinatalReport,
38)
41# =============================================================================
42# Unit tests
43# =============================================================================
46class APEQCPFTPerinatalReportTestCase(BasicDatabaseTestCase):
47 COL_Q = 0
48 COL_TOTAL = 1
49 COL_RESPONSE_START = 2
51 COL_FF_WHY = 1
53 def __init__(self, *args, **kwargs) -> None:
54 super().__init__(*args, **kwargs)
55 self.id_sequence = self.get_id()
57 def setUp(self) -> None:
58 super().setUp()
60 self.report = APEQCPFTPerinatalReport()
62 # Really only needed for tests
63 self.report.start_datetime = None
64 self.report.end_datetime = None
66 @staticmethod
67 def get_id() -> Generator[int, None, None]:
68 i = 1
70 while True:
71 yield i
72 i += 1
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
100 if era is not None:
101 task.when_created = pendulum.parse(era)
103 self.dbsession.add(task)
106class APEQCPFTPerinatalReportTests(APEQCPFTPerinatalReportTestCase):
107 def create_tasks(self) -> None:
108 """
109 Creates 20 tasks.
110 Should give us:
112 .. code-block:: none
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%
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")
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")
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")
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")
164 self.dbsession.commit()
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 ]
176 main_rows = self.report._get_main_rows(self.req)
178 # MySQL does floating point division
179 for row, expected in zip(main_rows, expected_percentages):
180 percentages = []
182 for p in row[1:]:
183 if p != "":
184 p = int(float(p))
186 percentages.append(p)
188 self.assertEqual(percentages, expected)
190 def test_main_rows_formatted(self) -> None:
191 expected_q1 = [20, "50.0%", "25.0%", "25.0%"]
193 main_rows = self.report._get_main_rows(
194 self.req, cell_format="{0:.1f}%"
195 )
197 self.assertEqual(main_rows[0][1:], expected_q1)
199 def test_ff_rows_contain_percentages(self) -> None:
200 expected_ff = [20, 25, 10, 15, 10, 5, 35]
202 ff_rows = self.report._get_ff_rows(self.req)
204 # MySQL does floating point division
205 percentages = [int(float(p)) for p in ff_rows[0][1:]]
207 self.assertEqual(percentages, expected_ff)
209 def test_ff_rows_formatted(self) -> None:
210 expected_ff = [20, "25.0%", "10.0%", "15.0%", "10.0%", "5.0%", "35.0%"]
212 ff_rows = self.report._get_ff_rows(self.req, cell_format="{0:.1f}%")
214 self.assertEqual(ff_rows[0][1:], expected_ff)
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 ]
228 ff_why_rows = self.report._get_ff_why_rows(self.req)
230 self.assertEqual(ff_why_rows, expected_reasons)
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)
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()
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"
306 rows = self.report._get_main_rows(self.req, cell_format="{0:.1f}%")
307 q1_row = rows[0]
309 # There should be three tasks included in the calculation.
310 self.assertEqual(q1_row[self.COL_TOTAL], 3)
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%")
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"
321 rows = self.report._get_ff_rows(self.req, cell_format="{0:.1f}%")
322 ff_row = rows[0]
324 # There should be three tasks included in the calculation.
325 self.assertEqual(ff_row[self.COL_TOTAL], 3)
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%")
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"
336 rows = self.report._get_ff_why_rows(self.req)
337 self.assertEqual(len(rows), 3)
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")
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"
347 comments = self.report._get_comments(self.req)
348 self.assertEqual(len(comments), 3)
350 self.assertEqual(comments[0], "comments 2")
351 self.assertEqual(comments[1], "comments 3")
352 self.assertEqual(comments[2], "comments 4")