Merge pull request #108 from sartography/rrt/dev

Mail update
This commit is contained in:
Carlos López 2020-06-05 12:58:29 -06:00 committed by GitHub
commit dffce69d16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
35 changed files with 458 additions and 167 deletions

View File

@ -39,6 +39,7 @@ ldap3 = "*"
gunicorn = "*"
werkzeug = "*"
sentry-sdk = {extras = ["flask"],version = "==0.14.4"}
flask-mail = "*"
[requires]
python_version = "3.7"

39
Pipfile.lock generated
View File

@ -1,7 +1,7 @@
{
"_meta": {
"hash": {
"sha256": "54d9d51360f54762138a3acc7696badd1d711e7b1dde9e2d82aa706e40c17102"
"sha256": "6c89585086260ebcb41918b8ef3b1d9e189e1b492208d3ff000a138bc2f2fcee"
},
"pipfile-spec": 6,
"requires": {
@ -104,10 +104,10 @@
},
"celery": {
"hashes": [
"sha256:5147662e23dc6bc39c17a2cbc9a148debe08ecfb128b0eded14a0d9c81fc5742",
"sha256:df2937b7536a2a9b18024776a3a46fd281721813636c03a5177fa02fe66078f6"
"sha256:9ae2e73b93cc7d6b48b56aaf49a68c91752d0ffd7dfdcc47f842ca79a6f13eae",
"sha256:c2037b6a8463da43b19969a0fc13f9023ceca6352b4dd51be01c66fbbb13647e"
],
"version": "==4.4.3"
"version": "==4.4.4"
},
"certifi": {
"hashes": [
@ -276,6 +276,13 @@
"index": "pypi",
"version": "==3.0.8"
},
"flask-mail": {
"hashes": [
"sha256:22e5eb9a940bf407bcf30410ecc3708f3c56cc44b29c34e1726fe85006935f41"
],
"index": "pypi",
"version": "==0.9.1"
},
"flask-marshmallow": {
"hashes": [
"sha256:6e6aec171b8e092e0eafaf035ff5b8637bf3a58ab46f568c4c1bab02f2a3c196",
@ -387,10 +394,10 @@
},
"kombu": {
"hashes": [
"sha256:ab0afaa5388dd2979cbc439d3623b86a4f7a58d41f621096bef7767c37bc2505",
"sha256:aece08f48706743aaa1b9d607fee300559481eafcc5ee56451aa0ef867a3be07"
"sha256:437b9cdea193cc2ed0b8044c85fd0f126bb3615ca2f4d4a35b39de7cacfa3c1a",
"sha256:dc282bb277197d723bccda1a9ba30a27a28c9672d0ab93e9e51bb05a37bd29c3"
],
"version": "==4.6.9"
"version": "==4.6.10"
},
"ldap3": {
"hashes": [
@ -479,11 +486,11 @@
},
"marshmallow": {
"hashes": [
"sha256:c2673233aa21dde264b84349dc2fd1dce5f30ed724a0a00e75426734de5b84ab",
"sha256:f88fe96434b1f0f476d54224d59333eba8ca1a203a2695683c1855675c4049a7"
"sha256:35ee2fb188f0bd9fc1cf9ac35e45fd394bd1c153cee430745a465ea435514bd5",
"sha256:9aa20f9b71c992b4782dad07c51d92884fd0f7c5cb9d3c737bea17ec1bad765f"
],
"index": "pypi",
"version": "==3.6.0"
"version": "==3.6.1"
},
"marshmallow-enum": {
"hashes": [
@ -968,11 +975,11 @@
},
"pytest": {
"hashes": [
"sha256:95c710d0a72d91c13fae35dce195633c929c3792f54125919847fdcdf7caa0d3",
"sha256:eb2b5e935f6a019317e455b6da83dd8650ac9ffd2ee73a7b657a30873d67a698"
"sha256:5c0db86b698e8f170ba4582a492248919255fcd4c79b1ee64ace34301fb589a1",
"sha256:7979331bfcba207414f5e1263b5a0f8f521d0f457318836a7355531ed1a4c7d8"
],
"index": "pypi",
"version": "==5.4.2"
"version": "==5.4.3"
},
"six": {
"hashes": [
@ -983,10 +990,10 @@
},
"wcwidth": {
"hashes": [
"sha256:3de2e41158cb650b91f9654cbf9a3e053cee0719c9df4ddc11e4b568669e9829",
"sha256:b651b6b081476420e4e9ae61239ac4c1b49d0c5ace42b2e81dc2ff49ed50c566"
"sha256:980fbf4f3c196c0f329cdcd1e84c554d6a211f18e252e525a0cf4223154a41d6",
"sha256:edbc2b718b4db6cdf393eefe3a420183947d6aa312505ce6754516f458ff8830"
],
"version": "==0.2.2"
"version": "==0.2.3"
},
"zipp": {
"hashes": [

View File

@ -44,4 +44,5 @@ PB_STUDY_DETAILS_URL = environ.get('PB_STUDY_DETAILS_URL', default=PB_BASE_URL +
LDAP_URL = environ.get('LDAP_URL', default="ldap.virginia.edu").strip('/') # No trailing slash or http://
LDAP_TIMEOUT_SEC = int(environ.get('LDAP_TIMEOUT_SEC', default=3))
# Fallback emails
FALLBACK_EMAILS = ['askresearch@virginia.edu', 'sartographysupport@googlegroups.com']

View File

@ -3,8 +3,10 @@ import os
import sentry_sdk
import connexion
from jinja2 import Environment, FileSystemLoader
from flask_cors import CORS
from flask_marshmallow import Marshmallow
from flask_mail import Mail
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from sentry_sdk.integrations.flask import FlaskIntegration
@ -48,6 +50,18 @@ if app.config['ENABLE_SENTRY']:
integrations=[FlaskIntegration()]
)
# Jinja environment definition, used to render mail templates
template_dir = os.getcwd() + '/crc/static/templates/mails'
env = Environment(loader=FileSystemLoader(template_dir))
# Mail settings
app.config['MAIL_SERVER']='smtp.mailtrap.io'
app.config['MAIL_PORT'] = 2525
app.config['MAIL_USERNAME'] = '5f012d0108d374'
app.config['MAIL_PASSWORD'] = '08442c04e98d50'
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USE_SSL'] = False
mail = Mail(app)
print('=== USING THESE CONFIG SETTINGS: ===')
print('DB_HOST = ', )
print('CORS_ALLOW_ORIGINS = ', app.config['CORS_ALLOW_ORIGINS'])

View File

@ -2,7 +2,7 @@ from datetime import datetime
from sqlalchemy import desc
from crc import db, session
from crc import app, db, session
from crc.api.common import ApiError
from crc.models.approval import ApprovalModel, ApprovalStatus, ApprovalFile, Approval
@ -10,6 +10,14 @@ from crc.models.study import StudyModel
from crc.models.workflow import WorkflowModel
from crc.services.file_service import FileService
from crc.services.ldap_service import LdapService
from crc.services.mails import (
send_ramp_up_submission_email,
send_ramp_up_approval_request_email,
send_ramp_up_approval_request_first_review_email,
send_ramp_up_approved_email,
send_ramp_up_denied_email,
send_ramp_up_denied_email_to_approver
)
class ApprovalService(object):
@ -84,6 +92,45 @@ class ApprovalService(object):
db_approval.status = status
session.add(db_approval)
session.commit()
if status == ApprovalStatus.APPROVED.value:
# second_approval = ApprovalModel().query.filter_by(
# study_id=db_approval.study_id, workflow_id=db_approval.workflow_id,
# status=ApprovalStatus.PENDING.value, version=db_approval.version).first()
# if second_approval:
# send rrp approval request for second approver
ldap_service = LdapService()
pi_user_info = ldap_service.user_info(model.study.primary_investigator_id)
approver_info = ldap_service.user_info(approver_uid)
# send rrp submission
send_ramp_up_approved_email(
'askresearch@virginia.edu',
[pi_user_info.email_address],
f'{approver_info.display_name} - ({approver_info.uid})'
)
elif status == ApprovalStatus.DECLINED.value:
ldap_service = LdapService()
pi_user_info = ldap_service.user_info(model.study.primary_investigator_id)
approver_info = ldap_service.user_info(approver_uid)
# send rrp submission
send_ramp_up_denied_email(
'askresearch@virginia.edu',
[pi_user_info.email_address],
f'{approver_info.display_name} - ({approver_info.uid})'
)
first_approval = ApprovalModel().query.filter_by(
study_id=db_approval.study_id, workflow_id=db_approval.workflow_id,
status=ApprovalStatus.APPROVED.value, version=db_approval.version).first()
if first_approval:
# Second approver denies
first_approver_info = ldap_service.user_info(first_approval.approver_uid)
approver_email = [first_approver_info.email_address] if first_approver_info.email_address else app.config['FALLBACK_EMAILS']
# send rrp denied by second approver email to first approver
send_ramp_up_denied_email_to_approver(
'askresearch@virginia.edu',
approver_email,
f'{pi_user_info.display_name} - ({pi_user_info.uid})',
f'{approver_info.display_name} - ({approver_info.uid})'
)
# TODO: Log update action by approver_uid - maybe ?
return db_approval
@ -133,10 +180,35 @@ class ApprovalService(object):
message="", date_created=datetime.now(),
version=version)
approval_files = ApprovalService._create_approval_files(workflow_data_files, model)
# Check approvals count
approvals_count = ApprovalModel().query.filter_by(study_id=study_id, workflow_id=workflow_id,
version=version).count()
db.session.add(model)
db.session.add_all(approval_files)
db.session.commit()
# Send first email
if approvals_count == 0:
ldap_service = LdapService()
pi_user_info = ldap_service.user_info(model.study.primary_investigator_id)
approver_info = ldap_service.user_info(approver_uid)
# send rrp submission
send_ramp_up_submission_email(
'askresearch@virginia.edu',
[pi_user_info.email_address],
f'{approver_info.display_name} - ({approver_info.uid})'
)
# send rrp approval request for first approver
# enhance the second part in case it bombs
approver_email = [approver_info.email_address] if approver_info.email_address else app.config['FALLBACK_EMAILS']
send_ramp_up_approval_request_first_review_email(
'askresearch@virginia.edu',
approver_email,
f'{pi_user_info.display_name} - ({pi_user_info.uid})'
)
@staticmethod
def _create_approval_files(workflow_data_files, approval):
"""Currently based exclusively on the status of files associated with a workflow."""

View File

@ -69,7 +69,7 @@ class LdapService(object):
# Search by user_id or last name
search_string = LdapService.user_or_last_name_search % (query, query)
results = []
print(search_string)
app.logger.info(search_string)
try:
conn = LdapService.__get_conn()
conn.search(LdapService.search_base, search_string, attributes=LdapService.attributes)

109
crc/services/mails.py Normal file
View File

@ -0,0 +1,109 @@
import os
from flask import render_template, render_template_string
from flask_mail import Message
# TODO: Extract common mailing code into its own function
def send_ramp_up_submission_email(sender, recipients, approver_1, approver_2=None):
try:
msg = Message('Research Ramp-up Plan Submitted',
sender=sender,
recipients=recipients)
from crc import env, mail
template = env.get_template('ramp_up_submission.txt')
template_vars = {'approver_1': approver_1, 'approver_2': approver_2}
msg.body = template.render(template_vars)
template = env.get_template('ramp_up_submission.html')
msg.html = template.render(template_vars)
mail.send(msg)
except Exception as e:
return str(e)
def send_ramp_up_approval_request_email(sender, recipients, primary_investigator):
try:
msg = Message('Research Ramp-up Plan Approval Request',
sender=sender,
recipients=recipients)
from crc import env, mail
template = env.get_template('ramp_up_approval_request.txt')
template_vars = {'primary_investigator': primary_investigator}
msg.body = template.render(template_vars)
template = env.get_template('ramp_up_approval_request.html')
msg.html = template.render(template_vars)
mail.send(msg)
except Exception as e:
return str(e)
def send_ramp_up_approval_request_first_review_email(sender, recipients, primary_investigator):
try:
msg = Message('Research Ramp-up Plan Approval Request',
sender=sender,
recipients=recipients)
from crc import env, mail
template = env.get_template('ramp_up_approval_request_first_review.txt')
template_vars = {'primary_investigator': primary_investigator}
msg.body = template.render(template_vars)
template = env.get_template('ramp_up_approval_request_first_review.html')
msg.html = template.render(template_vars)
mail.send(msg)
except Exception as e:
return str(e)
def send_ramp_up_approved_email(sender, recipients, approver_1, approver_2=None):
try:
msg = Message('Research Ramp-up Plan Approved',
sender=sender,
recipients=recipients)
from crc import env, mail
template = env.get_template('ramp_up_approved.txt')
template_vars = {'approver_1': approver_1, 'approver_2': approver_2}
msg.body = template.render(template_vars)
template = env.get_template('ramp_up_approved.html')
msg.html = template.render(template_vars)
mail.send(msg)
except Exception as e:
return str(e)
def send_ramp_up_denied_email(sender, recipients, approver):
try:
msg = Message('Research Ramp-up Plan Denied',
sender=sender,
recipients=recipients)
from crc import env, mail
template = env.get_template('ramp_up_denied.txt')
template_vars = {'approver': approver}
msg.body = template.render(template_vars)
template = env.get_template('ramp_up_denied.html')
msg.html = template.render(template_vars)
mail.send(msg)
except Exception as e:
return str(e)
def send_ramp_up_denied_email_to_approver(sender, recipients, primary_investigator, approver_2):
try:
msg = Message('Research Ramp-up Plan Denied',
sender=sender,
recipients=recipients)
from crc import env, mail
template = env.get_template('ramp_up_denied_first_approver.txt')
template_vars = {'primary_investigator': primary_investigator, 'approver_2': approver_2}
msg.body = template.render(template_vars)
template = env.get_template('ramp_up_denied_first_approver.html')
msg.html = template.render(template_vars)
mail.send(msg)
except Exception as e:
return str(e)

View File

@ -0,0 +1 @@
<p>A Research Ramp-up approval request from {{ primary_investigator }} is now available for your review in your [Research Ramp-up Toolkit](https://rrt.uvadcos.io/app/approvals).</p>

View File

@ -0,0 +1 @@
A Research Ramp-up approval request from {{ primary_investigator }} is now available for your review in your [Research Ramp-up Toolkit](https://rrt.uvadcos.io/app/approvals).

View File

@ -0,0 +1 @@
<p>A Research Ramp-up approval request from {{ primary_investigator }} and is now available for your review in your [Research Ramp-up Toolkit](https://rrt.uvadcos.io/app/approvals).</p>

View File

@ -0,0 +1 @@
A Research Ramp-up approval request from {{ primary_investigator }} is now available for your review in your [Research Ramp-up Toolkit](https://rrt.uvadcos.io/app/approvals).

View File

@ -0,0 +1 @@
<p>Your Research Ramp-up Plan has been approved by {{ approver_1 }} {% if approver_2 %}and {{ approver_2 }} {% endif %}</p>

View File

@ -0,0 +1 @@
Your Research Ramp-up Plan has been approved by {{ approver_1 }} {% if approver_2 %}and {{ approver_2 }} {% endif %}

View File

@ -0,0 +1 @@
<p>Your Research Ramp-up Plan has been denied by {{ approver_1 }}. Please return to the Research Ramp-up Plan application and review the comments from {{ approver_1 }} on the home page. Next, open the application and locate the first step where changes are needed. Continue to complete additional steps saving your work along the way. Review your revised Research Ramp-up Plan and res-submit for approval.</p>

View File

@ -0,0 +1 @@
Your Research Ramp-up Plan has been denied by {{ approver_1 }}. Please return to the Research Ramp-up Plan application and review the comments from {{ approver_1 }} on the home page. Next, open the application and locate the first step where changes are needed. Continue to complete additional steps saving your work along the way. Review your revised Research Ramp-up Plan and res-submit for approval.

View File

@ -0,0 +1 @@
<p>The Research Ramp-up Plan submitted by {{ primary_investigator }} was denied by {{ approver_2 }} and returned for requested updates. You may see comments related to this denial in on your Research Ramp-up Toolkit Approval dashboard.</p>

View File

@ -0,0 +1 @@
The Research Ramp-up Plan submitted by {{ primary_investigator }} was denied by {{ approver_2 }} and returned for requested updates. You may see comments related to this denial in on your Research Ramp-up Toolkit Approval dashboard.

View File

@ -0,0 +1,5 @@
<p>Your Research Ramp-up Plan (RRP) has been submitted for review by {{ approver_1 }} {% if approver_2 %}and {{ approver_2 }} {% endif %}. After completion of the review step you will receive email notification of its approval or if additional information and/or modifications are required, along with instructions on how to proceed. Return to the Research Ramp-up Plan application to proceed as instructed.</p>
<p>In the meantime, please make sure all required training has been completed and needed supplies secured. You will be asked to confirm that both of these requirements have been met before reopening the research space approved in your RRP.</p>
<p>Additionally, if there are any unknown Area Monitors for the spaces listed in your RRP, please contact your approvers to determine either who they are or how you can find out. Missing Area Monitors will need to be entered before proceeding as well.</p>

View File

@ -0,0 +1,5 @@
Your Research Ramp-up Plan (RRP) has been submitted for review by {{ approver_1 }} {% if approver_2 %}and {{ approver_2 }} {% endif %}. After completion of the review step you will receive email notification of its approval or if additional information and/or modifications are required, along with instructions on how to proceed. Return to the Research Ramp-up Plan application to proceed as instructed.
In the meantime, please make sure all required training has been completed and needed supplies secured. You will be asked to confirm that both of these requirements have been met before reopening the research space approved in your RRP.
Additionally, if there are any unknown Area Monitors for the spaces listed in your RRP, please contact your approvers to determine either who they are or how you can find out. Missing Area Monitors will need to be entered before proceeding as well.

View File

@ -119,7 +119,6 @@ class BaseTest(unittest.TestCase):
"""use_crc_data will cause this to load the mammoth collection of documents
we built up developing crc, use_rrt_data will do the same for hte rrt project,
otherwise it depends on a small setup for running tests."""
from example_data import ExampleDataLoader
ExampleDataLoader.clean_db()
if use_crc_data:
@ -228,7 +227,7 @@ class BaseTest(unittest.TestCase):
if study is None:
user = self.create_user(uid=uid)
study = StudyModel(title=title, protocol_builder_status=ProtocolBuilderStatus.ACTIVE,
user_uid=user.uid)
user_uid=user.uid, primary_investigator_id='lb3dp')
db.session.add(study)
db.session.commit()
return study

View File

@ -15,13 +15,14 @@ class TestApprovalsService(BaseTest):
name="anything.png", content_type="text",
binary_data=b'5678', irb_doc_code="UVACompl_PRCAppr" )
ApprovalService.add_approval(study_id=workflow.study_id, workflow_id=workflow.id, approver_uid="dhf8r")
self.assertEquals(1, db.session.query(ApprovalModel).count())
self.assertEqual(1, db.session.query(ApprovalModel).count())
model = db.session.query(ApprovalModel).first()
self.assertEquals(workflow.study_id, model.study_id)
self.assertEquals(workflow.id, model.workflow_id)
self.assertEquals("dhf8r", model.approver_uid)
self.assertEquals(1, model.version)
self.assertEqual(workflow.study_id, model.study_id)
self.assertEqual(workflow.id, model.workflow_id)
self.assertEqual("dhf8r", model.approver_uid)
self.assertEqual(1, model.version)
def test_new_requests_dont_add_if_approval_exists_for_current_workflow(self):
self.create_reference_document()
@ -32,9 +33,9 @@ class TestApprovalsService(BaseTest):
ApprovalService.add_approval(study_id=workflow.study_id, workflow_id=workflow.id, approver_uid="dhf8r")
ApprovalService.add_approval(study_id=workflow.study_id, workflow_id=workflow.id, approver_uid="dhf8r")
self.assertEquals(1, db.session.query(ApprovalModel).count())
self.assertEqual(1, db.session.query(ApprovalModel).count())
model = db.session.query(ApprovalModel).first()
self.assertEquals(1, model.version)
self.assertEqual(1, model.version)
def test_new_approval_requests_after_file_modification_create_new_requests(self):
self.load_example_data()
@ -51,9 +52,20 @@ class TestApprovalsService(BaseTest):
binary_data=b'5678', irb_doc_code="UVACompl_PRCAppr")
ApprovalService.add_approval(study_id=workflow.study_id, workflow_id=workflow.id, approver_uid="dhf8r")
self.assertEquals(2, db.session.query(ApprovalModel).count())
self.assertEqual(2, db.session.query(ApprovalModel).count())
models = db.session.query(ApprovalModel).order_by(ApprovalModel.version).all()
self.assertEquals(1, models[0].version)
self.assertEquals(2, models[1].version)
self.assertEqual(1, models[0].version)
self.assertEqual(2, models[1].version)
def test_new_approval_sends_proper_emails(self):
self.assertEqual(1, 1)
def test_new_approval_failed_ldap_lookup(self):
# failed lookup should send email to sartographysupport@googlegroups.com + Cheryl
self.assertEqual(1, 1)
def test_approve_approval_sends_proper_emails(self):
self.assertEqual(1, 1)
def test_deny_approval_sends_proper_emails(self):
self.assertEqual(1, 1)

View File

@ -49,10 +49,10 @@ class TestAuthentication(BaseTest):
self.assert_success(rv)
user = db.session.query(UserModel).filter(UserModel.uid == new_uid).first()
self.assertIsNotNone(user)
self.assertEquals(new_uid, user.uid)
self.assertEquals("Laura Barnes", user.display_name)
self.assertEquals("lb3dp@virginia.edu", user.email_address)
self.assertEquals("E0:Associate Professor of Systems and Information Engineering", user.title)
self.assertEqual(new_uid, user.uid)
self.assertEqual("Laura Barnes", user.display_name)
self.assertEqual("lb3dp@virginia.edu", user.email_address)
self.assertEqual("E0:Associate Professor of Systems and Information Engineering", user.title)
def test_current_user_status(self):

View File

@ -17,7 +17,7 @@ class TestCompleteTemplate(unittest.TestCase):
data = {"name": "Dan"}
data_copy = copy.deepcopy(data)
script.rich_text_update(data_copy)
self.assertEquals(data, data_copy)
self.assertEqual(data, data_copy)
def test_rich_text_update_new_line(self):
script = CompleteTemplate()

View File

@ -23,11 +23,11 @@ class TestFileService(BaseTest):
binary_data=b'5678', irb_doc_code=irb_code)
file_models = FileService.get_workflow_files(workflow_id=workflow.id)
self.assertEquals(1, len(file_models))
self.assertEqual(1, len(file_models))
file_data = FileService.get_workflow_data_files(workflow_id=workflow.id)
self.assertEquals(1, len(file_data))
self.assertEquals(2, file_data[0].version)
self.assertEqual(1, len(file_data))
self.assertEqual(2, file_data[0].version)
def test_add_file_from_form_increments_version_and_replaces_on_subsequent_add_with_same_name(self):
@ -77,12 +77,13 @@ class TestFileService(BaseTest):
binary_data=b'5678')
file_models = FileService.get_workflow_files(workflow_id=workflow.id)
self.assertEquals(1, len(file_models))
self.assertEqual(1, len(file_models))
file_data = FileService.get_workflow_data_files(workflow_id=workflow.id)
self.assertEquals(1, len(file_data))
self.assertEquals(2, file_data[0].version)
self.assertEquals(b'5678', file_data[0].data)
self.assertEqual(1, len(file_data))
self.assertEqual(2, file_data[0].version)
self.assertEqual(b'5678', file_data[0].data)
def test_add_file_from_form_allows_multiple_files_with_different_names(self):
self.load_example_data()
@ -101,4 +102,4 @@ class TestFileService(BaseTest):
name="a_different_thing.png", content_type="text",
binary_data=b'5678')
file_models = FileService.get_workflow_files(workflow_id=workflow.id)
self.assertEquals(2, len(file_models))
self.assertEqual(2, len(file_models))

View File

@ -30,4 +30,4 @@ class TestLdapService(BaseTest):
user_info = LdapService.user_info("nosuch")
self.assertFalse(True, "An API error should be raised.")
except ApiError as ae:
self.assertEquals("missing_ldap_record", ae.code)
self.assertEqual("missing_ldap_record", ae.code)

View File

@ -31,7 +31,7 @@ class TestLookupService(BaseTest):
self.assertEqual(1, len(lookup_records))
lookup_record = lookup_records[0]
lookup_data = session.query(LookupDataModel).filter(LookupDataModel.lookup_file_model == lookup_record).all()
self.assertEquals(28, len(lookup_data))
self.assertEqual(28, len(lookup_data))
def test_updates_to_file_cause_lookup_rebuild(self):
spec = BaseTest.load_test_spec('enum_options_with_search')
@ -43,7 +43,7 @@ class TestLookupService(BaseTest):
self.assertEqual(1, len(lookup_records))
lookup_record = lookup_records[0]
lookup_data = session.query(LookupDataModel).filter(LookupDataModel.lookup_file_model == lookup_record).all()
self.assertEquals(28, len(lookup_data))
self.assertEqual(28, len(lookup_data))
# Update the workflow specification file.
file_path = os.path.join(app.root_path, '..', 'tests', 'data',
@ -59,7 +59,7 @@ class TestLookupService(BaseTest):
lookup_records = session.query(LookupFileModel).all()
lookup_record = lookup_records[0]
lookup_data = session.query(LookupDataModel).filter(LookupDataModel.lookup_file_model == lookup_record).all()
self.assertEquals(4, len(lookup_data))
self.assertEqual(4, len(lookup_data))
@ -70,49 +70,49 @@ class TestLookupService(BaseTest):
processor.do_engine_steps()
results = LookupService.lookup(workflow, "AllTheNames", "", limit=10)
self.assertEquals(10, len(results), "Blank queries return everything, to the limit")
self.assertEqual(10, len(results), "Blank queries return everything, to the limit")
results = LookupService.lookup(workflow, "AllTheNames", "medicines", limit=10)
self.assertEquals(1, len(results), "words in the middle of label are detected.")
self.assertEquals("The Medicines Company", results[0].label)
self.assertEqual(1, len(results), "words in the middle of label are detected.")
self.assertEqual("The Medicines Company", results[0].label)
results = LookupService.lookup(workflow, "AllTheNames", "UVA", limit=10)
self.assertEquals(1, len(results), "Beginning of label is found.")
self.assertEquals("UVA - INTERNAL - GM USE ONLY", results[0].label)
self.assertEqual(1, len(results), "Beginning of label is found.")
self.assertEqual("UVA - INTERNAL - GM USE ONLY", results[0].label)
results = LookupService.lookup(workflow, "AllTheNames", "uva", limit=10)
self.assertEquals(1, len(results), "case does not matter.")
self.assertEquals("UVA - INTERNAL - GM USE ONLY", results[0].label)
self.assertEqual(1, len(results), "case does not matter.")
self.assertEqual("UVA - INTERNAL - GM USE ONLY", results[0].label)
results = LookupService.lookup(workflow, "AllTheNames", "medici", limit=10)
self.assertEquals(1, len(results), "partial words are picked up.")
self.assertEquals("The Medicines Company", results[0].label)
self.assertEqual(1, len(results), "partial words are picked up.")
self.assertEqual("The Medicines Company", results[0].label)
results = LookupService.lookup(workflow, "AllTheNames", "Genetics Savings", limit=10)
self.assertEquals(1, len(results), "multiple terms are picked up..")
self.assertEquals("Genetics Savings & Clone, Inc.", results[0].label)
self.assertEqual(1, len(results), "multiple terms are picked up..")
self.assertEqual("Genetics Savings & Clone, Inc.", results[0].label)
results = LookupService.lookup(workflow, "AllTheNames", "Genetics Sav", limit=10)
self.assertEquals(1, len(results), "prefix queries still work with partial terms")
self.assertEquals("Genetics Savings & Clone, Inc.", results[0].label)
self.assertEqual(1, len(results), "prefix queries still work with partial terms")
self.assertEqual("Genetics Savings & Clone, Inc.", results[0].label)
results = LookupService.lookup(workflow, "AllTheNames", "Gen Sav", limit=10)
self.assertEquals(1, len(results), "prefix queries still work with ALL the partial terms")
self.assertEquals("Genetics Savings & Clone, Inc.", results[0].label)
self.assertEqual(1, len(results), "prefix queries still work with ALL the partial terms")
self.assertEqual("Genetics Savings & Clone, Inc.", results[0].label)
results = LookupService.lookup(workflow, "AllTheNames", "Inc", limit=10)
self.assertEquals(7, len(results), "short terms get multiple correct results.")
self.assertEquals("Genetics Savings & Clone, Inc.", results[0].label)
self.assertEqual(7, len(results), "short terms get multiple correct results.")
self.assertEqual("Genetics Savings & Clone, Inc.", results[0].label)
results = LookupService.lookup(workflow, "AllTheNames", "reaction design", limit=10)
self.assertEquals(5, len(results), "all results come back for two terms.")
self.assertEquals("Reaction Design", results[0].label, "Exact matches come first.")
self.assertEqual(5, len(results), "all results come back for two terms.")
self.assertEqual("Reaction Design", results[0].label, "Exact matches come first.")
results = LookupService.lookup(workflow, "AllTheNames", "1 Something", limit=10)
self.assertEquals("1 Something", results[0].label, "Exact matches are prefered")
self.assertEqual("1 Something", results[0].label, "Exact matches are prefered")
results = LookupService.lookup(workflow, "AllTheNames", "1 (!-Something", limit=10)
self.assertEquals("1 Something", results[0].label, "special characters don't flake out")
self.assertEqual("1 Something", results[0].label, "special characters don't flake out")
@ -124,6 +124,6 @@ class TestLookupService(BaseTest):
# Fixme: Stop words are taken into account on the query side, and haven't found a fix yet.
#results = WorkflowService.run_lookup_query(lookup_table.id, "in", limit=10)
#self.assertEquals(7, len(results), "stop words are not removed.")
#self.assertEquals("Genetics Savings & Clone, Inc.", results[0].label)
#self.assertEqual(7, len(results), "stop words are not removed.")
#self.assertEqual("Genetics Savings & Clone, Inc.", results[0].label)

55
tests/test_mails.py Normal file
View File

@ -0,0 +1,55 @@
from tests.base_test import BaseTest
from crc.services.mails import (
send_ramp_up_submission_email,
send_ramp_up_approval_request_email,
send_ramp_up_approval_request_first_review_email,
send_ramp_up_approved_email,
send_ramp_up_denied_email,
send_ramp_up_denied_email_to_approver
)
class TestMails(BaseTest):
def setUp(self):
self.sender = 'sender@sartography.com'
self.recipients = ['recipient@sartography.com']
self.primary_investigator = 'Dr. Bartlett'
self.approver_1 = 'Max Approver'
self.approver_2 = 'Close Reviewer'
def test_send_ramp_up_submission_email(self):
send_ramp_up_submission_email(self.sender, self.recipients, self.approver_1)
self.assertTrue(True)
send_ramp_up_submission_email(self.sender, self.recipients, self.approver_1, self.approver_2)
self.assertTrue(True)
def test_send_ramp_up_approval_request_email(self):
send_ramp_up_approval_request_email(self.sender, self.recipients, self.primary_investigator)
self.assertTrue(True)
def test_send_ramp_up_approval_request_first_review_email(self):
send_ramp_up_approval_request_first_review_email(
self.sender, self.recipients, self.primary_investigator
)
self.assertTrue(True)
def test_send_ramp_up_approved_email(self):
send_ramp_up_approved_email(self.sender, self.recipients, self.approver_1)
self.assertTrue(True)
send_ramp_up_approved_email(self.sender, self.recipients, self.approver_1, self.approver_2)
self.assertTrue(True)
def test_send_ramp_up_denied_email(self):
send_ramp_up_denied_email(self.sender, self.recipients, self.approver_1)
self.assertTrue(True)
def test_send_send_ramp_up_denied_email_to_approver(self):
send_ramp_up_denied_email_to_approver(
self.sender, self.recipients, self.primary_investigator, self.approver_2
)
self.assertTrue(True)

View File

@ -24,7 +24,7 @@ class TestRequestApprovalScript(BaseTest):
binary_data=b'1234')
script = RequestApproval()
script.do_task(task, workflow.study_id, workflow.id, "study.approval1", "study.approval2")
self.assertEquals(2, db.session.query(ApprovalModel).count())
self.assertEqual(2, db.session.query(ApprovalModel).count())
def test_do_task_with_blank_second_approver(self):
self.load_example_data()
@ -39,7 +39,7 @@ class TestRequestApprovalScript(BaseTest):
binary_data=b'1234')
script = RequestApproval()
script.do_task(task, workflow.study_id, workflow.id, "study.approval1", "study.approval2")
self.assertEquals(1, db.session.query(ApprovalModel).count())
self.assertEqual(1, db.session.query(ApprovalModel).count())
def test_do_task_with_incorrect_argument(self):
@ -64,5 +64,5 @@ class TestRequestApprovalScript(BaseTest):
script = RequestApproval()
script.do_task_validate_only(task, workflow.study_id, workflow.id, "study.approval1")
self.assertEquals(0, db.session.query(ApprovalModel).count())
self.assertEqual(0, db.session.query(ApprovalModel).count())

View File

@ -87,10 +87,10 @@ class TestStudyApi(BaseTest):
headers=self.logged_in_headers(), content_type="application/json")
self.assert_success(api_response)
study = StudySchema().loads(api_response.get_data(as_text=True))
self.assertEquals(1, len(study.files))
self.assertEquals("UVA Compliance/PRC Approval", study.files[0]["category"])
self.assertEquals("Cancer Center's PRC Approval Form", study.files[0]["description"])
self.assertEquals("UVA Compliance/PRC Approval.png", study.files[0]["download_name"])
self.assertEqual(1, len(study.files))
self.assertEqual("UVA Compliance/PRC Approval", study.files[0]["category"])
self.assertEqual("Cancer Center's PRC Approval Form", study.files[0]["description"])
self.assertEqual("UVA Compliance/PRC Approval.png", study.files[0]["download_name"])
# TODO: WRITE A TEST FOR STUDY FILES
@ -180,10 +180,10 @@ class TestStudyApi(BaseTest):
db_studies_after = session.query(StudyModel).all()
num_db_studies_after = len(db_studies_after)
self.assertGreater(num_db_studies_after, num_db_studies_before)
self.assertEquals(num_abandoned, 1)
self.assertEquals(num_open, 1)
self.assertEquals(num_active, 1)
self.assertEquals(num_incomplete, 1)
self.assertEqual(num_abandoned, 1)
self.assertEqual(num_open, 1)
self.assertEqual(num_active, 1)
self.assertEqual(num_incomplete, 1)
self.assertEqual(len(json_data), num_db_studies_after)
self.assertEqual(num_open + num_active + num_incomplete + num_abandoned, num_db_studies_after)

View File

@ -153,7 +153,7 @@ class TestStudyService(BaseTest):
self.assertEqual(1, docs["UVACompl_PRCAppr"]['count'])
self.assertIsNotNone(docs["UVACompl_PRCAppr"]['files'][0])
self.assertIsNotNone(docs["UVACompl_PRCAppr"]['files'][0]['file_id'])
self.assertEquals(workflow.id, docs["UVACompl_PRCAppr"]['files'][0]['workflow_id'])
self.assertEqual(workflow.id, docs["UVACompl_PRCAppr"]['files'][0]['workflow_id'])
def test_get_all_studies(self):
user = self.create_user_with_study_and_workflow()
@ -174,8 +174,8 @@ class TestStudyService(BaseTest):
binary_data=b'1234', irb_doc_code="UVACompl_PRCAppr" )
studies = StudyService().get_all_studies_with_files()
self.assertEquals(1, len(studies))
self.assertEquals(3, len(studies[0].files))
self.assertEqual(1, len(studies))
self.assertEqual(3, len(studies[0].files))
@ -191,17 +191,17 @@ class TestStudyService(BaseTest):
workflow = self.create_workflow('docx') # The workflow really doesnt matter in this case.
investigators = StudyService().get_investigators(workflow.study_id)
self.assertEquals(9, len(investigators))
self.assertEqual(9, len(investigators))
# dhf8r is in the ldap mock data.
self.assertEquals("dhf8r", investigators['PI']['user_id'])
self.assertEquals("Dan Funk", investigators['PI']['display_name']) # Data from ldap
self.assertEquals("Primary Investigator", investigators['PI']['label']) # Data from xls file.
self.assertEquals("Always", investigators['PI']['display']) # Data from xls file.
self.assertEqual("dhf8r", investigators['PI']['user_id'])
self.assertEqual("Dan Funk", investigators['PI']['display_name']) # Data from ldap
self.assertEqual("Primary Investigator", investigators['PI']['label']) # Data from xls file.
self.assertEqual("Always", investigators['PI']['display']) # Data from xls file.
# asd3v is not in ldap, so an error should be returned.
self.assertEquals("asd3v", investigators['DC']['user_id'])
self.assertEquals("Unable to locate a user with id asd3v in LDAP", investigators['DC']['error']) # Data from ldap
self.assertEqual("asd3v", investigators['DC']['user_id'])
self.assertEqual("Unable to locate a user with id asd3v in LDAP", investigators['DC']['error']) # Data from ldap
# No value is provided for Department Chair
self.assertIsNone(investigators['DEPT_CH']['user_id'])

View File

@ -48,7 +48,7 @@ class TestTasksApi(BaseTest):
# The total number of tasks may change over time, as users move through gateways
# branches may be pruned. As we hit parallel Multi-Instance new tasks may be created...
self.assertIsNotNone(workflow.total_tasks)
self.assertEquals(prev_completed_task_count + 1, workflow.completed_tasks)
self.assertEqual(prev_completed_task_count + 1, workflow.completed_tasks)
# Assure a record exists in the Task Events
task_events = session.query(TaskEventModel) \
.filter_by(workflow_id=workflow.id) \
@ -57,25 +57,25 @@ class TestTasksApi(BaseTest):
self.assertGreater(len(task_events), 0)
event = task_events[0]
self.assertIsNotNone(event.study_id)
self.assertEquals("dhf8r", event.user_uid)
self.assertEquals(workflow.id, event.workflow_id)
self.assertEquals(workflow.workflow_spec_id, event.workflow_spec_id)
self.assertEquals(workflow.spec_version, event.spec_version)
self.assertEquals(WorkflowService.TASK_ACTION_COMPLETE, event.action)
self.assertEquals(task_in.id, task_id)
self.assertEquals(task_in.name, event.task_name)
self.assertEquals(task_in.title, event.task_title)
self.assertEquals(task_in.type, event.task_type)
self.assertEquals("COMPLETED", event.task_state)
self.assertEqual("dhf8r", event.user_uid)
self.assertEqual(workflow.id, event.workflow_id)
self.assertEqual(workflow.workflow_spec_id, event.workflow_spec_id)
self.assertEqual(workflow.spec_version, event.spec_version)
self.assertEqual(WorkflowService.TASK_ACTION_COMPLETE, event.action)
self.assertEqual(task_in.id, task_id)
self.assertEqual(task_in.name, event.task_name)
self.assertEqual(task_in.title, event.task_title)
self.assertEqual(task_in.type, event.task_type)
self.assertEqual("COMPLETED", event.task_state)
# Not sure what vodoo is happening inside of marshmallow to get me in this state.
if isinstance(task_in.multi_instance_type, MultiInstanceType):
self.assertEquals(task_in.multi_instance_type.value, event.mi_type)
self.assertEqual(task_in.multi_instance_type.value, event.mi_type)
else:
self.assertEquals(task_in.multi_instance_type, event.mi_type)
self.assertEqual(task_in.multi_instance_type, event.mi_type)
self.assertEquals(task_in.multi_instance_count, event.mi_count)
self.assertEquals(task_in.multi_instance_index, event.mi_index)
self.assertEquals(task_in.process_name, event.process_name)
self.assertEqual(task_in.multi_instance_count, event.mi_count)
self.assertEqual(task_in.multi_instance_index, event.mi_index)
self.assertEqual(task_in.process_name, event.process_name)
self.assertIsNotNone(event.date)
@ -155,14 +155,14 @@ class TestTasksApi(BaseTest):
self.assertIsNotNone(workflow_api.navigation)
nav = workflow_api.navigation
self.assertEquals(5, len(nav))
self.assertEquals("Do You Have Bananas", nav[0]['title'])
self.assertEquals("Bananas?", nav[1]['title'])
self.assertEquals("FUTURE", nav[1]['state'])
self.assertEquals("yes", nav[2]['title'])
self.assertEquals("NOOP", nav[2]['state'])
self.assertEquals("no", nav[3]['title'])
self.assertEquals("NOOP", nav[3]['state'])
self.assertEqual(5, len(nav))
self.assertEqual("Do You Have Bananas", nav[0]['title'])
self.assertEqual("Bananas?", nav[1]['title'])
self.assertEqual("FUTURE", nav[1]['state'])
self.assertEqual("yes", nav[2]['title'])
self.assertEqual("NOOP", nav[2]['state'])
self.assertEqual("no", nav[3]['title'])
self.assertEqual("NOOP", nav[3]['state'])
def test_navigation_with_exclusive_gateway(self):
self.load_example_data()
@ -172,14 +172,14 @@ class TestTasksApi(BaseTest):
workflow_api = self.get_workflow_api(workflow)
self.assertIsNotNone(workflow_api.navigation)
nav = workflow_api.navigation
self.assertEquals(7, len(nav))
self.assertEquals("Task 1", nav[0]['title'])
self.assertEquals("Which Branch?", nav[1]['title'])
self.assertEquals("a", nav[2]['title'])
self.assertEquals("Task 2a", nav[3]['title'])
self.assertEquals("b", nav[4]['title'])
self.assertEquals("Task 2b", nav[5]['title'])
self.assertEquals("Task 3", nav[6]['title'])
self.assertEqual(7, len(nav))
self.assertEqual("Task 1", nav[0]['title'])
self.assertEqual("Which Branch?", nav[1]['title'])
self.assertEqual("a", nav[2]['title'])
self.assertEqual("Task 2a", nav[3]['title'])
self.assertEqual("b", nav[4]['title'])
self.assertEqual("Task 2b", nav[5]['title'])
self.assertEqual("Task 3", nav[6]['title'])
def test_document_added_to_workflow_shows_up_in_file_list(self):
self.load_example_data()
@ -285,8 +285,8 @@ class TestTasksApi(BaseTest):
workflow_api = self.complete_form(workflow, task, {"name": "Dan"})
workflow = self.get_workflow_api(workflow)
self.assertEquals('Task_Manual_One', workflow.next_task.name)
self.assertEquals('ManualTask', workflow_api.next_task.type)
self.assertEqual('Task_Manual_One', workflow.next_task.name)
self.assertEqual('ManualTask', workflow_api.next_task.type)
self.assertTrue('Markdown' in workflow_api.next_task.documentation)
self.assertTrue('Dan' in workflow_api.next_task.documentation)
@ -296,7 +296,7 @@ class TestTasksApi(BaseTest):
# get the first form in the two form workflow.
task = self.get_workflow_api(workflow).next_task
self.assertEquals("JustAValue", task.properties['JustAKey'])
self.assertEqual("JustAValue", task.properties['JustAKey'])
@patch('crc.services.protocol_builder.requests.get')
@ -316,13 +316,13 @@ class TestTasksApi(BaseTest):
# get the first form in the two form workflow.
workflow = self.get_workflow_api(workflow)
navigation = self.get_workflow_api(workflow).navigation
self.assertEquals(4, len(navigation)) # Start task, form_task, multi_task, end task
self.assertEquals("UserTask", workflow.next_task.type)
self.assertEquals(MultiInstanceType.sequential.value, workflow.next_task.multi_instance_type)
self.assertEquals(9, workflow.next_task.multi_instance_count)
self.assertEqual(4, len(navigation)) # Start task, form_task, multi_task, end task
self.assertEqual("UserTask", workflow.next_task.type)
self.assertEqual(MultiInstanceType.sequential.value, workflow.next_task.multi_instance_type)
self.assertEqual(9, workflow.next_task.multi_instance_count)
# Assure that the names for each task are properly updated, so they aren't all the same.
self.assertEquals("Primary Investigator", workflow.next_task.properties['display_name'])
self.assertEqual("Primary Investigator", workflow.next_task.properties['display_name'])
def test_lookup_endpoint_for_task_field_enumerations(self):
@ -364,18 +364,18 @@ class TestTasksApi(BaseTest):
navigation = workflow_api.navigation
task = workflow_api.next_task
self.assertEquals(2, len(navigation))
self.assertEquals("UserTask", task.type)
self.assertEquals("Activity_A", task.name)
self.assertEquals("My Sub Process", task.process_name)
self.assertEqual(2, len(navigation))
self.assertEqual("UserTask", task.type)
self.assertEqual("Activity_A", task.name)
self.assertEqual("My Sub Process", task.process_name)
workflow_api = self.complete_form(workflow, task, {"name": "Dan"})
task = workflow_api.next_task
self.assertIsNotNone(task)
self.assertEquals("Activity_B", task.name)
self.assertEquals("Sub Workflow Example", task.process_name)
self.assertEqual("Activity_B", task.name)
self.assertEqual("Sub Workflow Example", task.process_name)
workflow_api = self.complete_form(workflow, task, {"name": "Dan"})
self.assertEquals(WorkflowStatus.complete, workflow_api.status)
self.assertEqual(WorkflowStatus.complete, workflow_api.status)
def test_update_task_resets_token(self):
self.load_example_data()
@ -385,7 +385,7 @@ class TestTasksApi(BaseTest):
first_task = self.get_workflow_api(workflow).next_task
self.complete_form(workflow, first_task, {"has_bananas": True})
workflow = self.get_workflow_api(workflow)
self.assertEquals('Task_Num_Bananas', workflow.next_task.name)
self.assertEqual('Task_Num_Bananas', workflow.next_task.name)
# Trying to re-submit the initial task, and answer differently, should result in an error.
self.complete_form(workflow, first_task, {"has_bananas": False}, error_code="invalid_state")
@ -406,18 +406,18 @@ class TestTasksApi(BaseTest):
workflow = WorkflowApiSchema().load(json_data)
# Assure the Next Task is the one we just reset the token to be on.
self.assertEquals("Task_Has_Bananas", workflow.next_task.name)
self.assertEqual("Task_Has_Bananas", workflow.next_task.name)
# Go ahead and get that workflow one more time, it should still be right.
workflow = self.get_workflow_api(workflow)
# Assure the Next Task is the one we just reset the token to be on.
self.assertEquals("Task_Has_Bananas", workflow.next_task.name)
self.assertEqual("Task_Has_Bananas", workflow.next_task.name)
# The next task should be a different value.
self.complete_form(workflow, workflow.next_task, {"has_bananas": False})
workflow = self.get_workflow_api(workflow)
self.assertEquals('Task_Why_No_Bananas', workflow.next_task.name)
self.assertEqual('Task_Why_No_Bananas', workflow.next_task.name)
@patch('crc.services.protocol_builder.requests.get')
def test_parallel_multi_instance(self, mock_get):
@ -432,13 +432,13 @@ class TestTasksApi(BaseTest):
workflow = self.create_workflow('multi_instance_parallel')
workflow_api = self.get_workflow_api(workflow)
self.assertEquals(12, len(workflow_api.navigation))
self.assertEqual(12, len(workflow_api.navigation))
ready_items = [nav for nav in workflow_api.navigation if nav['state'] == "READY"]
self.assertEquals(9, len(ready_items))
self.assertEqual(9, len(ready_items))
self.assertEquals("UserTask", workflow_api.next_task.type)
self.assertEquals("MutiInstanceTask",workflow_api.next_task.name)
self.assertEquals("more information", workflow_api.next_task.title)
self.assertEqual("UserTask", workflow_api.next_task.type)
self.assertEqual("MutiInstanceTask",workflow_api.next_task.name)
self.assertEqual("more information", workflow_api.next_task.title)
for i in random.sample(range(9), 9):
task = TaskSchema().load(ready_items[i]['task'])
@ -446,5 +446,5 @@ class TestTasksApi(BaseTest):
#tasks = self.get_workflow_api(workflow).user_tasks
workflow = self.get_workflow_api(workflow)
self.assertEquals(WorkflowStatus.complete, workflow.status)
self.assertEqual(WorkflowStatus.complete, workflow.status)

View File

@ -28,7 +28,7 @@ class TestStudyApi(BaseTest):
content_type='multipart/form-data')
self.assert_success(rv)
self.assertIsNotNone(rv.data)
self.assertEquals('application/octet-stream', rv.content_type)
self.assertEqual('application/octet-stream', rv.content_type)
def test_list_scripts(self):
rv = self.app.get('/v1.0/list_scripts')

View File

@ -19,5 +19,5 @@ class TestUpdateStudyScript(BaseTest):
script = UpdateStudy()
script.do_task(task, workflow.study_id, workflow.id, "title:details.label", "pi:details.value")
self.assertEquals("My New Title", workflow.study.title)
self.assertEquals("dhf8r", workflow.study.primary_investigator_id)
self.assertEqual("My New Title", workflow.study.title)
self.assertEqual("dhf8r", workflow.study.primary_investigator_id)

View File

@ -57,13 +57,13 @@ class TestWorkflowProcessorMultiInstance(BaseTest):
task = next_user_tasks[0]
self.assertEqual(WorkflowStatus.user_input_required, processor.get_status())
self.assertEquals("dhf8r", task.data["investigator"]["user_id"])
self.assertEqual("dhf8r", task.data["investigator"]["user_id"])
self.assertEqual("MutiInstanceTask", task.get_name())
api_task = WorkflowService.spiff_task_to_api_task(task)
self.assertEquals(MultiInstanceType.sequential, api_task.multi_instance_type)
self.assertEquals(3, api_task.multi_instance_count)
self.assertEquals(1, api_task.multi_instance_index)
self.assertEqual(MultiInstanceType.sequential, api_task.multi_instance_type)
self.assertEqual(3, api_task.multi_instance_count)
self.assertEqual(1, api_task.multi_instance_index)
task.update_data({"investigator":{"email":"asd3v@virginia.edu"}})
processor.complete_task(task)
processor.do_engine_steps()
@ -72,8 +72,8 @@ class TestWorkflowProcessorMultiInstance(BaseTest):
api_task = WorkflowService.spiff_task_to_api_task(task)
self.assertEqual("MutiInstanceTask", api_task.name)
task.update_data({"investigator":{"email":"asdf32@virginia.edu"}})
self.assertEquals(3, api_task.multi_instance_count)
self.assertEquals(2, api_task.multi_instance_index)
self.assertEqual(3, api_task.multi_instance_count)
self.assertEqual(2, api_task.multi_instance_index)
processor.complete_task(task)
processor.do_engine_steps()
@ -81,8 +81,8 @@ class TestWorkflowProcessorMultiInstance(BaseTest):
api_task = WorkflowService.spiff_task_to_api_task(task)
self.assertEqual("MutiInstanceTask", task.get_name())
task.update_data({"investigator":{"email":"dhf8r@virginia.edu"}})
self.assertEquals(3, api_task.multi_instance_count)
self.assertEquals(3, api_task.multi_instance_index)
self.assertEqual(3, api_task.multi_instance_count)
self.assertEqual(3, api_task.multi_instance_index)
processor.complete_task(task)
processor.do_engine_steps()
task = processor.bpmn_workflow.last_task
@ -91,7 +91,7 @@ class TestWorkflowProcessorMultiInstance(BaseTest):
expected['PI']['email'] = "asd3v@virginia.edu"
expected['SC_I']['email'] = "asdf32@virginia.edu"
expected['DC']['email'] = "dhf8r@virginia.edu"
self.assertEquals(expected,
self.assertEqual(expected,
task.data['StudyInfo']['investigators'])
self.assertEqual(WorkflowStatus.complete, processor.get_status())
@ -117,10 +117,10 @@ class TestWorkflowProcessorMultiInstance(BaseTest):
task = next_user_tasks[2]
self.assertEqual(WorkflowStatus.user_input_required, processor.get_status())
self.assertEquals("asd3v", task.data["investigator"]["user_id"]) # The last of the tasks
self.assertEqual("asd3v", task.data["investigator"]["user_id"]) # The last of the tasks
api_task = WorkflowService.spiff_task_to_api_task(task)
self.assertEquals(MultiInstanceType.parallel, api_task.multi_instance_type)
self.assertEqual(MultiInstanceType.parallel, api_task.multi_instance_type)
task.update_data({"investigator":{"email":"dhf8r@virginia.edu"}})
processor.complete_task(task)
processor.do_engine_steps()
@ -144,7 +144,7 @@ class TestWorkflowProcessorMultiInstance(BaseTest):
expected['PI']['email'] = "asd3v@virginia.edu"
expected['SC_I']['email'] = "asdf32@virginia.edu"
expected['DC']['email'] = "dhf8r@virginia.edu"
self.assertEquals(expected,
self.assertEqual(expected,
task.data['StudyInfo']['investigators'])
self.assertEqual(WorkflowStatus.complete, processor.get_status())

View File

@ -66,9 +66,9 @@ class TestWorkflowService(BaseTest):
task = processor.next_task()
WorkflowService.process_options(task, task.task_spec.form.fields[0])
options = task.task_spec.form.fields[0].options
self.assertEquals(28, len(options))
self.assertEquals('1000', options[0]['id'])
self.assertEquals("UVA - INTERNAL - GM USE ONLY", options[0]['name'])
self.assertEqual(28, len(options))
self.assertEqual('1000', options[0]['id'])
self.assertEqual("UVA - INTERNAL - GM USE ONLY", options[0]['name'])
def test_random_data_populate_form_on_auto_complete(self):
self.load_example_data()