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"""The start-up functions for batches of tests. 

2 

3We have divided the tests in batches. 

4Each batch is a separate file. 

5 

6The batches can be run alltogether in sequential order, 

7or they can be run individually. 

8 

9The `start` function achieves that when a batch is run as part of a bigger sequence, 

10the initial situation for the batch is the right one. 

11And also, if the batch is run individually, that it starts with exactly the same 

12state. 

13 

14## Clean slate 

15 

16The base line is clean database, i.e. a database with 

17all the value tables fully filled, with a set of test users, 

18with packages, criteria, and types, but not with user-contributed content, 

19such as contributions, assessments, and reviews. 

20 

21This is the *clean slate*. 

22 

23The starter functions may insert a few records in the database and fetch 

24a few value tables for usage in test functions. 

25""" 

26 

27from control.utils import pick as G 

28from example import ( 

29 ASSESS, 

30 COMMENTS, 

31 COMPLETE, 

32 CONTRIB, 

33 CRITERIA_ENTRY, 

34 CRITERIA_ENTRIES_N, 

35 COUNTRY, 

36 ELLIPS_DIV, 

37 EVIDENCE, 

38 EXPERT, 

39 FINAL, 

40 REVIEW, 

41 REVIEW_ENTRY, 

42 REVIEWER_E, 

43 REVIEWER_F, 

44 SCORE, 

45 START_ASSESSMENT, 

46 START_REVIEW, 

47 SUBMIT_ASSESSMENT, 

48 TYPE, 

49 TYPE1, 

50 TYPE2, 

51 USER, 

52) 

53from helpers import ( 

54 findDetails, 

55 findValues, 

56 getItem, 

57 getReviewEntryId, 

58 getScores, 

59) 

60from subtest import ( 

61 assertAddItem, 

62 assertEditor, 

63 assertModifyField, 

64 assertStage, 

65 assertStartTask, 

66 assertStatus, 

67) 

68 

69 

70def getValueTable(cl, table): 

71 """Get a mapping of values in a value table to their object ids. 

72 

73 We look directly in the list of items of a valueTable. 

74 

75 The mapping is stored in the dict `dest` keyed by the 

76 name of the valueTable. 

77 

78 Parameters 

79 ---------- 

80 table: string 

81 The name of a value table 

82 

83 Returns 

84 ------- 

85 dict 

86 The stored value dict for this valueTable 

87 """ 

88 

89 response = cl.get(f"/{table}/list") 

90 text = response.get_data(as_text=True) 

91 return findValues(table, text) 

92 

93 

94def makeItem(cl, table, cId=None, aId=None): 

95 """Makes a contribution/assessment/review. 

96 

97 Parameters 

98 ---------- 

99 cl: fixture 

100 table: string 

101 Either `contrib` or `assessment` or `review` 

102 cId: string(ObjectId), optional `None` 

103 If we make an assessment, the id of the contribution for which it is an 

104 assessment 

105 aId: string(ObjectId), optional `None` 

106 If we make a review, the id of the assessment for which it is a 

107 review 

108 

109 Returns 

110 ------- 

111 eid: string(ObjectId) 

112 the id of the contribution/assessment 

113 """ 

114 

115 if table == CONTRIB: 

116 return assertAddItem(cl, table, True) 

117 if table == ASSESS: 

118 return assertStartTask(cl, START_ASSESSMENT, cId, True) 

119 if table == REVIEW: 119 ↛ exitline 119 didn't return from function 'makeItem', because the condition on line 119 was never false

120 return assertStartTask(cl, START_REVIEW, aId, True) 

121 

122 

123def start( 

124 clientOffice=None, 

125 clientOwner=None, 

126 clientExpert=None, 

127 clientFinal=None, 

128 users=False, 

129 types=False, 

130 countries=False, 

131 contrib=False, 

132 assessment=False, 

133 fillout=False, 

134 submit=False, 

135 assign=False, 

136 review=False, 

137): 

138 """The start sequence for a batch of tests. 

139 

140 The first step is to start with a clean slate inth database: 

141 Only the value records, no user-contributed content. 

142 

143 It depends on the batch what we have to make on top of that.. 

144 

145 The result is always that certain records in the database are retrieved, 

146 of if they do not exist, created. 

147 

148 Records with user added content are stored in the dict `recordId`, 

149 under the name of the table as key. 

150 

151 Records in value tables are stored in the dict `valueTables`, 

152 under the name of the table as key. 

153 

154 !!! hint "Dependencies of parameters" 

155 Some things are dependent on others, for example, making an assessment 

156 presupposes that there is a contribution. 

157 The function will switch on all parameters that are implied before 

158 creating or finding stuff. 

159 

160 Parameters 

161 ---------- 

162 clientOffice, clientOwner: fixture 

163 users: boolean, optional `False` 

164 Whether to fetch the list of users 

165 types: boolean, optional `False` 

166 Whether to fetch the list of contribution types 

167 countries: boolean, optional `False` 

168 Whether to fetch the list of countries 

169 contrib: boolean, optional `False` 

170 Whether to find or make a contribution 

171 assessment: boolean, optional `False` 

172 Whether to find or make an assessment 

173 fillout: boolean, optional `False` 

174 Whether to fill out the criteria entries 

175 submit: boolean, optional `False` 

176 Whether to submit the completed assessment 

177 assign: boolean, optional `False` 

178 Whether to assign reviewers 

179 review: boolean, optional `False` 

180 Whether to start and fillout both reviews 

181 

182 Returns 

183 ------- 

184 valueTables: dict, optional `None` 

185 Where the retrieved data for the value tables end up 

186 recordId: dict, optional `None` 

187 Where the retrieved ids for the records end up 

188 ids: dict, optional `None` 

189 A resulting mapping between values in a value table and their corresponding ids 

190 """ 

