def test_get_users_page_only_returns_users_with_contributions(self):
        users = UserFactory.create_batch(2)
        TaskRunFactory.create(user=users[0])

        users_with_contrib = cached_users.get_users_page(1)

        assert len(users_with_contrib) == 1, users_with_contrib
Example #2
0
    def test_n_total_task_runs_site_returns_total_number_of_answers(self):
        AnonymousTaskRunFactory.create()
        TaskRunFactory.create()

        task_runs = stats.n_task_runs_site()

        assert task_runs == 2, task_runs
Example #3
0
 def test_trigger_webhook_without_url(self):
     """Test WEBHOOK is triggered without url."""
     project = ProjectFactory.create()
     task = TaskFactory.create(project=project, n_answers=1)
     TaskRunFactory.create(project=project, task=task)
     assert queue.enqueue.called is False, queue.enqueue.called
     queue.reset_mock()
    def test_create_result_event(self, mock_create_result):
        """Test create_result is called."""
        from pybossa.core import db
        task = TaskFactory.create(n_answers=1)
        TaskRunFactory.create(task=task)
        conn = db.engine.connect()
        result_id = create_result(conn, task.project_id, task.id)
        result = result_repo.filter_by(project_id=task.project_id,
                                       task_id=task.id,
                                       last_version=True)[0]

        assert mock_create_result.called
        err_msg = "The result should ID should be the same"
        assert result_id == result.id, err_msg

        task.n_answers = 2
        task_repo.update(task)
        TaskRunFactory.create(task=task)

        result_id = create_result(conn, task.project_id, task.id)
        assert mock_create_result.called
        result = result_repo.filter_by(project_id=task.project_id,
                                       task_id=task.id,
                                       last_version=True)
        assert len(result) == 1, len(result)
        result = result[0]
        err_msg = "The result should ID should be the same"
        assert result_id == result.id, err_msg
    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 #6
0
 def create_result(self, n_answers=1, filter_by=False):
     task = TaskFactory.create(n_answers=n_answers)
     TaskRunFactory.create(task=task)
     if filter_by:
         return self.result_repo.filter_by(project_id=1)
     else:
         return self.result_repo.get_by(project_id=1)
Example #7
0
 def test_warm_project(self):
     """Test JOB warm_project works."""
     project = ProjectFactory.create()
     task = TaskFactory.create(n_answers=1)
     for i in range(0,30):
         TaskRunFactory.create(project=project, task=task)
     res = warm_cache()
     assert res, res
Example #8
0
 def test_stats_dates_completed_tasks(self):
     """Test STATS stats_dates with tasks completed tasks"""
     today = unicode(datetime.date.today())
     TaskRunFactory.create(task=self.project.tasks[1])
     dates, dates_anon, dates_auth = stats.stats_dates(self.project.id)
     assert dates[today] == 1, dates
     assert dates_anon[today] == 4, dates_anon[today]
     assert dates_auth[today] == 5, dates_auth[today]
    def test_last_activity_returns_date_of_latest_contribution(self):
        project = ProjectFactory.create()
        first_task_run = TaskRunFactory.create(project=project)
        last_task_run = TaskRunFactory.create(project=project)

        activity = cached_projects.last_activity(project.id)

        assert activity == last_task_run.finish_time, last_task_run
Example #10
0
 def test_send_email_not_subscribed(self, mock):
     """Test JOB send email not subscribed works."""
     user = UserFactory.create(pro=False, subscribed=False)
     pr = ProjectFactory(owner=user, featured=True)
     task = TaskFactory.create(project=pr)
     TaskRunFactory.create(project=pr, task=task)
     res = send_weekly_stats_project(pr.id)
     assert res == "Owner does not want updates by email", res
Example #11
0
 def test_send_email(self, mock):
     """Test JOB send email works."""
     user = UserFactory.create(pro=False)
     pr = ProjectFactory(owner=user, featured=True)
     task = TaskFactory.create(project=pr)
     TaskRunFactory.create(project=pr, task=task)
     send_weekly_stats_project(pr.id)
     assert mock.called
Example #12
0
 def test_anon_week(self):
     """Test JOB leaderboard returns anon active week runs."""
     users = UserFactory.create_batch(20)
     for user in users:
         TaskRunFactory.create(user=user)
     leaderboard()
     top_users = get_leaderboard()
     assert len(top_users) == 20, len(top_users)
Example #13
0
    def test_count_task_runs_with_no_matches(self):
        """Test count_task_runs_with returns 0 if no taskruns match the query"""

        TaskRunFactory.create(info='info')

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

        assert count == 0, count
Example #14
0
    def test_get_top5_projects_24_hours_returns_required_fields(self):
        fields = ('id', 'name', 'short_name', 'info', 'n_answers')
        TaskRunFactory.create()

        top5 = stats.get_top5_projects_24_hours()

        for field in fields:
            assert field in top5[0].keys()
Example #15
0
    def test_get_task_run_by_returns_none_if_no_task_run(self):
        """Test get_task_run_by returns None if no taskrun matches the query"""

        TaskRunFactory.create(info='info')

        taskrun = self.task_repo.get_task_run_by(info='other info')

        assert taskrun is None, taskrun
