def test_browse_tasks_returns_pct_status(self):
        """Test CACHE PROJECTS browse_tasks returns also the completion
        percentage of each task"""

        project = ProjectFactory.create()
        task = TaskFactory.create( project=project, info={}, n_answers=4)

        cached_task = cached_projects.browse_tasks(project.id)[0]
        # 0 if no task runs
        assert cached_task.get('pct_status') == 0, cached_task.get('pct_status')

        TaskRunFactory.create(task=task)
        cached_task = cached_projects.browse_tasks(project.id)[0]
        # Gets updated with new task runs
        assert cached_task.get('pct_status') == 0.25, cached_task.get('pct_status')

        TaskRunFactory.create_batch(3, task=task)
        cached_task = cached_projects.browse_tasks(project.id)[0]
        # To a maximum of 1
        assert cached_task.get('pct_status') == 1.0, cached_task.get('pct_status')

        TaskRunFactory.create(task=task)
        cached_task = cached_projects.browse_tasks(project.id)[0]
        # And it does not go over 1 (that is 100%!!)
        assert cached_task.get('pct_status') == 1.0, cached_task.get('pct_status')
Example #2
0
 def test_05_app_stats_index(self):
     '''Test PRIVACY project stats privacy is respected'''
     # As Anonymou user
     admin, user, owner = UserFactory.create_batch(3)
     task = TaskFactory.create(n_answers=3)
     TaskRunFactory.create_batch(3, task=task)
     url = '/project/%s/stats' % task.project.short_name
     update_stats(task.project.id)
     res = self.app.get(url, follow_redirects=True)
     assert 'This feature requires being logged in' in res.data, res.data
     # As Authenticated user but NOT ADMIN
     self.set_proj_passwd_cookie(task.project, user)
     res = self.app.get(url + '?api_key=%s' % user.api_key,
                        follow_redirects=True)
     dom = BeautifulSoup(res.data)
     err_msg = 'Project Stats page should not be shown to authenticated users'
     assert dom.find(id='enforce_privacy') is not None, err_msg
     self.signout
     # As Authenticated user but ADMIN
     res = self.app.get(url + '?api_key=%s' % admin.api_key,
                        follow_redirects=True)
     dom = BeautifulSoup(res.data)
     err_msg = 'Project Stats page should be shown to admin users'
     assert dom.find(id='enforce_privacy') is None, err_msg
     self.signout()
Example #3
0
 def test_05_app_stats_index(self):
     '''Test PRIVACY project stats privacy is respected'''
     # As Anonymou user
     admin, user, owner = UserFactory.create_batch(3)
     task = TaskFactory.create(n_answers=3)
     TaskRunFactory.create_batch(3, task=task)
     url = '/project/%s/stats' % task.project.short_name
     update_stats(task.project.id)
     res = self.app.get(url, follow_redirects=True)
     dom = BeautifulSoup(res.data)
     err_msg = 'Project Stats page should not be shown to anonymous users'
     assert dom.find(id='enforce_privacy') is not None, res.data
     # As Authenticated user but NOT ADMIN
     res = self.app.get(url + '?api_key=%s' % user.api_key,
                        follow_redirects=True)
     dom = BeautifulSoup(res.data)
     err_msg = 'Project Stats page should not be shown to authenticated users'
     assert dom.find(id='enforce_privacy') is not None, err_msg
     self.signout
     # As Authenticated user but ADMIN
     res = self.app.get(url + '?api_key=%s' % admin.api_key,
                        follow_redirects=True)
     dom = BeautifulSoup(res.data)
     err_msg = 'Project Stats page should be shown to admin users'
     assert dom.find(id='enforce_privacy') is None, err_msg
     self.signout()
Example #4
0
    def test_query_taskrun(self):
        """Test API query for taskrun with params works"""
        app = AppFactory.create()
        TaskRunFactory.create_batch(10, app=app)
        # Test for real field
        res = self.app.get("/api/taskrun?app_id=1")
        data = json.loads(res.data)
        # Should return one result
        assert len(data) == 10, data
        # Correct result
        assert data[0]['app_id'] == 1, data

        # Valid field but wrong value
        res = self.app.get("/api/taskrun?app_id=99999999")
        data = json.loads(res.data)
        assert len(data) == 0, data

        # Multiple fields
        res = self.app.get('/api/taskrun?app_id=1&task_id=1')
        data = json.loads(res.data)
        # One result
        assert len(data) == 1, data
        # Correct result
        assert data[0]['app_id'] == 1, data
        assert data[0]['task_id'] == 1, data

        # Limits
        res = self.app.get("/api/taskrun?app_id=1&limit=5")
        data = json.loads(res.data)
        for item in data:
            assert item['app_id'] == 1, item
        assert len(data) == 5, data
