def test_handle_info_json(self): """Test handle info in JSON works.""" TaskFactory.create(info={'foo': 'bar'}) info = 'foo::bar' res = self.task_repo.filter_tasks_by(info=info) assert len(res) == 1 assert res[0].info['foo'] == 'bar', res[0]
def test_serialization(self): project = ProjectFactory.create() self.db.session.commit() serializer = ProjectSerializer(strict=True) data = serializer.dump(project).data assert data['id'] == project.id assert data['name'] == project.name assert data['description'] == project.description assert data['last_task'] is None assert not data['tasks'] assert data['client']['id'] == project.client.id task_1 = TaskFactory.create(project=project, status='open') task_2 = TaskFactory.create(project=project, status='closed') self.db.session.commit() # Last task data = serializer.dump(project).data assert data['last_task'] is not None assert data['last_task']['id'] == task_1.id assert data['last_task']['title'] == task_1.title assert 'time_entries' not in data['last_task'] # Tasks (with filtering) data = ProjectSerializer( strict=True, task_status='open').dump(project).data assert len(data['tasks']) == 1 assert data['tasks'][0]['id'] == task_1.id assert data['tasks'][0]['project_id'] == project.id data = ProjectSerializer( strict=True, task_status='closed').dump(project).data assert len(data['tasks']) == 1 assert data['tasks'][0]['id'] == task_2.id assert data['tasks'][0]['project_id'] == project.id
def test_warn_project_excludes_completed_projects(self, clean_mock): """Test JOB email excludes completed projects.""" from pybossa.core import mail with mail.record_messages() as outbox: date = '2010-10-22T11:02:00.000000' owner = UserFactory.create(consent=True, subscribed=True) project = ProjectFactory.create(updated=date, contacted=False, owner=owner) TaskFactory.create(created=date, project=project, state='completed') project_id = project.id project = project_repo.get(project_id) project.updated = date project_repo.update(project) project = ProjectFactory.create(updated=date, contacted=False, owner=owner) TaskFactory.create(created=date, project=project, state='ongoing') project_id = project.id project = project_repo.get(project_id) project.updated = date project_repo.update(project) warn_old_project_owners() assert len(outbox) == 1, outbox subject = 'Your PYBOSSA project: %s has been inactive' % project.name assert outbox[0].subject == subject err_msg = "project.contacted field should be True" assert project.contacted, err_msg err_msg = "project.published field should be False" assert project.published is False, err_msg err_msg = "cache of project should be cleaned" clean_mock.assert_called_with(project_id), err_msg err_msg = "The update date should be different" assert project.updated != date, err_msg
def test_admin_cannot_publish_if_project_has_no_presenter(self): """Test admins cannot publish a project that has no presenter""" owner = UserFactory.build_batch(2)[1] project = ProjectFactory.create(owner=owner, published=False, info={}) TaskFactory.create(project=project) assert_raises(Forbidden, ensure_authorized_to, 'publish', project)
def test_n_total_tasks_site_returns_aggregated_number_of_required_tasks(self): TaskFactory.create(n_answers=2) TaskFactory.create(n_answers=2) tasks = stats.n_total_tasks_site() assert tasks == 4, tasks
def test_project_published(self): owner = UserFactory.create(email_addr='*****@*****.**', pro=True) owner.set_password('1234') user_repo.save(owner) project = ProjectFactory.create(owner=owner, published=False) self.signin(email='*****@*****.**', password='******') TaskFactory.create(project=project) short_name = project.short_name url = "/project/%s/publish" % short_name attribute = 'published' new_string = 'true' old_value = 'false' self.data[attribute] = new_string self.app.post(url, follow_redirects=True) logs = auditlog_repo.filter_by(project_short_name=short_name) assert len(logs) == 1, logs for log in logs: assert log.attribute == attribute, log.attribute assert log.old_value == old_value, (log.old_value, old_value) assert log.new_value == self.data[attribute], log.new_value assert log.caller == 'web', log.caller assert log.action == 'update', log.action assert log.user_name == owner.name, log.user_name assert log.user_id == owner.id, log.user_id
def test_orderby(self): """Test orderby.""" project = ProjectFactory.create() task1 = TaskFactory.create(fav_user_ids=[1], project=project) task2 = TaskFactory.create(fav_user_ids=None, project=project) task3 = TaskFactory.create(fav_user_ids=[1, 2, 3], project=project) task = self.task_repo.filter_tasks_by(orderby='id', desc=True, project_id=project.id, limit=1)[0] assert task == task3, (task, task3) task = self.task_repo.filter_tasks_by(orderby='id', desc=False, project_id=project.id, limit=1)[0] assert task == task1, (task, task1) task = self.task_repo.filter_tasks_by(orderby='created', desc=True, project_id=project.id)[0] assert task == task3, (task.id, task3.id) task = self.task_repo.filter_tasks_by(orderby='created', desc=False, project_id=project.id)[0] assert task == task1, (task.created, task1.created) task = self.task_repo.filter_tasks_by(orderby='fav_user_ids', desc=True, project_id=project.id)[0][0] assert task == task3, (task.id, task3.id) task = self.task_repo.filter_tasks_by(orderby='fav_user_ids', desc=False, project_id=project.id)[0][0] assert task == task2, (task.fav_user_ids, task2.fav_user_ids)
def test_it_renders_template_when_get(self, fake_render): TaskFactory.create(project=self.project) resp = self.app.get('/project/%s/publish' % self.project.short_name) call_args = fake_render.call_args_list assert call_args[0][0][0] == 'projects/publish.html', call_args[0] assert call_args[0][1]['project'].id == self.project.id, call_args[0]
def test_get_task_by_returns_none_if_no_task(self): """Test get_task_by returns None if no task matches the query""" TaskFactory.create(state='done') task = self.task_repo.get_task_by(state='ongoing') assert task is None, task
def test_count_tasks_with_no_matches(self): """Test count_tasks_with returns 0 if no tasks match the query""" TaskFactory.create(state='done', n_answers=17) count = self.task_repo.count_tasks_with(state='ongoing') assert count == 0, count
def test_handle_info_json_multiple_keys(self): """Test handle info in JSON with multiple keys works.""" TaskFactory.create(info={'foo': 'bar', 'bar': 'foo'}) info = 'foo::bar|bar::foo' res = self.task_repo.filter_tasks_by(info=info) assert len(res) == 1 assert res[0].info['foo'] == 'bar', res[0] assert res[0].info['bar'] == 'foo', res[0]
def test_anonymous_01_newtask(self): """ Test SCHED newtask returns a Task for the Anonymous User""" project = ProjectFactory.create() TaskFactory.create(project=project, info='hola') res = self.app.get('api/project/%s/newtask' %project.id) data = json.loads(res.data) assert data['info'] == 'hola', data
def test_query_favorites_anon(self): """Test API Favorites works for anon.""" user = UserFactory.create() TaskFactory.create(fav_user_ids=[user.id]) res = self.app.get(self.url) data = json.loads(res.data) assert res.status_code == 401 assert data['status_code'] == 401
def test_admin_can_publish_if_project_has_tasks_and_presenter(self): """Test admins can publish a project that has tasks and a presenter""" owner = UserFactory.build_batch(2)[1] project = ProjectFactory.create(owner=owner, published=False) TaskFactory.create(project=project) assert project.owner.id != self.mock_admin.id, project.owner assert_not_raises(Exception, ensure_authorized_to, 'publish', project)
def test_it_changes_project_to_published_after_post(self): TaskFactory.create(project=self.project) resp = self.app.post('/project/%s/publish' % self.project.short_name, follow_redirects=True) project = project_repo.get(self.project.id) assert resp.status_code == 200, resp.status_code assert project.published == True, project
def test_get_query_with_api_key_context(self): """ Test API GET query with an API-KEY requesting only APIKEY results.""" users = UserFactory.create_batch(4) project_oc = ProjectFactory.create(owner=users[0], info={'total': 150}) projects = ProjectFactory.create_batch(3, owner=users[1]) task_oc = TaskFactory.create(project=project_oc, info={'url': 'my url'}) taskrun_oc = TaskRunFactory.create(task=task_oc, user=users[0], info={'answer': 'annakarenina'}) for p in projects: print p.owner_id task_tmp = TaskFactory.create(project=p) TaskRunFactory.create(task=task_tmp) # For project owner with associated data for endpoint in self.endpoints: url = '/api/' + endpoint + '?api_key=' + users[0].api_key res = self.app.get(url) data = json.loads(res.data) if endpoint == 'project': assert len(data) == 1, data project = data[0] assert project['owner_id'] == users[0].id, project['owner_id'] assert project['info']['total'] == 150, data assert res.mimetype == 'application/json', res if endpoint == 'task': assert len(data) == 1, data task = data[0] assert task['project_id'] == project_oc.id, task assert task['info']['url'] == 'my url', data assert res.mimetype == 'application/json', res if endpoint == 'taskrun': assert len(data) == 1, data taskrun = data[0] assert taskrun['project_id'] == project_oc.id, taskrun assert taskrun['info']['answer'] == 'annakarenina', data assert res.mimetype == 'application/json', res # For authenticated with non-associated data for endpoint in self.endpoints: url = '/api/' + endpoint + '?api_key=' + users[3].api_key res = self.app.get(url) data = json.loads(res.data) if endpoint == 'project': assert len(data) == 0, data assert res.mimetype == 'application/json', res if endpoint == 'task': assert len(data) == 0, data assert res.mimetype == 'application/json', res if endpoint == 'taskrun': assert len(data) == 0, data assert res.mimetype == 'application/json', res
def test_filter_tasks_by_no_matches(self): """Test filter_tasks_by returns an empty list if no tasks match the query""" TaskFactory.create(state='done', n_answers=17) retrieved_tasks = self.task_repo.filter_tasks_by(state='ongoing') assert isinstance(retrieved_tasks, list) assert len(retrieved_tasks) == 0, retrieved_tasks
def test_normal_auth_used_if_no_password_protected(self, fake_authorizer): """Test if a project is password protected, that is the only authorization required for it to be seen""" project = ProjectFactory.create() TaskFactory.create(project=project) self.app.get('/project/%s' % project.short_name, follow_redirects=True) assert fake_authorizer.called == True
def test_count_tasks_with_multiple_conditions(self): """Test count_tasks_with supports multiple-condition queries""" TaskFactory.create(state='done', n_answers=17) task = TaskFactory.create(state='done', n_answers=99) count = self.task_repo.count_tasks_with(state='done', n_answers=99) assert count == 1, count
def test_handle_info_json_multiple_keys_404_fulltextsearch(self): """Test handle info in JSON with full text search with multiple keys not found works.""" TaskFactory.create(info={'foo': 'bar', 'bar': 'foo'}) info = 'foo::bar|' res = self.task_repo.filter_tasks_by(info=info, fulltextsearch='1') assert len(res) == 1 assert res[0].info['foo'] == 'bar', res[0] assert res[0].info['bar'] == 'foo', res[0]
def test_password_not_required_for_anonymous_users_to_see_project(self): """Test when an anonymous user wants to visit a non-password protected project is able to do it""" project = ProjectFactory.create() TaskFactory.create(project=project) for endpoint in self.endpoints_requiring_password: res = self.app.get('/project/%s%s' % (project.short_name, endpoint), follow_redirects=True) assert 'Enter the password to contribute' not in res.data, endpoint
def test_get_draft_not_returns_published_projects(self): """Test CACHE PROJECTS get_draft does not return projects with either tasks or a presenter (REVIEW DEFINITION OF A DRAFT PROJECT REQUIRED)""" project_no_presenter = ProjectFactory.create(info={}) TaskFactory.create(project=project_no_presenter) project_no_task = ProjectFactory.create() drafts = cached_projects.get_draft() assert len(drafts) is 0, drafts
def test_handle_info_json_multiple_keys_and_fulltextsearch(self): """Test handle info in JSON with multiple keys and AND operator works.""" text = "agent myself you bar" TaskFactory.create(info={'foo': 'bar', 'bar': text}) info = 'foo::bar|bar::you&agent' res = self.task_repo.filter_tasks_by(info=info, fulltextsearch='1') assert len(res) == 1, len(res) assert res[0].info['foo'] == 'bar', res[0] assert res[0].info['bar'] == text, res[0]
def test_password_protection_overrides_normal_auth(self, fake_authorizer): """Test if a project is password protected, that is the only authorization required for it to be seen""" project = ProjectFactory.create(published=False) TaskFactory.create(project=project) project.set_password('mysecret') project_repo.update(project) self.app.get('/project/%s' % project.short_name, follow_redirects=True) assert fake_authorizer.called == False
def test_n_available_tasks_some_tasks_answered_by_authenticated_user(self): """Test n_available_tasks returns 1 for authenticated user if he has submitted taskruns for one of the tasks but there is still another task""" project = ProjectFactory.create() answered_task = TaskFactory.create(project=project) available_task = TaskFactory.create(project=project) user = UserFactory.create() taskrun = TaskRunFactory.create(task=answered_task, user=user) n_available_tasks = helpers.n_available_tasks(project.id, user_id=user.id) assert n_available_tasks == 1, n_available_tasks
def test_n_available_some_all_tasks_answered_by_anonymous_user(self): """Test n_available_tasks returns 1 for anonymous user if he has submitted taskruns for one of the tasks but there is still another task""" project = ProjectFactory.create() answered_task = TaskFactory.create(project=project) available_task = TaskFactory.create(project=project) taskrun = AnonymousTaskRunFactory.create(task=answered_task) n_available_tasks = helpers.n_available_tasks(project.id, user_ip=taskrun.user_ip) assert n_available_tasks == 1, n_available_tasks
def test_handle_info_json_fulltextsearch(self): """Test handle info fulltextsearch in JSON works.""" text = 'bar word agent something' TaskFactory.create(info={'foo': text}) info = 'foo::agent' res = self.task_repo.filter_tasks_by(info=info, fulltextsearch='1') assert len(res) == 1 assert res[0].info['foo'] == text, res[0] res = self.task_repo.filter_tasks_by(info=info) assert len(res) == 0, len(res)
def test_filter_tasks_by_multiple_conditions(self): """Test filter_tasks_by supports multiple-condition queries""" TaskFactory.create(state='done', n_answers=17) task = TaskFactory.create(state='done', n_answers=99) retrieved_tasks = self.task_repo.filter_tasks_by(state='done', n_answers=99) assert len(retrieved_tasks) == 1, retrieved_tasks assert task in retrieved_tasks, retrieved_tasks
def test_password_not_required_for_anonymous_contributors(self): """Test when an anonymous user wants to contribute to a non-password protected project is able to do it""" project = ProjectFactory.create() TaskFactory.create(project=project) res = self.app.get('/project/%s/newtask' % project.short_name, follow_redirects=True) assert 'Enter the password to contribute' not in res.data res = self.app.get('/project/%s/task/1' % project.short_name, follow_redirects=True) assert 'Enter the password to contribute' not in res.data
def test_hidden_projects_only_returns_hidden(self): """Test CACHE USERS hidden_projects does not return draft (even hidden) or another user's hidden projects""" user = UserFactory.create() another_user_hidden_project = ProjectFactory.create(hidden=1) TaskFactory.create(project=another_user_hidden_project) hidden_draft_project = ProjectFactory.create(owner=user, hidden=1, info={}) hidden_projects = cached_users.hidden_projects(user.id) assert len(hidden_projects) == 0, hidden_projects
def test_password_view_func_post(self, redirect): """Test when posting to /project/short_name/password and password is correct the user is redirected to where they came from""" project = ProjectFactory.create() task = TaskFactory.create(project=project) project.set_password('mysecret') project_repo.update(project) redirect_url = '/project/%s/task/%s' % (project.short_name, task.id) url = '/project/%s/password?next=%s' % (project.short_name, redirect_url) res = self.app.post(url, data={'password': '******'}) redirect.assert_called_with(redirect_url)
def test_password_view_func_post_wrong_passwd(self): """Test when posting to /project/short_name/password and password is incorrect an error message is flashed""" project = ProjectFactory.create() task = TaskFactory.create(project=project) project.set_password('mysecret') project_repo.update(project) url = '/project/%s/password?next=/project/%s/task/%s' % ( project.short_name, project.short_name, task.id) res = self.app.post(url, data={'password': '******'}) assert 'Sorry, incorrect password' in str( res.data), "No error message shown"
def test_taskrun_empty_info(self): with patch.dict(self.flask_app.config, self.patch_config): project = ProjectFactory.create() task = TaskFactory.create(project=project) self.app.get('/api/project/%s/newtask?api_key=%s' % (project.id, project.owner.api_key)) data = dict(project_id=project.id, task_id=task.id, info=None) datajson = json.dumps(data) url = '/api/taskrun?api_key=%s' % project.owner.api_key success = self.app.post(url, data=datajson) assert success.status_code == 200, success.data
def test_check_contributing_state_completed_user_not_contributed(self): """Test check_contributing_state returns 'completed' for a project with all tasks completed even if the user has not contributed to it""" project = ProjectFactory.create() task = TaskFactory.create(project=project, n_answers=2) TaskRunFactory.create_batch(2, task=task) user = UserFactory.create() update_stats(project.id) contributing_state = helpers.check_contributing_state(project=project, user_id=user.id) assert task.state == 'completed', task.state assert contributing_state == 'completed', contributing_state
def test_n_available_tasks_all_tasks_answered_by_authenticated_user(self): """Test n_available_tasks returns 0 for authenticated user if he has submitted taskruns for all the tasks""" project = ProjectFactory.create() task = TaskFactory.create(project=project, n_answers=2) user = UserFactory.create() taskrun = TaskRunFactory.create(task=task, user=user) n_available_tasks = helpers.n_available_tasks(project.id, user_id=user.id) assert task.state != 'completed', task.state assert n_available_tasks == 0, n_available_tasks
def test_project_owner_can_crud(self): """Test project owner can crud tasks""" user = UserFactory.create() owner = UserFactory.create() project = ProjectFactory.create(owner=owner) task = TaskFactory.create(project=project) assert self.mock_authenticated.id == owner.id assert_not_raises(Forbidden, ensure_authorized_to, 'create', task) assert_not_raises(Forbidden, ensure_authorized_to, 'read', task) assert_not_raises(Forbidden, ensure_authorized_to, 'read', Task) assert_not_raises(Forbidden, ensure_authorized_to, 'update', task) assert_not_raises(Forbidden, ensure_authorized_to, 'delete', task)
def test_published_projects_returns_fields(self): """Test CACHE USERS published_projects returns the info of the projects with the required fields""" user = UserFactory.create() published_project = ProjectFactory.create(owner=user) task = TaskFactory.create(project=published_project) fields = ('id', 'name', 'short_name', 'owner_id', 'description', 'overall_progress', 'n_tasks', 'n_volunteers', 'info') projects_published = cached_users.published_projects(user.id) for field in fields: assert field in projects_published[0].keys(), field
def test_browse_tasks_returns_required_attributes(self): """Test CACHE PROJECTS browse_tasks returns a list with objects with the required task attributes""" project = ProjectFactory.create() task = TaskFactory.create(project=project, info={}) attributes = ('id', 'n_answers') count, cached_tasks = cached_projects.browse_tasks(project.id, {}) cached_task = cached_tasks[0] for attr in attributes: assert cached_task.get(attr) == getattr(task, attr), attr
def test_project_report_with_task_details(self): """Test project report works with project details""" admin = UserFactory.create(admin=True) admin.set_password('1234') user_repo.save(admin) owner = UserFactory.create(pro=False) project = ProjectFactory.create(owner=owner) task = TaskFactory.create(project=project) TaskRunFactory.create(task=task) url = '/project/%s/projectreport/export?type=project&format=csv' % project.short_name res = self.app_get_json(url, follow_redirects=True) assert res.status_code == 200, res.data
def test_counter_works_default(self): """Test event listener when adding a task adds a counter.""" task = TaskFactory.create() counter = db.session.query(Counter).filter_by( project_id=task.project.id, task_id=task.id).all() assert len(counter) == 1, counter counter = counter[0] assert counter.n_task_runs == 0, counter assert counter.task_id == task.id, counter assert counter.project_id == task.project.id, counter
def test_check_contributing_state_completed(self): """Test check_contributing_state returns 'completed' for a project with all tasks completed and user that has contributed to it""" app = AppFactory.create() task = TaskFactory.create(app=app, n_answers=1) user = UserFactory.create() TaskRunFactory.create_batch(1, task=task, user=user) contributing_state = helpers.check_contributing_state(app_id=app.id, user_id=user.id) assert task.state == 'completed', task.state assert contributing_state == 'completed', contributing_state
def test_taskrun_authenticated_post(self, guard, mock_can_post): """Test API TaskRun creation and auth for authenticated users""" guard.return_value = mock_contributions_guard(True) mock_can_post.return_value = True project = ProjectFactory.create() task = TaskFactory.create(project=project) data = dict(project_id=project.id, task_id=task.id, info='my task result') # With wrong project_id data['project_id'] = 100000000000000000 datajson = json.dumps(data) url = '/api/taskrun?api_key=%s' % project.owner.api_key tmp = self.app.post(url, data=datajson) err_msg = "This post should fail as the project_id is wrong" err = json.loads(tmp.data) assert tmp.status_code == 403, (err, err_msg) assert err['status'] == 'failed', (err, err_msg) assert err['status_code'] == 403, (err, err_msg) assert err['exception_msg'] == 'Invalid project_id', (err, err_msg) assert err['exception_cls'] == 'Forbidden', (err, err_msg) assert err['target'] == 'taskrun', (err, err_msg) # With wrong task_id data['project_id'] = task.project_id data['task_id'] = 100000000000000000000 datajson = json.dumps(data) tmp = self.app.post(url, data=datajson) err_msg = "This post should fail as the task_id is wrong" err = json.loads(tmp.data) assert tmp.status_code == 403, (err, err_msg) assert err['status'] == 'failed', (err, err_msg) assert err['status_code'] == 403, (err, err_msg) assert err['exception_msg'] == 'Invalid task_id', (err, err_msg) assert err['exception_cls'] == 'Forbidden', (err, err_msg) assert err['target'] == 'taskrun', (err, err_msg) # Now with everything fine data = dict(project_id=task.project_id, task_id=task.id, user_id=project.owner.id, info='my task result') datajson = json.dumps(data) tmp = self.app.post(url, data=datajson) r_taskrun = json.loads(tmp.data) assert tmp.status_code == 200, r_taskrun # If the user tries again it should be forbidden tmp = self.app.post(url, data=datajson) assert tmp.status_code == 403, tmp.data
def test_taskrun_anonymous_post(self, guard, mock_request): """Test API TaskRun creation and auth for anonymous users""" guard.return_value = mock_contributions_guard(True) project = ProjectFactory.create() task = TaskFactory.create(project=project) data = dict(project_id=project.id, task_id=task.id, info='my task result') mock_request.data = json.dumps(data) # With wrong project_id mock_request.remote_addr = '127.0.0.0' data['project_id'] = 100000000000000000 datajson = json.dumps(data) tmp = self.app.post('/api/taskrun', data=datajson) err_msg = "This post should fail as the project_id is wrong" err = json.loads(tmp.data) assert tmp.status_code == 403, tmp.data assert err['status'] == 'failed', err_msg assert err['status_code'] == 403, err_msg assert err['exception_msg'] == 'Invalid project_id', err_msg assert err['exception_cls'] == 'Forbidden', err_msg assert err['target'] == 'taskrun', err_msg # With wrong task_id data['project_id'] = task.project_id data['task_id'] = 100000000000000000000 datajson = json.dumps(data) tmp = self.app.post('/api/taskrun', data=datajson) err = json.loads(tmp.data) assert tmp.status_code == 403, err_msg assert err['status'] == 'failed', err_msg assert err['status_code'] == 403, err_msg assert err['exception_msg'] == 'Invalid task_id', err_msg assert err['exception_cls'] == 'Forbidden', err_msg assert err['target'] == 'taskrun', err_msg # Now with everything fine data = dict(project_id=task.project_id, task_id=task.id, info='my task result') datajson = json.dumps(data) tmp = self.app.post('/api/taskrun', data=datajson) r_taskrun = json.loads(tmp.data) assert tmp.status_code == 200, r_taskrun # If the anonymous tries again it should be forbidden tmp = self.app.post('/api/taskrun', data=datajson) err_msg = ("Anonymous users should be only allowed to post \ one task_run per task") assert tmp.status_code == 403, err_msg
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 and project""" from pybossa import data_access from test_api import get_pwd_cookie owner = UserFactory.create(id=500) user_l1 = UserFactory.create(id=502, info=dict(data_access=["L1"])) user_l2 = UserFactory.create(id=503, info=dict(data_access=["L2"])) project1 = ProjectFactory.create(owner=owner, info=dict(data_access=["L1"])) project1.info['sched'] = Schedulers.locked project_repo.save(project1) project2 = ProjectFactory.create(owner=owner, info=dict(data_access=["L2"])) project2.info['sched'] = Schedulers.user_pref project_repo.save(project2) taskp11 = TaskFactory.create(project=project1, info=dict(question='q1'), n_answers=1) taskp12 = TaskFactory.create(project=project1, info=dict(question='q2'), n_answers=1) taskp21 = TaskFactory.create(project=project2, info=dict(question='q3'), n_answers=1) taskp22 = TaskFactory.create(project=project2, info=dict(question='q4'), n_answers=1) self.set_proj_passwd_cookie(project1, user_l1) with patch.dict(data_access.data_access_levels, self.patch_data_access_levels): res = self.app.get('api/project/{}/newtask?api_key={}' .format(project1.id, user_l1.api_key)) assert res.status_code == 200, res.status_code data = json.loads(res.data) assert data['id'] == taskp11.id, 'user_l1 should have obtained task {}'.format(taskp11.id) 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'] == taskp21.id, 'user_l2 should have obtained task {}'.format(taskp21.id)
def test_export_consesus_metadata(self): project = ProjectFactory.create() task = TaskFactory.create(project=project, info={'test': 2}, n_answers=1) task_run = TaskRunFactory.create(task=task, info={'hello': u'你好'}) with export_consensus(project, 'tsk', 'csv', True, None) as fp: zipfile = ZipFile(fp) filename = zipfile.namelist()[0] df = DataFrame.from_csv(StringIO(zipfile.read(filename))) row = df.to_dict(orient='records')[0] assert json.loads(row['task_run__info'])[task_run.user.name] == { 'hello': u'你好' }
def test_task_delete_deletes_zip_files(self, uploader): """Test API task delete deletes also zip files with tasks and taskruns""" admin = UserFactory.create() project = ProjectFactory.create(owner=admin) task = TaskFactory.create(project=project) url = '/api/task/%s?api_key=%s' % (task.id, admin.api_key) res = self.app.delete(url) expected = [ call('1_project1_task_json.zip', 'user_1'), call('1_project1_task_csv.zip', 'user_1'), call('1_project1_task_run_json.zip', 'user_1'), call('1_project1_task_run_csv.zip', 'user_1') ] assert uploader.delete_file.call_args_list == expected
def test_projects_contributed_contributions(self): """Test CACHE USERS projects_contributed returns a list of projects that has contributed to""" user = UserFactory.create() project_contributed = ProjectFactory.create() task = TaskFactory.create(project=project_contributed) TaskRunFactory.create(task=task, user=user) another_project = ProjectFactory.create() projects_contributed = cached_users.projects_contributed(user.id) assert len(projects_contributed) == 1 assert projects_contributed[0][ 'short_name'] == project_contributed.short_name, projects_contributed
def test_task_put_with_reserved_fields_returns_error(self): user = UserFactory.create() project = ProjectFactory.create(owner=user) task = TaskFactory.create(project=project) url = '/api/task/%s?api_key=%s' % (task.id, user.api_key) data = {'created': 'today', 'state': 'completed', 'id': 222} res = self.app.put(url, data=json.dumps(data)) assert res.status_code == 400, res.status_code error = json.loads(res.data) assert error['exception_msg'] == "Reserved keys in payload", error
def test_apps_contributed_contributions(self): """Test CACHE USERS apps_contributed returns a list of projects that has contributed to""" user = UserFactory.create() app_contributed = AppFactory.create() task = TaskFactory.create(app=app_contributed) TaskRunFactory.create(task=task, user=user) another_app = AppFactory.create() apps_contributed = cached_users.apps_contributed(user.id) assert len(apps_contributed) == 1 assert apps_contributed[0][ 'short_name'] == app_contributed.short_name, apps_contributed
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
def test_taskrun_authenticated_post(self): """Test API TaskRun creation and auth for authenticated users""" app = AppFactory.create() task = TaskFactory.create(app=app) data = dict(app_id=app.id, task_id=task.id, info='my task result') # With wrong app_id data['app_id'] = 100000000000000000 datajson = json.dumps(data) url = '/api/taskrun?api_key=%s' % app.owner.api_key tmp = self.app.post(url, data=datajson) err_msg = "This post should fail as the app_id is wrong" err = json.loads(tmp.data) assert tmp.status_code == 403, err_msg assert err['status'] == 'failed', err_msg assert err['status_code'] == 403, err_msg assert err['exception_msg'] == 'Invalid app_id', err_msg assert err['exception_cls'] == 'Forbidden', err_msg assert err['target'] == 'taskrun', err_msg # With wrong task_id data['app_id'] = task.app_id data['task_id'] = 100000000000000000000 datajson = json.dumps(data) tmp = self.app.post(url, data=datajson) err_msg = "This post should fail as the task_id is wrong" err = json.loads(tmp.data) assert tmp.status_code == 403, err_msg assert err['status'] == 'failed', err_msg assert err['status_code'] == 403, err_msg assert err['exception_msg'] == 'Invalid task_id', err_msg assert err['exception_cls'] == 'Forbidden', err_msg assert err['target'] == 'taskrun', err_msg # Now with everything fine data = dict(app_id=task.app_id, task_id=task.id, user_id=app.owner.id, info='my task result') datajson = json.dumps(data) tmp = self.app.post(url, data=datajson) r_taskrun = json.loads(tmp.data) assert tmp.status_code == 200, r_taskrun # If the user tries again it should be forbidden tmp = self.app.post(url, data=datajson) err_msg = ("Authorized users should be only allowed to post \ one task_run per task") task_runs = self.app.get('/api/taskrun') assert tmp.status_code == 403, tmp.data
def test_password_view_func_post_wrong_passwd(self): """Test when posting to /app/short_name/password and password is incorrect an error message is flashed""" app = AppFactory.create() task = TaskFactory.create(app=app) app.set_password('mysecret') db.session.add(app) db.session.commit() user = UserFactory.create() url = '/app/%s/password?next=/app/%s/task/%s' % ( app.short_name, app.short_name, task.id) res = self.app.post(url, data={'password': '******'}) assert 'Sorry, incorrect password' in res.data, "No error message shown"
def test_get_valid_project_levels_for_task(self): from pybossa import data_access task = TaskFactory.create(info={}) with patch.object(data_access, 'data_access_levels', self.patch_data_access_levels): self.patch_data_access_levels[ 'valid_project_levels_for_task_level'] = { 'A': ['B'] } assert data_access.get_valid_project_levels_for_task(task) == set() task.info['data_access'] = ['A'] assert data_access.get_valid_project_levels_for_task(task) == set( ['B'])
def test_password_view_func_post(self, redirect): """Test when posting to /app/short_name/password and password is correct the user is redirected to where they came from""" app = AppFactory.create() task = TaskFactory.create(app=app) app.set_password('mysecret') db.session.add(app) db.session.commit() user = UserFactory.create() redirect_url = '/app/%s/task/%s' % (app.short_name, task.id) url = '/app/%s/password?next=%s' % (app.short_name, redirect_url) res = self.app.post(url, data={'password': '******'}) redirect.assert_called_with(redirect_url)
def test_trigger_webhook_with_url(self): """Test WEBHOOK is triggered with url.""" url = 'http://server.com' project = ProjectFactory.create(webhook=url,) task = TaskFactory.create(project=project, n_answers=1) TaskRunFactory.create(project=project, task=task) payload = dict(event='task_completed', project_short_name=project.short_name, project_id=project.id, task_id=task.id, fired_at=datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")) assert queue.enqueue.called assert queue.called_with(webhook, url, payload) queue.reset_mock()
def test_projects_contributed_returns_fields(self): """Test CACHE USERS projects_contributed returns the info of the projects with the required fields""" user = UserFactory.create() project_contributed = ProjectFactory.create() task = TaskFactory.create(project=project_contributed) TaskRunFactory.create(task=task, user=user) fields = ('id', 'name', 'short_name', 'owner_id', 'description', 'overall_progress', 'n_tasks', 'n_volunteers', 'info') projects_contributed = cached_users.projects_contributed(user.id) for field in fields: assert field in list(projects_contributed[0].keys()), field
def test_newtask_default_orderby(self): """Test SCHED depth first works with orderby.""" project = ProjectFactory.create(info=dict(sched="depth_first")) task1 = TaskFactory.create(project=project, fav_user_ids=None) task2 = TaskFactory.create(project=project, fav_user_ids=[1,2,3]) api_key = project.owner.api_key url = "/api/project/%s/newtask?orderby=%s&desc=%s&api_key=%s" % (project.id, 'id', False, api_key) res = self.app.get(url) data = json.loads(res.data) assert data['id'] == task1.id, data url = "/api/project/%s/newtask?orderby=%s&desc=%s&api_key=%s" % (project.id, 'id', True, api_key) res = self.app.get(url) data = json.loads(res.data) assert data['id'] == task2.id, data url = "/api/project/%s/newtask?orderby=%s&desc=%s&api_key=%s" % (project.id, 'created', False, api_key) res = self.app.get(url) data = json.loads(res.data) assert data['id'] == task1.id, data url = "/api/project/%s/newtask?orderby=%s&desc=%s&api_key=%s" % (project.id, 'created', True, api_key) res = self.app.get(url) data = json.loads(res.data) assert data['id'] == task2.id, data url = "/api/project/%s/newtask?orderby=%s&desc=%s&api_key=%s" % (project.id, 'fav_user_ids', False, api_key) res = self.app.get(url) data = json.loads(res.data) assert data['id'] == task1.id, data url = "/api/project/%s/newtask?orderby=%s&desc=%s&api_key=%s" % (project.id, 'fav_user_ids', True, api_key) res = self.app.get(url) data = json.loads(res.data) assert data['id'] == task2.id, data assert data['fav_user_ids'] == task2.fav_user_ids, data
def test_n_results_site_returns_valid_results_with_info(self): project = ProjectFactory.create() task = TaskFactory.create(n_answers=1, project=project) TaskRunFactory.create(task=task, project=project) result = result_repo.get_by(project_id=project.id) result.info = dict(foo='bar') result_repo.update(result) n_results = stats.n_results_site() assert n_results == 1, n_results project = ProjectFactory.create() task = TaskFactory.create(n_answers=1, project=project) TaskRunFactory.create(task=task, project=project) result = result_repo.get_by(project_id=project.id) result.info = dict(foo='bar2') result_repo.update(result) n_results = stats.n_results_site() assert n_results == 2, n_results self.create_result(n_results=10) assert n_results == 2, n_results
def test_stats_dates_with_period(self): """Test CACHE PROJECT STATS dates with period works.""" pr = ProjectFactory.create() d = date.today() - timedelta(days=6) task = TaskFactory.create(project=pr, n_answers=1, created=d) TaskRunFactory.create(project=pr, task=task, created=d, finish_time=d) dd = date.today() - timedelta(days=16) AnonymousTaskRunFactory.create(project=pr, created=dd, finish_time=dd) dates, dates_anon, dates_auth = stats_dates(pr.id, '1 week') assert len(dates) == 7, len(dates) assert len(dates_anon) == 7, len(dates_anon) assert len(dates_auth) == 7, len(dates_auth) assert dates[d.strftime('%Y-%m-%d')] == 1 assert dates_anon[d.strftime('%Y-%m-%d')] == 0 assert dates_auth[d.strftime('%Y-%m-%d')] == 1