Example #16
0
    def test_get_query_with_api_key_context(self):
        """ Test API GET query with an API-KEY requesting only APIKEY results."""
        users = UserFactory.create_batch(4)
        project_oc = ProjectFactory.create(owner=users[0], info={'total': 150})
        projects = ProjectFactory.create_batch(3, owner=users[1])
        task_oc = TaskFactory.create(project=project_oc, info={'url': 'my url'})
        taskrun_oc = TaskRunFactory.create(task=task_oc, user=users[0],
                                        info={'answer': 'annakarenina'})
        for p in projects:
            print p.owner_id
            task_tmp = TaskFactory.create(project=p)
            TaskRunFactory.create(task=task_tmp)

        # For project owner with associated data
        for endpoint in self.endpoints:
            url = '/api/' + endpoint + '?api_key=' + users[0].api_key
            res = self.app.get(url)
            data = json.loads(res.data)

            if endpoint == 'project':
                assert len(data) == 1, data
                project = data[0]
                assert project['owner_id'] == users[0].id, project['owner_id']
                assert project['info']['total'] == 150, data
                assert res.mimetype == 'application/json', res

            if endpoint == 'task':
                assert len(data) == 1, data
                task = data[0]
                assert task['project_id'] == project_oc.id, task
                assert task['info']['url'] == 'my url', data
                assert res.mimetype == 'application/json', res

            if endpoint == 'taskrun':
                assert len(data) == 1, data
                taskrun = data[0]
                assert taskrun['project_id'] == project_oc.id, taskrun
                assert taskrun['info']['answer'] == 'annakarenina', data
                assert res.mimetype == 'application/json', res

        # For authenticated with non-associated data
        for endpoint in self.endpoints:
            url = '/api/' + endpoint + '?api_key=' + users[3].api_key

            res = self.app.get(url)
            data = json.loads(res.data)

            if endpoint == 'project':
                assert len(data) == 0, data
                assert res.mimetype == 'application/json', res

            if endpoint == 'task':
                assert len(data) == 0, data
                assert res.mimetype == 'application/json', res

            if endpoint == 'taskrun':
                assert len(data) == 0, data
                assert res.mimetype == 'application/json', res
 def test_stats_users(self):
     """Test CACHE PROJECT STATS user stats works."""
     pr = ProjectFactory.create()
     TaskRunFactory.create(project=pr)
     AnonymousTaskRunFactory.create(project=pr)
     users, anon_users, auth_users = stats_users(pr.id)
     assert len(users) == 2, len(users)
     assert len(anon_users) == 1, len(anon_users)
     assert len(auth_users) == 1, len(auth_users)
Example #18
0
    def test_get_users_page_supports_pagination(self):
        users = UserFactory.create_batch(3)
        for user in users:
            TaskRunFactory.create(user=user)

        paginated_users = cached_users.get_users_page(page=2, per_page=1)

        assert len(paginated_users) == 1, paginated_users
        assert paginated_users[0]['id'] == users[1].id
Example #19
0
    def test_limits_query(self):
        """Test API GET limits works"""
        owner = UserFactory.create()
        projects = ProjectFactory.create_batch(30, owner=owner)
        for project in projects:
            task = TaskFactory.create(project=project)
            TaskRunFactory.create(task=task)

        res = self.app.get('/api/project')
        data = json.loads(res.data)
        assert len(data) == 20, len(data)

        res = self.app.get('/api/project?limit=10')
        data = json.loads(res.data)
        assert len(data) == 10, len(data)

        # DEPRECATED
        res = self.app.get('/api/project?limit=10&offset=10')
        data = json.loads(res.data)
        assert len(data) == 10, len(data)
        assert data[0].get('name') == projects[10].name, data[0]

        # Keyset pagination
        url = '/api/project?limit=10&last_id=%s' % projects[9].id
        res = self.app.get(url)
        data = json.loads(res.data)
        assert len(data) == 10, len(data)
        assert data[0].get('name') == projects[10].name, data[0]

        res = self.app.get('/api/task')
        data = json.loads(res.data)
        assert len(data) == 20, len(data)

        res = self.app.get('/api/taskrun')
        data = json.loads(res.data)
        assert len(data) == 20, len(data)

        UserFactory.create_batch(30)

        res = self.app.get('/api/user')
        data = json.loads(res.data)
        assert len(data) == 20, len(data)

        res = self.app.get('/api/user?limit=10')
        data = json.loads(res.data)
        assert len(data) == 10, len(data)

        # DEPRECATED
        res = self.app.get('/api/user?limit=10&offset=10')
        data = json.loads(res.data)
        assert len(data) == 10, len(data)
        assert data[0].get('name') == 'user11', data

        res = self.app.get('/api/user?limit=10&last_id=10')
        data = json.loads(res.data)
        assert len(data) == 10, len(data)
        assert data[0].get('name') == 'user11', data
Example #20
0
    def test_get_inactive_users_jobs_with_users(self):
        """Test JOB get with users returns empty list."""
        TaskRunFactory.create()
        jobs_generator = get_inactive_users_jobs()
        jobs = []
        for job in jobs_generator:
            jobs.append(job)

        msg = "There should not be any job."
        assert len(jobs) == 0,  msg
