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
« 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
4===============================================================================
6 Copyright (C) 2012, University of Cambridge, Department of Psychiatry.
7 Created by Rudolf Cardinal (rnc1001@cam.ac.uk).
9 This file is part of CamCOPS.
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.
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.
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/>.
24===============================================================================
26"""
28import pendulum
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
36# =============================================================================
37# Unit tests
38# =============================================================================
41class APEQCPFTPerinatalReportTestCase(DemoRequestTestCase):
42 COL_Q = 0
43 COL_TOTAL = 1
44 COL_RESPONSE_START = 2
46 COL_FF_WHY = 1
48 def setUp(self) -> None:
49 super().setUp()
51 self.report = APEQCPFTPerinatalReport()
53 # Really only needed for tests
54 self.report.start_datetime = None
55 self.report.end_datetime = None
58class APEQCPFTPerinatalReportTests(APEQCPFTPerinatalReportTestCase):
59 def setUp(self) -> None:
60 """
61 Creates 20 tasks.
62 Should give us:
64 .. code-block:: none
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%
88 """
89 super().setUp()
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 )
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 )
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 )
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 )
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 ]
187 main_rows = self.report._get_main_rows(self.req)
189 # MySQL does floating point division
190 for row, expected in zip(main_rows, expected_percentages):
191 percentages = []
193 for p in row[1:]:
194 if p != "":
195 p = str(int(float(p)))
197 percentages.append(p)
199 self.assertEqual(percentages, expected)
201 def test_main_rows_formatted(self) -> None:
202 expected_q1 = [20, "50.0%", "25.0%", "25.0%"]
204 main_rows = self.report._get_main_rows(
205 self.req, cell_format="{0:.1f}%"
206 )
208 self.assertEqual(main_rows[0][1:], expected_q1)
210 def test_ff_rows_contain_percentages(self) -> None:
211 expected_ff = [20, 25, 10, 15, 10, 5, 35]
213 ff_rows = self.report._get_ff_rows(self.req)
215 # MySQL does floating point division
216 percentages = [int(float(p)) for p in ff_rows[0][1:]]
218 self.assertEqual(percentages, expected_ff)
220 def test_ff_rows_formatted(self) -> None:
221 expected_ff = [20, "25.0%", "10.0%", "15.0%", "10.0%", "5.0%", "35.0%"]
223 ff_rows = self.report._get_ff_rows(self.req, cell_format="{0:.1f}%")
225 self.assertEqual(ff_rows[0][1:], expected_ff)
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 ]
239 ff_why_rows = self.report._get_ff_why_rows(self.req)
241 self.assertEqual(ff_why_rows, expected_reasons)
243 def test_comments(self) -> None:
244 expected_comments = ["comments_2", "comments_5", "comments_20"]
246 comments = self.report._get_comments(self.req)
247 self.assertEqual(comments, expected_comments)
250class APEQCPFTPerinatalReportDateRangeTests(APEQCPFTPerinatalReportTestCase):
251 def setUp(self) -> None:
252 super().setUp()
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 )
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"
319 rows = self.report._get_main_rows(self.req, cell_format="{0:.1f}%")
320 q1_row = rows[0]
322 # There should be three tasks included in the calculation.
323 self.assertEqual(q1_row[self.COL_TOTAL], 3)
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%")
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"
334 rows = self.report._get_ff_rows(self.req, cell_format="{0:.1f}%")
335 ff_row = rows[0]
337 # There should be three tasks included in the calculation.
338 self.assertEqual(ff_row[self.COL_TOTAL], 3)
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%")
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"
349 rows = self.report._get_ff_why_rows(self.req)
350 self.assertEqual(len(rows), 3)
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")
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"
360 comments = self.report._get_comments(self.req)
361 self.assertEqual(len(comments), 3)
363 self.assertEqual(comments[0], "comments 2")
364 self.assertEqual(comments[1], "comments 3")
365 self.assertEqual(comments[2], "comments 4")