Hide keyboard shortcuts

Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1#!/usr/bin/env python 

2 

3""" 

4camcops_server/tasks/tests/core10_tests.py 

5 

6=============================================================================== 

7 

8 Copyright (C) 2012-2020 Rudolf Cardinal (rudolf@pobox.com). 

9 

10 This file is part of CamCOPS. 

11 

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

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

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

15 (at your option) any later version. 

16 

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

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

19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

20 GNU General Public License for more details. 

21 

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

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

24 

25=============================================================================== 

26 

27""" 

28 

29import pendulum 

30from camcops_server.cc_modules.cc_patient import Patient 

31from camcops_server.tasks.core10 import Core10, Core10Report 

32 

33from camcops_server.cc_modules.tests.cc_report_tests import ( 

34 AverageScoreReportTestCase 

35) 

36 

37 

38class Core10ReportTestCase(AverageScoreReportTestCase): 

39 def create_report(self) -> Core10Report: 

40 return Core10Report(via_index=False) 

41 

42 def create_task(self, patient: Patient, 

43 q1: int = 0, q2: int = 0, q3: int = 0, q4: int = 0, 

44 q5: int = 0, q6: int = 0, q7: int = 0, q8: int = 0, 

45 q9: int = 0, q10: int = 0, era: str = None) -> None: 

46 task = Core10() 

47 self.apply_standard_task_fields(task) 

48 task.id = next(self.task_id_sequence) 

49 

50 task.patient_id = patient.id 

51 

52 task.q1 = q1 

53 task.q2 = q2 

54 task.q3 = q3 

55 task.q4 = q4 

56 task.q5 = q5 

57 task.q6 = q6 

58 task.q7 = q7 

59 task.q8 = q8 

60 task.q9 = q9 

61 task.q10 = q10 

62 

63 if era is not None: 

64 task.when_created = pendulum.parse(era) 

65 # log.info(f"Creating task, when_created = {task.when_created}") 

66 

67 self.dbsession.add(task) 

68 

69 

70class Core10ReportTests(Core10ReportTestCase): 

71 def create_tasks(self) -> None: 

72 self.patient_1 = self.create_patient(idnum_value=333) 

73 self.patient_2 = self.create_patient(idnum_value=444) 

74 self.patient_3 = self.create_patient(idnum_value=555) 

75 

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

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

78 

79 self.create_task(patient=self.patient_1, q1=4, q2=4, 

80 era="2018-06-01") # Score 8 

81 self.create_task(patient=self.patient_1, q7=1, q8=1, 

82 era="2018-10-04") # Score 2 

83 

84 self.create_task(patient=self.patient_2, q3=3, q4=3, 

85 era="2018-05-02") # Score 6 

86 self.create_task(patient=self.patient_2, q3=2, q4=1, 

87 era="2018-10-03") # Score 3 

88 

89 self.create_task(patient=self.patient_3, q5=2, q6=2, 

90 era="2018-01-10") # Score 4 

91 self.create_task(patient=self.patient_3, q9=1, q10=3, 

92 era="2018-10-01") # Score 4 

93 self.dbsession.commit() 

94 

95 def test_row_has_totals_and_averages(self) -> None: 

96 tsv_pages = self.report.get_tsv_pages(req=self.req) 

97 # log.info(f"\n{tsv_pages[0]}") 

98 # log.info(f"\n{tsv_pages[1]}") 

99 expected_rows = [ 

100 [ 

101 3, # n initial 

102 3, # n latest 

103 6.0, # Initial average 

104 3.0, # Latest average 

105 3.0, # Average progress 

106 ] 

107 ] 

108 self.assertEqual(tsv_pages[0].plainrows, expected_rows) 

109 

110 

111class Core10ReportEmptyTests(Core10ReportTestCase): 

112 def test_no_rows_when_no_data(self) -> None: 

113 tsv_pages = self.report.get_tsv_pages(req=self.req) 

114 no_data = self.report.no_data_value() 

115 expected_rows = [ 

116 [ 

117 0, 0, no_data, no_data, no_data, 

118 ] 

119 ] 

120 self.assertEqual(tsv_pages[0].plainrows, expected_rows) 

121 

122 

123class Core10ReportDoubleCountingTests(Core10ReportTestCase): 

124 def create_tasks(self) -> None: 

125 self.patient_1 = self.create_patient(idnum_value=333) 

126 self.patient_2 = self.create_patient(idnum_value=444) 