Example #21
0
    def test_authenticated_user_update_other_users_taskrun(self):
        """Test authenticated user cannot update any user taskrun"""
        own_taskrun = TaskRunFactory.create()
        other_users_taskrun = TaskRunFactory.create()

        assert self.mock_authenticated.id == own_taskrun.user.id
        assert self.mock_authenticated.id != other_users_taskrun.user.id
        assert_raises(Forbidden, ensure_authorized_to, 'update', own_taskrun)
        assert_raises(Forbidden,
                      ensure_authorized_to, 'update', other_users_taskrun)
 def test_notify_blog_users_featured_project(self, mock):
     """Test Notify Blog users with featured project works."""
     user = UserFactory.create(subscribed=False)
     project = ProjectFactory.create(featured=True)
     TaskRunFactory.create(project=project)
     TaskRunFactory.create(project=project, user=user)
     blog = BlogpostFactory.create(project=project)
     res = notify_blog_users(blog.id, blog.project.id)
     msg = "1 users notified by email"
     assert res == msg, res
Example #23
0
    def test_filter_task_runs_by_no_matches(self):
        """Test filter_task_runs_by returns an empty list if no taskruns match
        the query"""

        TaskRunFactory.create(info='info')

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

        assert isinstance(retrieved_taskruns, list)
        assert len(retrieved_taskruns) == 0, retrieved_taskruns
    def test_it_deletes_project_taskruns_before_publishing(self, task_repo):
        task = TaskFactory.create(project=self.project)
        TaskRunFactory.create(task=task)
        resp = self.app.post('/project/%s/publish' % self.project.short_name,
                             follow_redirects=True)

        taskruns = task_repo.filter_task_runs_by(project_id=self.project.id)

        repo_call = task_repo.delete_taskruns_from_project.call_args_list[0][0][0]
        assert repo_call.id == self.project.id, repo_call
Example #25
0
    def test_count_task_runs_with_multiple_conditions(self):
        """Test count_task_runs_with supports multiple-condition queries"""

        TaskRunFactory.create(info='info', user_ip='8.8.8.8')
        taskrun = TaskRunFactory.create(info='info', user_ip='1.1.1.1')

        count = self.task_repo.count_task_runs_with(info='info',
                                                    user_ip='1.1.1.1')

        assert count == 1, count
Example #26
0
 def test_trigger_webhook_with_url_not_completed_task(self):
     """Test WEBHOOK is not triggered for uncompleted tasks."""
     import random
     project = ProjectFactory.create()
     task = TaskFactory.create(project=project)
     for i in range(1, random.randrange(2, 5)):
         TaskRunFactory.create(project=project, task=task)
     assert queue.enqueue.called is False, queue.enqueue.called
     assert task.state != 'completed'
     queue.reset_mock()
Example #27
0
    def test_get_users_page_returns_fields(self):
        user = UserFactory.create()
        TaskRunFactory.create(user=user)
        fields = User.public_attributes()

        users = cached_users.get_users_page(1)

        for field in fields:
            assert field in users[0].keys(), field
        assert len(users[0].keys()) == len(fields)
 def create_mock_ip_addresses(self, geoip_mock):
     geoip_instance = MagicMock()
     locs = [{'latitude': 1, 'longitude': 1, 'country_name': 'England',
              'city': 'London', 'continent': 'Europe'},
             {'latitude': 2, 'longitude': 2, 'country_name': 'France',
              'city': 'Paris', 'continent': 'Europe'}]
     geoip_instance.record_by_addr.side_effect = locs
     geoip_mock.return_value = geoip_instance
     AnonymousTaskRunFactory.create(info={'ip_address': '1.1.1.1'})
     TaskRunFactory.create(info={'ip_address': '2.2.2.2'})
    def test_check_contributing_state_ongoing_tasks_contributed(self):
        """Test check_contributing_state returns 'cannot_contribute' for a project
        with ongoing tasks to which the user has already contributed"""
        project = ProjectFactory.create()
        task = TaskFactory.create(project=project, n_answers=3)
        user = UserFactory.create()
        TaskRunFactory.create(task=task, user=user)
        contributing_state = helpers.check_contributing_state(project=project,
                                                              user_id=user.id)

        assert contributing_state == 'cannot_contribute', contributing_state
Example #30
0
    def test_filter_task_runs_by_multiple_conditions(self):
        """Test filter_task_runs_by supports multiple-condition queries"""

        TaskRunFactory.create(info='info', user_ip='8.8.8.8')
        taskrun = TaskRunFactory.create(info='info', user_ip='1.1.1.1')

        retrieved_taskruns = self.task_repo.filter_task_runs_by(info='info',
                                                                user_ip='1.1.1.1')

        assert len(retrieved_taskruns) == 1, retrieved_taskruns
        assert taskrun in retrieved_taskruns, retrieved_taskruns
