Coverage for tasks/tests/core10_tests.py: 26%

1"""

2 camcops_server/tasks/tests/core10_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

28 import pendulum

29

30 from camcops_server.cc_modules.cc_testfactories import (

31 PatientFactory,

32 UserFactory,

33)

34 from camcops_server.cc_modules.cc_unittest import DemoRequestTestCase

35 from camcops_server.tasks.core10 import Core10, Core10Report

36 from camcops_server.tasks.tests.factories import Core10Factory

37

38

39 class Core10ReportTestCase(DemoRequestTestCase):

40 def setUp(self) -> None:

41 super().setUp()

42

43 self.report = self.create_report()

44 self.req._debugging_user = UserFactory(superuser=True)

45

46 def create_report(self) -> Core10Report:

47 return Core10Report(via_index=False)

48

49

50 class Core10ReportTotalsTests(Core10ReportTestCase):

51 def setUp(self) -> None:

52 super().setUp()

53

54 patient_1 = PatientFactory()

55 patient_2 = PatientFactory()

56 patient_3 = PatientFactory()

57

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

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

60

61 Core10Factory(

62 patient=patient_1,

63 q1=4,

64 q2=4,

65 when_created=pendulum.parse("2018-06-01"),

66 ) # Score 8

67 Core10Factory(

68 patient=patient_1,

69 q7=1,

70 q8=1,

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

72 ) # Score 2

73

74 Core10Factory(

75 patient=patient_2,

76 q3=3,

77 q4=3,

78 when_created=pendulum.parse("2018-05-02"),

79 ) # Score 6

80 Core10Factory(

81 patient=patient_2,

82 q3=2,

83 q4=1,

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

85 ) # Score 3

86

87 Core10Factory(

88 patient=patient_3,

89 q5=2,

90 q6=2,

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

92 ) # Score 4

93 Core10Factory(

94 patient=patient_3,

95 q9=1,

96 q10=3,

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

98 ) # Score 4

99

100 def test_row_has_totals_and_averages(self) -> None:

101 pages = self.report.get_spreadsheet_pages(req=self.req)

102 expected_rows = [

103 [

104 3, # n initial

105 3, # n latest

106 6.0, # Initial average

107 3.0, # Latest average

108 3.0, # Average progress

109 ]

110 ]

111 self.assertEqual(pages[0].plainrows, expected_rows)

112

113

114 class Core10ReportEmptyTests(Core10ReportTestCase):

115 def test_no_rows_when_no_data(self) -> None:

116 pages = self.report.get_spreadsheet_pages(req=self.req)

117 no_data = self.report.no_data_value()

118 expected_rows = [[0, 0, no_data, no_data, no_data]]

119 self.assertEqual(pages[0].plainrows, expected_rows)

120

121

122 class Core10ReportDoubleCountingTests(Core10ReportTestCase):

123 def setUp(self) -> None:

124 super().setUp()

125

126 patient_1 = PatientFactory()

127 patient_2 = PatientFactory()

128 patient_3 = PatientFactory()

129

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

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

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

133

134 Core10Factory(

135 patient=patient_1,

136 q1=4,

137 q2=4,

138 when_created=pendulum.parse("2018-06-01"),

139 ) # Score 8

140

141 Core10Factory(

142 patient=patient_2,

143 q3=3,

144 q4=3,

145 when_created=pendulum.parse("2018-05-02"),

146 ) # Score 6

147 Core10Factory(

148 patient=patient_2,

149 q3=2,

150 q4=1,

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

152 ) # Score 3

153

154 Core10Factory(

155 patient=patient_3,

156 q5=2,

157 q6=2,

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

159 ) # Score 4

160 Core10Factory(

161 patient=patient_3,

162 q9=1,

163 q10=2,

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

165 ) # Score 3

166

167 def test_record_does_not_appear_in_first_and_latest(self) -> None:

168 pages = self.report.get_spreadsheet_pages(req=self.req)

169 expected_rows = [

170 [

171 3, # n initial

172 2, # n latest

173 6.0, # Initial average

174 3.0, # Latest average

175 2.0, # Average progress

176 ]

177 ]

178 self.assertEqual(pages[0].plainrows, expected_rows)

179

180

181 class Core10ReportDateRangeTests(Core10ReportTestCase):

182 """

183 Test code:

184

185 .. code-block:: sql

186

187 -- 2019-10-21

188 -- For SQLite:

189

190 CREATE TABLE core10

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

192

193 .schema core10

194

195 INSERT INTO core10

196 (_pk,patient_id,when_created,_current)

197 VALUES

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

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

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

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

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

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

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

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

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

207

208 SELECT * from core10;

209

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

211 -- ... gives e.g.

212 -- 2018-06-01 00:00:00.000

213

214 SELECT *

215 FROM core10

216 WHERE core10._current = 1

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

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

219

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

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

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

223

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

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

226

227 See

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

229

230 """ # noqa

231

232 def setUp(self) -> None:

233 super().setUp()

234

235 patient_1 = PatientFactory()

236 patient_2 = PatientFactory()

237 patient_3 = PatientFactory()

238

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

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

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

242

243 Core10Factory(

244 patient=patient_1,

245 q1=4,

246 q2=4,

247 when_created=pendulum.parse("2018-06-01"),

248 ) # Score 8

249 Core10Factory(

250 patient=patient_1,

251 q7=3,

252 q8=1,

253 when_created=pendulum.parse("2018-08-01"),

254 ) # Score 4

255 Core10Factory(

256 patient=patient_1,

257 q7=1,

258 q8=1,

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

260 ) # Score 2

261

262 Core10Factory(

263 patient=patient_2,

264 q3=3,

265 q4=3,

266 when_created=pendulum.parse("2018-06-01"),

267 ) # Score 6

268 Core10Factory(

269 patient=patient_2,

270 q3=2,

271 q4=2,

272 when_created=pendulum.parse("2018-08-01"),

273 ) # Score 4

274 Core10Factory(

275 patient=patient_2,

276 q3=1,

277 q4=2,

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

279 ) # Score 3

280

281 Core10Factory(

282 patient=patient_3,

283 q5=2,

284 q6=2,

285 when_created=pendulum.parse("2018-06-01"),

286 ) # Score 4

287 Core10Factory(

288 patient=patient_3,

289 q9=1,

290 q10=3,

291 when_created=pendulum.parse("2018-08-01"),

292 ) # Score 4

293 Core10Factory(

294 patient=patient_3,

295 q9=1,

296 q10=3,

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

298 ) # Score 4

299

300 self.dump_table(

301 Core10.__tablename__,

302 ["_pk", "patient_id", "when_created", "_current"],

303 )

304

305 def test_report_filtered_by_date_range(self) -> None:

306 self.report.start_datetime = "2018-06-01T00:00:00.000000+00:00"

307 self.report.end_datetime = "2018-09-01T00:00:00.000000+00:00"

308

309 self.set_echo(True)

310 pages = self.report.get_spreadsheet_pages(req=self.req)

311 self.set_echo(False)

312 expected_rows = [

313 [

314 3, # n initial

315 3, # n latest

316 6.0, # Initial average

317 4.0, # Latest average

318 2.0, # Average progress

319 ]

320 ]

321 self.assertEqual(pages[0].plainrows, expected_rows)