def test_task_query_with_params(self): """Test API query for task with params works""" project = ProjectFactory.create() TaskFactory.create_batch(10, project=project) # Test for real field res = self.app.get("/api/task?project_id=1") data = json.loads(res.data) # Should return one result assert len(data) == 10, data # Correct result assert data[0]['project_id'] == 1, data # Valid field but wrong value res = self.app.get("/api/task?project_id=99999999") data = json.loads(res.data) assert len(data) == 0, data # Multiple fields res = self.app.get('/api/task?project_id=1&state=ongoing') data = json.loads(res.data) # One result assert len(data) == 10, data # Correct result assert data[0]['project_id'] == 1, data assert data[0]['state'] == u'ongoing', data # Limits res = self.app.get("/api/task?project_id=1&limit=5") data = json.loads(res.data) for item in data: assert item['project_id'] == 1, item assert len(data) == 5, data
def test_task_priority(self): """Test SCHED respects priority_0 field""" project = ProjectFactory.create(info=dict(sched='depth_first_all'), owner=UserFactory.create(id=500)) TaskFactory.create_batch(10, project=project) # Register self.register() self.signin() # By default, tasks without priority should be ordered by task.id (FIFO) tasks = db.session.query(Task).filter_by(project_id=1).order_by('id').all() url = 'api/project/%s/newtask' % project.id res = self.app.get(url) task1 = json.loads(res.data) # Check that we received a Task err_msg = "Task.id should be the same" assert task1.get('id') == tasks[0].id, err_msg # Now let's change the priority to a random task import random t = random.choice(tasks) # Increase priority to maximum t.priority_0 = 1 db.session.add(t) db.session.commit() # Request again a new task res = self.app.get(url + '?orderby=priority_0&desc=true') task1 = json.loads(res.data) # Check that we received a Task err_msg = "Task.id should be the same" assert task1.get('id') == t.id, err_msg err_msg = "Task.priority_0 should be the 1" assert task1.get('priority_0') == 1, err_msg
def test_user_01_newtask(self): """ Test SCHED newtask returns a Task for John Doe User""" project = ProjectFactory.create(info=dict(sched='depth_first_all'), owner=UserFactory.create(id=500)) TaskFactory.create_batch(2, project=project, n_answers=2) # Register self.register() self.signin() url = 'api/project/%s/newtask' % project.id res = self.app.get(url) data = json.loads(res.data) task_id = data['id'] assert data['id'], data taskrun = dict(project_id=data['project_id'], task_id=data['id'], info="hola") res = self.app.post('api/taskrun', data=json.dumps(taskrun)) res = self.app.get(url) data = json.loads(res.data) assert data['id'], data assert data['id'] != task_id, data self.signout()
def test_task_preloading_limit(self): """Test TASK Pre-loading with limit works""" # Register project = ProjectFactory.create(info=dict(sched='depth_first_all'), owner=UserFactory.create(id=500)) TaskFactory.create_batch(10, project=project) self.register() self.signin() assigned_tasks = [] url = 'api/project/%s/newtask?limit=2' % project.id res = self.app.get(url) tasks1 = json.loads(res.data) # Check that we received a Task for t in tasks1: assert t.get('id'), t # Pre-load the next tasks for the user res = self.app.get(url + '&offset=2') tasks2 = json.loads(res.data) # Check that we received a Task for t in tasks2: assert t.get('id'), t # Check that both tasks are different tasks1_ids = set([t['id'] for t in tasks1]) tasks2_ids = set([t['id'] for t in tasks2]) assert len(tasks1_ids.union(tasks2_ids)) == 4, "Tasks should be different" ## Save the assigned task for t in tasks1: assigned_tasks.append(t) for t in tasks2: assigned_tasks.append(t) # Submit an Answer for the assigned and pre-loaded task for t in assigned_tasks: tr = dict(project_id=t['project_id'], task_id=t['id'], info={'answer': 'No'}) tr = json.dumps(tr) self.app.post('/api/taskrun', data=tr) # Get two tasks again res = self.app.get(url) tasks3 = json.loads(res.data) # Check that we received a Task for t in tasks3: assert t.get('id'), t # Pre-load the next task for the user res = self.app.get(url + '&offset=2') tasks4 = json.loads(res.data) # Check that we received a Task for t in tasks4: assert t.get('id'), t # Check that both tasks are different tasks3_ids = set([t['id'] for t in tasks3]) tasks4_ids = set([t['id'] for t in tasks4]) assert len(tasks3_ids.union(tasks4_ids)) == 4, "Tasks should be different" # Check that a big offset returns None res = self.app.get(url + '&offset=11') assert json.loads(res.data) == {}, res.data
def test_get_random_task(self, user=None): task = pybossa.sched.new_task(project_id=1, sched='random') assert task is None, task project = ProjectFactory.create() TaskFactory.create_batch(3, project=project) task = pybossa.sched.new_task(project_id=1, sched='random') assert task is not None, task assert task.project_id == project.id
def test_count_tasks_with_one_condition(self): """Test count_tasks_with returns the number of tasks that meet the filtering condition""" TaskFactory.create_batch(3, state='done') should_be_missing = TaskFactory.create(state='ongoing') count = self.task_repo.count_tasks_with(state='done') assert count == 3, count
def test_n_draft_no_drafts(self): """Test CACHE PROJECTS _n_draft returns 0 if there are no draft projects""" # Here, we are suposing that a project is draft iff has no presenter AND has no tasks project = ProjectFactory.create(info={}) TaskFactory.create_batch(2, project=project) number_of_drafts = cached_projects._n_draft() assert number_of_drafts == 0, number_of_drafts
def test_browse_tasks_returns_all_tasks(self): """Test CACHE PROJECTS browse_tasks returns a list with all the tasks from a given project""" project = ProjectFactory.create() TaskFactory.create_batch(2, project=project) browse_tasks = cached_projects.browse_tasks(project.id) assert len(browse_tasks) == 2, browse_tasks
def test_filter_tasks_by_one_condition(self): """Test filter_tasks_by returns a list of tasks that meet the filtering condition""" TaskFactory.create_batch(3, state='done') should_be_missing = TaskFactory.create(state='ongoing') retrieved_tasks = self.task_repo.filter_tasks_by(state='done') assert len(retrieved_tasks) == 3, retrieved_tasks assert should_be_missing not in retrieved_tasks, retrieved_tasks
def test_task_query_without_params(self): """ Test API Task query""" project = ProjectFactory.create() TaskFactory.create_batch(10, project=project, info={"question": "answer"}) res = self.app.get("/api/task") tasks = json.loads(res.data) assert len(tasks) == 10, tasks task = tasks[0] assert task["info"]["question"] == "answer", task # The output should have a mime-type: application/json assert res.mimetype == "application/json", res
def test_task_preloading_external_uid(self): """Test TASK Pre-loading for external user IDs works""" project = ProjectFactory.create(info=dict(sched='depth_first_all'), owner=UserFactory.create(id=500)) TaskFactory.create_batch(10, project=project) assigned_tasks = [] # Get Task until scheduler returns None project = project_repo.get(1) headers = self.get_headers_jwt(project) url = 'api/project/%s/newtask?external_uid=2xb' % project.id res = self.app.get(url, headers=headers) task1 = json.loads(res.data) # Check that we received a Task assert task1.get('id'), task1 # Pre-load the next task for the user res = self.app.get(url + '&offset=1', headers=headers) task2 = json.loads(res.data) # Check that we received a Task assert task2.get('id'), task2 # Check that both tasks are different assert task1.get('id') != task2.get('id'), "Tasks should be different" ## Save the assigned task assigned_tasks.append(task1) assigned_tasks.append(task2) # Submit an Answer for the assigned and pre-loaded task for t in assigned_tasks: tr = dict(project_id=t['project_id'], task_id=t['id'], info={'answer': 'No'}, external_uid='2xb') tr = json.dumps(tr) res = self.app.post('/api/taskrun?external_uid=2xb', data=tr, headers=headers) # Get two tasks again res = self.app.get(url, headers=headers) task3 = json.loads(res.data) # Check that we received a Task assert task3.get('id'), task1 # Pre-load the next task for the user res = self.app.get(url + '&offset=1', headers=headers) task4 = json.loads(res.data) # Check that we received a Task assert task4.get('id'), task2 # Check that both tasks are different assert task3.get('id') != task4.get('id'), "Tasks should be different" assert task1.get('id') != task3.get('id'), "Tasks should be different" assert task2.get('id') != task4.get('id'), "Tasks should be different" # Check that a big offset returns None res = self.app.get(url + '&offset=11', headers=headers) assert json.loads(res.data) == {}, res.data
def test_update_tasks_redundancy_changes_all_project_tasks_redundancy(self): """Test update_tasks_redundancy updates the n_answers value for every task in the project""" project = ProjectFactory.create() TaskFactory.create_batch(2, project=project, n_answers=1) self.task_repo.update_tasks_redundancy(project, 2) tasks = self.task_repo.filter_tasks_by(project_id=project.id) for task in tasks: assert task.n_answers == 2, task.n_answers
def test_task_query_without_params(self): """ Test API Task query""" project = ProjectFactory.create() TaskFactory.create_batch(10, project=project, info={'question': 'answer'}) res = self.app.get('/api/task') tasks = json.loads(res.data) assert len(tasks) == 10, tasks task = tasks[0] assert task['info']['question'] == 'answer', task # The output should have a mime-type: application/json assert res.mimetype == 'application/json', res
def test_task_preloading(self): """Test TASK Pre-loading works""" # Del previous TaskRuns project = ProjectFactory.create(info=dict(sched='depth_first_all'), owner=UserFactory.create(id=500)) TaskFactory.create_batch(10, project=project) # Register self.register() self.signin() assigned_tasks = [] # Get Task until scheduler returns None url = 'api/project/%s/newtask' % project.id res = self.app.get(url) task1 = json.loads(res.data) # Check that we received a Task assert task1.get('id'), task1 # Pre-load the next task for the user res = self.app.get(url + '?offset=1') task2 = json.loads(res.data) # Check that we received a Task assert task2.get('id'), task2 # Check that both tasks are different assert task1.get('id') != task2.get('id'), "Tasks should be different" ## Save the assigned task assigned_tasks.append(task1) assigned_tasks.append(task2) # Submit an Answer for the assigned and pre-loaded task for t in assigned_tasks: tr = dict(project_id=t['project_id'], task_id=t['id'], info={'answer': 'No'}) tr = json.dumps(tr) self.app.post('/api/taskrun', data=tr) # Get two tasks again res = self.app.get(url) task3 = json.loads(res.data) # Check that we received a Task assert task3.get('id'), task1 # Pre-load the next task for the user res = self.app.get(url + '?offset=1') task4 = json.loads(res.data) # Check that we received a Task assert task4.get('id'), task2 # Check that both tasks are different assert task3.get('id') != task4.get('id'), "Tasks should be different" assert task1.get('id') != task3.get('id'), "Tasks should be different" assert task2.get('id') != task4.get('id'), "Tasks should be different" # Check that a big offset returns None res = self.app.get(url + '?offset=11') assert json.loads(res.data) == {}, res.data
def test_filter_tasks_limit_offset(self): """Test that filter_tasks_by supports limit and offset options""" TaskFactory.create_batch(4) all_tasks = self.task_repo.filter_tasks_by() first_two = self.task_repo.filter_tasks_by(limit=2) last_two = self.task_repo.filter_tasks_by(limit=2, offset=2) assert len(first_two) == 2, first_two assert len(last_two) == 2, last_two assert first_two == all_tasks[:2] assert last_two == all_tasks[2:]
def test_no_more_tasks_limit(self): """Test that a users gets always tasks with limit""" owner = UserFactory.create() project = ProjectFactory.create(info=dict(sched='depth_first_all'), owner=owner, short_name='egil', name='egil', description='egil') project_id = project.id all_tasks = TaskFactory.create_batch(20, project=project, n_answers=10) for t in all_tasks[0:10]: TaskRunFactory.create_batch(10, task=t, project=project) tasks = db.session.query(Task).filter_by(project_id=project.id, state='ongoing').all() assert tasks[0].n_answers == 10 url = 'api/project/%s/newtask?limit=2&orderby=id' % project_id res = self.app.get(url) data = json.loads(res.data) err_msg = "User should get a task" i = 0 for t in data: print t['id'] assert 'project_id' in t.keys(), err_msg assert t['project_id'] == project_id, err_msg assert t['id'] == all_tasks[i].id, (err_msg, t, all_tasks[i].id) assert t['state'] == 'completed', err_msg i += 1
def test_anonymous_02_gets_different_tasks(self): """ Test SCHED newtask returns N different Tasks for the Anonymous User""" assigned_tasks = [] # Get a Task until scheduler returns None project = ProjectFactory.create() tasks = TaskFactory.create_batch(3, project=project, info={}) res = self.app.get('api/project/%s/newtask' %project.id) data = json.loads(res.data) while data.get('info') is not None: # Save the assigned task assigned_tasks.append(data) task = db.session.query(Task).get(data['id']) # Submit an Answer for the assigned task tr = AnonymousTaskRunFactory.create(project=project, task=task) res = self.app.get('api/project/%s/newtask' %project.id) data = json.loads(res.data) # Check if we received the same number of tasks that the available ones assert len(assigned_tasks) == len(tasks), len(assigned_tasks) # Check if all the assigned Task.id are equal to the available ones err_msg = "Assigned Task not found in DB Tasks" for at in assigned_tasks: assert self.is_task(at['id'], tasks), err_msg # Check that there are no duplicated tasks err_msg = "One Assigned Task is duplicated" for at in assigned_tasks: assert self.is_unique(at['id'], assigned_tasks), err_msg
def test_user_progress_anonymous(self): """Test API userprogress as anonymous works""" user = UserFactory.create() project = ProjectFactory.create(owner=user) tasks = TaskFactory.create_batch(2, project=project) taskruns = [] for task in tasks: taskruns.extend(AnonymousTaskRunFactory.create_batch(2, task=task)) res = self.app.get('/api/project/1/userprogress', follow_redirects=True) data = json.loads(res.data) error_msg = "The reported total number of tasks is wrong" assert len(tasks) == data['total'], error_msg error_msg = "The reported number of done tasks is wrong" assert len(taskruns) == data['done'], data # Add a new TaskRun and check again taskrun = AnonymousTaskRunFactory.create(task=tasks[0], info={'answer': u'hello'}) res = self.app.get('/api/project/1/userprogress', follow_redirects=True) data = json.loads(res.data) error_msg = "The reported total number of tasks is wrong" assert len(tasks) == data['total'], error_msg error_msg = "Number of done tasks is wrong: %s" % len(taskruns) assert len(taskruns) + 1 == data['done'], error_msg
def test_user_03_respects_limit_tasks(self): """ Test SCHED newtask respects the limit of 30 TaskRuns per Task""" project = ProjectFactory.create(info=dict(sched='depth_first_all'), owner=UserFactory.create(id=500)) orig_tasks = TaskFactory.create_batch(1, project=project, n_answers=10) user = UserFactory.create() tasks = get_depth_first_all_task(project.id, user.id) assert len(tasks) == 1, len(tasks) assert tasks[0].id == orig_tasks[0].id, tasks assert tasks[0].state == 'ongoing', tasks for i in range(10): tr = TaskRun(project_id=project.id, task_id=orig_tasks[0].id, user_ip='127.0.0.%s' % i) db.session.add(tr) db.session.commit() tasks = get_depth_first_all_task(project.id, user.id) assert len(tasks) == 1, len(tasks) assert tasks[0].id == orig_tasks[0].id, tasks assert tasks[0].state == 'completed', tasks assert len(tasks[0].task_runs) == 10, tasks tr = TaskRun(project_id=project.id, task_id=orig_tasks[0].id, user_id=user.id) db.session.add(tr) db.session.commit() tasks = get_depth_first_all_task(project.id, user.id) assert len(tasks) == 0, tasks
def test_user_progress_anonymous(self): """Test API userprogress as anonymous works""" user = UserFactory.create() app = AppFactory.create(owner=user) tasks = TaskFactory.create_batch(2, app=app) for task in tasks: taskruns = AnonymousTaskRunFactory.create_batch(2, task=task) taskruns = db.session.query(TaskRun)\ .filter(TaskRun.app_id == app.id)\ .filter(TaskRun.user_ip == '127.0.0.1')\ .all() res = self.app.get('/api/app/1/userprogress', follow_redirects=True) data = json.loads(res.data) error_msg = "The reported total number of tasks is wrong" assert len(tasks) == data['total'], error_msg error_msg = "The reported number of done tasks is wrong" assert len(taskruns) == data['done'], data # Add a new TaskRun and check again taskrun = AnonymousTaskRunFactory.create(task=tasks[0], info={'answer': u'hello'}) res = self.app.get('/api/app/1/userprogress', follow_redirects=True) data = json.loads(res.data) error_msg = "The reported total number of tasks is wrong" assert len(tasks) == data['total'], error_msg error_msg = "Number of done tasks is wrong: %s" % len(taskruns) assert len(taskruns) + 1 == data['done'], error_msg
def test_anonymous_01_newtask(self): """ Test SCHED newtask returns a Task for the Anonymous User""" project = ProjectFactory.create(info=dict(sched='depth_first_all')) TaskFactory.create_batch(2, project=project, info='hola') res = self.app.get('api/project/%s/newtask' %project.id) data = json.loads(res.data) task_id = data['id'] assert data['info'] == 'hola', data taskrun = dict(project_id=data['project_id'], task_id=data['id'], info="hola") res = self.app.post('api/taskrun', data=json.dumps(taskrun)) res = self.app.get('api/project/%s/newtask' %project.id) data = json.loads(res.data) assert data['info'] == 'hola', data assert data['id'] != task_id, data
def test_user_02_gets_different_tasks_limit(self): """ Test SCHED newtask returns N different list of Tasks for John Doe User""" # Register self.register() self.signin() project = ProjectFactory.create(info=dict(sched='depth_first_all'), owner=UserFactory.create(id=500)) TaskFactory.create_batch(10, project=project) assigned_tasks = [] # Get Task until scheduler returns None url = 'api/project/%s/newtask?limit=5' % project.id res = self.app.get(url) data = json.loads(res.data) while len(data) > 0: # Check that we received a Task for t in data: assert t.get('id'), t # Save the assigned task assigned_tasks.append(t) # Submit an Answer for the assigned task tr = dict(project_id=t['project_id'], task_id=t['id'], info={'answer': 'No'}) tr = json.dumps(tr) self.app.post('/api/taskrun', data=tr) res = self.app.get(url) data = json.loads(res.data) # Check if we received the same number of tasks that the available ones tasks = db.session.query(Task).filter_by(project_id=1).all() assert len(assigned_tasks) == len(tasks), assigned_tasks # Check if all the assigned Task.id are equal to the available ones tasks = db.session.query(Task).filter_by(project_id=1).all() err_msg = "Assigned Task not found in DB Tasks" for at in assigned_tasks: assert self.is_task(at['id'], tasks), err_msg # Check that there are no duplicated tasks err_msg = "One Assigned Task is duplicated" for at in assigned_tasks: assert self.is_unique(at['id'], assigned_tasks), err_msg
def test_counter_table(self): """Test API Counter table is updated accordingly.""" project = ProjectFactory.create() task = TaskFactory.create(project=project) items = db.session.query(Counter).filter_by(project_id=project.id).all() assert len(items) == 1 TaskFactory.create_batch(9, project=project) items = db.session.query(Counter).filter_by(project_id=project.id).all() assert len(items) == 10 task_id = task.id task_repo.delete(task) items = db.session.query(Counter).filter_by(project_id=project.id).all() assert len(items) == 9 items = db.session.query(Counter).filter_by(task_id=task_id).all() assert len(items) == 0
def test_delete_all_deletes_many_tasks(self): """Test delete_all deletes many tasks at once""" tasks = TaskFactory.create_batch(2) self.task_repo.delete_all(tasks) for task in tasks: assert self.task_repo.get_task(task.id) is None, task
def test_newtask_allow_anonymous_contributors(self): """Test API get a newtask - allow anonymous contributors""" app = AppFactory.create() user = UserFactory.create() tasks = TaskFactory.create_batch(2, app=app, info={'question': 'answer'}) # All users are allowed to participate by default # As Anonymous user url = '/api/app/%s/newtask' % app.id res = self.app.get(url, follow_redirects=True) task = json.loads(res.data) err_msg = "The task.app_id is different from the app.id" assert task['app_id'] == app.id, err_msg err_msg = "There should not be an error message" assert task['info'].get('error') is None, err_msg err_msg = "There should be a question" assert task['info'].get('question') == 'answer', err_msg # As registered user url = '/api/app/%s/newtask?api_key=%s' % (app.id, user.api_key) res = self.app.get(url, follow_redirects=True) task = json.loads(res.data) err_msg = "The task.app_id is different from the app.id" assert task['app_id'] == app.id, err_msg err_msg = "There should not be an error message" assert task['info'].get('error') is None, err_msg err_msg = "There should be a question" assert task['info'].get('question') == 'answer', err_msg # Now only allow authenticated users app.allow_anonymous_contributors = False db.session.add(app) db.session.commit() # As Anonymous user url = '/api/app/%s/newtask' % app.id res = self.app.get(url, follow_redirects=True) task = json.loads(res.data) err_msg = "The task.app_id should be null" assert task['app_id'] is None, err_msg err_msg = "There should be an error message" err = "This project does not allow anonymous contributors" assert task['info'].get('error') == err, err_msg err_msg = "There should not be a question" assert task['info'].get('question') is None, err_msg # As registered user url = '/api/app/%s/newtask?api_key=%s' % (app.id, user.api_key) res = self.app.get(url, follow_redirects=True) task = json.loads(res.data) err_msg = "The task.app_id is different from the app.id" assert task['app_id'] == app.id, err_msg err_msg = "There should not be an error message" assert task['info'].get('error') is None, err_msg err_msg = "There should be a question" assert task['info'].get('question') == 'answer', err_msg
def test_anonymous_user_create_taskrun(self): """Test anonymous user can create a taskrun for a task even though he has posted taskruns for different tasks in the same project""" tasks = TaskFactory.create_batch(2) taskrun1 = AnonymousTaskRunFactory.create(task=tasks[0]) taskrun2 = AnonymousTaskRunFactory.build(task_id=tasks[1].id) assert_not_raises(Exception, ensure_authorized_to, 'create', taskrun2)
def test_task_query_without_params_with_context(self): """ Test API Task query with context""" user = UserFactory.create() project_oc = ProjectFactory.create(owner=user) project_two = ProjectFactory.create() TaskFactory.create_batch(10, project=project_oc, info={'question': 'answer'}) TaskFactory.create_batch(10, project=project_two, info={'question': 'answer'}) res = self.app.get('/api/task?api_key=' + user.api_key) tasks = json.loads(res.data) assert len(tasks) == 10, tasks for task in tasks: assert task['project_id'] == project_oc.id, task assert task['info']['question'] == 'answer', task # The output should have a mime-type: application/json assert res.mimetype == 'application/json', res res = self.app.get('/api/task?api_key=' + user.api_key + "&all=1") tasks = json.loads(res.data) assert len(tasks) == 20, tasks
def test_filter_tasks_support_yield_option(self): """Test that filter_tasks_by with the yielded=True option returns the results as a generator""" tasks = TaskFactory.create_batch(2, state='done') yielded_tasks = self.task_repo.filter_tasks_by(state='done', yielded=True) import types assert isinstance(yielded_tasks.__iter__(), types.GeneratorType) for task in yielded_tasks: assert task in tasks
def test_delete_valid_from_project_deletes_many_tasks(self): """Test delete_valid_from_project deletes many tasks at once""" tasks = TaskFactory.create_batch(2) project = project_repo.get(tasks[0].project_id) self.task_repo.delete_valid_from_project(project) tasks = self.task_repo.filter_tasks_by(project_id=project.id) assert len(tasks) == 0, len(tasks)
def test_authenticated_user_create_taskrun(self): """Test authenticated user can create a taskrun for a task even though he has posted taskruns for different tasks in the same project""" user = UserFactory.create_batch(2)[1] tasks = TaskFactory.create_batch(2) taskrun1 = TaskRunFactory.create(task=tasks[0], user=user) taskrun2 = TaskRunFactory.build(task_id=tasks[1].id, user_id=user.id) assert self.mock_authenticated.id == taskrun2.user_id assert_not_raises(Exception, ensure_authorized_to, 'create', taskrun2)
def test_task_priority_limit(self): """Test SCHED respects priority_0 field with limit""" project = ProjectFactory.create(info=dict(sched='depth_first_all'), owner=UserFactory.create(id=500)) TaskFactory.create_batch(10, project=project) # Register self.register() self.signin() # By default, tasks without priority should be ordered by task.id (FIFO) tasks = db.session.query(Task).filter_by( project_id=project.id).order_by('id').all() url = 'api/project/%s/newtask?limit=2' % project.id self.set_proj_passwd_cookie(project, username='******') res = self.app.get(url) tasks1 = json.loads(res.data) # Check that we received a Task err_msg = "Task.id should be the same" assert tasks1[0].get('id') == tasks[0].id, err_msg # Now let's change the priority to a random task import random t = random.choice(tasks) # Increase priority to maximum t.priority_0 = 1 db.session.add(t) db.session.commit() # Request again a new task res = self.app.get(url + '&orderby=priority_0&desc=true') tasks1 = json.loads(res.data) # Check that we received a Task err_msg = "Task.id should be the same" assert tasks1[0].get('id') == t.id, (err_msg, tasks1[0]) err_msg = "Task.priority_0 should be the 1" assert tasks1[0].get('priority_0') == 1, err_msg
def test_newtask(self): """Test API project new_task method and authentication""" project = ProjectFactory.create() TaskFactory.create_batch(2, project=project) user = UserFactory.create() # anonymous # test getting a new task res = self.app.get('/api/project/%s/newtask' % project.id) assert res, res task = json.loads(res.data) assert_equal(task['project_id'], project.id) # The output should have a mime-type: application/json assert res.mimetype == 'application/json', res # as a real user url = '/api/project/%s/newtask?api_key=%s' % (project.id, user.api_key) res = self.app.get(url) assert res, res task = json.loads(res.data) assert_equal(task['project_id'], project.id) # Get NotFound for an non-existing project url = '/api/project/5000/newtask' res = self.app.get(url) err = json.loads(res.data) err_msg = "The project does not exist" assert err['status'] == 'failed', err_msg assert err['status_code'] == 404, err assert err['exception_cls'] == 'NotFound', err_msg assert err['target'] == 'project', err_msg # Get an empty task url = '/api/project/%s/newtask?offset=1000' % project.id res = self.app.get(url) assert res.data == '{}', res.data
def test_user_progress_authenticated_user(self): """Test API userprogress as an authenticated user works""" user = UserFactory.create() app = AppFactory.create(owner=user) tasks = TaskFactory.create_batch(2, app=app) for task in tasks: taskruns = TaskRunFactory.create_batch(2, task=task, user=user) taskruns = db.session.query(TaskRun)\ .filter(TaskRun.app_id == app.id)\ .filter(TaskRun.user_id == user.id)\ .all() url = '/api/app/1/userprogress?api_key=%s' % user.api_key res = self.app.get(url, follow_redirects=True) data = json.loads(res.data) error_msg = "The reported total number of tasks is wrong" assert len(tasks) == data['total'], error_msg url = '/api/app/%s/userprogress?api_key=%s' % (app.short_name, user.api_key) res = self.app.get(url, follow_redirects=True) data = json.loads(res.data) error_msg = "The reported total number of tasks is wrong" assert len(tasks) == data['total'], error_msg url = '/api/app/5000/userprogress?api_key=%s' % user.api_key res = self.app.get(url, follow_redirects=True) assert res.status_code == 404, res.status_code url = '/api/app/userprogress?api_key=%s' % user.api_key res = self.app.get(url, follow_redirects=True) assert res.status_code == 404, res.status_code error_msg = "The reported number of done tasks is wrong" assert len(taskruns) == data['done'], error_msg # Add a new TaskRun and check again taskrun = TaskRunFactory.create(task=tasks[0], info={'answer': u'hello'}, user=user) url = '/api/app/1/userprogress?api_key=%s' % user.api_key res = self.app.get(url, follow_redirects=True) data = json.loads(res.data) error_msg = "The reported total number of tasks is wrong" assert len(tasks) == data['total'], error_msg error_msg = "Number of done tasks is wrong: %s" % len(taskruns) assert len(taskruns) + 1 == data['done'], error_msg
def test_newtask_unpublish_project(self): """Test user obtains newtask with published projects only; 404 with unpublished projects""" project = ProjectFactory.create(info=dict(published=True, task_presenter='task presenter')) admin, subadmin_coowner, regular_coowner, user = UserFactory.create_batch(4) make_admin(admin) make_subadmin(subadmin_coowner) tasks = TaskFactory.create_batch(10, project=project, 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)) task = json.loads(res.data) assert res.status_code == 200 and task['id'] == tasks[0].id, 'User should have obtained new task' # submit answer for the task task_run = dict(project_id=project.id, task_id=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 #unpublish project project.published = False project.owners_ids.append(regular_coowner.id) project.owners_ids.append(subadmin_coowner.id) project_repo.save(project) project = project_repo.get(project.id) assert not project.published, 'Project should not be published' # for unpublished project, obtaining newtask would succeed for admin res = self.app.get('api/project/{}/newtask?api_key={}' .format(project.id, admin.api_key)) assert res.status_code == 200, 'newtask to unpublished project should succeed for admin' # for unpublished project, obtaining newtask would succeed for subadmin coowner res = self.app.get('api/project/{}/newtask?api_key={}' .format(project.id, subadmin_coowner.api_key)) assert res.status_code == 200, 'newtask to unpublished project should succeed for admin' # for unpublished project, obtaining newtask would succeed for regular coowner res = self.app.get('api/project/{}/newtask?api_key={}' .format(project.id, regular_coowner.api_key)) assert res.status_code == 200, 'newtask to unpublished project should succeed for admin' # for unpublished project, obtaining newtask would fail for regular user res = self.app.get('api/project/{}/newtask?api_key={}' .format(project.id, user.api_key)) assert res.status_code == 404, 'newtask to unpublished project should return 404'
def test_task_query_with_params(self, auth): """Test API query for task with params works""" auth.return_value = True project = ProjectFactory.create() user = UserFactory.create() tasks = TaskFactory.create_batch(10, project=project) # Test for real field res = self.app.get('/api/task?project_id=1&all=1&api_key=' + user.api_key) data = json.loads(res.data) # Should return one result assert len(data) == 10, data # Correct result assert data[0]['project_id'] == 1, data # Valid field but wrong value res = self.app.get('/api/task?project_id=99999999&all=1&api_key=' + user.api_key) data = json.loads(res.data) assert len(data) == 0, data # Multiple fields res = self.app.get( '/api/task?project_id=1&state=ongoing&all=1&api_key=' + user.api_key) data = json.loads(res.data) # One result assert len(data) == 10, data # Correct result assert data[0]['project_id'] == 1, data assert data[0]['state'] == u'ongoing', data # Limits res = self.app.get('/api/task?project_id=1&limit=5&all=1&api_key=' + user.api_key) data = json.loads(res.data) for item in data: assert item['project_id'] == 1, item assert len(data) == 5, data # Keyset pagination url = "/api/task?project_id=1&limit=5&last_id=%s&all=1&api_key=%s" % ( tasks[4].id, user.api_key) res = self.app.get(url) data = json.loads(res.data) for item in data: assert item['project_id'] == 1, item assert len(data) == 5, data assert data[0]['id'] == tasks[5].id, data
def test_list_tasks(self, auth): """Get a list of tasks using a list of project_ids.""" auth.return_value = True users = UserFactory.create_batch(3) project = ProjectFactory.create(owner=users[1]) tasks = TaskFactory.create_batch(2, project=project) url = '/api/task?api_key=%s&all=1' with patch.dict(self.flask_app.config, {'ENABLE_ENCRYPTION': True}): for u in users: res = self.app.get(url % u.api_key, follow_redirects=True) tasks = json.loads(res.data) for task in tasks: assert 'signature' not in task
def test_newtask_extends_expiration_by_timeout(self): """Test API project new_task extends expiration according to timeout""" project = ProjectFactory.create( info={ 'timeout': 120 * 60, 'data_classification': dict(input_data="L4 - public", output_data="L4 - public") }) project.set_password('the_password') project_repo.save(project) TaskFactory.create_batch(2, project=project, info={'question': 'answer'}) user = UserFactory.create() url = '/project/%s/password?api_key=%s' % (project.short_name, user.api_key) data = dict(password='******') res = self.app.post(url, data=data) c, v, e = get_pwd_cookie(project.short_name, res) assert c self.app.set_cookie('/', c, v) now = datetime.utcnow() url = '/api/project/%s/newtask?api_key=%s' % (project.id, user.api_key) res = self.app.get(url) assert res.status_code == 200, (res, res.data) task = json.loads(res.data) assert task['info'].get('question') == 'answer' c, v, new_exp = get_pwd_cookie(project.short_name, res) assert new_exp - now > timedelta(minutes=115) assert new_exp - now < timedelta(minutes=125)
def test_anonymous_01_newtask_limits(self): """ Test SCHED newtask returns a list of Tasks for the Anonymous User""" project = ProjectFactory.create(info=dict(sched='depth_first_all')) TaskFactory.create_batch(100, project=project, info='hola') url = 'api/project/%s/newtask?limit=100' % project.id res = self.app.get(url) data = json.loads(res.data) assert len(data) == 100 for t in data: assert t['info'] == 'hola', t task_ids = [task['id'] for task in data] task_ids = set(task_ids) assert len(task_ids) == 100, task_ids url = 'api/project/%s/newtask?limit=200' % project.id res = self.app.get(url) data = json.loads(res.data) assert len(data) == 100 for t in data: assert t['info'] == 'hola', t task_ids = [task['id'] for task in data] task_ids = set(task_ids) assert len(task_ids) == 100, task_ids
def test_newtask(self): """Test API project new_task method and authentication""" project = ProjectFactory.create() project.set_password('the_password') project_repo.save(project) TaskFactory.create_batch(2, project=project, info={'question': 'answer'}) user = UserFactory.create() # anonymous # test getting a new task res = self.app.get('/api/project/%s/newtask' % project.id) assert res, res task = json.loads(res.data) assert 'error' in task['info'], 'No anonymous contributors' # as a real user, no password url = '/api/project/%s/newtask?api_key=%s' % (project.id, user.api_key) res = self.app.get(url) assert res.status_code == 403, res task = json.loads(res.data) assert task['exception_msg'] == 'No project password provided' url = '/project/%s/password?api_key=%s' % (project.short_name, user.api_key) data = dict(password='******') res = self.app.post(url, data=data) c, v, e = get_pwd_cookie(project.short_name, res) assert c self.app.set_cookie('/', c, v) url = '/api/project/%s/newtask?api_key=%s' % (project.id, user.api_key) res = self.app.get(url) assert res.status_code == 200, res task = json.loads(res.data) assert task['info'].get('question') == 'answer'
def test_external_uid_02_gets_different_tasks_limits(self): """ Test SCHED newtask returns N different list of Tasks for a external User ID.""" assigned_tasks = [] # Get a Task until scheduler returns None project = ProjectFactory.create() tasks = TaskFactory.create_batch(10, project=project, info={}) headers = self.get_headers_jwt(project) url = 'api/project/%s/newtask?limit=5&external_uid=%s' % (project.id, '1xa') res = self.app.get(url, headers=headers) data = json.loads(res.data) assert 'error' in data['info']
def test_avg_task_per_job(self): """Test average task per job created since current time""" date_recent = (datetime.datetime.utcnow() - datetime.timedelta(29)).isoformat() date_old = (datetime.datetime.utcnow() - datetime.timedelta(60)).isoformat() date_now = datetime.datetime.utcnow().isoformat() expected_avg_tasks = 5 project = ProjectFactory.create(created=date_recent) old_project = ProjectFactory.create(created=date_old) TaskFactory.create_batch(5, n_answers=1, project=project, created=date_now) TaskFactory.create_batch(5, n_answers=1, project=old_project, created=date_old) avg_tasks = stats.avg_task_per_job() assert avg_tasks == expected_avg_tasks, "Average task created per job should be {}".format( expected_avg_tasks)
def test_user_01_newtask(self): """ Test SCHED newtask returns a Task for John Doe User""" project = ProjectFactory.create(owner=UserFactory.create(id=500)) TaskFactory.create_batch(2, project=project, n_answers=2) # Register self.register() self.signin() url = 'api/project/%s/newtask' % project.id self.set_proj_passwd_cookie(project, username='******') res = self.app.get(url) data = json.loads(res.data) task_id = data['id'] assert data['id'], data taskrun = dict(project_id=data['project_id'], task_id=data['id'], info="hola") res = self.app.post('api/taskrun', data=json.dumps(taskrun)) res = self.app.get(url) data = json.loads(res.data) assert data['id'], data assert data['id'] != task_id, data self.signout()
def test_user_01_newtask_limits(self): """ Test SCHED newtask returns a Task for John Doe User with limits""" self.register() self.signin() project = ProjectFactory.create(owner=UserFactory.create(id=500)) tasks = TaskFactory.create_batch(10, project=project, info=dict(foo=1)) # Register url = 'api/project/%s/newtask?limit=2' % project.id res = self.app.get(url) data = json.loads(res.data) assert len(data) == 2, data for t in data: assert t['info']['foo'] == 1, t self.signout()
def test_task_4(self): ''' Tasks match user profile ''' owner = UserFactory.create(id=500) owner.user_pref = {'languages': ['de', 'en']} user_repo.save(owner) project = ProjectFactory.create(owner=owner) project.info['sched'] = Schedulers.user_pref tasks = TaskFactory.create_batch(2, project=project, n_answers=10) tasks[0].user_pref = {'languages': ['en', 'zh']} task_repo.save(tasks[0]) tasks[1].user_pref = {'languages': ['de']} task_repo.save(tasks[1]) assert n_available_tasks_for_user(project, 500) == 2
def test_task_routing_3(self): ''' User has empty profile set, only tasks that have empty filter can be assigned to user ''' user_info = dict(metadata={"profile": json.dumps({})}) owner = UserFactory.create(id=500, info=user_info) user_repo.save(owner) project = ProjectFactory.create(owner=owner) project.info['sched'] = Schedulers.user_pref tasks = TaskFactory.create_batch(3, project=project, n_answers=10) tasks[0].worker_filter = {'finance': [0.8, '>=']} task_repo.save(tasks[0]) tasks[1].worker_filter = {'geography': [0.5, '>=']} task_repo.save(tasks[1]) assert n_available_tasks_for_user(project, 500) == 1
def test_external_user_id_progress_anonymous(self): """Test API userprogress as external_uid works""" user = UserFactory.create() project = ProjectFactory.create(owner=user) tasks = TaskFactory.create_batch(5, project=project) taskruns = [] taskruns_external_2 = [] for task in tasks: taskruns.extend( ExternalUidTaskRunFactory.create_batch(2, task=task)) for task in tasks: taskruns_external_2.extend( ExternalUidTaskRunFactory.create_batch( 5, task=task, external_uid='*****@*****.**')) res = self.app.get('/api/project/1/userprogress?external_uid=1xa', follow_redirects=True) data = json.loads(res.data) error_msg = "The reported total number of tasks is wrong" assert len(tasks) == data['total'], error_msg res = self.app.get( '/api/project/1/[email protected]', follow_redirects=True) data_external_uid_2 = json.loads(res.data) error_msg = "The reported total number of tasks is wrong" assert data['total'] == len(tasks), error_msg error_msg = "The reported number of task runs is wrong" assert len(taskruns) == data['done'], data assert len(taskruns_external_2) == data_external_uid_2['done'], data # Add a new TaskRun and check again taskrun = ExternalUidTaskRunFactory.create(task=tasks[0], info={'answer': 'hello'}) res = self.app.get('/api/project/1/userprogress?external_uid=1xa', follow_redirects=True) data = json.loads(res.data) error_msg = "The reported total number of tasks is wrong" assert len(tasks) == data['total'], error_msg error_msg = "Number of done tasks is wrong: %s" % len(taskruns) assert len(taskruns) + 1 == data['done'], error_msg
def test_get_leaderboard_returns_users_ordered_by_rank(self): leader = UserFactory.create() second = UserFactory.create() third = UserFactory.create() project = ProjectFactory.create() tasks = TaskFactory.create_batch(3, project=project) i = 3 for user in [leader, second, third]: TaskRunFactory.create_batch(i, user=user, task=tasks[i - 1]) i -= 1 leaderboard = cached_users.get_leaderboard(3) assert leaderboard[0]['id'] == leader.id assert leaderboard[1]['id'] == second.id assert leaderboard[2]['id'] == third.id
def test_external_uid_02_gets_different_tasks(self): """ Test SCHED newtask does not return tasks for a external User ID.""" assigned_tasks = [] # Get a Task until scheduler returns None project = ProjectFactory.create(info=dict(sched='depth_first_all')) tasks = TaskFactory.create_batch(3, project=project, info={}) headers = self.get_headers_jwt(project) url = 'api/project/%s/newtask?external_uid=%s' % (project.id, '1xa') res = self.app.get(url, headers=headers) data = json.loads(res.data) assert 'error' in data['info']
def test_get_task_owner_pwd(self): """Owners do not need password""" project = ProjectFactory.create() tasks = [] project.set_password('hello') project_repo.save(project) num_task = 2 tmp = TaskFactory.create_batch(num_task, project=project) for t in tmp: tasks.append(t) url = '/api/task?project_id=%s&limit=100&all=1&api_key=%s' % ( project.id, project.owner.api_key) res = self.app.get(url) data = json.loads(res.data) assert len(data) == num_task, len(data)
def test_user_progress_authenticated_user(self): """Test API userprogress as an authenticated user works""" user = UserFactory.create() project = ProjectFactory.create(owner=user) tasks = TaskFactory.create_batch(2, project=project) taskruns = [] for task in tasks: taskruns.extend( TaskRunFactory.create_batch(2, task=task, user=user)) url = '/api/project/1/userprogress?api_key=%s' % user.api_key res = self.app.get(url, follow_redirects=True) data = json.loads(res.data) error_msg = "The reported total number of tasks is wrong" assert len(tasks) == data['total'], error_msg url = '/api/project/%s/userprogress?api_key=%s' % (project.short_name, user.api_key) res = self.app.get(url, follow_redirects=True) data = json.loads(res.data) error_msg = "The reported total number of tasks is wrong" assert len(tasks) == data['total'], error_msg url = '/api/project/5000/userprogress?api_key=%s' % user.api_key res = self.app.get(url, follow_redirects=True) assert res.status_code == 404, res.status_code url = '/api/project/userprogress?api_key=%s' % user.api_key res = self.app.get(url, follow_redirects=True) assert res.status_code == 404, res.status_code error_msg = "The reported number of done tasks is wrong" assert len(taskruns) == data['done'], error_msg # Add a new TaskRun and check again taskrun = TaskRunFactory.create(task=tasks[0], info={'answer': u'hello'}, user=user) url = '/api/project/1/userprogress?api_key=%s' % user.api_key res = self.app.get(url, follow_redirects=True) data = json.loads(res.data) error_msg = "The reported total number of tasks is wrong" assert len(tasks) == data['total'], error_msg error_msg = "Number of done tasks is wrong: %s" % len(taskruns) assert len(taskruns) + 1 == data['done'], error_msg
def test_get_task_user_pwd(self): """Get a list of tasks.""" project = ProjectFactory.create() tasks = [] project.set_password('hello') project_repo.save(project) num_task = 2 tmp = TaskFactory.create_batch(num_task, project=project) for t in tmp: tasks.append(t) user = UserFactory.create() # no password - get a specific task url = '/api/task/%d?api_key=%s' % (tmp[0].id, user.api_key) res = self.app.get(url) assert res.status_code == 403, res.data data = json.loads(res.data) # no password - no task is returned url = '/api/task?project_id=%s&limit=100&all=1&api_key=%s' % ( project.id, user.api_key) res = self.app.get(url) data = json.loads(res.data) assert len(data) == 0, len(data) url = '/project/%s/password?api_key=%s' % (project.short_name, user.api_key) data = dict(password='******') res = self.app.post(url, data=data) c, v, r = get_pwd_cookie(project.short_name, res) self.app.set_cookie('/', c, v) # get a specific task url = '/api/task/%d?api_key=%s' % (tmp[0].id, user.api_key) res = self.app.get(url) assert res.status_code == 200, res.data data = json.loads(res.data) assert data['info'] == tmp[0].info, data # get a list of tasks url = '/api/task?project_id=%s&limit=100&all=1&api_key=%s' % ( project.id, user.api_key) res = self.app.get(url) data = json.loads(res.data) assert len(data) == num_task, len(data)
def test_rank_and_score(self): """Test CACHE USERS rank_and_score returns the correct rank and score""" i = 0 project = ProjectFactory.create() tasks = TaskFactory.create_batch(4, project=project) users = UserFactory.create_batch(4) for user in users: i += 1 taskruns = TaskRunFactory.create_batch(i, user=user, task=tasks[i - 1]) first_in_rank = cached_users.rank_and_score(users[3].id) last_in_rank = cached_users.rank_and_score(users[0].id) print first_in_rank assert first_in_rank['rank'] == 1, first_in_rank['rank'] assert first_in_rank['score'] == 4, first_in_rank['score'] assert last_in_rank['rank'] == 4, last_in_rank['rank'] assert last_in_rank['score'] == 1, last_in_rank['score']
def test_get_leaderboard_includes_specific_user_even_is_not_in_top(self): leader = UserFactory.create() second = UserFactory.create() third = UserFactory.create() project = ProjectFactory.create() tasks = TaskFactory.create_batch(3, project=project) i = 3 for user in [leader, second, third]: TaskRunFactory.create_batch(i, user=user, task=tasks[i - 1]) i -= 1 user_out_of_top = UserFactory.create() leaderboard = cached_users.get_leaderboard(3, user_id=user_out_of_top.id) assert len(leaderboard) is 4 assert leaderboard[-1]['id'] == user_out_of_top.id
def test_external_uid_03_respects_limit_tasks_limits(self): """ Test SCHED newtask external uid limits respects the limit of 30 TaskRuns per list of Tasks for external user id""" # Get Task until scheduler returns None project = ProjectFactory.create(info=dict(sched='depth_first_all')) orig_tasks = TaskFactory.create_batch(2, project=project, n_answers=5) headers = self.get_headers_jwt(project) uid = '1xa' url = 'api/project/%s/newtask?external_uid=%s&limit=2' % (project.id, uid) tasks = get_depth_first_all_task(project.id, external_uid=uid, limit=2) assert len(tasks) == 2, len(tasks) assert tasks[0].id == orig_tasks[0].id, tasks assert tasks[0].state == 'ongoing', tasks assert tasks[1].id == orig_tasks[1].id, tasks assert tasks[1].state == 'ongoing', tasks
def test_task_6(self): ''' Task is assigned to a user whose profile doesn't match task preference ''' owner = UserFactory.create(id=500) owner.user_pref = {'languages': ['de', 'en']} owner.email_addr = '*****@*****.**' user_repo.save(owner) project = ProjectFactory.create(owner=owner) project.info['sched'] = Schedulers.user_pref task = TaskFactory.create_batch(1, project=project, n_answers=10)[0] task.user_pref = { 'languages': ['ch', 'zh'], 'assign_user': ['*****@*****.**'] } task_repo.save(task) assert n_available_tasks_for_user(project, 500) == 0
def test_delete_app_cascade(self): """Test API delete project deletes associated tasks and taskruns""" app = AppFactory.create() tasks = TaskFactory.create_batch(2, app=app) task_runs = TaskRunFactory.create_batch(2, app=app) url = '/api/app/%s?api_key=%s' % (1, app.owner.api_key) self.app.delete(url) tasks = db.session.query(Task)\ .filter_by(app_id=1)\ .all() assert len(tasks) == 0, "There should not be any task" task_runs = db.session.query(TaskRun)\ .filter_by(app_id=1)\ .all() assert len(task_runs) == 0, "There should not be any task run"
def test_status_update_on_fail(self): '''Test user quiz status transitions to failed once quiz is complete and wrong answer count exceeds limit''' project, user = self.create_project_and_user() task_answers = {} for i in range(10): gold_answers = {'answer': i} golden_task = TaskFactory.create(project=project, n_answers=1, calibration=1, gold_answers=gold_answers) task_answers[golden_task.id] = gold_answers non_golden_tasks = TaskFactory.create_batch(10, project=project, n_answers=1, calibration=0) quiz = user.get_quiz_for_project(project) user.set_quiz_for_project( project.id, { 'status': 'in_progress', 'result': { 'right': quiz['config']['passing'] - 1, 'wrong': quiz['config']['questions'] - quiz['config']['passing'] }, 'config': quiz['config'] }) new_task_url = '/api/project/{}/newtask'.format(project.id) new_task_response = self.app.get(new_task_url) task = json.loads(new_task_response.data) task_run_url = '/api/taskrun' task_run_data = { 'project_id': project.id, 'task_id': task['id'], 'info': { 'answer': 'wrong' } } task_run_response = self.app.post(task_run_url, data=json.dumps(task_run_data)) updated_quiz = user.get_quiz_for_project(project) assert updated_quiz['status'] == 'failed' assert user.get_quiz_failed(project)
def test_anonymous_03_respects_limit_tasks_limits(self): """ Test SCHED newtask limit respects the limit of 30 TaskRuns per Task using limits""" assigned_tasks = [] user = UserFactory.create() project = ProjectFactory.create(info=dict(sched='depth_first_all')) orig_tasks = TaskFactory.create_batch(2, project=project, n_answers=5) tasks = get_depth_first_all_task(project.id, user.id, limit=2) assert len(tasks) == 2, len(tasks) assert tasks[0].id == orig_tasks[0].id assert tasks[1].id == orig_tasks[1].id for i in range(5): tr = TaskRun(project_id=project.id, task_id=tasks[0].id, user_ip='127.0.0.%s' % i) db.session.add(tr) db.session.commit() # Task should be marked as completed, but as user has no # participated it should get the completed one as well. tasks = get_depth_first_all_task(project.id, user.id, limit=2, orderby='id', desc=False) assert len(tasks) == 2, len(tasks) assert tasks[0].id == orig_tasks[0].id, tasks[0] assert tasks[0].state == 'completed', tasks[0].state assert len(tasks[0].task_runs) == 5 assert tasks[1].id == orig_tasks[1].id assert tasks[1].state == 'ongoing', tasks[1].state assert len(tasks[1].task_runs) == 0 # User contributes, so only one task should be returned tr = TaskRun(project_id=project.id, task_id=tasks[0].id, user_id=user.id) db.session.add(tr) db.session.commit() tasks = get_depth_first_all_task(project.id, user.id, limit=2, orderby='id', desc=False) assert len(tasks) == 1, len(tasks) assert tasks[0].id == orig_tasks[1].id, tasks[0] assert tasks[0].state == 'ongoing', tasks[0].state assert len(tasks[0].task_runs) == 0
def test_update_tasks_redundancy_updates_state_when_incrementing(self): """Test update_tasks_redundancy changes 'completed' tasks to 'ongoing' if n_answers is incremented enough""" project = ProjectFactory.create() tasks = TaskFactory.create_batch(2, project=project, n_answers=2) TaskRunFactory.create_batch(2, task=tasks[0]) tasks[0].state = 'completed' self.task_repo.update(tasks[0]) assert tasks[0].state == 'completed', tasks[0].state assert tasks[1].state == 'ongoing', tasks[1].state self.task_repo.update_tasks_redundancy(project, 3) tasks = self.task_repo.filter_tasks_by(project_id=project.id) for task in tasks: assert task.state == 'ongoing', task.state