Exemplo n.º 1
0
    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
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
    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()
Exemplo n.º 4
0
    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
Exemplo n.º 6
0
    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
Exemplo n.º 7
0
    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
Exemplo n.º 8
0
    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
Exemplo n.º 9
0
    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
Exemplo n.º 10
0
    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
Exemplo n.º 11
0
    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
Exemplo n.º 12
0
    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
Exemplo n.º 13
0
    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
Exemplo n.º 14
0
    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
Exemplo n.º 15
0
    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:]
Exemplo n.º 16
0
    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
Exemplo n.º 17
0
    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
Exemplo n.º 18
0
    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
Exemplo n.º 19
0
    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
Exemplo n.º 20
0
    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
Exemplo n.º 21
0
    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
Exemplo n.º 22
0
    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
Exemplo n.º 23
0
    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
Exemplo n.º 24
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
Exemplo n.º 25
0
    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
Exemplo n.º 26
0
    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)
Exemplo n.º 27
0
    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
Exemplo n.º 28
0
    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
Exemplo n.º 29
0
    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)
Exemplo n.º 30
0
    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)
Exemplo n.º 31
0
    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
Exemplo n.º 32
0
    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
Exemplo n.º 33
0
    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
Exemplo n.º 34
0
    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'
Exemplo n.º 35
0
    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
Exemplo n.º 36
0
    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
Exemplo n.º 37
0
    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
Exemplo n.º 39
0
    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
Exemplo n.º 40
0
    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'
Exemplo n.º 41
0
    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']
Exemplo n.º 42
0
    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)
Exemplo n.º 43
0
    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()
Exemplo n.º 44
0
    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()
Exemplo n.º 45
0
 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
Exemplo n.º 46
0
 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
Exemplo n.º 47
0
    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
Exemplo n.º 48
0
    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
Exemplo n.º 49
0
    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']
Exemplo n.º 50
0
    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)
Exemplo n.º 51
0
    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
Exemplo n.º 52
0
    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)
Exemplo n.º 53
0
    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']
Exemplo n.º 54
0
    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
Exemplo n.º 55
0
    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
Exemplo n.º 56
0
 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
Exemplo n.º 57
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"
Exemplo n.º 58
0
    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
Exemplo n.º 60
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