Example #31
0
    def test_get_non_contrib_users_returns_jobs(self):
        """Test JOB get non contrib users returns a list of jobs."""

        TaskRunFactory.create()
        user = user_repo.get(1)

        jobs_generator = get_non_contributors_users_jobs()
        jobs = []
        for job in jobs_generator:
            jobs.append(job)

        msg = "There should be one job."
        print jobs
        assert len(jobs) == 1, msg
        job = jobs[0]
        args = job['args'][0]
        assert job['queue'] == 'quaterly', job['queue']
        assert len(args['recipients']) == 1
        assert args['recipients'][0] == user.email_addr, args['recipients'][0]
        assert "UNSUBSCRIBE" in args['body']
        assert "Update" in args['html']
 def create_result(self,
                   n_results=1,
                   n_answers=1,
                   owner=None,
                   filter_by=False):
     if owner:
         owner = owner
     else:
         owner = UserFactory.create()
     project = ProjectFactory.create(owner=owner)
     tasks = []
     for i in range(n_results):
         tasks.append(
             TaskFactory.create(n_answers=n_answers, project=project))
     for i in range(n_answers):
         for task in tasks:
             TaskRunFactory.create(task=task, project=project)
     if filter_by:
         return result_repo.filter_by(project_id=1)
     else:
         return result_repo.get_by(project_id=1)
    def test_get_inactive_users_returns_jobs(self):
        """Test JOB get inactive users returns a list of jobs."""

        today = datetime.datetime.today()
        old_date = today + relativedelta(months=-1)
        date_str = old_date.strftime('%Y-%m-%dT%H:%M:%S.%f')
        # substract six months and take care of leap years
        one_year = today + relativedelta(months=-6, leapdays=1)
        one_year_str = one_year.strftime('%Y-%m-%dT%H:%M:%S.%f')
        user = UserFactory.create()
        user_recent = UserFactory.create()
        # 1 month old contribution
        tr = TaskRunFactory.create(finish_time=date_str)
        print(tr.user_id, tr.finish_time)
        # 1 year old contribution
        tr_year = TaskRunFactory.create(finish_time=one_year_str)
        print(tr_year.user_id, tr_year.finish_time)
        # User with a contribution from a long time ago
        tr2 = TaskRunFactory.create(finish_time="2010-08-08T18:23:45.714110",
                                    user=user)
        # User with a recent contribution
        tr3 = TaskRunFactory.create(user=user)
        print(tr2.user_id, tr2.finish_time)
        print(tr3.user_id, tr3.finish_time)
        user = user_repo.get(tr.user_id)

        jobs_generator = get_inactive_users_jobs()
        jobs = []
        for job in jobs_generator:
            jobs.append(job)

        msg = "There should be one job."
        assert len(jobs) == 1, msg
        job = jobs[0]
        args = job['args'][0]
        assert job['queue'] == 'quaterly', job['queue']
        assert len(args['recipients']) == 1
        assert args['recipients'][0] == tr_year.user.email_addr, args['recipients'][0]
        assert "UNSUBSCRIBE" in args['body']
        assert "Update" in args['html']
Example #34
0
 def test_taskrun_creation(self):
     """Test ACTIVITY FEED works for task_run creation."""
     task_run = TaskRunFactory.create()
     update_feed = get_update_feed()
     err_msg = "It should be the same task_run"
     assert update_feed[0]['id'] == task_run.user.id, err_msg
     assert update_feed[0]['name'] == task_run.user.name, err_msg
     assert update_feed[0]['fullname'] == task_run.user.fullname, err_msg
     assert update_feed[0]['project_name'] == task_run.project.name, err_msg
     assert update_feed[0]['project_short_name'] == task_run.project.short_name, err_msg
     # assert update_feed[0].get('info') is not None, err_msg
     err_msg = "The update action should be Project"
     assert update_feed[0]['action_updated'] == 'UserContribution', err_msg
Example #35
0
    def test_get_last_version(self):
        """Test API result returns always latest version."""
        result = self.create_result()
        project = project_repo.get(result.project_id)
        task = task_repo.get_task(result.task_id)
        task.n_answers = 2
        TaskRunFactory.create(task=task, project=project)
        result = result_repo.get_by(project_id=project.id)

        assert result.last_version is True, result.last_version

        result_id = result.id

        results = result_repo.filter_by(project_id=project.id,
                                        last_version=False)
        assert len(results) == 2, len(results)

        for r in results:
            if r.id == result_id:
                assert r.last_version is True, r.last_version
            else:
                assert r.last_version is False, r.last_version
Example #36
0
    def test_n_available_tasks_for_user_answered_by_you_tasks(self):
        """Test n_available_tasks_for_user returns 0 for user if he has
        submitted taskruns for all the tasks"""
        project = ProjectFactory.create()
        task = TaskFactory.create(project=project, n_answers=2)
        user = UserFactory.create()
        taskrun = TaskRunFactory.create(task=task, user=user)

        n_available_tasks = helpers.n_available_tasks_for_user(project,
                                                               user_id=user.id)

        assert task.state != 'completed', task.state
        assert n_available_tasks == 0, n_available_tasks