Example #5
0
    def test_no_more_tasks_limit(self):
        """Test that a users gets always tasks with limit"""
        owner = UserFactory.create()
        project = ProjectFactory.create(owner=owner, short_name='egil', name='egil',
                  description='egil')

        project_id = project.id

        tasks = TaskFactory.create_batch(20, project=project, n_answers=10)

        for t in 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&api_key=%s' % (project_id, owner.api_key)
        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'] == tasks[i].id, (err_msg, t, tasks[i].id)
            i += 1
Example #6
0
    def test_browse_tasks_returns_pct_status(self):
        """Test CACHE PROJECTS browse_tasks returns also the completion
        percentage of each task"""

        project = AppFactory.create()
        task = TaskFactory.create( app=project, info={}, n_answers=4)

        cached_task = cached_apps.browse_tasks(project.id)[0]
        # 0 if no task runs
        assert cached_task.get('pct_status') == 0, cached_task.get('pct_status')

        TaskRunFactory.create(task=task)
        cached_task = cached_apps.browse_tasks(project.id)[0]
        # Gets updated with new task runs
        assert cached_task.get('pct_status') == 0.25, cached_task.get('pct_status')

        TaskRunFactory.create_batch(3, task=task)
        cached_task = cached_apps.browse_tasks(project.id)[0]
        # To a maximum of 1
        assert cached_task.get('pct_status') == 1.0, cached_task.get('pct_status')

        TaskRunFactory.create(task=task)
        cached_task = cached_apps.browse_tasks(project.id)[0]
        # And it does not go over 1 (that is 100%!!)
        assert cached_task.get('pct_status') == 1.0, cached_task.get('pct_status')
Example #7
0
    def test_update_tasks_redundancy_updates_state_when_updating_redundancy_to_task_group(
            self):
        """Test update_tasks_redundancy changes only the corresponding tasks to 'complete'
        if a user_pref is applied """

        project = ProjectFactory.create()
        tasks = TaskFactory.create_batch(1, project=project, n_answers=2)
        TaskRunFactory.create_batch(1, task=tasks[0])
        tasks2 = TaskFactory.create_batch(
            2,
            project=project,
            n_answers=2,
            user_pref={"languages": ["japanese"]})
        TaskRunFactory.create_batch(1, task=tasks2[1])

        assert tasks[0].state == 'ongoing', tasks[0].state
        assert tasks2[0].state == 'ongoing', tasks2[0].state
        filters = json.loads(
            '{"filter_by_upref": {"languages": ["japanese"]}}')
        self.task_repo.update_tasks_redundancy(project, 1, filters)
        tasks = self.task_repo.filter_tasks_by(project_id=project.id)
        assert tasks[0].n_answers == 1, tasks[0].n_answers
        assert tasks[0].state == 'completed', tasks[0].state

        assert tasks[1].n_answers == 1, tasks[1].n_answers
        assert tasks[1].state == 'ongoing', tasks[1].state

        assert tasks[2].n_answers == 1, tasks[2].n_answers
        assert tasks[2].state == 'completed', tasks[2].state
    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_no_more_tasks(self):
        """Test that a users gets always tasks"""
        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' % project.id
        res = self.app.get(url)
        data = json.loads(res.data)

        err_msg = "User should get a task"
        assert 'project_id' in data.keys(), err_msg
        assert data['project_id'] == project_id, err_msg
        assert data['id'] == all_tasks[0].id, err_msg
        assert data['state'] == 'completed', err_msg
