def test_anonymous_taskrun_submission(self): owner = UserFactory.create(id=500) project = ProjectFactory.create(owner=owner) project.info['sched'] = 'locked' project_repo.save(project) task1 = TaskFactory.create(project=project, info='task 1', n_answers=1) task2 = TaskFactory.create(project=project, info='task 2', n_answers=1) res = self.app.get('api/project/{}/newtask'.format(project.id)) rec_task1 = json.loads(res.data) res = self.app.get('api/project/{}/newtask?api_key={}'.format( project.id, owner.api_key)) rec_task2 = json.loads(res.data) # users get different tasks assert rec_task1['info'] != rec_task2['info'] tr = {'project_id': project.id, 'task_id': task1.id, 'info': 'hello'} # submit answer for the right task res = self.app.post('api/taskrun', data=json.dumps(tr)) assert res.status_code == 200, res.status_code
def password_protect_hidden_projects(): import random from pybossa.core import project_repo, user_repo, mail from pybossa.jobs import enqueue_job, send_mail def generate_random_password(): CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' password = '' for i in range(8): password += random.choice(CHARS) return password def generate_email_for(project_name, owner_name, password): subject = "Changes in your hidden project %s" % project_name content = ( """ Dear %s, We are writing you to let you know that, due to recent changes in Crowdcrafting, hidden projects will soon no longer be supported. However, you can still protect your project with a password, allowing only people with it to access and contribute to it. We have checked that your project %s is hidden. We don't want to expose it to the public, so we have protected it with a password instead. The current password for your project is: %s You will be able to change it on your project settings page. You can find more information about passwords in the documentation (http://docs.pybossa.com/user/tutorial/#protecting-the-project-with-a-password). If you have any doubts, please contact us and we will be pleased to help you! Best regards, Crowdcrafting team. """ % (owner_name, project_name, password)) return subject, content with app.app_context(): for project in project_repo.filter_by(hidden=1): password = generate_random_password() subject, content = generate_email_for(project.name, project.owner.name, password) message = dict(recipients=[project.owner.email_addr], subject=subject, body=content) job = dict(name=send_mail, args=[message], kwargs={}, timeout=(600), queue='medium') enqueue_job(job) project.set_password(password) project_repo.save(project)
def test_anonymous_taskrun_submission_external_uid(self): owner = UserFactory.create(id=500) project = ProjectFactory.create(owner=owner) project.info['sched'] = 'locked' project_repo.save(project) task1 = TaskFactory.create(project=project, info='task 1', n_answers=1) task2 = TaskFactory.create(project=project, info='task 2', n_answers=1) headers = self.get_headers_jwt(project) res = self.app.get('api/project/{}/newtask?external_uid={}'.format( project.id, '1xa'), headers=headers) rec_task1 = json.loads(res.data) res = self.app.get('api/project/{}/newtask?external_uid={}'.format( project.id, '2xa'), headers=headers) rec_task2 = json.loads(res.data) # users get different tasks print(rec_task1) print(rec_task2) assert rec_task1['info'] != rec_task2['info'] tr = {'project_id': project.id, 'task_id': task1.id, 'info': 'hello'} # submit answer for the right task res = self.app.post('api/taskrun?external_uid=1xa', data=json.dumps(tr), headers=headers) assert res.status_code == 200, res.status_code
def test_user_logout_unlocks_locked_tasks(self, release_lock): """ Test user logout unlocks/expires all locks locked by user """ owner = UserFactory.create(id=500) project = ProjectFactory.create(owner=owner) project.info['sched'] = Schedulers.locked project_repo.save(project) task1 = TaskFactory.create(project=project, info='project 1', n_answers=1) project2 = ProjectFactory.create(owner=owner) project2.info['sched'] = Schedulers.locked task2 = TaskFactory.create(project=project2, info='project 2', n_answers=1) self.register(name='johndoe') self.signin(email='*****@*****.**') self.set_proj_passwd_cookie(project, user=None, username='******') res = self.app.get('api/project/1/newtask') data = json.loads(res.data) assert data.get('info'), data self.set_proj_passwd_cookie(project2, user=None, username='******') res = self.app.get('api/project/2/newtask') data = json.loads(res.data) assert data.get('info'), data self.signout() key_args = [args[0] for args, kwargs in release_lock.call_args_list] assert get_task_users_key(task1.id) in key_args assert get_task_users_key(task2.id) in key_args
def test_tasks_assigned_as_per_user_access_levels_l2(self): """ Test tasks assigned by locked scheduler are as per access levels set for user, task and project""" from pybossa import data_access from test_api import get_pwd_cookie owner = UserFactory.create(id=500) user_l2 = UserFactory.create(id=502, info=dict(data_access=["L2"])) project = ProjectFactory.create(owner=owner, info=dict(data_access=["L1", "L2"])) project.info['sched'] = Schedulers.locked project_repo.save(project) project2 = ProjectFactory.create(owner=owner, info=dict(data_access=["L1", "L2"])) project2.info['sched'] = Schedulers.user_pref project_repo.save(project2) task1 = TaskFactory.create(project=project, info=dict(question='q1', data_access=["L1"]), n_answers=1) task2 = TaskFactory.create(project=project, info=dict(question='q2', data_access=["L2"]), n_answers=1) task3 = TaskFactory.create(project=project2, info=dict(question='q3', data_access=["L1"]), n_answers=1) task4 = TaskFactory.create(project=project2, info=dict(question='q4', data_access=["L2"]), n_answers=1) self.set_proj_passwd_cookie(project, user_l2) with patch.dict(data_access.data_access_levels, self.patch_data_access_levels): res = self.app.get('api/project/{}/newtask?api_key={}'.format( project.id, user_l2.api_key)) assert res.status_code == 200, res.status_code data = json.loads(res.data) assert data[ 'id'] == task2.id, 'user_l2 should have obtained task {}'.format( task2.id) assert data['info']['data_access'] == task2.info['data_access'], \ 'user_l2 should have obtained task with level {}'.format(task1.info['data_access']) self.set_proj_passwd_cookie(project2, user_l2) res = self.app.get('api/project/{}/newtask?api_key={}'.format( project2.id, user_l2.api_key)) assert res.status_code == 200, res.status_code data = json.loads(res.data) assert data[ 'id'] == task4.id, 'user_l2 should have obtained task {}'.format( task4.id) assert data['info']['data_access'] == task4.info['data_access'], \ 'user_l1 should have obtained task with level {}'.format(task4.info['data_access'])
def password_protect_hidden_projects(): import random from pybossa.core import project_repo, user_repo, mail from pybossa.jobs import enqueue_job, send_mail def generate_random_password(): CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' password = '' for i in range(8): password += random.choice(CHARS) return password def generate_email_for(project_name, owner_name, password): subject = "Changes in your hidden project %s" % project_name content = ( """ Dear %s, We are writing you to let you know that, due to recent changes in Crowdcrafting, hidden projects will soon no longer be supported. However, you can still protect your project with a password, allowing only people with it to access and contribute to it. We have checked that your project %s is hidden. We don't want to expose it to the public, so we have protected it with a password instead. The current password for your project is: %s You will be able to change it on your project settings page. You can find more information about passwords in the documentation (http://docs.pybossa.com/en/latest/user/tutorial.html#protecting-the-project-with-a-password). If you have any doubts, please contact us and we will be pleased to help you! Best regards, Crowdcrafting team. """ % (owner_name, project_name, password)) return subject, content with app.app_context(): for project in project_repo.filter_by(hidden=1): password = generate_random_password() subject, content = generate_email_for(project.name, project.owner.name, password) message = dict(recipients=[project.owner.email_addr], subject=subject, body=content) job = dict(name=send_mail, args=[message], kwargs={}, timeout=(600), queue='medium') enqueue_job(job) project.set_password(password) project_repo.save(project)
def test_locked_sched_gold_task(self): """ Test gold tasks presented with locked scheduler """ [admin, owner, user] = UserFactory.create_batch(3) make_admin(admin) make_subadmin(owner) project = ProjectFactory.create(owner=owner) project.info['sched'] = Schedulers.locked project.set_gold_task_probability(1.0) project_repo.save(project) tasks = TaskFactory.create_batch(4, project=project, n_answers=1) gold_task = tasks[3] gold_task.calibration = 1; gold_task.gold_answers = dict(field_3='someans') # user #1 self.set_proj_passwd_cookie(project, user) res = self.app.get('api/project/{}/newtask?api_key={}' .format(project.id, user.api_key)) assert res.status_code == 200, res.status_code resp = json.loads(res.data) assert resp['id'] == gold_task.id, \ 'task presented to regular user under locked sched should be gold task' # submit answer for gold task task_run = dict(project_id=project.id, task_id=gold_task.id, info='hi there!') res = self.app.post('api/taskrun?api_key={}'.format(user.api_key), data=json.dumps(task_run)) assert res.status_code == 200, res.status_code # user #2 also gets gold_task even when redundancy was set to 1 res = self.app.get('api/project/{}/newtask?api_key={}' .format(project.id, owner.api_key)) assert res.status_code == 200, res.status_code resp = json.loads(res.data) assert resp['id'] == gold_task.id, \ 'task presented to owner under locked sched should be gold task' # after two task run submissions for gold task, state is unchanged to ongoing task_run = dict(project_id=project.id, task_id=gold_task.id, info='hi there!') res = self.app.post('api/taskrun?api_key={}'.format(owner.api_key), data=json.dumps(task_run)) assert res.status_code == 200, res.status_code res = self.app.get('api/task/{}?api_key={}' .format(gold_task.id, admin.api_key)) assert res.status_code == 200, res.status_code resp = json.loads(res.data) assert resp['id'] == gold_task.id and resp['state'] == 'ongoing', \ 'gold task state should be unchanged to ongoing' project.set_gold_task_probability(0.0) res = self.app.get('api/project/{}/newtask?api_key={}' .format(project.id, admin.api_key)) assert res.status_code == 200, res.status_code resp = json.loads(res.data) assert resp['id'] == tasks[0].id, \ 'task presented should not be gold task'
def test_get_locked_task_gold_first(self): owner = UserFactory.create(id=500) project = ProjectFactory.create(owner=owner) project.info['sched'] = Schedulers.locked project_repo.save(project) TaskFactory.create(project=project, info='task 1', calibration=0, n_answers=2) task2 = TaskFactory.create(project=project, info='task 1', calibration=1, n_answers=2) task = get_locked_task(project.id, 1, task_type='gold_first')[0] assert task.id == task2.id, (task, task2)
def test_get_locked_task_gold_only(self): owner = UserFactory.create(id=500) project = ProjectFactory.create(owner=owner) project.info['sched'] = Schedulers.locked project_repo.save(project) TaskFactory.create(project=project, info='task 1', calibration=0, n_answers=2) assert not get_locked_task(project.id, 1, task_type='gold') TaskFactory.create(project=project, info='task 1', calibration=1, n_answers=2) assert get_locked_task(project.id, 1, task_type='gold')
def test_creator_is_added_as_owner(self): """ Test that project_repo.save includes the creator as an owner even if not explicitly specified """ from pybossa.core import project_repo self.register() project = Fixtures.create_project({'passwd_hash': 'hello'}) project.owner_id = 1 project_repo.save(project) assert project.owners_ids == [1]
def test_taskrun_submission(self): """ Test submissions with locked scheduler """ owner = UserFactory.create(id=500) user = UserFactory.create(id=501) project = ProjectFactory.create(owner=owner) project.info['sched'] = Schedulers.locked project_repo.save(project) task1 = TaskFactory.create(project=project, info='task 1', n_answers=1) task2 = TaskFactory.create(project=project, info='task 2', n_answers=1) self.set_proj_passwd_cookie(project, user) res = self.app.get('api/project/{}/newtask?api_key={}'.format( project.id, user.api_key)) user_rec_task = json.loads(res.data) res = self.app.get('api/project/{}/newtask?api_key={}'.format( project.id, owner.api_key)) owner_rec_task = json.loads(res.data) # users get different tasks assert user_rec_task['info'] != owner_rec_task['info'] user_task = task1 if task1.id == user_rec_task['id'] else task2 owner_task = task1 if task1.id == owner_rec_task['id'] else task2 # submit answer for the wrong task # stamp contribution guard first guard = ContributionsGuard(sentinel.master) guard._remove_task_stamped(owner_task, {'user_id': owner.id}) tr = { 'project_id': project.id, 'task_id': owner_task.id, 'info': 'hello' } res = self.app.post('api/taskrun?api_key={}'.format(owner.api_key), data=json.dumps(tr)) assert res.status_code == 403, (res.status_code, res.data) # submit answer for the right task guard.stamp(owner_task, {'user_id': owner.id}) tr['task_id'] = owner_task.id res = self.app.post('api/taskrun?api_key={}'.format(owner.api_key), data=json.dumps(tr)) assert res.status_code == 200, res.status_code tr['task_id'] = user_task.id res = self.app.post('api/taskrun?api_key={}'.format(user.api_key), data=json.dumps(tr)) assert res.status_code == 200, res.status_code
def import_tasks(project_id, current_user_fullname, from_auto=False, **form_data): """Import tasks for a project.""" from pybossa.core import project_repo import pybossa.cache.projects as cached_projects project = project_repo.get(project_id) recipients = [project.owner.email_addr] for user in project.coowners: recipients.append(user.email_addr) try: report = importer.create_tasks(task_repo, project, **form_data) except JobTimeoutException: from pybossa.core import db db.session.rollback() n_tasks = _num_tasks_imported(project_id) subject = 'Your import task has timed out' body = '\n'.join( ['Hello,\n', 'Import task to your project {} by {} failed because the file was too large.', 'It was able to process approximately {} tasks.', 'Please break up your task upload into smaller CSV files.', 'Thank you,\n', 'The {} team.']).format(project.name, current_user_fullname, n_tasks, current_app.config.get('BRAND')) mail_dict = dict(recipients=recipients, subject=subject, body=body) send_mail(mail_dict) raise except Exception as e: msg = (u'Import tasks to your project {0} by {1} failed' .format(project.name, current_user_fullname)) subject = 'Tasks Import to your project %s' % project.name body = ('Hello,\n\n{0}\n\nPlease contact {1} administrator,\nThe {1} team.' .format(msg, current_app.config.get('BRAND'))) mail_dict = dict(recipients=recipients, subject=subject, body=body) send_mail(mail_dict) raise cached_projects.delete_browse_tasks(project_id) if from_auto: form_data['last_import_meta'] = report.metadata project.set_autoimporter(form_data) project_repo.save(project) msg = report.message + u' to your project {0} by {1}'.format(project.name, current_user_fullname) subject = 'Tasks Import to your project %s' % project.name body = 'Hello,\n\n' + msg + '\n\nAll the best,\nThe %s team.'\ % current_app.config.get('BRAND') mail_dict = dict(recipients=recipients, subject=subject, body=body) send_mail(mail_dict) return msg
def test_tasks_assigned_as_per_user_access_levels_l4(self): """ Test tasks assigned by locked scheduler are as per access levels set for user, task and project""" from pybossa import data_access from test_api import get_pwd_cookie owner = UserFactory.create(id=500) user_l4 = UserFactory.create(id=502, info=dict(data_access=["L4"])) project = ProjectFactory.create(owner=owner, info=dict(data_access=["L1", "L2"])) project.info['sched'] = Schedulers.locked project_repo.save(project) project2 = ProjectFactory.create(owner=owner, info=dict(data_access=["L1", "L2"])) project2.info['sched'] = Schedulers.user_pref project_repo.save(project2) task1 = TaskFactory.create(project=project, info=dict(question='q1', data_access=["L1"]), n_answers=1) task2 = TaskFactory.create(project=project, info=dict(question='q2', data_access=["L2"]), n_answers=1) task3 = TaskFactory.create(project=project, info=dict(question='q3', data_access=["L2"]), n_answers=1) task4 = TaskFactory.create(project=project, info=dict(question='q4', data_access=["L2"]), n_answers=1) self.set_proj_passwd_cookie(project, user_l4) with patch.object(data_access, 'data_access_levels', self.patch_data_access_levels): res = self.app.get('api/project/{}/newtask?api_key={}'.format( project.id, user_l4.api_key)) assert res.status_code == 200, res.status_code data = json.loads(res.data) assert not data, 'user_l4 with L4 access should not have obtained any task under locked scheduler' self.set_proj_passwd_cookie(project2, user_l4) res = self.app.get('api/project/{}/newtask?api_key={}'.format( project2.id, user_l4.api_key)) assert res.status_code == 200, res.status_code data = json.loads(res.data) assert not data, 'user_l4 with L4 access should not have obtained any task under user pref scheduler'
def test_invalid_offset(self): owner = UserFactory.create(id=500) project = ProjectFactory.create(owner=owner) project.info['sched'] = Schedulers.locked project_repo.save(project) task1 = TaskFactory.create(project=project, info='task 1', n_answers=2) task1 = TaskFactory.create(project=project, info='task 2', n_answers=2) res = self.app.get('api/project/{}/newtask?api_key={}&offset=3'.format( project.id, owner.api_key)) assert res.status_code == 400, res.data
def test_get_locked_task_randomize(self): owner = UserFactory.create(id=500) project = ProjectFactory.create(owner=owner) project.info['sched'] = Schedulers.locked project_repo.save(project) TaskFactory.create(project=project, info='task 1', n_answers=2) TaskFactory.create(project=project, info='task 2', n_answers=2) assert get_locked_task(project.id, 1, rand_within_priority=True) assert get_locked_task(project.id, 2, rand_within_priority=True) assert get_locked_task(project.id, 3, rand_within_priority=True) assert get_locked_task(project.id, 4, rand_within_priority=True) assert not get_locked_task(project.id, 5, rand_within_priority=True)
def test_get_locked_task_offset(self): owner = UserFactory.create(id=500) project = ProjectFactory.create(owner=owner) project.info['sched'] = Schedulers.locked project_repo.save(project) task1 = TaskFactory.create(project=project, info='task 1', n_answers=2) task2 = TaskFactory.create(project=project, info='task 2', n_answers=2) task3 = TaskFactory.create(project=project, info='task 2', n_answers=2) t1 = get_locked_task(project.id, 1) assert t1[0].id == task1.id t2 = get_locked_task(project.id, 1, offset=1) assert t2 is None t3 = get_locked_task(project.id, 1, offset=2) assert t3 is None
def import_tasks(project_id, from_auto=False, **form_data): """Import tasks for a project.""" from pybossa.core import project_repo project = project_repo.get(project_id) report = importer.create_tasks(task_repo, project_id, **form_data) if from_auto: form_data["last_import_meta"] = report.metadata project.set_autoimporter(form_data) project_repo.save(project) msg = report.message + " to your project %s!" % project.name subject = "Tasks Import to your project %s" % project.name body = "Hello,\n\n" + msg + "\n\nAll the best,\nThe %s team." % current_app.config.get("BRAND") mail_dict = dict(recipients=[project.owner.email_addr], subject=subject, body=body) send_mail(mail_dict) return msg
def test_one_task(self): owner = UserFactory.create(id=500) project = ProjectFactory.create(owner=owner) project.info['sched'] = 'locked' project_repo.save(project) task1 = TaskFactory.create(project=project, info='task 1', n_answers=1) res = self.app.get('api/project/{}/newtask'.format(project.id)) rec_task1 = json.loads(res.data) res = self.app.get('api/project/{}/newtask?api_key={}'.format( project.id, owner.api_key)) rec_task2 = json.loads(res.data) assert not rec_task2
def test_creator_is_added_as_owner(self): """ Test that project_repo.save includes the creator as an owner even if not explicitly specified """ from pybossa.core import project_repo self.register() project = Fixtures.create_project({ 'passwd_hash': 'hello', 'data_classification': dict(input_data="L4 - public", output_data="L4 - public") }) project.owner_id = 1 project_repo.save(project) assert project.owners_ids == [1]
def import_tasks(project_id, from_auto=False, **form_data): """Import tasks for a project.""" from pybossa.core import project_repo project = project_repo.get(project_id) report = importer.create_tasks(task_repo, project_id, **form_data) if from_auto: form_data['last_import_meta'] = report.metadata project.set_autoimporter(form_data) project_repo.save(project) msg = report.message + ' to your project %s!' % project.name subject = 'Tasks Import to your project %s' % project.name body = 'Hello,\n\n' + msg + '\n\nAll the best,\nThe %s team.'\ % current_app.config.get('BRAND') mail_dict = dict(recipients=[project.owner.email_addr], subject=subject, body=body) send_mail(mail_dict) return msg
def test_get_reserve_task_category_info(self, get_task_category_lock): owner = UserFactory.create(id=500) project = ProjectFactory.create(owner=owner) reserve_task_config = ["field_a", "field_b"] timeout = 60 * 60 # test bad project id, user id returns empty sql_filters, category_keys project_id, user_id = -52, 9999 sql_filters, category_keys = get_reserve_task_category_info( reserve_task_config, project_id, timeout, user_id) assert sql_filters == "" and category_keys == [], "sql_filters, category_keys must be '', []" # empty sql_filters, category_keys for projects with scheduler other than task_queue project.info['sched'] = Schedulers.locked project_repo.save(project) sql_filters, category_keys = get_reserve_task_category_info( reserve_task_config, project.id, timeout, owner.id) assert sql_filters == "" and category_keys == [], "sql_filters, category_keys must be '', []" # with no categories configured under project config # empty sql_filters, category_keys for projects with task queue scheduler project.info['sched'] = Schedulers.task_queue project_repo.save(project) sql_filters, category_keys = get_reserve_task_category_info( reserve_task_config, project.id, timeout, owner.id) assert sql_filters == "" and category_keys == [], "sql_filters, category_keys must be '', []" # with categories configured under project config # empty sql_filters, category_keys for projects with task queue scheduler # when there's no category lock present in redis cache project.info['sched'] = Schedulers.task_queue project.info['reserve_tasks'] = {"category": reserve_task_config} project_repo.save(project) get_task_category_lock.return_value = [] sql_filters, category_keys = get_reserve_task_category_info( reserve_task_config, project.id, timeout, owner.id) assert sql_filters == "" and category_keys == [], "sql_filters, category_keys must be '', []" # with categories configured under project config # sql_filters, category_keys for projects with task queue scheduler # to be built as per category lock present in redis cache project.info['sched'] = Schedulers.task_queue project.info['reserve_tasks'] = {"category": reserve_task_config} project_repo.save(project) expected_category_keys = [ "reserve_task:project:{}:category:name1:value1:name2:value2:user:1008:task:454" .format(project.id), "reserve_task:project:{}:category:x:1:y:2:z:3:user:1008:task:2344". format(project.id) ] get_task_category_lock.return_value = expected_category_keys sql_filters, category_keys = get_reserve_task_category_info( reserve_task_config, project.id, timeout, owner.id) assert sql_filters == " AND (task.info->>'y' IN ('2') AND task.info->>'x' IN ('1') AND task.info->>'z' IN ('3') AND task.info->>'name2' IN ('value2') AND task.info->>'name1' IN ('value1')) " and \ category_keys == expected_category_keys, "sql_filters, category_keys must be non empty"
def handle_valid_project_form(form, template, volume, category): """Handle a valid project form.""" import_data = volume.get('data', {}) import_data['type'] = volume.get('importer') # Use enhanced IIIF importer for IIIF projects if import_data['type'] == 'iiif': import_data['type'] = 'iiif-enhanced' # Check for parent if template['parent_template_id']: if volume.get('importer') != 'iiif': flash('Only IIIF projects can be built from parents.', 'error') return parent = get_parent(template['parent_template_id'], volume['id'], category) if not parent: msg = 'There is no valid parent for this template and volume.' flash(msg, 'error') return import_data['parent_id'] = parent.id # Create project webhook = '{0}lc/analysis'.format(request.url_root) project = Project(name=form.name.data, short_name=form.short_name.data, description=template['description'], long_description='', owner_id=current_user.id, info={ 'volume_id': volume['id'], 'template_id': template['id'] }, webhook=webhook, published=True, category_id=category.id, owners_ids=[current_user.id]) add_avatar_to_project_info(project, volume) project_repo.save(project) return generate_tasks(project, import_data, template)
def test_lock_expiration(self): owner = UserFactory.create(id=500) project = ProjectFactory.create(owner=owner) project.info['sched'] = 'locked' project_repo.save(project) task1 = TaskFactory.create(project=project, info='task 1', n_answers=2) task1 = TaskFactory.create(project=project, info='task 2', n_answers=2) res = self.app.get('api/project/{}/newtask?api_key={}'.format( project.id, owner.api_key)) # fake expired user lock acquire_lock(task1.id, 1000, 2, -10) res = self.app.get('api/project/{}/newtask'.format(project.id)) rec_task1 = json.loads(res.data) assert rec_task1['info'] == 'task 1'
def test_taskrun_submission(self): owner = UserFactory.create(id=500) user = UserFactory.create(id=501) project = ProjectFactory.create(owner=owner) project.info['sched'] = 'locked' project_repo.save(project) task1 = TaskFactory.create(project=project, info='task 1', n_answers=1) task2 = TaskFactory.create(project=project, info='task 2', n_answers=1) res = self.app.get('api/project/{}/newtask?api_key={}'.format( project.id, user.api_key)) rec_task1 = json.loads(res.data) res = self.app.get('api/project/{}/newtask?api_key={}'.format( project.id, owner.api_key)) rec_task2 = json.loads(res.data) # users get different tasks assert rec_task1['info'] != rec_task2['info'] # submit answer for the wrong task # stamp contribution guard first guard = ContributionsGuard(sentinel.master) guard.stamp(task1, {'user_id': owner.id}) tr = {'project_id': project.id, 'task_id': task1.id, 'info': 'hello'} res = self.app.post('api/taskrun?api_key={}'.format(owner.api_key), data=json.dumps(tr)) assert res.status_code == 403, res.status_code # submit answer for the right task tr['task_id'] = task2.id res = self.app.post('api/taskrun?api_key={}'.format(owner.api_key), data=json.dumps(tr)) assert res.status_code == 200, res.status_code tr['task_id'] = task1.id res = self.app.post('api/taskrun?api_key={}'.format(user.api_key), data=json.dumps(tr)) assert res.status_code == 200, res.status_code
def test_acquire_and_release_reserve_task_lock(self): user = UserFactory.create() # project w/o reserve_tasks configured don't acquire lock project_info = dict(sched="task_queue_scheduler") task_info = dict(field_1="abc", field_2=123) category_fields = ["field_1", "field_2"] project = ProjectFactory.create(owner=user, info=project_info) task = TaskFactory.create_batch(1, project=project, n_answers=1, info=task_info)[0] timeout = 100 assert acquire_reserve_task_lock( project.id, task.id, user.id, timeout ) == False, "reserve task cannot be acquired due to missing required config" project.info['reserve_tasks'] = {"category": ["some_field"]} project_repo.save(project) assert acquire_reserve_task_lock( project.id, task.id, user.id, timeout) == False, "task not having reserve tasks config fields" project.info['reserve_tasks'] = {"category": category_fields} project_repo.save(project) acquire_reserve_task_lock(project.id, task.id, user.id, timeout) category_key = ":".join([ "{}:{}".format(field, task.info[field]) for field in category_fields ]) expected_reserve_task_key = "reserve_task:project:{}:category:{}:user:{}:task:{}".format( project.id, category_key, user.id, task.id) assert expected_reserve_task_key in sentinel.master.keys( ), "reserve task key must exist in redis cache" # release reserve task lock expiry = 1 release_reserve_task_lock_by_keys([expected_reserve_task_key], timeout, expiry=expiry) time.sleep(expiry) assert expected_reserve_task_key not in sentinel.master.keys( ), "reserve task key should not exist in redis cache"
def test_sync_L3_without_target(self, mock_cat): project_syncer = ProjectSyncer(self.target_url, self.target_key) user = UserFactory.create(admin=True, email_addr=u'*****@*****.**') project_syncer.syncer = user project = ProjectFactory.create() project.info['data_classification'] = dict( input_data="L3 - community", output_data="L3 - community") project_repo.save(project) # no sync info by default assert not project.info.get("sync") payload = project_syncer._build_payload(project) # sync existing does put request headers = [('Authorization', user.api_key)] res = self.app.put("/api/project/{}".format(project.id), headers=headers, data=json.dumps(payload)) assert res.status_code == 200, 'build_payload output should result in valid api query' assert res.json["info"]["sync"] == payload["info"]["sync"]
def test_email_notif(self, get_contrib_emails): """ if the project is configured, email notifications will be sent """ owner = UserFactory.create(id=500, user_pref={'languages': ['en']}) project = ProjectFactory.create(owner=owner, email_notif=True) project.info['sched'] = Schedulers.user_pref project_repo.save(project) tasks = TaskFactory.create_batch(1, project=project, n_answers=1, user_pref={'languages': ['en']}) TaskRunFactory.create(task=tasks[0], user=owner) TaskFactory.create_batch(1, project=project, n_answers=1, user_pref={'languages': ['en']}) send_email_notifications() get_contrib_emails.assert_called()
def test_get_locked_task(self): owner = UserFactory.create(id=500) project = ProjectFactory.create(owner=owner) project.info['sched'] = Schedulers.locked project_repo.save(project) task1 = TaskFactory.create(project=project, info='task 1', n_answers=2) task2 = TaskFactory.create(project=project, info='task 2', n_answers=2) t1 = get_locked_task(project.id, 11) t2 = get_locked_task(project.id, 1) assert t1[0].id == task1.id assert t2[0].id == task1.id t3 = get_locked_task(project.id, 2) t4 = get_locked_task(project.id, 3) assert t3[0].id == task2.id assert t4[0].id == task2.id t5 = get_locked_task(project.id, 11) assert t5[0].id == task1.id t6 = get_locked_task(project.id, 4) assert not t6