Example #37
0
 def test_redundancy_not_increased_when_no_values(self, mock_client):
     """Test Z3950 task redundancy is not updated when no values."""
     n_answers = 3
     target = 'example.com'
     task = self.ctx.create_task(n_answers,
                                 target,
                                 max_answers=n_answers + 1)
     for i in range(n_answers):
         TaskRunFactory.create(task=task,
                               info={
                                   'reference': '',
                                   'control_number': '',
                                   '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)
     updated_task = self.task_repo.get_task(task.id)
     assert_equal(updated_task.n_answers, n_answers)
     assert_equal(mock_client.create_annotation.called, False)
Example #38
0
    def test_email_notif(self, get_contrib_emails):
        """
        if the project is configured, email notifications will be sent
        """
        owner = UserFactory.create(id=500, user_pref={'languages': ['en']})

        project = ProjectFactory.create(owner=owner, email_notif=True)
        project.info['sched'] = Schedulers.user_pref
        project_repo.save(project)
        tasks = TaskFactory.create_batch(1,
                                         project=project,
                                         n_answers=1,
                                         user_pref={'languages': ['en']})

        TaskRunFactory.create(task=tasks[0], user=owner)

        TaskFactory.create_batch(1,
                                 project=project,
                                 n_answers=1,
                                 user_pref={'languages': ['en']})
        send_email_notifications()
        get_contrib_emails.assert_called()
    def test_it_deletes_project_taskruns_before_publishing(self, mock_task_repo,
                                                           mock_result_repo,
                                                           mock_webhook_repo):
        task = TaskFactory.create(project=self.project, n_answers=1)
        TaskRunFactory.create(task=task)
        result = result_repo.get_by(project_id=task.project_id)
        assert result, "There should be a result"
        resp = self.app.post('/project/%s/publish' % self.project.short_name,
                             follow_redirects=True)

        taskruns = task_repo.filter_task_runs_by(project_id=self.project.id)

        repo_call = mock_task_repo.delete_taskruns_from_project.call_args_list[0][0][0]
        assert repo_call.id == self.project.id, repo_call

        mock_webhook_repo.assert_called_with(self.project)
        mock_result_repo.assert_called_with(self.project)

        # Try again
        resp = self.app.post('/project/%s/publish' % self.project.short_name,
                             follow_redirects=True)
        assert 'Project already published' in str(resp.data)
Example #40
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]
        project = ProjectFactory.create()
        tasks = TaskFactory.create_batch(2, project=project)
        taskrun1 = TaskRunFactory.create(task=tasks[0], user=user)
        taskrun2 = TaskRunFactory.build(task_id=tasks[1].id,
                                        user_id=user.id,
                                        project_id=tasks[1].project_id)

        assert self.mock_authenticated.id == taskrun2.user_id
        assert_not_raises(Exception, ensure_authorized_to, 'create', taskrun2)
Example #41
0
 def test_taskrun_creation_state_completed(self):
     """Test ACTIVITY FEED works for task_run creation state completed."""
     task = TaskFactory.create(n_answers=1)
     task_run = TaskRunFactory.create(task=task)
     update_feed = get_update_feed()
     err_msg = "It should be the same task_run"
     assert update_feed[0]['id'] == task_run.project.id, err_msg
     assert update_feed[0]['name'] == task_run.project.name, err_msg
     assert update_feed[0][
         'short_name'] == task_run.project.short_name, err_msg
     assert update_feed[0].get('info') is not None, err_msg
     err_msg = "The update action should be Project"
     assert update_feed[0]['action_updated'] == 'TaskCompleted', err_msg
Example #42
0
 def test_export_consesus_metadata(self):
     project = ProjectFactory.create()
     task = TaskFactory.create(project=project,
                               info={'test': 2},
                               n_answers=1)
     task_run = TaskRunFactory.create(task=task, info={'hello': u'你好'})
     with export_consensus(project, 'tsk', 'csv', True, None) as fp:
         zipfile = ZipFile(fp)
         filename = zipfile.namelist()[0]
         df = DataFrame.from_csv(StringIO(zipfile.read(filename)))
     row = df.to_dict(orient='records')[0]
     assert json.loads(row['task_run__info'])[task_run.user.name] == {
         'hello': u'你好'
     }
Example #43
0
    def test_get_inactive_users_returns_jobs(self):
        """Test JOB get inactive users returns a list of jobs."""

        tr = TaskRunFactory.create(finish_time="2010-07-07T17:23:45.714210")
        user = user_repo.get(tr.user_id)

        jobs = get_inactive_users_jobs()
        msg = "There should be one job."
        assert len(jobs) == 1, msg
        job = jobs[0]
        args = job['args'][0]
        assert job['queue'] == 'quaterly', job['queue']
        assert len(args['recipients']) == 1
        assert args['recipients'][0] == user.email_addr, args['recipients'][0]
    def test_has_child_added_to_parent_results(self, mock_wa_client, requests):
        """Test that the has_children key is added to parent results."""
        manifest = self.create_manifest()
        headers = {'Content-Type': 'application/json'}
        response = FakeResponse(text=json.dumps(manifest),
                                status_code=200,
                                headers=headers,
                                encoding='utf-8')
        requests.get.return_value = response
        anno_collection_iri = 'example.org/annotations'

        # Create a task for each canvas
        n_tasks = 3
        category = CategoryFactory(
            info={'annotations': {
                'results': anno_collection_iri
            }})
        parent = ProjectFactory(category=category)
        tasks = TaskFactory.create_batch(n_tasks, project=parent, n_answers=1)
        for task in tasks:
            TaskRunFactory.create(task=task)
            result = self.result_repo.get_by(task_id=task.id)
            result.info = dict(annotations=anno_collection_iri)
            self.result_repo.update(result)

        importer = BulkTaskIIIFEnhancedImporter(manifest_uri=self.manifest_uri,
                                                parent_id=parent.id)
        mock_wa_client.search_annotations.return_value = []
        tasks = importer.tasks()

        results = self.result_repo.filter_by(project_id=parent.id)
        result_info = [result.info for result in results]
        expected = [{
            'annotations': anno_collection_iri,
            'has_children': True
        }] * n_tasks
        assert_equal(result_info, expected)
Example #45
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 #46
0
    def test_n_results_site_returns_valid_results_with_info(self):
        project = ProjectFactory.create()
        task = TaskFactory.create(n_answers=1, project=project)
        TaskRunFactory.create(task=task, project=project)
        result = result_repo.get_by(project_id=project.id)
        result.info = dict(foo='bar')
        result_repo.update(result)
        n_results = stats.n_results_site()

        assert n_results == 1, n_results

        project = ProjectFactory.create()
        task = TaskFactory.create(n_answers=1, project=project)
        TaskRunFactory.create(task=task, project=project)
        result = result_repo.get_by(project_id=project.id)
        result.info = dict(foo='bar2')
        result_repo.update(result)
        n_results = stats.n_results_site()

        assert n_results == 2, n_results

        self.create_result(n_results=10)

        assert n_results == 2, n_results
Example #47
0
    def test_get_inactive_users_returns_jobs_unsubscribed(self):
        """Test JOB get inactive users returns an empty list of jobs."""

        tr = TaskRunFactory.create(finish_time="2010-07-07T17:23:45.714210")
        user = user_repo.get(tr.user_id)
        user.subscribed = False
        user_repo.update(user)

        jobs_generator = get_inactive_users_jobs()
        jobs = []
        for job in jobs_generator:
            jobs.append(job)

        msg = "There should be zero jobs."
        assert len(jobs) == 0, msg
Example #48
0
    def test_taskrun_delete(self):
        """Test TaskRun API delete works"""
        admin = UserFactory.create()
        owner = UserFactory.create()
        non_owner = UserFactory.create()
        project = ProjectFactory.create(owner=owner)
        task = TaskFactory.create(project=project)
        anonymous_taskrun = AnonymousTaskRunFactory.create(task=task, info='my task result')
        user_taskrun = TaskRunFactory.create(task=task, user=owner, info='my task result')

        ## anonymous
        res = self.app.delete('/api/taskrun/%s' % user_taskrun.id)
        error_msg = 'Anonymous should not be allowed to delete'
        assert_equal(res.status, '401 UNAUTHORIZED', error_msg)

        ### real user but not allowed to delete anonymous TaskRuns
        url = '/api/taskrun/%s?api_key=%s' % (anonymous_taskrun.id, owner.api_key)
        res = self.app.delete(url)
        error_msg = 'Authenticated user should not be allowed ' \
                    'to delete anonymous TaskRuns'
        assert_equal(res.status, '403 FORBIDDEN', error_msg)

        ### real user but not allowed as not owner!
        url = '/api/taskrun/%s?api_key=%s' % (user_taskrun.id, non_owner.api_key)
        res = self.app.delete(url)
        error_msg = 'Should not be able to delete TaskRuns of others'
        assert_equal(res.status, '403 FORBIDDEN', error_msg)

        #### real user
        # DELETE with not allowed args
        url = '/api/taskrun/%s?api_key=%s' % (user_taskrun.id, owner.api_key)
        res = self.app.delete(url + "&foo=bar")
        err = json.loads(res.data)
        assert res.status_code == 415, err
        assert err['status'] == 'failed', err
        assert err['target'] == 'taskrun', err
        assert err['action'] == 'DELETE', err
        assert err['exception_cls'] == 'AttributeError', err

        # Owner with valid args can delete
        res = self.app.delete(url)
        assert_equal(res.status, '204 NO CONTENT', res.data)

        ### root
        url = '/api/taskrun/%s?api_key=%s' % (anonymous_taskrun.id, admin.api_key)
        res = self.app.delete(url)
        error_msg = 'Admin should be able to delete TaskRuns of others'
        assert_equal(res.status, '204 NO CONTENT', error_msg)
Example #49
0
    def test_export(self, m1, m2, m3, m4, m5):
        """Check email is sent to user."""
        user = UserFactory.create()
        project = ProjectFactory.create(owner=user)
        taskrun = TaskRunFactory.create(user=user)

        m4.delete_file.return_value = True

        export_userdata(user.id)

        upload_method = 'uploads.uploaded_file'

        personal_data_link = url_for(
            upload_method,
            filename="user_%s/%s_sec_personal_data.zip" % (user.id, 'random'),
            _external=True)
        personal_projects_link = url_for(
            upload_method,
            filename="user_%s/%s_sec_user_projects.zip" % (user.id, 'random'),
            _external=True)
        personal_contributions_link = url_for(
            upload_method,
            filename="user_%s/%s_sec_user_contributions.zip" %
            (user.id, 'random'),
            _external=True)

        body = render_template(
            '/account/email/exportdata.md',
            user=user.dictize(),
            personal_data_link=personal_data_link,
            personal_projects_link=personal_projects_link,
            personal_contributions_link=personal_contributions_link,
            config=current_app.config)

        html = render_template(
            '/account/email/exportdata.html',
            user=user.dictize(),
            personal_data_link=personal_data_link,
            personal_projects_link=personal_projects_link,
            personal_contributions_link=personal_contributions_link,
            config=current_app.config)
        subject = 'Your personal data'
        mail_dict = dict(recipients=[user.email_addr],
                         subject=subject,
                         body=body,
                         html=html)
        m1.assert_called_with(mail_dict)
        assert 'https' in personal_contributions_link
Example #50
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 #51
0
    def test_export_tasks_csv_json(self, mail):
        """Test JOB export_tasks task csv works."""
        user = UserFactory.create(admin=True)
        project = ProjectFactory.create(name='test_project')
        task = TaskFactory.create(project=project)
        task_run = TaskRunFactory.create(project=project, task=task)

        export_tasks(user.email_addr, project.short_name, 'task', False, 'csv')
        args, kwargs = mail.send.call_args
        message = args[0]
        assert message.recipients[0] == user.email_addr, message.recipients
        assert message.subject == 'Data exported for your project: test_project', message.subject

        attachment = message.attachments[0]
        proj_name = unidecode(project.short_name)
        filename = '{}_{}'.format(project.id, proj_name)
        assert attachment.filename == '{}_task_csv.zip'.format(filename)

        export_tasks(user.email_addr, project.short_name, 'task', False,
                     'json')
        args, kwargs = mail.send.call_args
        message = args[0]
        assert message.recipients[0] == user.email_addr, message.recipients
        assert message.subject == 'Data exported for your project: test_project', message.subject

        attachment = message.attachments[0]
        assert attachment.filename == '{}_task_json.zip'.format(filename)

        export_tasks(user.email_addr, project.short_name, 'task_run', False,
                     'csv')
        args, kwargs = mail.send.call_args
        message = args[0]
        assert message.recipients[0] == user.email_addr, message.recipients
        assert message.subject == 'Data exported for your project: test_project', message.subject

        attachment = message.attachments[0]
        assert attachment.filename == '{}_task_run_csv.zip'.format(filename)

        export_tasks(user.email_addr, project.short_name, 'task_run', False,
                     'json')
        args, kwargs = mail.send.call_args
        message = args[0]
        assert message.recipients[0] == user.email_addr, message.recipients
        assert message.subject == 'Data exported for your project: test_project', message.subject

        attachment = message.attachments[0]
        assert attachment.filename == '{}_task_run_json.zip'.format(filename)
Example #52
0
    def test_delete_also_removes_dependant_resources(self):
        """Test delete removes project tasks and taskruns too"""
        from factories import TaskFactory, TaskRunFactory, BlogpostFactory
        from pybossa.repositories import TaskRepository, BlogRepository

        project = ProjectFactory.create()
        task = TaskFactory.create(project=project)
        taskrun = TaskRunFactory.create(task=task)
        blogpost = BlogpostFactory.create(project=project)

        self.project_repo.delete(project)
        deleted_task = TaskRepository(db).get_task(task.id)
        deleted_taskrun = TaskRepository(db).get_task_run(taskrun.id)
        deleted_blogpost = BlogRepository(db).get(blogpost.id)

        assert deleted_task is None, deleted_task
        assert deleted_taskrun is None, deleted_taskrun
Example #53
0
    def test_get_by_returns_result(self):
        """Test get_by method returns a result if exists"""

        n_answers = 1

        task = TaskFactory.create(n_answers=n_answers)
        task_run = TaskRunFactory.create(task=task)

        result = self.result_repo.get_by(project_id=1)

        err_msg = "There should be a result"
        assert result.project_id == 1, err_msg
        assert result.task_id == task.id, err_msg
        assert len(result.task_run_ids) == n_answers, err_msg
        err_msg = "The task_run id is missing in the results array"
        for tr_id in result.task_run_ids:
            assert tr_id == task_run.id, err_msg
Example #54
0
    def test_exporters_generates_zip(self, json_uploader, csv_uploader):
        """Test that CsvExporter and JsonExporter generate zip works."""

        user = UserFactory.create(admin=True)
        project = ProjectFactory.create(name='test_project')
        task = TaskFactory.create(project=project)
        task_run = TaskRunFactory.create(project=project, task=task)
        csv_exporter = CsvExporter()
        json_exporter = JsonExporter()
        csv_exporter.pregenerate_zip_files(project)
        call_csv_params = csv_uploader.upload_file.call_args_list
        expected_csv_params = set(['1_project1_task_run_csv.zip', '1_project1_result_csv.zip', '1_project1_task_csv.zip'])
        assert self._check_func_called_with_params(call_csv_params, expected_csv_params)

        json_exporter.pregenerate_zip_files(project)
        call_json_params = json_uploader.upload_file.call_args_list
        expected_json_params = set(['1_project1_task_run_json.zip', '1_project1_result_json.zip', '1_project1_task_json.zip'])
        assert self._check_func_called_with_params(call_json_params, expected_json_params)
Example #55
0
    def test_export_tasks(self, task_json_exporter, task_csv_exporter, mail):
        """Test JOB export_tasks works."""
        user = UserFactory.create(admin=True)
        project = ProjectFactory.create(name='test_project')
        task = TaskFactory.create(project=project)
        task_run = TaskRunFactory.create(project=project, task=task)

        task_csv_exporter.make_zip.return_value = None
        task_json_exporter.make_zip.return_value = None

        export_tasks(user.email_addr, project.short_name, 'task', False, 'csv')
        export_tasks(user.email_addr, project.short_name, 'task', False,
                     'json')

        task_csv_exporter.make_zip.assert_called_once_with(
            project, 'task', False)
        task_json_exporter.make_zip.assert_called_once_with(
            project, 'task', False)
Example #56
0
    def test_authenticated_user_create_repeated_taskrun(self):
        """Test authenticated user cannot create a taskrun for a task to which
        he has previously posted a taskrun"""

        task = TaskFactory.create()
        taskrun1 = TaskRunFactory.create(task=task)
        taskrun2 = TaskRunFactory.build(task=task, user=taskrun1.user)

        assert self.mock_authenticated.id == taskrun1.user.id
        assert_raises(Forbidden, getattr(require, 'taskrun').create, taskrun2)

        # But the user can still create taskruns for different tasks
        task2 = TaskFactory.create(app=task.app)
        taskrun3 = TaskRunFactory.build(task=task2, user=taskrun1.user)

        assert self.mock_authenticated.id == taskrun3.user.id
        assert_not_raises(Exception,
                          getattr(require, 'taskrun').create, taskrun3)
Example #57
0
    def test_delete_taskrun_adds_counter(self):
        """Delete event for task run adds a counter."""
        task_run = TaskRunFactory.create()

        counters = db.session.query(Counter).filter_by(project_id=task_run.project.id,
                                                       task_id=task_run.task.id)\
                     .order_by(Counter.id).all()

        assert len(counters) == 2, counters
        for c in counters:
            assert c.task_id == task_run.task.id, c
            assert c.project_id == task_run.project.id, c

        counters = db.session.query(Counter.project_id, Counter.task_id, func.sum(Counter.n_task_runs))\
                     .filter_by(project_id=task_run.project.id,
                                task_id=task_run.task.id)\
                     .group_by(Counter.project_id, Counter.task_id).all()

        assert len(counters) == 1, counters
        counter = counters[0]
        assert counter[2] == 1, counter

        db.session.delete(task_run)
        db.session.commit()

        counters = db.session.query(Counter).filter_by(project_id=task_run.project.id,
                                                       task_id=task_run.task.id)\
                     .order_by(Counter.id).all()

        assert len(counters) == 3, counters
        for c in counters:
            assert c.task_id == task_run.task.id, c
            assert c.project_id == task_run.project.id, c


        counters = db.session.query(Counter.project_id, Counter.task_id, func.sum(Counter.n_task_runs))\
                     .filter_by(project_id=task_run.project.id,
                                task_id=task_run.task.id)\
                     .group_by(Counter.project_id, Counter.task_id).all()

        assert len(counters) == 1, counters
        counter = counters[0]
        assert counter[2] == 0, counter
Example #58
0
    def test_task_query_list_project_ids(self, auth):
        """Get a list of tasks using a list of project_ids."""
        auth.return_value = True
        projects = ProjectFactory.create_batch(3)
        tasks = []
        for project in projects:
            tmp = TaskFactory.create_batch(2, project=project)
            for t in tmp:
                tasks.append(t)

        user = UserFactory.create()
        project_ids = [project.id for project in projects]
        url = '/api/task?all=1&project_id=%s&limit=100&api_key=%s' % (
            project_ids, user.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_project_ids = list(set([task['project_id'] for task in data]))
        assert sorted(project_ids) == sorted(task_project_ids)

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

        task_orig = tasks[0]
        task_run = TaskRunFactory.create(task=task_orig, user=user)

        project_ids = [project.id for project in projects]
        url = '/api/task?project_id=%s&limit=100&participated=true&api_key=%s' % (
            project_ids, user.api_key)
        res = self.app.get(url)
        data = json.loads(res.data)
        assert len(data) == (3 * 2) - 1, len(data)
        for task in data:
            assert task['project_id'] in project_ids
        task_project_ids = list(set([task['project_id'] for task in data]))
        assert sorted(project_ids) == sorted(task_project_ids)
        task_ids = [task['id'] for task in data]
        err_msg = 'This task should not be in the list as the user participated.'
        assert task_orig.id not in task_ids, err_msg
    def test_create_new_row(self):
        answer_fields = {
            'hello': {
                'type': 'categorical',
                'config': {
                    'labels': ['A', 'B']
                }
            }
        }
        project = ProjectFactory.create(info={'answer_fields': answer_fields})
        task = TaskFactory.create(project=project,
                                  calibration=1,
                                  gold_answers={'hello': 'A'})
        task_run = TaskRunFactory.create(task=task, info={'hello': 'A'})

        update_gold_stats(task_run.user_id, task.id, task_run.dictize())
        stats = performance_repo.filter_by(project_id=project.id)
        assert len(stats) == 1
        assert stats[0].info['matrix'] == [[1, 0], [0, 0]]
Example #60
0
    def test_result_admin_post(self):
        """Test API Result creation"""
        admin = UserFactory.create()
        user = UserFactory.create()
        project = ProjectFactory.create(owner=user)
        data = dict(info='final result')

        # now the root user
        res = self.app.post('/api/result?api_key=' + admin.api_key,
                            data=json.dumps(data))
        assert res.status == '400 BAD REQUEST', res.status
        assert json.loads(res.data)['exception_msg'] == 'Invalid task id'

        task = TaskFactory.create(project=project, n_answers=1)
        data['task_id'] = task.id

        res = self.app.post('/api/result?api_key=' + admin.api_key,
                            data=json.dumps(data))
        assert res.status == '400 BAD REQUEST', res.status
        assert json.loads(res.data)['exception_msg'] == 'Invalid task'

        taskrun = TaskRunFactory.create(task=task)

        res = self.app.post('/api/result?api_key=' + admin.api_key,
                            data=json.dumps(data))
        assert res.status == '400 BAD REQUEST', res.status
        assert json.loads(
            res.data)['exception_msg'] == 'Record is already present'

        from pybossa.core import result_repo
        result_repo.delete_results_from_project(project)

        res = self.app.post('/api/result?api_key=' + admin.api_key,
                            data=json.dumps(data))
        assert res.status == '200 OK', res.status
        res_data = json.loads(res.data)

        assert res_data['task_id'] == task.id
        assert res_data['project_id'] == project.id
        assert res_data['info'] == data['info']
        assert res_data['last_version']
        assert res_data['task_run_ids'] == [taskrun.id]