127 self.patient_3 = self.create_patient(idnum_value=555) 

128 

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

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

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

132 self.create_task(patient=self.patient_1, q1=4, q2=4, 

133 era="2018-06-01") # Score 8 

134 

135 self.create_task(patient=self.patient_2, q3=3, q4=3, 

136 era="2018-05-02") # Score 6 

137 self.create_task(patient=self.patient_2, q3=2, q4=1, 

138 era="2018-10-03") # Score 3 

139 

140 self.create_task(patient=self.patient_3, q5=2, q6=2, 

141 era="2018-01-10") # Score 4 

142 self.create_task(patient=self.patient_3, q9=1, q10=2, 

143 era="2018-10-01") # Score 3 

144 self.dbsession.commit() 

145 

146 def test_record_does_not_appear_in_first_and_latest(self) -> None: 

147 tsv_pages = self.report.get_tsv_pages(req=self.req) 

148 expected_rows = [ 

149 [ 

150 3, # n initial 

151 2, # n latest 

152 6.0, # Initial average 

153 3.0, # Latest average 

154 2.0, # Average progress 

155 ] 

156 ] 

157 self.assertEqual(tsv_pages[0].plainrows, expected_rows) 

158 

159 

160class Core10ReportDateRangeTests(Core10ReportTestCase): 

161 """ 

162 Test code: 

163 

164 .. code-block:: sql 

165 

166 -- 2019-10-21 

167 -- For SQLite: 

168 

169 CREATE TABLE core10 

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

171 

172 .schema core10 

173 

174 INSERT INTO core10 

175 (_pk,patient_id,when_created,_current) 

176 VALUES 

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

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

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

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

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

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

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

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

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

186 

187 SELECT * from core10; 

188 

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

190 -- ... gives e.g. 

191 -- 2018-06-01 00:00:00.000 

192 

193 SELECT * 

194 FROM core10 

195 WHERE core10._current = 1 

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

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

198 

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

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

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

202 

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

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

205 

206 See 

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

208 

209 """ # noqa 

210 

211 def create_tasks(self) -> None: 

212 self.patient_1 = self.create_patient(idnum_value=333) 

213 self.patient_2 = self.create_patient(idnum_value=444) 

214 self.patient_3 = self.create_patient(idnum_value=555) 

215 

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

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

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

219 

220 self.create_task(patient=self.patient_1, q1=4, q2=4, 

221 era="2018-06-01") # Score 8 

222 self.create_task(patient=self.patient_1, q7=3, q8=1, 

223 era="2018-08-01") # Score 4 

224 self.create_task(patient=self.patient_1, q7=1, q8=1, 

225 era="2018-10-01") # Score 2 

226 

227 self.create_task(patient=self.patient_2, q3=3, q4=3, 

228 era="2018-06-01") # Score 6 

229 self.create_task(patient=self.patient_2, q3=2, q4=2, 

230 era="2018-08-01") # Score 4 

231 self.create_task(patient=self.patient_2, q3=1, q4=2, 

232 era="2018-10-01") # Score 3 

233 

234 self.create_task(patient=self.patient_3, q5=2, q6=2, 

235 era="2018-06-01") # Score 4 

236 self.create_task(patient=self.patient_3, q9=1, q10=3, 

237 era="2018-08-01") # Score 4 

238 self.create_task(patient=self.patient_3, q9=1, q10=3, 

239 era="2018-10-01") # Score 4 

240 self.dbsession.commit() 

241 

242 self.dump_table(Core10.__tablename__, [ 

243 "_pk", "patient_id", "when_created", "_current", 

244 ]) 

245 

246 def test_report_filtered_by_date_range(self) -> None: 

247 # self.report.start_datetime = pendulum.parse("2018-05-01T00:00:00.000000+00:00") # noqa 

248 self.report.start_datetime = pendulum.parse("2018-06-01T00:00:00.000000+00:00") # noqa 

249 self.report.end_datetime = pendulum.parse("2018-09-01T00:00:00.000000+00:00") # noqa 

250 

251 self.set_echo(True) 

252 tsv_pages = self.report.get_tsv_pages(req=self.req) 

253 self.set_echo(False) 

254 expected_rows = [ 

255 [ 

256 3, # n initial 

257 3, # n latest 

258 6.0, # Initial average 

259 4.0, # Latest average 

260 2.0, # Average progress 

261 ] 

262 ] 

263 self.assertEqual(tsv_pages[0].plainrows, expected_rows)