Example #10
0
    def test_query_taskrun(self):
        """Test API query for taskrun with params works"""
        project = ProjectFactory.create()
        TaskRunFactory.create_batch(10, project=project)
        # Test for real field
        res = self.app.get("/api/taskrun?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/taskrun?project_id=99999999")
        data = json.loads(res.data)
        assert len(data) == 0, data

        # Multiple fields
        res = self.app.get('/api/taskrun?project_id=1&task_id=1')
        data = json.loads(res.data)
        # One result
        assert len(data) == 1, data
        # Correct result
        assert data[0]['project_id'] == 1, data
        assert data[0]['task_id'] == 1, data

        # Limits
        res = self.app.get("/api/taskrun?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
Example #11
0
 def test_with_matching_transcriptions(self, mock_client):
     """Test IIIF results with matching transcriptions."""
     n_answers = 3
     target = 'example.com'
     anno_collection = 'http://eg.com/collection'
     task = self.ctx.create_task(n_answers,
                                 target,
                                 rules={},
                                 anno_collection=anno_collection)
     value = 'foo'
     tag = 'bar'
     TaskRunFactory.create_batch(n_answers,
                                 task=task,
                                 info=[{
                                     'motivation':
                                     'describing',
                                     'body': [{
                                         'purpose': 'describing',
                                         'value': value
                                     }, {
                                         'purpose': 'tagging',
                                         'value': tag
                                     }]
                                 }])
     result = self.result_repo.filter_by(project_id=task.project_id)[0]
     fake_search = MagicMock()
     fake_search.return_value = []
     mock_client.search_annotations = fake_search
     self.iiif_analyst.analyse(result.id)
     func = mock_client.create_annotation
     func.assert_called_once_with(
         anno_collection, {
             'motivation':
             'describing',
             'type':
             'Annotation',
             'generator':
             [{
                 "id": flask_app.config.get('GITHUB_REPO'),
                 "type": "Software",
                 "name": "LibCrowds",
                 "homepage": flask_app.config.get('SPA_SERVER_NAME')
             }, {
                 "id": url_for('api.api_task', oid=task.id),
                 "type": "Software"
             }],
             'body': [{
                 'type': 'TextualBody',
                 'purpose': 'describing',
                 'value': value,
                 'format': 'text/plain'
             }, {
                 'type': 'TextualBody',
                 'purpose': 'tagging',
                 'value': tag
             }],
             'target':
             target
         })
Example #12
0
 def test_07_user_public_profile_json(self):
     '''Test PRIVACY user public profile privacy is respected for API access'''
     # As Anonymous user
     admin, user, owner = UserFactory.create_batch(3)
     project = ProjectFactory.create(owner=owner)
     TaskRunFactory.create_batch(30, project=project)
     TaskRunFactory.create(user=owner)
     update_stats(project.id)
     url = '/account/%s' % owner.name
     # Use a full url to avoid redirection on API access.
     full_url = 'http://localhost%s/' % url
     res = self.app.get(full_url, content_type='application/json')
     data = json.loads(res.data)
     print(list(data.keys()))
     # this data should be public visible in user
     err_msg = 'name should be public'
     assert data['user']['name'] == owner.name, err_msg
     err_msg = 'fullname should be public'
     assert data['user']['fullname'] == owner.fullname, err_msg
     err_msg = 'rank should be public'
     assert 'rank' in data['user'], err_msg
     err_msg = 'score should be public'
     assert 'score' in data['user'], err_msg
     # this data should not be public in user
     err_msg = 'id should not be public'
     assert 'id' not in data['user'], err_msg
     err_msg = 'api_key should not be public'
     assert 'api_key' not in data['user'], err_msg
     err_msg = 'confirmation_email_sent should not be public'
     assert 'confirmation_email_sent' not in data['user'], err_msg
     err_msg = 'email_addr should not be public'
     assert 'email_addr' not in data['user'], err_msg
     err_msg = 'valid_email should not be public'
     assert 'valid_email' not in data['user'], err_msg
     # public projects data
     project = data['projects'][0]
     err_msg = 'info should be public'
     assert 'info' in project, err_msg
     err_msg = 'description should be public'
     assert 'description' in project, err_msg
     err_msg = 'short_name should be public'
     assert 'short_name' in project, err_msg
     err_msg = 'n_tasks should be public'
     assert 'n_tasks' in project, err_msg
     err_msg = 'n_volunteers should be public'
     assert 'n_volunteers' in project, err_msg
     err_msg = 'overall_progress should be public'
     assert 'overall_progress' in project, err_msg
     err_msg = 'name should be public'
     assert 'name' in project, err_msg
     # non public projects data
     # err_msg = 'id should not be public'
     # assert 'id' not in project, err_msg
     err_msg = 'secret_key should not be public'
     assert 'secret_key' not in project, err_msg
     err_msg = 'results should not be public'
     assert 'results' not in project['info'], err_msg
     err_msg = 'onesignal should not be public'
     assert 'onesignal' not in project['info'], err_msg
Example #13
0
 def test_comment_annotation_created(self, mock_client):
     """Test IIIF comment annotations are created."""
     n_answers = 1
     target = 'example.com'
     anno_collection = 'http://eg.com/collection'
     task = self.ctx.create_task(n_answers,
                                 target,
                                 anno_collection=anno_collection)
     user = UserFactory()
     value = 'foo'
     TaskRunFactory.create_batch(n_answers,
                                 user=user,
                                 task=task,
                                 info=[{
                                     'motivation': 'commenting',
                                     'body': {
                                         'value': value
                                     }
                                 }])
     result = self.result_repo.filter_by(project_id=task.project_id)[0]
     fake_search = MagicMock()
     fake_search.return_value = []
     mock_client.search_annotations = fake_search
     self.iiif_analyst.analyse(result.id)
     func = mock_client.create_annotation
     func.assert_called_once_with(
         anno_collection, {
             'motivation':
             'commenting',
             'type':
             'Annotation',
             'creator': {
                 'id': url_for('api.api_user', oid=user.id),
                 'type': 'Person',
                 'name': user.fullname,
                 'nickname': user.name
             },
             'generator':
             [{
                 "id": flask_app.config.get('GITHUB_REPO'),
                 "type": "Software",
                 "name": "LibCrowds",
                 "homepage": flask_app.config.get('SPA_SERVER_NAME')
             }, {
                 "id": url_for('api.api_task', oid=task.id),
                 "type": "Software"
             }],
             'body': {
                 'type': 'TextualBody',
                 'purpose': 'commenting',
                 'value': value,
                 'format': 'text/plain'
             },
             'target':
             target
         })
Example #14
0
 def test_n_answers_reduced_when_task_complete(self):
     """Test n answers reduced to number of task runs when task complete."""
     n_answers = 3
     task = TaskFactory.create(n_answers=n_answers)
     TaskRunFactory.create_batch(n_answers - 1, task=task)
     self.base_analyst.update_n_answers_required(task,
                                                 True,
                                                 max_answers=n_answers)
     assert_equal(task.n_answers, n_answers - 1)
     assert_equal(task.state, 'completed')
Example #15
0
    def test_browse_completed(self):
        project = ProjectFactory.create()
        task = TaskFactory.create(project=project, info={}, n_answers=2)
        TaskRunFactory.create_batch(3, task=task)

        count, cached_tasks = cached_projects.browse_tasks(
            project.id, {'pcomplete_to': 100})

        assert count == 1
        assert cached_tasks[0]['id'] == task.id
Example #16
0
 def test_n_answers_not_increased_when_max_answers_reached(self):
     """Test n answers not updated when max answers reached."""
     n_answers = 3
     task = TaskFactory.create(n_answers=n_answers)
     TaskRunFactory.create_batch(n_answers, task=task)
     self.base_analyst.update_n_answers_required(task,
                                                 False,
                                                 max_answers=n_answers)
     assert_equal(task.n_answers, n_answers)
     assert_equal(task.state, 'completed')
Example #17
0
    def test_count_task_runs_with_one_condition(self):
        """Test count_task_runs_with returns the number of taskruns that meet the
        filtering condition"""

        TaskRunFactory.create_batch(3, info='info')
        should_be_missing = TaskRunFactory.create(info='other info')

        count = self.task_repo.count_task_runs_with(info='info')

        assert count == 3, count
Example #18
0
    def test_count_task_runs_with_one_condition(self):
        """Test count_task_runs_with returns the number of taskruns that meet the
        filtering condition"""

        TaskRunFactory.create_batch(3, info='info')
        should_be_missing = TaskRunFactory.create(info='other info')

        count = self.task_repo.count_task_runs_with(info='info')

        assert count == 3, count
Example #19
0
    def test_taskrun_query_without_params(self):
        """Test API TaskRun query"""
        TaskRunFactory.create_batch(10, info={'answer': 'annakarenina'})
        res = self.app.get('/api/taskrun')
        taskruns = json.loads(res.data)
        assert len(taskruns) == 10, taskruns
        taskrun = taskruns[0]
        assert taskrun['info']['answer'] == 'annakarenina', taskrun

        # The output should have a mime-type: application/json
        assert res.mimetype == 'application/json', res
Example #20
0
    def test_filter_task_runs_by_one_condition(self):
        """Test filter_task_runs_by returns a list of taskruns that meet the
        filtering condition"""

        TaskRunFactory.create_batch(3, info='info')
        should_be_missing = TaskFactory.create(info='other info')

        retrieved_taskruns = self.task_repo.filter_task_runs_by(info='info')

        assert len(retrieved_taskruns) == 3, retrieved_taskruns
        assert should_be_missing not in retrieved_taskruns, retrieved_taskruns
Example #21
0
    def test_filter_task_runs_by_one_condition(self):
        """Test filter_task_runs_by returns a list of taskruns that meet the
        filtering condition"""

        TaskRunFactory.create_batch(3, info='info')
        should_be_missing = TaskFactory.create(info='other info')

        retrieved_taskruns = self.task_repo.filter_task_runs_by(info='info')

        assert len(retrieved_taskruns) == 3, retrieved_taskruns
        assert should_be_missing not in retrieved_taskruns, retrieved_taskruns
Example #22
0
    def test_taskrun_query_without_params(self):
        """Test API TaskRun query"""
        TaskRunFactory.create_batch(10, info={'answer': 'annakarenina'})
        res = self.app.get('/api/taskrun')
        taskruns = json.loads(res.data)
        assert len(taskruns) == 10, taskruns
        taskrun = taskruns[0]
        assert taskrun['info']['answer'] == 'annakarenina', taskrun

        # The output should have a mime-type: application/json
        assert res.mimetype == 'application/json', res
Example #23
0
    def test_get_top5_projects_24_hours_does_not_include_hidden_projects(self):
        good_project = ProjectFactory.create()
        best_but_hidden_project = ProjectFactory.create(hidden=1)

        TaskRunFactory.create(project=good_project)
        TaskRunFactory.create_batch(2, project=best_but_hidden_project)

        top5 = stats.get_top5_projects_24_hours()
        top5_ids = [top['id'] for top in top5]

        assert good_project.id in top5_ids
        assert best_but_hidden_project.id not in top5_ids
    def test_check_contributing_state_completed(self):
        """Test check_contributing_state returns 'completed' for a project with all
        tasks completed and user that has contributed to it"""
        project = ProjectFactory.create()
        task = TaskFactory.create(project=project, n_answers=1)
        user = UserFactory.create()
        TaskRunFactory.create_batch(1, task=task, user=user)

        contributing_state = helpers.check_contributing_state(project=project,
                                                              user_id=user.id)

        assert task.state == 'completed', task.state
        assert contributing_state == 'completed', contributing_state
Example #25
0
    def test_filter_tasks_limit_offset(self):
        """Test that filter_tasks_by supports limit and offset options"""

        TaskRunFactory.create_batch(4)
        all_task_runs = self.task_repo.filter_task_runs_by()

        first_two = self.task_repo.filter_task_runs_by(limit=2)
        last_two = self.task_repo.filter_task_runs_by(limit=2, offset=2)

        assert len(first_two) == 2, first_two
        assert len(last_two) == 2, last_two
        assert first_two == all_task_runs[:2]
        assert last_two == all_task_runs[2:]
Example #26
0
    def test_check_contributing_state_completed(self):
        """Test check_contributing_state returns 'completed' for a project with all
        tasks completed and user that has contributed to it"""
        project = ProjectFactory.create()
        task = TaskFactory.create(project=project, n_answers=1)
        user = UserFactory.create()
        TaskRunFactory.create_batch(1, task=task, user=user)

        contributing_state = helpers.check_contributing_state(project=project,
                                                              user_id=user.id)

        assert task.state == 'completed', task.state
        assert contributing_state == 'completed', contributing_state
Example #27
0
    def test_check_contributing_state_completed_user_not_contributed(self):
        """Test check_contributing_state returns 'completed' for a project with all
        tasks completed even if the user has not contributed to it"""
        project = ProjectFactory.create()
        task = TaskFactory.create(project=project, n_answers=2)
        TaskRunFactory.create_batch(2, task=task)
        user = UserFactory.create()
        update_stats(project.id)
        contributing_state = helpers.check_contributing_state(project=project,
                                                              user_id=user.id)

        assert task.state == 'completed', task.state
        assert contributing_state == 'completed', contributing_state
Example #28
0
    def test_filter_tasks_runs_limit_offset(self):
        """Test that filter_tasks_by supports limit and offset options"""

        TaskRunFactory.create_batch(4)
        all_task_runs = self.task_repo.filter_task_runs_by()

        first_two = self.task_repo.filter_task_runs_by(limit=2)
        last_two = self.task_repo.filter_task_runs_by(limit=2, offset=2)

        assert len(first_two) == 2, first_two
        assert len(last_two) == 2, last_two
        assert first_two == all_task_runs[:2]
        assert last_two == all_task_runs[2:]
    def test_check_contributing_state_completed_user_not_contributed(self):
        """Test check_contributing_state returns 'completed' for a project with all
        tasks completed even if the user has not contributed to it"""
        project = ProjectFactory.create()
        task = TaskFactory.create(project=project, n_answers=2)
        TaskRunFactory.create_batch(2, task=task)
        user = UserFactory.create()

        contributing_state = helpers.check_contributing_state(project=project,
                                                              user_id=user.id)

        assert task.state == 'completed', task.state
        assert contributing_state == 'completed', contributing_state
Example #30
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
Example #31
0
    def test_taskrun_query_list_project_ids(self):
        """Get a list of tasks runs using a list of project_ids."""
        admin = UserFactory.create()
        projects = ProjectFactory.create_batch(3)
        task_runs = []
        for project in projects:
            tmp = TaskRunFactory.create_batch(2, project=project)
            for t in tmp:
                task_runs.append(t)

        project_ids = [project.id for project in projects]
        url = '/api/taskrun?project_id=%s&limit=100&all=1&api_key=%s' % (
            project_ids, admin.api_key)
        res = self.app.get(url)
        data = json.loads(res.data)
        assert len(data) == 3 * 2, len(data)
        for task in data:
            assert task['project_id'] in project_ids
        task_run_project_ids = list(set([task['project_id'] for task in data]))
        assert sorted(project_ids) == sorted(task_run_project_ids)

        # more filters
        res = self.app.get(url + '&orderby=created&desc=true')
        data = json.loads(res.data)
        assert data[0]['id'] == task_runs[-1].id
Example #32
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 = 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()

        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 = TaskRunFactory.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
Example #33
0
    def test_get_top5_users_24_hours_returns_best_5_users_only(self):
        users = UserFactory.create_batch(5)
        i = 5
        for user in users:
            TaskRunFactory.create_batch(i, user=user)
            i -= 1

        worst_user = UserFactory.create()

        top5 = stats.get_top5_users_24_hours()
        top5_ids = [top['id'] for top in top5]

        assert len(top5) == 5
        assert worst_user.id not in top5_ids
        for i in range(len(top5)):
            assert users[i].id == top5_ids[i]
Example #34
0
    def test_get_top5_projects_24_hours_returns_best_5_only(self):
        projects = ProjectFactory.create_batch(5)
        i = 5
        for project in projects:
            TaskRunFactory.create_batch(i, project=project)
            i -= 1

        worst_project = ProjectFactory.create()

        top5 = stats.get_top5_projects_24_hours()
        top5_ids = [top['id'] for top in top5]

        assert len(top5) == 5
        assert worst_project.id not in top5_ids
        for i in range(len(top5)):
            assert projects[i].id == top5_ids[i]
Example #35
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
Example #36
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 = 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()

        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 = TaskRunFactory.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
Example #37
0
    def test_get_top5_users_24_hours_returns_best_5_users_only(self):
        users = UserFactory.create_batch(5)
        i = 5
        for user in users:
            TaskRunFactory.create_batch(i, user=user)
            i -= 1

        worst_user = UserFactory.create()

        top5 = stats.get_top5_users_24_hours()
        top5_ids = [top['id'] for top in top5]

        assert len(top5) == 5
        assert worst_user.id not in top5_ids
        for i in range(len(top5)):
            assert users[i].id == top5_ids[i]
Example #38
0
    def test_get_top5_projects_24_hours_returns_best_5_only(self):
        projects = ProjectFactory.create_batch(5)
        i = 5
        for project in projects:
            TaskRunFactory.create_batch(i, project=project)
            i -= 1

        worst_project = ProjectFactory.create()

        top5 = stats.get_top5_projects_24_hours()
        top5_ids = [top['id'] for top in top5]

        assert len(top5) == 5
        assert worst_project.id not in top5_ids
        for i in range(len(top5)):
            assert projects[i].id == top5_ids[i]
    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
Example #40
0
    def test_number_of_active_users(self):
        """Test number of active users in last 30 days"""
        date_now = datetime.datetime.utcnow()
        date_60_days_old = (datetime.datetime.utcnow() -  datetime.timedelta(60)).isoformat()

        recent_users = 4
        users = UserFactory.create_batch(recent_users)
        i = recent_users
        for user in users:
            TaskRunFactory.create_batch(i, user=user, finish_time=date_now)
            i -= 1

        old_user = UserFactory.create()
        TaskRunFactory.create(user=old_user, finish_time=date_60_days_old)

        total_users = stats.number_of_active_users()
        assert total_users == recent_users, "Total active users in last 30 days should be {}".format(recent_users)
    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
Example #42
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
Example #43
0
    def test_delete_all_deletes_many_taskruns(self):
        """Test delete_all deletes many taskruns at once"""

        taskruns = TaskRunFactory.create_batch(2)

        self.task_repo.delete_all(taskruns)

        for taskrun in taskruns:
            assert self.task_repo.get_task_run(taskrun.id) is None, taskrun
Example #44
0
 def test_analysis_with_no_reference(self, mock_client):
     """Test Z3950 analysis with no reference."""
     n_answers = 3
     target = 'example.com'
     task = self.ctx.create_task(n_answers, target)
     TaskRunFactory.create_batch(n_answers,
                                 task=task,
                                 info={
                                     'control_number': 'foo',
                                     'reference': '',
                                     'comments': ''
                                 })
     result = self.result_repo.filter_by(project_id=task.project_id)[0]
     fake_search = MagicMock()
     fake_search.return_value = []
     mock_client.search_annotations = fake_search
     self.z3950_analyst.analyse(result.id)
     assert_equal(mock_client.create_annotation.called, False)
Example #45
0
 def test_analysis_with_no_transcriptions_and_old_keys(self, mock_client):
     """Test Z3950 analysis with no transcriptions and old keys."""
     n_answers = 3
     target = 'example.com'
     task = self.ctx.create_task(n_answers, target)
     TaskRunFactory.create_batch(n_answers,
                                 task=task,
                                 info={
                                     'oclc': '',
                                     'shelfmark': '',
                                     'comments': ''
                                 })
     result = self.result_repo.filter_by(project_id=task.project_id)[0]
     fake_search = MagicMock()
     fake_search.return_value = []
     mock_client.search_annotations = fake_search
     self.z3950_analyst.analyse(result.id)
     assert_equal(mock_client.create_annotation.called, False)
Example #46
0
    def test_delete_all_deletes_many_taskruns(self):
        """Test delete_all deletes many taskruns at once"""

        taskruns = TaskRunFactory.create_batch(2)

        self.task_repo.delete_all(taskruns)

        for taskrun in taskruns:
            assert self.task_repo.get_task_run(taskrun.id) is None, taskrun
Example #47
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
Example #48
0
    def test_delete_task_cascade(self):
        """Test API delete task deletes associated taskruns"""
        task = TaskFactory.create()
        task_runs = TaskRunFactory.create_batch(3, task=task)
        url = '/api/task/%s?api_key=%s' % (task.id, task.project.owner.api_key)
        res = self.app.delete(url)

        assert_equal(res.status, '204 NO CONTENT', res.data)
        task_runs = task_repo.filter_task_runs_by(task_id=task.id)
        assert len(task_runs) == 0, "There should not be any task run for task"
Example #49
0
    def test_delete_task_cascade(self):
        """Test API delete task deletes associated taskruns"""
        task = TaskFactory.create()
        task_runs = TaskRunFactory.create_batch(3, task=task)
        url = '/api/task/%s?api_key=%s' % (task.id, task.project.owner.api_key)
        res = self.app.delete(url)

        assert_equal(res.status, '204 NO CONTENT', res.data)
        task_runs = task_repo.filter_task_runs_by(task_id=task.id)
        assert len(task_runs) == 0, "There should not be any task run for task"
Example #50
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 = task_repo.filter_tasks_by(app_id=app.id)
        assert len(tasks) == 0, "There should not be any task"

        task_runs = task_repo.filter_task_runs_by(app_id=app.id)
        assert len(task_runs) == 0, "There should not be any task run"
Example #51
0
    def test_delete_project_cascade(self):
        """Test API delete project deletes associated tasks and taskruns"""
        project = ProjectFactory.create()
        tasks = TaskFactory.create_batch(2, project=project)
        task_runs = TaskRunFactory.create_batch(2, project=project)
        url = '/api/project/%s?api_key=%s' % (1, project.owner.api_key)
        self.app.delete(url)

        tasks = task_repo.filter_tasks_by(project_id=project.id)
        assert len(tasks) == 0, "There should not be any task"

        task_runs = task_repo.filter_task_runs_by(project_id=project.id)
        assert len(task_runs) == 0, "There should not be any task run"
Example #52
0
 def test_fake_user_id(self):
     """Test remove user ID works and it's replaced by a fake IP."""
     user = UserFactory.create()
     taskruns = TaskRunFactory.create_batch(3, user=user)
     fake_ips = []
     assert taskruns[0].user_id == user.id
     self.user_repo.fake_user_id(user)
     for taskrun in taskruns:
         taskrun = self.task_repo.get_task_run_by(id=taskrun.id)
         assert taskrun.user_id is None
         assert taskrun.user_ip is not None
         fake_ips.append(taskrun.user_ip)
     assert len(set(fake_ips)) == 3
Example #53
0
    def test_filter_task_runs_support_yield_option(self):
        """Test that filter_task_runs_by with the yielded=True option returns
        the results as a generator"""

        task_runs = TaskRunFactory.create_batch(2, info='info')

        yielded_task_runs = self.task_repo.filter_task_runs_by(info='info',
                                                               yielded=True)

        import types
        assert isinstance(yielded_task_runs.__iter__(), types.GeneratorType)
        for taskrun in yielded_task_runs:
            assert taskrun in task_runs
Example #54
0
 def test_delete_user_with_task_runs(self):
     """Delete user with task runs works."""
     user = UserFactory.create()
     taskruns = TaskRunFactory.create_batch(3, user=user)
     fake_ips = []
     user_id = user.id
     assert taskruns[0].user_id == user.id
     self.user_repo.delete(user)
     for taskrun in taskruns:
         taskrun = self.task_repo.get_task_run_by(id=taskrun.id)
         assert taskrun.user_id is None
         assert taskrun.user_ip is not None
         fake_ips.append(taskrun.user_ip)
     assert len(set(fake_ips)) == 3
     user = self.user_repo.get_by(id=user_id)
     assert user is None
Example #55
0
    def test_delete_app_cascade(self):
        """Test API delete app 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"
Example #56
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
Example #57
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']
Example #58
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
Example #59
0
    def test_query_taskrun(self):
        """Test API query for taskrun with params works"""
        project = ProjectFactory.create()
        task_runs = TaskRunFactory.create_batch(10, project=project)
        # Test for real field
        res = self.app.get("/api/taskrun?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/taskrun?project_id=99999999")
        data = json.loads(res.data)
        assert len(data) == 0, data

        # Multiple fields
        res = self.app.get('/api/taskrun?project_id=1&task_id=1')
        data = json.loads(res.data)
        # One result
        assert len(data) == 1, data
        # Correct result
        assert data[0]['project_id'] == 1, data
        assert data[0]['task_id'] == 1, data

        # Limits
        res = self.app.get("/api/taskrun?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

        # Keyset pagination
        url = "/api/taskrun?project_id=1&limit=5&last_id=%s" % task_runs[4].id
        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'] == task_runs[5].id, data[0]['id']
Example #60
0
    def test_taskrun_query_list_project_ids(self):
        """Get a list of tasks runs using a list of project_ids."""
        projects = ProjectFactory.create_batch(3)
        task_runs = []
        for project in projects:
            tmp = TaskRunFactory.create_batch(2, project=project)
            for t in tmp:
                task_runs.append(t)

        project_ids = [project.id for project in projects]
        url = '/api/taskrun?project_id=%s&limit=100' % project_ids
        res = self.app.get(url)
        data = json.loads(res.data)
        assert len(data) == 3 * 2, len(data)
        for task in data:
            assert task['project_id'] in project_ids
        task_run_project_ids = list(set([task['project_id'] for task in data]))
        assert sorted(project_ids) == sorted(task_run_project_ids)

        # more filters
        res = self.app.get(url + '&orderby=created&desc=true')
        data = json.loads(res.data)
        assert data[0]['id'] == task_runs[-1].id