Coverage for tests/test_40_assess30.py : 100%

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"""Test scenario for assessments.
3## Domain
5* Users as in `conftest`, under *players*
6* Clean slate, see `starters`.
7* The user table
8* The country table
9* One contribution record
10* One assessment record
12## Acts
14Filling out an assessment.
16`test_criteriaEntries`
17: All users try to see the criteria entries.
18 Only **owner**, **editor** and the power users succeed.
20`test_fillEvidenceAll`
21: All users try to fill out the evidence for the first entry.
22 Only some users succeed.
24`test_fillEvidenceOwner`
25: **owner** fills out the evidence for all entries.
27`test_fillScore`
28: **owner** tries to fill out a score.
30`test_fillScoreWrong`
31: **owner** tries to fill out a score that belongs to another criterion.
33 !!! note "Not tested before"
34 This is the first time that we use a value table where the possible
35 values are constrained by another constraint:
37 Only those scores are eligible that have the same `criteria` master as
38 the `criteriaEntry` record.
40`test_submitAssessment`
41: **owner tries to submit the assessment, but fails, because not all fields
42 are filled out.
44`test_complete`
45: **owner** fills out the criteria.
46 If not all fields are filled in, the status remains `incomplete`,
47 and at the end the status is `complete`.
49`test_assignReviewers`
50: All users try to assign reviewers to this assessment, but they all fail.
51 Most users fail because they do not have the right permission level.
52 The office user fails because of a workflow condition:
53 the assessment is complete, not yet submitted.
55`test_withdrawAssessment`
56: **owner** tries to withdraw the assessment, unsuccessfully,
57 because it has not been submitted.
59`test_inspectTitleAll2`
60: We check of the assessment is still private to **owner**.
62`test_resubmitAssessment`
63: **owner** tries to re-submit the assessment, unsuccessfully,
64 because it has not been submitted.
66`test_submitAssessmentRevised`
67: **owner** tries to submit the assessment as revision, unsuccessfully.
69`test_submitAssessment2`
70: **owner** tries to submit the assessment, successfully.
72`test_revokeDelay`
73 There is a delay time during which the submission can be revoked.
74 We'll test what happens when the delay time is past.
75 We do this by updating the `dateSubmitted` field under water, directly
76 in Mongo.
77 We shift the time back 0.5 hours
78 **owner** withdraws and succeeds and then submits again.
79 We shift the time back 1.5 hours.
80 **owner** withdraws and fails.
81 We shift the time forward 1.5 hours again.
83`test_assignReviewers2`
84: All users try to assign reviewers to this assessment.
85 The office user succeeds because of a workflow condition:
86 the assessment is submitted.
88`test_sidebar`
89: All users check the entries in the sidebar.
90 The office user should now see an entrie for assessment needing reviewers.
92`test_inspectTitleAll3`
93: We check of the assessment is still private to **owner**.
95* **owner** tries to submit the assessment, unsuccessfully,
96 because it has already been submitted.
97* **owner** tries to withdraw the assessment, successfully.
98* **owner** tries to submit the assessment as revision, unsuccessfully.
99* **owner** tries to resubmit the assessment successfully.
100* We check of the assessment is still private to **owner**.
102`test_withdrawAssessment2`
103: **owner** tries to withdraw the assessment, successfully.
105`test_sidebar2`
106: All users check the entries in the sidebar.
107 The office user should not not see any entrie for assessment needing reviewers.
109`test_assignReviewers3`
110: All users try to assign reviewers to this assessment.
111 The office user fails because of a workflow condition:
112 the assessment is withdrawn.
114`test_submitAssessmentRevised2`
115: **owner** cannot submit this assessment as a revision.
117`test_resubmitAssessment2`
118: **owner** re-submits this assessment.
120`test_assignReviewers4`
121: All users try to assign reviewers to this assessment.
122 The office user succeeds because of a workflow condition:
123 the assessment is submitted.
124"""
126import pytest
128import magic # noqa
129from control.utils import pick as G
130from conftest import USERS, POWER_USERS, RIGHTFUL_USERS
131from example import (
132 ASSESS,
133 BELGIUM,
134 COMPLETE,
135 CRITERIA_ENTRY,
136 CRITERIA_ENTRIES_N,
137 DATE_SUBMITTED,
138 EDITOR,
139 ELLIPS_DIV,
140 EVIDENCE,
141 EXPERT,
142 FINAL,
143 INCOMPLETE,
144 MYCOORD,
145 OFFICE,
146 OWNER,
147 RESUBMIT_ASSESSMENT,
148 REVIEWER_E,
149 REVIEWER_F,
150 SCORE,
151 SUBMIT_ASSESSMENT,
152 SUBMIT_REVISED,
153 TITLE,
154 TYPE1,
155 USER,
156 WITHDRAW_ASSESSMENT,
157)
158from helpers import findDetails, forall, getItem, getRelatedValues
159from starters import start
160from subtest import (
161 assertModifyField,
162 assertShiftDate,
163 assertStage,
164 assertStatus,
165 inspectTitleAll,
166 assignReviewers,
167 sidebar,
168)
170startInfo = {}
173@pytest.mark.usefixtures("db")
174def test_start(clientOffice, clientOwner):
175 startInfo.update(
176 start(
177 clientOffice=clientOffice,
178 clientOwner=clientOwner,
179 users=True,
180 assessment=True,
181 countries=True,
182 )
183 )
186def test_criteriaEntries(clients):
187 recordId = startInfo["recordId"]
189 aId = G(recordId, ASSESS)
191 def assertIt(cl, exp):
192 assessInfo = getItem(cl, ASSESS, aId)
193 text = assessInfo["text"]
194 criteriaEntries = findDetails(text, CRITERIA_ENTRY)
195 nEntries = len(criteriaEntries)
196 if exp:
197 assert nEntries == CRITERIA_ENTRIES_N[TYPE1]
198 for (cId, material) in criteriaEntries:
199 assert ELLIPS_DIV in material
200 else:
201 assert nEntries == 0
203 expect = {user: False for user in USERS}
204 expect.update({user: True for user in RIGHTFUL_USERS})
205 forall(clients, expect, assertIt)
208def test_fillEvidenceAll(clients):
209 recordId = startInfo["recordId"]
211 aId = G(recordId, ASSESS)
212 clientOwner = clients[OWNER]
213 assessInfo = assertStage(clientOwner, ASSESS, aId, INCOMPLETE)
214 text = assessInfo["text"]
215 criteriaEntries = findDetails(text, CRITERIA_ENTRY)
216 cId = criteriaEntries[0][0]
218 def assertIt(cl, exp):
219 theEvidence = ["evidence for 1", "see the internet"]
220 theEvidenceRep = ",".join(theEvidence)
221 assertModifyField(
222 cl, CRITERIA_ENTRY, cId, EVIDENCE, (theEvidence, theEvidenceRep), exp
223 )
225 expect = {user: False for user in USERS}
226 expect.update({user: True for user in RIGHTFUL_USERS})
227 forall(clients, expect, assertIt)
230def test_fillEvidenceOwner(clientOwner):
231 recordId = startInfo["recordId"]
233 aId = G(recordId, ASSESS)
235 assessInfo = assertStage(clientOwner, ASSESS, aId, INCOMPLETE)
236 text = assessInfo["text"]
238 criteriaEntries = findDetails(text, CRITERIA_ENTRY)
239 assert len(criteriaEntries) == CRITERIA_ENTRIES_N[TYPE1]
241 cIds = []
243 for (i, (cId, material)) in enumerate(criteriaEntries):
244 assert ELLIPS_DIV in material
245 theEvidence = [f"evidence for {i + 1}", "see the internet"]
246 theEvidenceRep = ",".join(theEvidence)
247 assertModifyField(
248 clientOwner,
249 CRITERIA_ENTRY,
250 cId,
251 EVIDENCE,
252 (theEvidence, theEvidenceRep),
253 True,
254 )
255 cIds.append(cId)
257 recordId[CRITERIA_ENTRY] = cIds
260def test_fillScore(clientOwner):
261 recordId = startInfo["recordId"]
263 cId = recordId[CRITERIA_ENTRY][0]
264 scores = getRelatedValues(clientOwner, CRITERIA_ENTRY, cId, SCORE)
265 (scoreValue, scoreId) = sorted(scores.items())[0]
266 assertModifyField(
267 clientOwner, CRITERIA_ENTRY, cId, SCORE, (scoreId, scoreValue), True
268 )
271def test_fillScoreWrong(clientOwner):
272 recordId = startInfo["recordId"]
274 cIds = recordId[CRITERIA_ENTRY]
275 cId = cIds[0]
276 cIdx = cIds[1]
277 scores = getRelatedValues(clientOwner, CRITERIA_ENTRY, cIdx, SCORE)
278 (scoreValue, scoreId) = sorted(scores.items())[0]
279 assertModifyField(
280 clientOwner, CRITERIA_ENTRY, cId, SCORE, (scoreId, scoreValue), False
281 )
284def test_submitAssessment(clientOwner):
285 recordId = startInfo["recordId"]
287 aId = G(recordId, ASSESS)
288 url = f"/api/task/{SUBMIT_ASSESSMENT}/{aId}"
289 assertStatus(clientOwner, url, False)
292def test_complete(clientOwner):
293 recordId = startInfo["recordId"]
295 aId = G(recordId, ASSESS)
296 cIds = recordId[CRITERIA_ENTRY]
297 nCId = len(cIds)
299 for (i, cId) in enumerate(cIds):
300 scores = getRelatedValues(clientOwner, CRITERIA_ENTRY, cId, SCORE)
301 (scoreValue, scoreId) = sorted(scores.items())[1]
302 if i == nCId - 1:
303 assertStage(clientOwner, ASSESS, aId, INCOMPLETE)
305 assertModifyField(
306 clientOwner, CRITERIA_ENTRY, cId, SCORE, (scoreId, scoreValue), True
307 )
308 assertStage(clientOwner, ASSESS, aId, COMPLETE)
311@pytest.mark.parametrize(
312 ("field", USER), ((REVIEWER_E, EXPERT), (REVIEWER_F, FINAL),),
313)
314def test_assignReviewers(clients, field, user):
315 valueTables = startInfo["valueTables"]
316 recordId = startInfo["recordId"]
318 aId = G(recordId, ASSESS)
319 users = G(valueTables, USER)
320 expect = {user: False for user in USERS}
321 assignReviewers(clients, users, aId, field, user, False, expect)
324def test_withdrawAssessment(clientOwner):
325 recordId = startInfo["recordId"]
327 aId = G(recordId, ASSESS)
328 url = f"/api/task/{WITHDRAW_ASSESSMENT}/{aId}"
329 assertStatus(clientOwner, url, False)
332def test_inspectTitleAll2(clients):
333 recordId = startInfo["recordId"]
334 recordInfo = startInfo["recordInfo"]
336 aId = G(recordId, ASSESS)
337 assessInfo = getItem(clients[OWNER], ASSESS, aId)
338 fields = assessInfo["fields"]
339 recordInfo[ASSESS] = assessInfo
340 aTitle = G(fields, TITLE)
341 expect = {user: None for user in USERS}
342 expect.update({user: aTitle for user in RIGHTFUL_USERS})
343 inspectTitleAll(clients, ASSESS, aId, expect)
346def test_resubmitAssessment(clientOwner):
347 recordId = startInfo["recordId"]
349 aId = G(recordId, ASSESS)
350 url = f"/api/task/{RESUBMIT_ASSESSMENT}/{aId}"
351 assertStatus(clientOwner, url, False)
354def test_submitAssessmentRevised(clientOwner):
355 recordId = startInfo["recordId"]
357 aId = G(recordId, ASSESS)
358 url = f"/api/task/{SUBMIT_REVISED}/{aId}"
359 assertStatus(clientOwner, url, False)
362def test_submitAssessment2(clientOwner):
363 recordId = startInfo["recordId"]
365 aId = G(recordId, ASSESS)
366 url = f"/api/task/{SUBMIT_ASSESSMENT}/{aId}"
367 assertStatus(clientOwner, url, True)
370def test_revokeDelay(clientOwner, clientSystem):
371 recordId = startInfo["recordId"]
372 aId = G(recordId, ASSESS)
374 assertShiftDate(clientSystem, ASSESS, aId, DATE_SUBMITTED, -0.5)
375 for url in (
376 f"/api/task/{WITHDRAW_ASSESSMENT}/{aId}",
377 f"/api/task/{RESUBMIT_ASSESSMENT}/{aId}",
378 ):
379 assertStatus(clientOwner, url, True)
380 assertShiftDate(clientSystem, ASSESS, aId, DATE_SUBMITTED, -1.5)
381 for url in (
382 f"/api/task/{WITHDRAW_ASSESSMENT}/{aId}",
383 ):
384 assertStatus(clientOwner, url, False)
385 assertShiftDate(clientSystem, ASSESS, aId, DATE_SUBMITTED, 1.5)
388@pytest.mark.parametrize(
389 ("field", USER), ((REVIEWER_E, EXPERT), (REVIEWER_F, FINAL),),
390)
391def test_assignReviewers2(clients, field, user):
392 valueTables = startInfo["valueTables"]
393 recordId = startInfo["recordId"]
395 aId = G(recordId, ASSESS)
396 users = G(valueTables, USER)
397 expect = {user: False for user in USERS}
398 expect[OFFICE] = True
399 assignReviewers(clients, users, aId, field, user, False, expect)
402def test_sidebar(clients):
403 amounts = {
404 "All contributions": [1],
405 "My contributions": [({OWNER, EDITOR}, 1)],
406 f"{BELGIUM} contributions": [1],
407 "Contributions to be selected": [({MYCOORD}, 1)],
408 "Contributions I am assessing": [({OWNER, EDITOR}, 1)],
409 "My assessments": [({OWNER, EDITOR}, 1)],
410 "All assessments": [(POWER_USERS, 1)],
411 "Assessments needing reviewers": [({OFFICE}, 1)],
412 }
413 sidebar(clients, amounts)
416def test_inspectTitleAll3(clients):
417 recordId = startInfo["recordId"]
418 recordInfo = startInfo["recordInfo"]
420 aId = G(recordId, ASSESS)
421 assessInfo = recordInfo[ASSESS]
422 fields = assessInfo["fields"]
423 aTitle = G(fields, TITLE)
424 expect = {user: None for user in USERS}
425 expect.update({user: aTitle for user in RIGHTFUL_USERS})
426 expect.update({MYCOORD: aTitle})
427 inspectTitleAll(clients, ASSESS, aId, expect)
430def test_withdrawAssessment2(clientOwner):
431 recordId = startInfo["recordId"]
433 aId = G(recordId, ASSESS)
434 url = f"/api/task/{WITHDRAW_ASSESSMENT}/{aId}"
435 assertStatus(clientOwner, url, True)
438def test_sidebar2(clients):
439 amounts = {
440 "All contributions": [1],
441 "My contributions": [({OWNER, EDITOR}, 1)],
442 f"{BELGIUM} contributions": [1],
443 "Contributions to be selected": [({MYCOORD}, 1)],
444 "Contributions I am assessing": [({OWNER, EDITOR}, 0)],
445 "My assessments": [({OWNER, EDITOR}, 1)],
446 "All assessments": [(POWER_USERS, 1)],
447 }
448 sidebar(clients, amounts)
451@pytest.mark.parametrize(
452 ("field", USER), ((REVIEWER_E, EXPERT), (REVIEWER_F, FINAL),),
453)
454def test_assignReviewers3(clients, field, user):
455 valueTables = startInfo["valueTables"]
456 recordId = startInfo["recordId"]
458 aId = G(recordId, ASSESS)
459 users = G(valueTables, USER)
460 expect = {user: False for user in USERS}
461 assignReviewers(clients, users, aId, field, user, False, expect)
464def test_submitAssessmentRevised2(clientOwner):
465 recordId = startInfo["recordId"]
467 aId = G(recordId, ASSESS)
468 url = f"/api/task/{SUBMIT_REVISED}/{aId}"
469 assertStatus(clientOwner, url, False)
472def test_resubmitAssessment2(clientOwner):
473 recordId = startInfo["recordId"]
475 aId = G(recordId, ASSESS)
476 url = f"/api/task/{RESUBMIT_ASSESSMENT}/{aId}"
477 assertStatus(clientOwner, url, True)
480@pytest.mark.parametrize(
481 ("field", USER), ((REVIEWER_E, EXPERT), (REVIEWER_F, FINAL),),
482)
483def test_assignReviewers4(clients, field, user):
484 valueTables = startInfo["valueTables"]
485 recordId = startInfo["recordId"]
487 aId = G(recordId, ASSESS)
488 users = G(valueTables, USER)
489 expect = {user: False for user in USERS}
490 expect[OFFICE] = True
491 assignReviewers(clients, users, aId, field, user, True, expect)