Merge pull request #347 from sartography/bug/pi_name_missing_246

Bug/pi name missing 246
This commit is contained in:
Dan Funk 2021-08-10 16:29:09 -04:00 committed by GitHub
commit fd468f1013
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 140 additions and 107 deletions

41
crc/api.yml Normal file → Executable file
View File

@ -190,8 +190,8 @@ paths:
/workflow_sync/{workflow_spec_id}/spec: /workflow_sync/{workflow_spec_id}/spec:
parameters: parameters:
- name: workflow_spec_id - name: workflow_spec_id
required: true
in: path in: path
required: true
description: The unique id of an existing workflow specification to modify. description: The unique id of an existing workflow specification to modify.
schema: schema:
type: string type: string
@ -394,6 +394,30 @@ paths:
application/json: application/json:
schema: schema:
$ref: "#/components/schemas/Study" $ref: "#/components/schemas/Study"
/study/{study_id}/associates:
parameters:
- name: study_id
in: path
required: true
description: The id of the study for which associates should be returned.
schema:
type: integer
format: int32
get:
operationId: crc.api.study.get_study_associates
summary: Provides a list of associates for a particular study
tags:
- Studies
responses:
'200':
description: list of Study Associate Objects
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/StudyAssociate"
/workflow-specification: /workflow-specification:
get: get:
operationId: crc.api.workflow.all_specifications operationId: crc.api.workflow.all_specifications
@ -561,7 +585,7 @@ paths:
- name: test_until - name: test_until
in: query in: query
required: false required: false
description: Optional name of task to stop validating at description: Optional name of task to stop validating at
schema: schema:
type: string type: string
get: get:
@ -1607,6 +1631,17 @@ components:
type: string type: string
x-nullable: true x-nullable: true
example: "27b-6-1212" example: "27b-6-1212"
StudyAssociate:
properties:
uid:
type: string
example: "dhf8r"
access:
type: boolean
example: False
role:
type: string
example: "TODO"
DocumentDirectory: DocumentDirectory:
properties: properties:
level: level:
@ -1727,7 +1762,7 @@ components:
example: "random_fact" example: "random_fact"
x-nullable: true x-nullable: true
file: file:
type: string type: string
Workflow: Workflow:
properties: properties:
id: id:

View File

@ -7,7 +7,7 @@ from crc import session
from crc.api.common import ApiError, ApiErrorSchema from crc.api.common import ApiError, ApiErrorSchema
from crc.models.protocol_builder import ProtocolBuilderStatus from crc.models.protocol_builder import ProtocolBuilderStatus
from crc.models.study import Study, StudyEvent, StudyEventType, StudyModel, StudySchema, StudyForUpdateSchema, \ from crc.models.study import Study, StudyEvent, StudyEventType, StudyModel, StudySchema, StudyForUpdateSchema, \
StudyStatus StudyStatus, StudyAssociatedSchema
from crc.services.study_service import StudyService from crc.services.study_service import StudyService
from crc.services.user_service import UserService from crc.services.user_service import UserService
from crc.services.workflow_service import WorkflowService from crc.services.workflow_service import WorkflowService
@ -81,6 +81,10 @@ def get_study(study_id, update_status=False):
return StudySchema().dump(study) return StudySchema().dump(study)
def get_study_associates(study_id):
return StudyAssociatedSchema(many=True).dump(StudyService.get_study_associates(study_id))
def delete_study(study_id): def delete_study(study_id):
try: try:
StudyService.delete_study(study_id) StudyService.delete_study(study_id)

View File

@ -80,6 +80,13 @@ class StudyAssociated(db.Model):
send_email = db.Column(db.Boolean, nullable=True) send_email = db.Column(db.Boolean, nullable=True)
access = db.Column(db.Boolean, nullable=True) access = db.Column(db.Boolean, nullable=True)
class StudyAssociatedSchema(ma.Schema):
class Meta:
fields=['uid', 'role', 'send_email', 'access']
model = StudyAssociated
unknown = INCLUDE
class StudyEvent(db.Model): class StudyEvent(db.Model):
__tablename__ = 'study_event' __tablename__ = 'study_event'
id = db.Column(db.Integer, primary_key=True) id = db.Column(db.Integer, primary_key=True)

