Module starters
The start-up functions for batches of tests.
We have divided the tests in batches. Each batch is a separate file.
The batches can be run alltogether in sequential order, or they can be run individually.
The start()
function achieves that when a batch is run as part of a bigger sequence,
the initial situation for the batch is the right one.
And also, if the batch is run individually, that it starts with exactly the same
state.
Clean slate
The base line is clean database, i.e. a database with all the value tables fully filled, with a set of test users, with packages, criteria, and types, but not with user-contributed content, such as contributions, assessments, and reviews.
This is the clean slate.
The starter functions may insert a few records in the database and fetch a few value tables for usage in test functions.
Expand source code
"""The start-up functions for batches of tests.
We have divided the tests in batches.
Each batch is a separate file.
The batches can be run alltogether in sequential order,
or they can be run individually.
The `start` function achieves that when a batch is run as part of a bigger sequence,
the initial situation for the batch is the right one.
And also, if the batch is run individually, that it starts with exactly the same
state.
## Clean slate
The base line is clean database, i.e. a database with
all the value tables fully filled, with a set of test users,
with packages, criteria, and types, but not with user-contributed content,
such as contributions, assessments, and reviews.
This is the *clean slate*.
The starter functions may insert a few records in the database and fetch
a few value tables for usage in test functions.
"""
from control.utils import pick as G
from example import (
ASSESS,
COMMENTS,
COMPLETE,
CONTRIB,
CRITERIA_ENTRY,
CRITERIA_ENTRIES_N,
COUNTRY,
ELLIPS_DIV,
EVIDENCE,
EXPERT,
FINAL,
REVIEW,
REVIEW_ENTRY,
REVIEWER_E,
REVIEWER_F,
SCORE,
START_ASSESSMENT,
START_REVIEW,
SUBMIT_ASSESSMENT,
TYPE,
TYPE1,
TYPE2,
USER,
)
from helpers import (
findDetails,
findValues,
getItem,
getReviewEntryId,
getScores,
)
from subtest import (
assertAddItem,
assertEditor,
assertModifyField,
assertStage,
assertStartTask,
assertStatus,
)
def getValueTable(cl, table):
"""Get a mapping of values in a value table to their object ids.
We look directly in the list of items of a valueTable.
The mapping is stored in the dict `dest` keyed by the
name of the valueTable.
Parameters
----------
table: string
The name of a value table
Returns
-------
dict
The stored value dict for this valueTable
"""
response = cl.get(f"/{table}/list")
text = response.get_data(as_text=True)
return findValues(table, text)
def makeItem(cl, table, cId=None, aId=None):
"""Makes a contribution/assessment/review.
Parameters
----------
cl: fixture
table: string
Either `contrib` or `assessment` or `review`
cId: string(ObjectId), optional `None`
If we make an assessment, the id of the contribution for which it is an
assessment
aId: string(ObjectId), optional `None`
If we make a review, the id of the assessment for which it is a
review
Returns
-------
eid: string(ObjectId)
the id of the contribution/assessment
"""
if table == CONTRIB:
return assertAddItem(cl, table, True)
if table == ASSESS:
return assertStartTask(cl, START_ASSESSMENT, cId, True)
if table == REVIEW:
return assertStartTask(cl, START_REVIEW, aId, True)
def start(
clientOffice=None,
clientOwner=None,
clientExpert=None,
clientFinal=None,
users=False,
types=False,
countries=False,
contrib=False,
assessment=False,
fillout=False,
submit=False,
assign=False,
review=False,
):
"""The start sequence for a batch of tests.
The first step is to start with a clean slate inth database:
Only the value records, no user-contributed content.
It depends on the batch what we have to make on top of that..
The result is always that certain records in the database are retrieved,
of if they do not exist, created.
Records with user added content are stored in the dict `recordId`,
under the name of the table as key.
Records in value tables are stored in the dict `valueTables`,
under the name of the table as key.
!!! hint "Dependencies of parameters"
Some things are dependent on others, for example, making an assessment
presupposes that there is a contribution.
The function will switch on all parameters that are implied before
creating or finding stuff.
Parameters
----------
clientOffice, clientOwner: fixture
users: boolean, optional `False`
Whether to fetch the list of users
types: boolean, optional `False`
Whether to fetch the list of contribution types
countries: boolean, optional `False`
Whether to fetch the list of countries
contrib: boolean, optional `False`
Whether to find or make a contribution
assessment: boolean, optional `False`
Whether to find or make an assessment
fillout: boolean, optional `False`
Whether to fill out the criteria entries
submit: boolean, optional `False`
Whether to submit the completed assessment
assign: boolean, optional `False`
Whether to assign reviewers
review: boolean, optional `False`
Whether to start and fillout both reviews
Returns
-------
valueTables: dict, optional `None`
Where the retrieved data for the value tables end up
recordId: dict, optional `None`
Where the retrieved ids for the records end up
ids: dict, optional `None`
A resulting mapping between values in a value table and their corresponding ids
"""
if review:
assign = True
if assign:
submit = True
if submit:
fillout = True
if fillout:
assessment = True
if assessment:
contrib = True
types = True
if contrib:
users = True
valueTables = {}
recordId = {}
recordInfo = {}
ids = {}
def startReviews():
aId = recordId[ASSESS]
cIds = recordId[CRITERIA_ENTRY]
recordId.setdefault(REVIEW, {})
clr = {EXPERT: clientExpert, FINAL: clientFinal}
for (user, cl) in clr.items():
rId = makeItem(cl, REVIEW, aId=aId)
recordId[REVIEW][user] = rId
for (user, cl) in clr.items():
rId = recordId[REVIEW][user]
for (i, cId) in enumerate(cIds):
rEId = recordId[REVIEW][EXPERT]
rFId = recordId[REVIEW][FINAL]
reId = getReviewEntryId(clr, cId, rEId, rFId)
reId = reId[user]
newValue = [f"{user}'s comment on criteria {i + 1}"]
newValueRep = ",".join(newValue)
assertModifyField(
cl, REVIEW_ENTRY, reId, COMMENTS, (newValue, newValueRep), True
)
def startAssign():
aId = recordId[ASSESS]
users = G(valueTables, USER)
for (field, user) in ((REVIEWER_E, EXPERT), (REVIEWER_F, FINAL)):
value = G(users, user)
assertModifyField(clientOffice, ASSESS, aId, field, (value, user), True)
if review:
startReviews()
def startSubmit():
aId = recordId[ASSESS]
url = f"/api/task/{SUBMIT_ASSESSMENT}/{aId}"
assertStatus(clientOwner, url, True)
if assign:
startAssign()
def startFillout():
aId = recordId[ASSESS]
assessInfo = getItem(clientOwner, ASSESS, aId)
criteriaEntries = findDetails(assessInfo["text"], CRITERIA_ENTRY)
nCId = len(criteriaEntries)
assert nCId == CRITERIA_ENTRIES_N[TYPE1]
cIds = []
for (i, (cId, material)) in enumerate(criteriaEntries):
cIds.append(cId)
assert ELLIPS_DIV in material
scores = getScores(cId)
(scoreValue, scoreId) = sorted(scores.items())[1]
assertModifyField(
clientOwner, CRITERIA_ENTRY, cId, SCORE, (scoreId, scoreValue), True,
)
theEvidence = [f"evidence for {i + 1}", "see the internet"]
theEvidenceRep = ",".join(theEvidence)
assertModifyField(
clientOwner,
CRITERIA_ENTRY,
cId,
EVIDENCE,
(theEvidence, theEvidenceRep),
True,
)
recordId[CRITERIA_ENTRY] = cIds
assertStage(clientOwner, ASSESS, aId, COMPLETE)
if submit:
startSubmit()
def startAssessment():
eid = recordId[CONTRIB]
assertModifyField(
clientOwner, CONTRIB, eid, TYPE, (ids["TYPE1"], TYPE1), True,
)
aId = makeItem(clientOwner, ASSESS, cId=eid)
recordId[ASSESS] = aId
assertEditor(clientOwner, ASSESS, aId, valueTables, True)
if fillout:
startFillout()
def startContrib():
eid = makeItem(clientOwner, CONTRIB)
recordId[CONTRIB] = eid
assertEditor(clientOwner, CONTRIB, eid, valueTables, True)
if assessment:
startAssessment()
if users:
valueTables[USER] = getValueTable(clientOffice, USER)
if countries:
valueTables[COUNTRY] = getValueTable(clientOffice, COUNTRY)
if types:
typeValues = getValueTable(clientOffice, TYPE)
ids["TYPE1"] = typeValues[TYPE1]
ids["TYPE2"] = typeValues[TYPE2]
valueTables[TYPE] = typeValues
if contrib:
startContrib()
return dict(
valueTables=valueTables, recordId=recordId, recordInfo=recordInfo, ids=ids
)
Functions
def getValueTable(cl, table)
-
Get a mapping of values in a value table to their object ids.
We look directly in the list of items of a valueTable.
The mapping is stored in the dict
dest
keyed by the name of the valueTable.Parameters
table
:string
- The name of a value table
Returns
dict
- The stored value dict for this valueTable
Expand source code
def getValueTable(cl, table): """Get a mapping of values in a value table to their object ids. We look directly in the list of items of a valueTable. The mapping is stored in the dict `dest` keyed by the name of the valueTable. Parameters ---------- table: string The name of a value table Returns ------- dict The stored value dict for this valueTable """ response = cl.get(f"/{table}/list") text = response.get_data(as_text=True) return findValues(table, text)
def makeItem(cl, table, cId=None, aId=None)
-
Makes a contribution/assessment/review.
Parameters
cl
:fixture
table
:string
- Either
contrib
orassessment
orreview
cId
:string(ObjectId)
, optionalNone
- If we make an assessment, the id of the contribution for which it is an assessment
aId
:string(ObjectId)
, optionalNone
- If we make a review, the id of the assessment for which it is a review
Returns
eid
:string(ObjectId)
- the id of the contribution/assessment
Expand source code
def makeItem(cl, table, cId=None, aId=None): """Makes a contribution/assessment/review. Parameters ---------- cl: fixture table: string Either `contrib` or `assessment` or `review` cId: string(ObjectId), optional `None` If we make an assessment, the id of the contribution for which it is an assessment aId: string(ObjectId), optional `None` If we make a review, the id of the assessment for which it is a review Returns ------- eid: string(ObjectId) the id of the contribution/assessment """ if table == CONTRIB: return assertAddItem(cl, table, True) if table == ASSESS: return assertStartTask(cl, START_ASSESSMENT, cId, True) if table == REVIEW: return assertStartTask(cl, START_REVIEW, aId, True)
def start(clientOffice=None, clientOwner=None, clientExpert=None, clientFinal=None, users=False, types=False, countries=False, contrib=False, assessment=False, fillout=False, submit=False, assign=False, review=False)
-
The start sequence for a batch of tests.
The first step is to start with a clean slate inth database: Only the value records, no user-contributed content.
It depends on the batch what we have to make on top of that..
The result is always that certain records in the database are retrieved, of if they do not exist, created.
Records with user added content are stored in the dict
recordId
, under the name of the table as key.Records in value tables are stored in the dict
valueTables
, under the name of the table as key.Dependencies of parameters
Some things are dependent on others, for example, making an assessment presupposes that there is a contribution. The function will switch on all parameters that are implied before creating or finding stuff.
Parameters
clientOffice
,clientOwner
:fixture
users
:boolean
, optionalFalse
- Whether to fetch the list of users
types
:boolean
, optionalFalse
- Whether to fetch the list of contribution types
countries
:boolean
, optionalFalse
- Whether to fetch the list of countries
contrib
:boolean
, optionalFalse
- Whether to find or make a contribution
assessment
:boolean
, optionalFalse
- Whether to find or make an assessment
fillout
:boolean
, optionalFalse
- Whether to fill out the criteria entries
submit
:boolean
, optionalFalse
- Whether to submit the completed assessment
assign
:boolean
, optionalFalse
- Whether to assign reviewers
review
:boolean
, optionalFalse
- Whether to start and fillout both reviews
Returns
valueTables
:dict
, optionalNone
- Where the retrieved data for the value tables end up
recordId
:dict
, optionalNone
- Where the retrieved ids for the records end up
ids
:dict
, optionalNone
- A resulting mapping between values in a value table and their corresponding ids
Expand source code
def start( clientOffice=None, clientOwner=None, clientExpert=None, clientFinal=None, users=False, types=False, countries=False, contrib=False, assessment=False, fillout=False, submit=False, assign=False, review=False, ): """The start sequence for a batch of tests. The first step is to start with a clean slate inth database: Only the value records, no user-contributed content. It depends on the batch what we have to make on top of that.. The result is always that certain records in the database are retrieved, of if they do not exist, created. Records with user added content are stored in the dict `recordId`, under the name of the table as key. Records in value tables are stored in the dict `valueTables`, under the name of the table as key. !!! hint "Dependencies of parameters" Some things are dependent on others, for example, making an assessment presupposes that there is a contribution. The function will switch on all parameters that are implied before creating or finding stuff. Parameters ---------- clientOffice, clientOwner: fixture users: boolean, optional `False` Whether to fetch the list of users types: boolean, optional `False` Whether to fetch the list of contribution types countries: boolean, optional `False` Whether to fetch the list of countries contrib: boolean, optional `False` Whether to find or make a contribution assessment: boolean, optional `False` Whether to find or make an assessment fillout: boolean, optional `False` Whether to fill out the criteria entries submit: boolean, optional `False` Whether to submit the completed assessment assign: boolean, optional `False` Whether to assign reviewers review: boolean, optional `False` Whether to start and fillout both reviews Returns ------- valueTables: dict, optional `None` Where the retrieved data for the value tables end up recordId: dict, optional `None` Where the retrieved ids for the records end up ids: dict, optional `None` A resulting mapping between values in a value table and their corresponding ids """ if review: assign = True if assign: submit = True if submit: fillout = True if fillout: assessment = True if assessment: contrib = True types = True if contrib: users = True valueTables = {} recordId = {} recordInfo = {} ids = {} def startReviews(): aId = recordId[ASSESS] cIds = recordId[CRITERIA_ENTRY] recordId.setdefault(REVIEW, {}) clr = {EXPERT: clientExpert, FINAL: clientFinal} for (user, cl) in clr.items(): rId = makeItem(cl, REVIEW, aId=aId) recordId[REVIEW][user] = rId for (user, cl) in clr.items(): rId = recordId[REVIEW][user] for (i, cId) in enumerate(cIds): rEId = recordId[REVIEW][EXPERT] rFId = recordId[REVIEW][FINAL] reId = getReviewEntryId(clr, cId, rEId, rFId) reId = reId[user] newValue = [f"{user}'s comment on criteria {i + 1}"] newValueRep = ",".join(newValue) assertModifyField( cl, REVIEW_ENTRY, reId, COMMENTS, (newValue, newValueRep), True ) def startAssign(): aId = recordId[ASSESS] users = G(valueTables, USER) for (field, user) in ((REVIEWER_E, EXPERT), (REVIEWER_F, FINAL)): value = G(users, user) assertModifyField(clientOffice, ASSESS, aId, field, (value, user), True) if review: startReviews() def startSubmit(): aId = recordId[ASSESS] url = f"/api/task/{SUBMIT_ASSESSMENT}/{aId}" assertStatus(clientOwner, url, True) if assign: startAssign() def startFillout(): aId = recordId[ASSESS] assessInfo = getItem(clientOwner, ASSESS, aId) criteriaEntries = findDetails(assessInfo["text"], CRITERIA_ENTRY) nCId = len(criteriaEntries) assert nCId == CRITERIA_ENTRIES_N[TYPE1] cIds = [] for (i, (cId, material)) in enumerate(criteriaEntries): cIds.append(cId) assert ELLIPS_DIV in material scores = getScores(cId) (scoreValue, scoreId) = sorted(scores.items())[1] assertModifyField( clientOwner, CRITERIA_ENTRY, cId, SCORE, (scoreId, scoreValue), True, ) theEvidence = [f"evidence for {i + 1}", "see the internet"] theEvidenceRep = ",".join(theEvidence) assertModifyField( clientOwner, CRITERIA_ENTRY, cId, EVIDENCE, (theEvidence, theEvidenceRep), True, ) recordId[CRITERIA_ENTRY] = cIds assertStage(clientOwner, ASSESS, aId, COMPLETE) if submit: startSubmit() def startAssessment(): eid = recordId[CONTRIB] assertModifyField( clientOwner, CONTRIB, eid, TYPE, (ids["TYPE1"], TYPE1), True, ) aId = makeItem(clientOwner, ASSESS, cId=eid) recordId[ASSESS] = aId assertEditor(clientOwner, ASSESS, aId, valueTables, True) if fillout: startFillout() def startContrib(): eid = makeItem(clientOwner, CONTRIB) recordId[CONTRIB] = eid assertEditor(clientOwner, CONTRIB, eid, valueTables, True) if assessment: startAssessment() if users: valueTables[USER] = getValueTable(clientOffice, USER) if countries: valueTables[COUNTRY] = getValueTable(clientOffice, COUNTRY) if types: typeValues = getValueTable(clientOffice, TYPE) ids["TYPE1"] = typeValues[TYPE1] ids["TYPE2"] = typeValues[TYPE2] valueTables[TYPE] = typeValues if contrib: startContrib() return dict( valueTables=valueTables, recordId=recordId, recordInfo=recordInfo, ids=ids )