191 

192 if review: 

193 assign = True 

194 if assign: 

195 submit = True 

196 if submit: 

197 fillout = True 

198 if fillout: 

199 assessment = True 

200 if assessment: 

201 contrib = True 

202 types = True 

203 if contrib: 

204 users = True 

205 

206 valueTables = {} 

207 recordId = {} 

208 recordInfo = {} 

209 ids = {} 

210 

211 def startReviews(): 

212 aId = recordId[ASSESS] 

213 cIds = recordId[CRITERIA_ENTRY] 

214 

215 recordId.setdefault(REVIEW, {}) 

216 clr = {EXPERT: clientExpert, FINAL: clientFinal} 

217 

218 for (user, cl) in clr.items(): 

219 rId = makeItem(cl, REVIEW, aId=aId) 

220 recordId[REVIEW][user] = rId 

221 

222 for (user, cl) in clr.items(): 

223 rId = recordId[REVIEW][user] 

224 for (i, cId) in enumerate(cIds): 

225 rEId = recordId[REVIEW][EXPERT] 

226 rFId = recordId[REVIEW][FINAL] 

227 reId = getReviewEntryId(clr, cId, rEId, rFId) 

228 reId = reId[user] 

229 newValue = [f"{user}'s comment on criteria {i + 1}"] 

230 newValueRep = ",".join(newValue) 

231 assertModifyField( 

232 cl, REVIEW_ENTRY, reId, COMMENTS, (newValue, newValueRep), True 

233 ) 

234 

235 def startAssign(): 

236 aId = recordId[ASSESS] 

237 users = G(valueTables, USER) 

238 for (field, user) in ((REVIEWER_E, EXPERT), (REVIEWER_F, FINAL)): 

239 value = G(users, user) 

240 assertModifyField(clientOffice, ASSESS, aId, field, (value, user), True) 

241 

242 if review: 

243 startReviews() 

244 

245 def startSubmit(): 

246 aId = recordId[ASSESS] 

247 url = f"/api/task/{SUBMIT_ASSESSMENT}/{aId}" 

248 assertStatus(clientOwner, url, True) 

249 

250 if assign: 250 ↛ exitline 250 didn't return from function 'startSubmit', because the condition on line 250 was never false

251 startAssign() 

252 

253 def startFillout(): 

254 aId = recordId[ASSESS] 

255 assessInfo = getItem(clientOwner, ASSESS, aId) 

256 criteriaEntries = findDetails(assessInfo["text"], CRITERIA_ENTRY) 

257 nCId = len(criteriaEntries) 

258 assert nCId == CRITERIA_ENTRIES_N[TYPE1] 

259 cIds = [] 

260 

261 for (i, (cId, material)) in enumerate(criteriaEntries): 

262 cIds.append(cId) 

263 assert ELLIPS_DIV in material 

264 scores = getScores(cId) 

265 (scoreValue, scoreId) = sorted(scores.items())[1] 

266 assertModifyField( 

267 clientOwner, CRITERIA_ENTRY, cId, SCORE, (scoreId, scoreValue), True, 

268 ) 

269 theEvidence = [f"evidence for {i + 1}", "see the internet"] 

270 theEvidenceRep = ",".join(theEvidence) 

271 assertModifyField( 

272 clientOwner, 

273 CRITERIA_ENTRY, 

274 cId, 

275 EVIDENCE, 

276 (theEvidence, theEvidenceRep), 

277 True, 

278 ) 

279 recordId[CRITERIA_ENTRY] = cIds 

280 

281 assertStage(clientOwner, ASSESS, aId, COMPLETE) 

282 

283 if submit: 283 ↛ exitline 283 didn't return from function 'startFillout', because the condition on line 283 was never false

284 startSubmit() 

285 

286 def startAssessment(): 

287 eid = recordId[CONTRIB] 

288 assertModifyField( 

289 clientOwner, CONTRIB, eid, TYPE, (ids["TYPE1"], TYPE1), True, 

290 ) 

291 aId = makeItem(clientOwner, ASSESS, cId=eid) 

292 recordId[ASSESS] = aId 

293 assertEditor(clientOwner, ASSESS, aId, valueTables, True) 

294 

295 if fillout: 

296 startFillout() 

297 

298 def startContrib(): 

299 eid = makeItem(clientOwner, CONTRIB) 

300 recordId[CONTRIB] = eid 

301 assertEditor(clientOwner, CONTRIB, eid, valueTables, True) 

302 

303 if assessment: 

304 startAssessment() 

305 

306 if users: 

307 valueTables[USER] = getValueTable(clientOffice, USER) 

308 

309 if countries: 

310 valueTables[COUNTRY] = getValueTable(clientOffice, COUNTRY) 

311 

312 if types: 

313 typeValues = getValueTable(clientOffice, TYPE) 

314 ids["TYPE1"] = typeValues[TYPE1] 

315 ids["TYPE2"] = typeValues[TYPE2] 

316 valueTables[TYPE] = typeValues 

317 

318 if contrib: 

319 startContrib() 

320 

321 return dict( 

322 valueTables=valueTables, recordId=recordId, recordInfo=recordInfo, ids=ids 

323 )