View File

@ -114,7 +114,7 @@ email (subject="My Subject", recipients=["dhf8r@virginia.edu", pi.email], cc='as
associated_emails = [] associated_emails = []
associates = StudyService.get_study_associates(study_id) associates = StudyService.get_study_associates(study_id)
for associate in associates: for associate in associates:
if associate['send_email'] is True: if associate.send_email is True:
user_info = LdapService.user_info(associate['uid']) user_info = LdapService.user_info(associate.uid)
associated_emails.append(user_info.email_address) associated_emails.append(user_info.email_address)
return associated_emails return associated_emails

View File

@ -1,24 +1,24 @@
from crc.api.common import ApiError from crc.api.common import ApiError
from crc.models.study import StudyAssociatedSchema
from crc.scripts.script import Script from crc.scripts.script import Script
from crc.services.study_service import StudyService from crc.services.study_service import StudyService
class GetStudyAssociates(Script): class GetStudyAssociate(Script):
def get_description(self): def get_description(self):
return """ return """
Returns people associated with a study or an error if one is not associated. Returns how a single person is associated with a study and what access they need,
or raises an error if the person is not associated with the study.
example : get_study_associate('sbp3ey') => {'uid':'sbp3ey','role':'Unicorn Herder', 'send_email': False, example : get_study_associate('sbp3ey') => {'uid':'sbp3ey','role':'Unicorn Herder', 'send_email': False,
'access':True} 'access':True}
""" """
def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs): def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs):
if len(args) < 1: if len(args) < 1:
raise ApiError('no_user_id_specified', 'A uva uid is the sole argument to this function') raise ApiError('no_user_id_specified', 'A uva uid is the sole argument to this function')
return {'uid': 'sbp3ey', 'role': 'Unicorn Herder', 'send_email': False, 'access': True} return {'uid': 'sbp3ey', 'role': 'Unicorn Herder', 'send_email': False, 'access': True}
def do_task(self, task, study_id, workflow_id, *args, **kwargs): def do_task(self, task, study_id, workflow_id, *args, **kwargs):
@ -26,4 +26,5 @@ example : get_study_associate('sbp3ey') => {'uid':'sbp3ey','role':'Unicorn Herde
raise ApiError('no_user_id_specified', 'A uva uid is the sole argument to this function') raise ApiError('no_user_id_specified', 'A uva uid is the sole argument to this function')
if not isinstance(args[0], str): if not isinstance(args[0], str):
raise ApiError('argument_should_be_string', 'A uva uid is always a string, please check type') raise ApiError('argument_should_be_string', 'A uva uid is always a string, please check type')
return StudyService.get_study_associate(study_id=study_id, uid=args[0]) associate = StudyService.get_study_associate(study_id=study_id, uid=args[0])
return StudyAssociatedSchema().dump(associate)

View File

@ -1,4 +1,5 @@
from crc.api.common import ApiError from crc.api.common import ApiError
from crc.models.study import StudyAssociatedSchema
from crc.scripts.script import Script from crc.scripts.script import Script
from crc.services.study_service import StudyService from crc.services.study_service import StudyService
@ -26,7 +27,6 @@ example : get_study_associates() => [{'uid':'sbp3ey','role':'Unicorn Herder', 's
return study_associates return study_associates
def do_task(self, task, study_id, workflow_id, *args, **kwargs): def do_task(self, task, study_id, workflow_id, *args, **kwargs):
return StudyAssociatedSchema(many=True).dump(StudyService.get_study_associates(study_id))
return StudyService.get_study_associates(study_id)

View File

@ -16,10 +16,11 @@ from crc.models.data_store import DataStoreModel
from crc.models.email import EmailModel from crc.models.email import EmailModel
from crc.models.file import FileModel, File from crc.models.file import FileModel, File
from crc.models.ldap import LdapSchema from crc.models.ldap import LdapSchema
from crc.models.protocol_builder import ProtocolBuilderStudy
from crc.models.study import StudyModel, Study, StudyStatus, Category, \ from crc.models.protocol_builder import ProtocolBuilderStudy, ProtocolBuilderStatus
WorkflowMetadata, StudyEventType, StudyEvent, IrbStatus, StudyAssociated from crc.models.study import StudyModel, Study, StudyStatus, Category, WorkflowMetadata, StudyEventType, StudyEvent, \
from crc.models.task_event import TaskEventModel IrbStatus, StudyAssociated, StudyAssociatedSchema
from crc.models.task_event import TaskEventModel, TaskEvent
from crc.models.workflow import WorkflowSpecCategoryModel, WorkflowModel, WorkflowSpecModel, WorkflowState, \ from crc.models.workflow import WorkflowSpecCategoryModel, WorkflowModel, WorkflowSpecModel, WorkflowState, \
WorkflowStatus, WorkflowSpecDependencyFile WorkflowStatus, WorkflowSpecDependencyFile
from crc.services.document_service import DocumentService from crc.services.document_service import DocumentService
@ -43,15 +44,15 @@ class StudyService(object):
def get_studies_for_user(self, user): def get_studies_for_user(self, user):
"""Returns a list of all studies for the given user.""" """Returns a list of all studies for the given user."""
associated = session.query(StudyAssociated).filter_by(uid=user.uid,access=True).all() associated = session.query(StudyAssociated).filter_by(uid=user.uid, access=True).all()
associated_studies = [x.study_id for x in associated] associated_studies = [x.study_id for x in associated]
db_studies = session.query(StudyModel).filter((StudyModel.user_uid==user.uid)| db_studies = session.query(StudyModel).filter((StudyModel.user_uid == user.uid) |
(StudyModel.id.in_(associated_studies))).all() (StudyModel.id.in_(associated_studies))).all()
studies = [] studies = []
for study_model in db_studies: for study_model in db_studies:
if self._is_valid_study(study_model.id): if self._is_valid_study(study_model.id):
studies.append(StudyService.get_study(study_model.id, study_model,do_status=False)) studies.append(StudyService.get_study(study_model.id, study_model, do_status=False))
return studies return studies
@staticmethod @staticmethod
@ -75,8 +76,8 @@ class StudyService(object):
study = Study.from_model(study_model) study = Study.from_model(study_model)
study.create_user_display = LdapService.user_info(study.user_uid).display_name study.create_user_display = LdapService.user_info(study.user_uid).display_name
last_event: TaskEventModel = session.query(TaskEventModel)\ last_event: TaskEventModel = session.query(TaskEventModel) \
.filter_by(study_id=study_id,action='COMPLETE')\ .filter_by(study_id=study_id, action='COMPLETE') \
.order_by(TaskEventModel.date.desc()).first() .order_by(TaskEventModel.date.desc()).first()
if last_event is None: if last_event is None:
study.last_activity_user = 'Not Started' study.last_activity_user = 'Not Started'
@ -108,9 +109,9 @@ class StudyService(object):
return study return study
@staticmethod @staticmethod
def get_study_associate(study_id = None, uid=None): def get_study_associate(study_id=None, uid=None):
""" """
gets all associated people for a study from the database gets details on how one uid is related to a study, returns a StudyAssociated model
""" """
study = db.session.query(StudyModel).filter(StudyModel.id == study_id).first() study = db.session.query(StudyModel).filter(StudyModel.id == study_id).first()
@ -118,23 +119,18 @@ class StudyService(object):
raise ApiError('study_not_found', 'No study found with id = %d' % study_id) raise ApiError('study_not_found', 'No study found with id = %d' % study_id)
if uid is None: if uid is None:
raise ApiError('uid not specified','A valid uva uid is required for this function') raise ApiError('uid not specified', 'A valid uva uid is required for this function')
if uid == study.user_uid: if uid == study.user_uid:
return {'uid': ownerid, 'role': 'owner', 'send_email': True, 'access': True} return StudyAssociated(uid=uid, role='owner', send_email=True, access=True)
people = db.session.query(StudyAssociated).filter((StudyAssociated.study_id == study_id) &
(StudyAssociated.uid == uid)).first()
person = db.session.query(StudyAssociated).filter((StudyAssociated.study_id == study_id)&( if people:
StudyAssociated.uid == uid)).first() return people
if person: else:
newAssociate = {'uid':person.uid} raise ApiError('uid_not_associated_with_study', "user id %s was not associated with study number %d" % (uid,
newAssociate['role'] = person.role study_id))
newAssociate['send_email'] = person.send_email
newAssociate['access'] = person.access
return newAssociate
raise ApiError('uid_not_associated_with_study',"user id %s was not associated with study number %d"%(uid,
study_id))
@staticmethod @staticmethod
def get_study_associates(study_id): def get_study_associates(study_id):
@ -144,22 +140,15 @@ class StudyService(object):
study = db.session.query(StudyModel).filter(StudyModel.id == study_id).first() study = db.session.query(StudyModel).filter(StudyModel.id == study_id).first()
if study is None: if study is None:
raise ApiError('study_not_found','No study found with id = %d'%study_id) raise ApiError('study_not_found', 'No study found with id = %d' % study_id)
ownerid = study.user_uid
people_list = [{'uid':ownerid,'role':'owner','send_email':True,'access':True}]
people = db.session.query(StudyAssociated).filter(StudyAssociated.study_id == study_id)
for person in people:
newAssociate = {'uid':person.uid}
newAssociate['role'] = person.role
newAssociate['send_email'] = person.send_email
newAssociate['access'] = person.access
people_list.append(newAssociate)
return people_list
people = db.session.query(StudyAssociated).filter(StudyAssociated.study_id == study_id).all()
owner = StudyAssociated(uid=study.user_uid, role='owner', send_email=True, access=True)
people.append(owner)
return people
@staticmethod @staticmethod
def update_study_associates(study_id,associates): def update_study_associates(study_id, associates):
""" """
updates the list of associates in the database for a study_id and a list updates the list of associates in the database for a study_id and a list
of dicts that contains associates of dicts that contains associates
@ -168,20 +157,19 @@ class StudyService(object):
raise ApiError('study_id not specified', "This function requires the study_id parameter") raise ApiError('study_id not specified', "This function requires the study_id parameter")
for person in associates: for person in associates:
if not LdapService.user_exists(person.get('uid','impossible_uid')): if not LdapService.user_exists(person.get('uid', 'impossible_uid')):
if person.get('uid','impossible_uid') == 'impossible_uid': if person.get('uid', 'impossible_uid') == 'impossible_uid':
raise ApiError('associate with no uid','One of the associates passed as a parameter doesnt have ' raise ApiError('associate with no uid', 'One of the associates passed as a parameter doesnt have '
'a uid specified') 'a uid specified')
raise ApiError('trying_to_grant_access_to_user_not_found_in_ldap',"You are trying to grant access to " raise ApiError('trying_to_grant_access_to_user_not_found_in_ldap', "You are trying to grant access to "
"%s, but that user was not found in " "%s, but that user was not found in "
"ldap " "ldap "
"- please check to ensure it is a " "- please check to ensure it is a "
"valid uva uid"%person.get('uid')) "valid uva uid" % person.get('uid'))
study = db.session.query(StudyModel).filter(StudyModel.id == study_id).first() study = db.session.query(StudyModel).filter(StudyModel.id == study_id).first()
if study is None: if study is None:
raise ApiError('study_id not found', "A study with id# %d was not found"%study_id) raise ApiError('study_id not found', "A study with id# %d was not found" % study_id)
db.session.query(StudyAssociated).filter(StudyAssociated.study_id == study_id).delete() db.session.query(StudyAssociated).filter(StudyAssociated.study_id == study_id).delete()
for person in associates: for person in associates:
@ -190,27 +178,27 @@ class StudyService(object):
newAssociate.uid = person['uid'] newAssociate.uid = person['uid']
newAssociate.role = person.get('role', None) newAssociate.role = person.get('role', None)
newAssociate.send_email = person.get('send_email', False) newAssociate.send_email = person.get('send_email', False)
newAssociate.access = person.get('access',False) newAssociate.access = person.get('access', False)
session.add(newAssociate) session.add(newAssociate)
session.commit() session.commit()
@staticmethod @staticmethod
def update_study_associate(study_id=None,uid=None,role="",send_email=False,access=False): def update_study_associate(study_id=None, uid=None, role="", send_email=False, access=False):
if study_id is None: if study_id is None:
raise ApiError('study_id not specified', "This function requires the study_id parameter") raise ApiError('study_id not specified', "This function requires the study_id parameter")
if uid is None: if uid is None:
raise ApiError('uid not specified', "This function requires a uva uid parameter") raise ApiError('uid not specified', "This function requires a uva uid parameter")
if not LdapService.user_exists(uid): if not LdapService.user_exists(uid):
raise ApiError('trying_to_grant_access_to_user_not_found_in_ldap',"You are trying to grant access to " raise ApiError('trying_to_grant_access_to_user_not_found_in_ldap', "You are trying to grant access to "
"%s but they were not found in ldap " "%s but they were not found in ldap "
"- please check to ensure it is a " "- please check to ensure it is a "
"valid uva uid"%uid) "valid uva uid" % uid)
study = db.session.query(StudyModel).filter(StudyModel.id == study_id).first() study = db.session.query(StudyModel).filter(StudyModel.id == study_id).first()
if study is None: if study is None:
raise ApiError('study_id not found', "A study with id# %d was not found"%study_id) raise ApiError('study_id not found', "A study with id# %d was not found" % study_id)
db.session.query(StudyAssociated).filter((StudyAssociated.study_id == study_id)&(StudyAssociated.uid == db.session.query(StudyAssociated).filter((StudyAssociated.study_id == study_id) & (StudyAssociated.uid ==
uid) ).delete() uid)).delete()
newAssociate = StudyAssociated() newAssociate = StudyAssociated()
newAssociate.study_id = study_id newAssociate.study_id = study_id
@ -222,7 +210,6 @@ class StudyService(object):
session.commit() session.commit()
return True return True
@staticmethod @staticmethod
def delete_study(study_id): def delete_study(study_id):
session.query(TaskEventModel).filter_by(study_id=study_id).delete() session.query(TaskEventModel).filter_by(study_id=study_id).delete()
@ -305,18 +292,18 @@ class StudyService(object):
# when we run tests - it doesn't look like the user is available # when we run tests - it doesn't look like the user is available
# so we return a bogus token # so we return a bogus token
token = 'not_available' token = 'not_available'
if hasattr(flask.g,'user'): if hasattr(flask.g, 'user'):
token = flask.g.user.encode_auth_token() token = flask.g.user.encode_auth_token()
for file in doc_files: for file in doc_files:
file_data = {'file_id': file.id, file_data = {'file_id': file.id,
'name': file.name, 'name': file.name,
'url': app.config['APPLICATION_ROOT']+ 'url': app.config['APPLICATION_ROOT'] +
'file/' + str(file.id) + 'file/' + str(file.id) +
'/download?auth_token='+ '/download?auth_token=' +
urllib.parse.quote_plus(token), urllib.parse.quote_plus(token),
'workflow_id': file.workflow_id 'workflow_id': file.workflow_id
} }
data = db.session.query(DataStoreModel).filter(DataStoreModel.file_id==file.id).all() data = db.session.query(DataStoreModel).filter(DataStoreModel.file_id == file.id).all()
data_store_data = {} data_store_data = {}
for d in data: for d in data:
data_store_data[d.key] = d.value data_store_data[d.key] = d.value

View File

@ -770,7 +770,7 @@ class WorkflowService(object):
else: else:
if not hasattr(spiff_task.task_spec, 'lane') or spiff_task.task_spec.lane is None: if not hasattr(spiff_task.task_spec, 'lane') or spiff_task.task_spec.lane is None:
associated = StudyService.get_study_associates(processor.workflow_model.study.id) associated = StudyService.get_study_associates(processor.workflow_model.study.id)
return [user['uid'] for user in associated if user['access']] return [user.uid for user in associated if user.access]
if spiff_task.task_spec.lane not in spiff_task.data: if spiff_task.task_spec.lane not in spiff_task.data:
return [] # No users are assignable to the task at this moment return [] # No users are assignable to the task at this moment
lane_users = spiff_task.data[spiff_task.task_spec.lane] lane_users = spiff_task.data[spiff_task.task_spec.lane]

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_0kmksnn" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.5.0"> <bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_0kmksnn" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.7.3">
<bpmn:process id="Process_0exnnpv" isExecutable="true"> <bpmn:process id="Process_0exnnpv" isExecutable="true">
<bpmn:startEvent id="StartEvent_1"> <bpmn:startEvent id="StartEvent_1">
<bpmn:outgoing>SequenceFlow_1nfe5m9</bpmn:outgoing> <bpmn:outgoing>SequenceFlow_1nfe5m9</bpmn:outgoing>
@ -32,7 +32,7 @@ out4 = get_study_associate('lb3dp')</bpmn:script>
<bpmn:outgoing>Flow_1vlh6s0</bpmn:outgoing> <bpmn:outgoing>Flow_1vlh6s0</bpmn:outgoing>
<bpmn:script>uids = [] <bpmn:script>uids = []
for assoc in out: for assoc in out:
uids.append(assoc['uid']) uids.append(assoc.uid)
update_study_associates([{'uid':'lb3dp','role':'SuperGal','send_email':False,'access':True}])</bpmn:script> update_study_associates([{'uid':'lb3dp','role':'SuperGal','send_email':False,'access':True}])</bpmn:script>
</bpmn:scriptTask> </bpmn:scriptTask>
<bpmn:sequenceFlow id="Flow_1vlh6s0" sourceRef="Activity_0run091" targetRef="Activity_0d8iftx" /> <bpmn:sequenceFlow id="Flow_1vlh6s0" sourceRef="Activity_0run091" targetRef="Activity_0d8iftx" />
@ -46,6 +46,22 @@ out2 = get_study_associate('lb3dp')</bpmn:script>
</bpmn:process> </bpmn:process>
<bpmndi:BPMNDiagram id="BPMNDiagram_1"> <bpmndi:BPMNDiagram id="BPMNDiagram_1">
<bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_0exnnpv"> <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_0exnnpv">
<bpmndi:BPMNEdge id="Flow_14n3ixy_di" bpmnElement="Flow_14n3ixy">
<di:waypoint x="680" y="117" />
<di:waypoint x="750" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_1vlh6s0_di" bpmnElement="Flow_1vlh6s0">
<di:waypoint x="850" y="117" />
<di:waypoint x="900" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_0cttkwp_di" bpmnElement="Flow_0cttkwp">
<di:waypoint x="1000" y="117" />
<di:waypoint x="1042" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="Flow_09cika8_di" bpmnElement="Flow_09cika8">
<di:waypoint x="540" y="117" />
<di:waypoint x="580" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge id="SequenceFlow_1bqiin0_di" bpmnElement="SequenceFlow_1bqiin0"> <bpmndi:BPMNEdge id="SequenceFlow_1bqiin0_di" bpmnElement="SequenceFlow_1bqiin0">
<di:waypoint x="370" y="117" /> <di:waypoint x="370" y="117" />
<di:waypoint x="440" y="117" /> <di:waypoint x="440" y="117" />
@ -60,10 +76,6 @@ out2 = get_study_associate('lb3dp')</bpmn:script>
<bpmndi:BPMNShape id="ScriptTask_1mp6xid_di" bpmnElement="Task_Script_Load_Study_Sponsors"> <bpmndi:BPMNShape id="ScriptTask_1mp6xid_di" bpmnElement="Task_Script_Load_Study_Sponsors">
<dc:Bounds x="270" y="77" width="100" height="80" /> <dc:Bounds x="270" y="77" width="100" height="80" />
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_09cika8_di" bpmnElement="Flow_09cika8">
<di:waypoint x="540" y="117" />
<di:waypoint x="580" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Activity_0wnwluq_di" bpmnElement="Activity_0cm6tn2"> <bpmndi:BPMNShape id="Activity_0wnwluq_di" bpmnElement="Activity_0cm6tn2">
<dc:Bounds x="440" y="77" width="100" height="80" /> <dc:Bounds x="440" y="77" width="100" height="80" />
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
@ -73,24 +85,12 @@ out2 = get_study_associate('lb3dp')</bpmn:script>
<bpmndi:BPMNShape id="Event_0c8gcuh_di" bpmnElement="Event_0c8gcuh"> <bpmndi:BPMNShape id="Event_0c8gcuh_di" bpmnElement="Event_0c8gcuh">
<dc:Bounds x="1042" y="99" width="36" height="36" /> <dc:Bounds x="1042" y="99" width="36" height="36" />
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_0cttkwp_di" bpmnElement="Flow_0cttkwp">
<di:waypoint x="1000" y="117" />
<di:waypoint x="1042" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Activity_0run091_di" bpmnElement="Activity_0run091"> <bpmndi:BPMNShape id="Activity_0run091_di" bpmnElement="Activity_0run091">
<dc:Bounds x="750" y="77" width="100" height="80" /> <dc:Bounds x="750" y="77" width="100" height="80" />
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_1vlh6s0_di" bpmnElement="Flow_1vlh6s0">
<di:waypoint x="850" y="117" />
<di:waypoint x="900" y="117" />
</bpmndi:BPMNEdge>
<bpmndi:BPMNShape id="Activity_14td33q_di" bpmnElement="Activity_14td33q"> <bpmndi:BPMNShape id="Activity_14td33q_di" bpmnElement="Activity_14td33q">
<dc:Bounds x="580" y="77" width="100" height="80" /> <dc:Bounds x="580" y="77" width="100" height="80" />
</bpmndi:BPMNShape> </bpmndi:BPMNShape>
<bpmndi:BPMNEdge id="Flow_14n3ixy_di" bpmnElement="Flow_14n3ixy">
<di:waypoint x="680" y="117" />
<di:waypoint x="750" y="117" />
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane> </bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram> </bpmndi:BPMNDiagram>
</bpmn:definitions> </bpmn:definitions>

View File

@ -53,19 +53,18 @@ class TestSudySponsorsScript(BaseTest):
self.assertIn('sponsors', data) self.assertIn('sponsors', data)
self.assertIn('out', data) self.assertIn('out', data)
print(data['out']) print(data['out'])
self.assertEquals([{'uid': 'dhf8r', 'role': 'owner', 'send_email': True, 'access': True}, self.assertDictEqual({'uid': 'dhf8r', 'role': 'owner', 'send_email': True, 'access': True},
{'uid': 'lb3dp', 'role': 'SuperDude', 'send_email': False, 'access': True}] data['out'][1])
, data['out']) self.assertDictEqual({'uid': 'lb3dp', 'role': 'SuperDude', 'send_email': False, 'access': True},
self.assertEquals({'uid': 'lb3dp', 'role': 'SuperDude', 'send_email': False, 'access': True} data['out'][0])
, data['out2']) self.assertDictEqual({'uid': 'lb3dp', 'role': 'SuperDude', 'send_email': False, 'access': True},
data['out2'])
self.assertEquals([{'uid': 'dhf8r', 'role': 'owner', 'send_email': True, 'access': True}, self.assertDictEqual({'uid': 'dhf8r', 'role': 'owner', 'send_email': True, 'access': True},
{'uid': 'lb3dp', 'role': 'SuperGal', 'send_email': False, 'access': True}] data['out3'][1])
, data['out3']) self.assertDictEqual({'uid': 'lb3dp', 'role': 'SuperGal', 'send_email': False, 'access': True},
self.assertEquals({'uid': 'lb3dp', 'role': 'SuperGal', 'send_email': False, 'access': True} data['out3'][0])
, data['out4']) self.assertDictEqual({'uid': 'lb3dp', 'role': 'SuperGal', 'send_email': False, 'access': True},
data['out4'])
self.assertEquals(3, len(data['sponsors'])) self.assertEquals(3, len(data['sponsors']))