def test_max_limit(self):
        """Test ACTIVITY FEED limit works."""
        ProjectFactory.create_batch(101)

        update_feed = get_update_feed()
        err_msg = "There should be at max 100 updates."
        assert len(update_feed) == 100, err_msg
    def test_n_published_counts_published_projects(self):
        published_project = ProjectFactory.create_batch(2, published=True)
        ProjectFactory.create(published=False)

        number_of_published = cached_projects.n_published()

        assert number_of_published == 2, number_of_published
Exemple #3
0
    def test_warn_project_excludes_completed_projects(self, clean_mock):
        """Test JOB email excludes completed projects."""
        from pybossa.core import mail
        with mail.record_messages() as outbox:
            date = '2010-10-22T11:02:00.000000'

            owner = UserFactory.create(consent=True, subscribed=True)
            project = ProjectFactory.create(updated=date, contacted=False,
                                            owner=owner)
            TaskFactory.create(created=date, project=project, state='completed')
            project_id = project.id
            project = project_repo.get(project_id)
            project.updated = date
            project_repo.update(project)

            project = ProjectFactory.create(updated=date, contacted=False,
                                            owner=owner)
            TaskFactory.create(created=date, project=project, state='ongoing')
            project_id = project.id
            project = project_repo.get(project_id)
            project.updated = date
            project_repo.update(project)

            warn_old_project_owners()
            assert len(outbox) == 1, outbox
            subject = 'Your PYBOSSA project: %s has been inactive' % project.name
            assert outbox[0].subject == subject
            err_msg = "project.contacted field should be True"
            assert project.contacted, err_msg
            err_msg = "project.published field should be False"
            assert project.published is False, err_msg
            err_msg = "cache of project should be cleaned"
            clean_mock.assert_called_with(project_id), err_msg
            err_msg = "The update date should be different"
            assert project.updated != date, err_msg
Exemple #4
0
    def test_blogpost_update_errors(self):
        """Test blogposts update for non existing projects raises errors"""
        self.register()
        user = user_repo.get(1)
        project1 = ProjectFactory.create(owner=user)
        project2 = ProjectFactory.create(owner=user)
        blogpost = BlogpostFactory.create(project=project1, body='body')

        # To a non-existing project
        url = "/project/non-existing-project/%s/update" % blogpost.id
        res = self.app.post(url, data={'title':'new title', 'body':'body'},
                            follow_redirects=True)
        assert res.status_code == 404, res.status_code

        # To a non-existing post
        url = "/project/%s/999999/update" % project1.short_name
        res = self.app.post(url, data={'title':'new title', 'body':'body'},
                            follow_redirects=True)
        assert res.status_code == 404, res.status_code

        # To an existing post but with a project in the URL it does not belong to
        url = "/project/%s/%s/update" % (project2.short_name, blogpost.id)
        res = self.app.post(url, data={'title':'new title', 'body':'body'},
                            follow_redirects=True)
        assert res.status_code == 404, res.status_code
    def test_n_featured_returns_featured(self):
        """Test CACHE PROJECTS _n_featured returns number of featured projects"""
        ProjectFactory.create(featured=True)

        number_of_featured = cached_projects._n_featured()

        assert number_of_featured == 1, number_of_featured
    def test_n_draft_with_drafts(self):
        """Test CACHE PROJECTS _n_draft returns 2 if there are 2 draft projects"""
        ProjectFactory.create_batch(2, published=False)

        number_of_drafts = cached_projects._n_draft()

        assert number_of_drafts == 2, number_of_drafts
    def test_filter_by_one_condition(self):
        """Test filter_by returns a list of logs that meet the filtering
        condition"""

        project = ProjectFactory.create()
        AuditlogFactory.create_batch(
            size=3,
            project_id=project.id,
            project_short_name=project.short_name,
            user_id=project.owner.id,
            user_name=project.owner.name,
        )

        project2 = ProjectFactory.create()
        should_be_missing = AuditlogFactory.create_batch(
            size=3,
            project_id=project2.id,
            project_short_name=project2.short_name,
            user_id=project2.owner.id,
            user_name=project2.owner.name,
        )

        retrieved_logs = self.auditlog_repo.filter_by(user_id=project.owner.id)

        assert len(retrieved_logs) == 3, retrieved_logs
        assert should_be_missing not in retrieved_logs, retrieved_logs
Exemple #8
0
    def test_get_featured_returns_required_fields(self):
        """Test CACHE PROJECTS get_featured returns the required info
        about each featured project"""

        fields = (
            "id",
            "name",
            "short_name",
            "info",
            "created",
            "description",
            "last_activity",
            "last_activity_raw",
            "overall_progress",
            "n_tasks",
            "n_volunteers",
            "owner",
            "info",
            "updated",
        )

        ProjectFactory.create(featured=True)

        featured = cached_projects.get_featured()[0]

        for field in fields:
            assert featured.has_key(field), "%s not in project info" % field
    def test_get_used_returns_only_categories_with_projects(self):
        used_category = CategoryFactory.create()
        ProjectFactory.create(category=used_category)
        unused_category = CategoryFactory.create()

        used_categories = cached_categories.get_used()

        assert used_categories[0]["id"] == used_category.id, used_categories
    def test_get_featured(self):
        """Test CACHE PROJECTS get_featured returns featured projects"""

        ProjectFactory.create(featured=True)

        featured = cached_projects.get_featured()

        assert len(featured) is 1, featured
    def test_get_by_returns_none_if_no_project(self):
        """Test get_by returns None if no project matches the query"""

        ProjectFactory.create(name='My Project', short_name='myproject')

        project = self.project_repo.get_by(name='no_name')

        assert project is None, project
    def test_get_dont_return_projects_with_password(self):
        """Test CACHE PROJECTS get does not return projects with a password"""

        project = ProjectFactory.create(published=True, info={'passwd_hash': '2'})
        ProjectFactory.create(category=project.category, published=True)
        projects = cached_projects.get(project.category.short_name)

        assert len(projects) is 1, projects
    def test_get_only_return_published(self):
        """Test CACHE PROJECTS get returns only published projects"""

        project = ProjectFactory.create(published=True)
        ProjectFactory.create(category=project.category, published=False)
        projects = cached_projects.get(project.category.short_name)

        assert len(projects) is 1, projects
    def test_get_draft_not_returns_hidden_projects(self):
        """Test CACHE PROJECTS get_draft does not return hidden projects"""

        ProjectFactory.create(info={}, hidden=1)

        drafts = cached_projects.get_draft()

        assert len(drafts) is 0, drafts
Exemple #15
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_get_only_returns_projects_from_category(self):
        """Test CACHE PROJECTS get returns only projects from required category"""

        project = ProjectFactory.create(published=True)
        ProjectFactory.create(published=True)

        projects = cached_projects.get(project.category.short_name)

        assert len(projects) is 1, projects
    def test_n_draft_with_drafts(self):
        """Test CACHE PROJECTS _n_draft returns 2 if there are 2 draft projects"""
        # Here, we are suposing that a project is draft iff has no presenter AND has no tasks

        ProjectFactory.create_batch(2, info={})

        number_of_drafts = cached_projects._n_draft()

        assert number_of_drafts == 2, number_of_drafts
    def test_filter_by_no_matches(self):
        """Test filter_by returns an empty list if no projects match the query"""

        ProjectFactory.create(name='My Project', short_name='myproject')

        retrieved_projects = self.project_repo.filter_by(name='no_name')

        assert isinstance(retrieved_projects, list)
        assert len(retrieved_projects) == 0, retrieved_projects
    def test_n_count_with_password_protected_projects(self):
        """Test CACHE PROJECTS n_count returns the number of published projects
        of a given category, excluding projects with a password"""
        project = ProjectFactory.create(published=True, info={'passwd_hash': '2'})
        ProjectFactory.create(category=project.category, published=True)

        n_projects = cached_projects.n_count(project.category.short_name)

        assert n_projects == 1, n_projects
    def test_get_from_pro_user_projects_no_projects(self):
        """Test CACHE PROJECTS get_from_pro_user returns empty list if no projects
        with 'pro' owners"""
        pro_user = UserFactory.create(pro=True)
        ProjectFactory.create()

        pro_owned_projects = cached_projects.get_from_pro_user()

        assert pro_owned_projects == [], pro_owned_projects
    def test_get_draft(self):
        """Test CACHE PROJECTS get_draft returns draft_projects"""
        # Here, we are suposing that a project is draft iff has no presenter AND has no tasks

        ProjectFactory.create(info={})

        drafts = cached_projects.get_draft()

        assert len(drafts) is 1, drafts
    def test_get_featured_only_returns_featured(self):
        """Test CACHE PROJECTS get_featured returns only featured projects"""

        featured_project = ProjectFactory.create(featured=True)
        non_featured_project = ProjectFactory.create()

        featured = cached_projects.get_featured()

        assert len(featured) is 1, featured
    def test_get_only_returns_category_projects(self):
        """Test CACHE PROJECTS get returns only projects from required category"""

        project = self.create_project_with_tasks(1, 0)
        #create a non published project too
        ProjectFactory.create()

        projects = cached_projects.get(project.category.short_name)

        assert len(projects) is 1, projects
Exemple #24
0
    def test_autoimport_jobs_without_pro(self):
        """Test JOB autoimport jobs works without pro users."""
        ProjectFactory.create()
        jobs_generator = get_autoimport_jobs()
        jobs = []
        for job in jobs_generator:
            jobs.append(job)

        msg = "There should be 0 jobs."
        assert len(jobs) == 0, msg
    def test_get_not_returns_draft_projects(self):
        """Test CACHE PROJECTS get does not return draft (non-published) projects"""

        project = self.create_project_with_contributors(1, 0)
        # Create a project wothout presenter
        ProjectFactory.create(info={}, category=project.category)

        projects = cached_projects.get(project.category.short_name)

        assert len(projects) is 1, projects
    def test_get_from_pro_users_returns_required_fields(self):
        """Test CACHE PROJECTS get_from_pro_user returns required fields"""
        pro_user = UserFactory.create(pro=True)
        ProjectFactory.create(owner=pro_user)
        fields = ('id', 'short_name')

        pro_owned_projects = cached_projects.get_from_pro_user()

        for field in fields:
            assert field in pro_owned_projects[0].keys(), field
    def test_get_used_returns_requiered_fields(self):
        used_category = CategoryFactory.create()
        ProjectFactory.create(category=used_category)
        fields = ("id", "name", "short_name", "description")

        used_categories = cached_categories.get_used()

        for field in fields:
            assert field in used_categories[0].keys()
        assert len(fields) == len(used_categories[0].keys())
    def test_get_draft_not_returns_published_projects(self):
        """Test CACHE PROJECTS get_draft does not return projects with either tasks or a presenter (REVIEW DEFINITION OF A DRAFT PROJECT REQUIRED)"""

        project_no_presenter = ProjectFactory.create(info={})
        TaskFactory.create(project=project_no_presenter)
        project_no_task = ProjectFactory.create()

        drafts = cached_projects.get_draft()

        assert len(drafts) is 0, drafts
    def test_get_project_jobs_for_non_pro_users(self):
        """Test JOB get project jobs works for non pro users."""
        ProjectFactory.create()
        jobs_generator = get_project_jobs()
        jobs = []
        for job in jobs_generator:
            jobs.append(job)

        err_msg = "There should be only 0 jobs"
        assert len(jobs) == 0, err_msg
    def test_n_count_with_published_projects(self):
        """Test CACHE PROJECTS n_count returns the number of published projects
        of a given category"""
        project = self.create_project_with_tasks(1, 0)
        #create a non published project too
        ProjectFactory.create()

        n_projects = cached_projects.n_count(project.category.short_name)

        assert n_projects == 1, n_projects
    def test_taskrun_post_requires_newtask_first_external_uid(self):
        """Test API TaskRun post fails if task was not previously requested for
        external user"""
        project = ProjectFactory.create()
        url = '/api/auth/project/%s/token' % project.short_name
        headers = {'Authorization': project.secret_key}
        token = self.app.get(url, headers=headers)
        headers['Authorization'] = 'Bearer %s' % token.data
        task = TaskFactory.create(project=project)
        external_uid = 'as2d-4cab-3daf-234a-2344x'
        data = dict(
            project_id=project.id,
            task_id=task.id,
            info='my task result',
            external_uid=external_uid)
        datajson = json.dumps(data)
        fail = self.app.post('/api/taskrun', data=datajson, headers=headers)
        err = json.loads(fail.data)

        assert fail.status_code == 403, fail.status_code
        assert err['status'] == 'failed', err
        assert err['status_code'] == 403, err
        assert err['exception_msg'] == 'You must request a task first!', err
        assert err['exception_cls'] == 'Forbidden', err
        assert err['target'] == 'taskrun', err

        # Succeeds after requesting a task
        res = self.app.get('/api/project/%s/newtask?external_uid=%s' %
                           (project.id, external_uid))
        assert res.status_code == 401
        assert json.loads(res.data) == INVALID_HEADER_MISSING


        # Succeeds after requesting a task
        self.app.get('/api/project/%s/newtask?external_uid=%s' % (project.id,
                                                                  external_uid),
                     headers=headers)
        success = self.app.post('/api/taskrun', data=datajson, headers=headers)
        assert success.status_code == 200, success.data
    def test_create_dict_job(self):
        """Test JOB create dict job works."""
        user = UserFactory.create(pro=True)
        project = ProjectFactory.create(owner=user)
        from sqlalchemy.sql import text
        from pybossa.core import db
        sql = text(
            '''SELECT project.id, project.short_name FROM project, "user"
                   WHERE project.owner_id="user".id AND "user".pro=True;''')
        results = db.slave_session.execute(sql)
        jobs_generator = create_dict_jobs(results, get_project_stats,
                                          (10 * 60))
        jobs = []
        for job in jobs_generator:
            jobs.append(job)

        err_msg = "There should be only one job"
        assert len(jobs) == 1, err_msg

        job = jobs[0]
        assert 'get_project_stats' in job['name'].__name__
        assert job['args'] == [project.id, project.short_name]
Exemple #33
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()
Exemple #34
0
 def test_webhook_handler_post_oid(self):
     """Test WEBHOOK post oid works."""
     self.register()
     self.signin()
     user = user_repo.get(1)
     project = ProjectFactory.create(owner=user)
     task = TaskFactory.create(project=project, n_answers=1)
     AnonymousTaskRunFactory.create(project=project, task=task)
     payload = self.payload(project, task)
     webhook = Webhook(project_id=project.id,
                       payload=payload,
                       response='OK',
                       response_status_code=200)
     webhook_repo.save(webhook)
     webhook = webhook_repo.get(1)
     url = "/project/%s/webhook/%s" % (project.short_name, webhook.id)
     res = self.app.post(url)
     tmp = json.loads(res.data)
     assert res.status_code == 200, res.status_code
     assert tmp['payload']['project_short_name'] == project.short_name
     assert tmp['payload']['project_id'] == project.id
     assert tmp['payload']['task_id'] == task.id
    def test_project_update_scheduler(self):
        """Test Auditlog API project update info scheduler works."""
        project = ProjectFactory.create()

        owner_id = project.owner.id
        owner_name = project.owner.name
        data = {'info': {'sched': 'depth_first'}}
        url = '/api/project/%s?api_key=%s' % (project.id,
                                              project.owner.api_key)
        self.app.put(url, data=json.dumps(data))
        logs = auditlog_repo.filter_by(project_id=project.id)

        assert len(logs) == 1, logs
        for log in logs:
            assert log.user_id == owner_id, log.user_id
            assert log.user_name == owner_name, log.user_name
            assert log.project_short_name == project.short_name, log.project_short_name
            assert log.action == 'update', log.action
            assert log.caller == 'api', log.caller
            assert log.attribute == 'sched', log.attribute
            msg = "%s != %s" % (data['info']['sched'], log.new_value)
            assert data['info']['sched'] == log.new_value, msg
    def test_sync_L3_without_target(self, mock_cat):
        project_syncer = ProjectSyncer(self.target_url, self.target_key)
        user = UserFactory.create(admin=True, email_addr=u'*****@*****.**')
        project_syncer.syncer = user

        project = ProjectFactory.create()
        project.info['data_classification'] = dict(
            input_data="L3 - community", output_data="L3 - community")
        project_repo.save(project)

        # no sync info by default
        assert not project.info.get("sync")

        payload = project_syncer._build_payload(project)

        # sync existing does put request
        headers = [('Authorization', user.api_key)]
        res = self.app.put("/api/project/{}".format(project.id),
                           headers=headers,
                           data=json.dumps(payload))
        assert res.status_code == 200, 'build_payload output should result in valid api query'
        assert res.json["info"]["sync"] == payload["info"]["sync"]
Exemple #37
0
    def test_blogpost_update_by_anonymous(self):
        """Test blogpost update, anonymous users are redirected to signin"""
        project = ProjectFactory.create()
        blogpost = BlogpostFactory.create(project=project, title='title')
        url = "/project/%s/%s/update" % (project.short_name, blogpost.id)

        res = self.app.get(url, follow_redirects=True)
        assert res.status_code == 200, res.status_code
        assert "Please sign in to access this page" in res.data, res.data

        res = self.app.post(url,
                            data={
                                'id': blogpost.id,
                                'title': 'new title',
                                'body': 'new body'
                            },
                            follow_redirects=True)
        assert res.status_code == 200, res.status_code
        assert "Please sign in to access this page" in res.data

        blogpost = blog_repo.get_by()
        assert blogpost.title == 'title', blogpost.title
Exemple #38
0
    def test_newtask(self):
        """Test API project new_task method and authentication"""
        project = ProjectFactory.create()
        project.set_password('the_password')
        project_repo.save(project)
        TaskFactory.create_batch(2,
                                 project=project,
                                 info={'question': 'answer'})
        user = UserFactory.create()

        # anonymous
        # test getting a new task
        res = self.app.get('/api/project/%s/newtask' % project.id)
        assert res, res
        task = json.loads(res.data)
        assert 'error' in task['info'], 'No anonymous contributors'

        # as a real user, no password
        url = '/api/project/%s/newtask?api_key=%s' % (project.id, user.api_key)
        res = self.app.get(url)
        assert res.status_code == 403, res
        task = json.loads(res.data)
        assert task['exception_msg'] == 'No project password provided'

        url = '/project/%s/password?api_key=%s' % (project.short_name,
                                                   user.api_key)
        data = dict(password='******')
        res = self.app.post(url, data=data)

        c, v, e = get_pwd_cookie(project.short_name, res)

        assert c
        self.app.set_cookie('/', c, v)

        url = '/api/project/%s/newtask?api_key=%s' % (project.id, user.api_key)
        res = self.app.get(url)
        assert res.status_code == 200, res
        task = json.loads(res.data)
        assert task['info'].get('question') == 'answer'
Exemple #39
0
    def test_project_update_two_info_objects(self):
        """Test Auditlog API project update two info objects works."""
        project = ProjectFactory.create()

        owner_id = project.owner.id
        owner_name = project.owner.name
        data = {'info': {'sched': 'depth_first', 'task_presenter': 'new'}}
        attributes = data['info'].keys()
        url = '/api/project/%s?api_key=%s' % (project.id, project.owner.api_key)
        self.app.put(url, data=json.dumps(data))
        logs = auditlog_repo.filter_by(project_id=project.id)

        assert len(logs) == 2, logs
        for log in logs:
            assert log.user_id == owner_id, log.user_id
            assert log.user_name == owner_name, log.user_name
            assert log.project_short_name == project.short_name, log.project_short_name
            assert log.action == 'update', log.action
            assert log.caller == 'api', log.caller
            assert log.attribute in attributes, log.attribute
            msg = "%s != %s" % (data['info'][log.attribute], log.new_value)
            assert data['info'][log.attribute] == log.new_value, msg
 def create_project_with_contributors(self,
                                      anonymous,
                                      registered,
                                      two_tasks=False,
                                      name='my_app',
                                      info={}):
     project = ProjectFactory.create(name=name, info=info)
     task = TaskFactory(project=project)
     if two_tasks:
         task2 = TaskFactory(project=project)
     for i in range(anonymous):
         task_run = AnonymousTaskRunFactory(task=task,
                                            user_ip='127.0.0.%s' % i)
         if two_tasks:
             task_run2 = AnonymousTaskRunFactory(task=task2,
                                                 user_ip='127.0.0.%s' % i)
     for i in range(registered):
         user = UserFactory.create()
         task_run = TaskRunFactory(task=task, user=user)
         if two_tasks:
             task_run2 = TaskRunFactory(task=task2, user=user)
     return project
    def test_task_update_state(self):
        """Test API task n_answers updates state properly."""
        user = UserFactory.create()
        project = ProjectFactory.create(owner=user)
        task = TaskFactory.create(project=project, n_answers=1,
                                  state='ongoing')
        data = {'n_answers': 2}
        datajson = json.dumps(data)

        url = '/api/task/%s?api_key=%s' % (task.id, user.api_key)
        res = self.app.put(url, data=datajson)
        out = json.loads(res.data)
        assert_equal(res.status, '200 OK', res.data)
        assert_equal(task.n_answers, data['n_answers'])
        assert_equal(task.state, 'ongoing')
        assert task.id == out['id'], out

        task.state = 'completed'
        task_repo.update(task)

        data = {'n_answers': 1}
        datajson = json.dumps(data)

        res = self.app.put(url, data=datajson)
        out = json.loads(res.data)
        assert_equal(res.status, '200 OK', res.data)
        assert_equal(task.n_answers, data['n_answers'])
        assert_equal(task.state, 'completed')
        assert task.id == out['id'], out

        data = {'n_answers': 5}
        datajson = json.dumps(data)

        res = self.app.put(url, data=datajson)
        out = json.loads(res.data)
        assert_equal(res.status, '200 OK', res.data)
        assert_equal(task.n_answers, data['n_answers'])
        assert_equal(task.state, 'ongoing')
        assert task.id == out['id'], out
Exemple #42
0
    def test_blogpost_update_by_owner(self, mock_redirect):
        """Test blogposts, project owners can update"""
        self.register()
        user = user_repo.get(1)
        project = ProjectFactory.create(owner=user)
        blogpost = BlogpostFactory.create(project=project)
        url = "/project/%s/%s/update" % (project.short_name, blogpost.id)

        res = self.app.get(url, follow_redirects=True)
        assert res.status_code == 200, res.status_code

        res = self.app.post(url,
                            data={'id': blogpost.id,
                                  'title':'blogpost title',
                                  'body':'new body'},
                            follow_redirects=True)
        assert res.status_code == 200, res.status_code
        mock_redirect.assert_called_with('/project/%E2%9C%93project1/blog')

        blogpost = blog_repo.get_by(title='blogpost title')
        assert blogpost.title == 'blogpost title', blogpost.title
        assert blogpost.body == 'new body', blogpost.body
Exemple #43
0
    def test_completedtask_completedtaskrun_with_params(self):
        """Test API query for completedtask and completedtaskrun with params works"""
        project = ProjectFactory.create()
        task = TaskFactory.create(project=project,
                                  n_answers=2,
                                  state='ongoing',
                                  exported=False)
        admin = UserFactory.create()
        # Test no completedtask yet
        url = '/api/completedtask?project_id=1&api_key=api-key1'
        res = self.app.get(url)
        data = json.loads(res.data)
        assert len(data) == 0, data

        # mark task as completed
        task_runs = TaskRunFactory.create_batch(2, task=task)
        task.state = 'completed'
        task_repo.update(task)

        #  test task is completed
        url = '/api/completedtask?project_id=1&api_key=api-key1'
        res = self.app.get(url)
        data = json.loads(res.data)

        # correct result
        assert data[0]['project_id'] == 1, data
        assert data[0]['state'] == u'completed', data

        # call completedtask but with wrong project_id
        url = '/api/completedtask?project_id=99999999&api_key=api-key1'
        res = self.app.get(url)
        data = json.loads(res.data)
        assert len(data) == 0, data

        # get completed task runs
        url = '/api/completedtaskrun?project_id=1&api_key=api-key1'
        res = self.app.get(url)
        data = json.loads(res.data)
        assert len(data) == 2, data
Exemple #44
0
    def create_auditlogs(self):
        project = ProjectFactory.create(
            info={
                'task_presenter':
                'version1',
                'task_guidelines':
                'version1',
                'data_classification':
                dict(input_data="L4 - public", output_data="L4 - public")
            })

        AuditlogFactory.create(project_id=project.id,
                               project_short_name=project.short_name,
                               user_id=project.owner.id,
                               user_name=project.owner.name,
                               attribute='task_presenter',
                               old_value="old_task_presenter1",
                               new_value="new_task_presenter2",
                               created='2019-01-11T15:24:42.263980')

        AuditlogFactory.create_batch(size=3,
                                     project_id=project.id,
                                     project_short_name=project.short_name,
                                     user_id=project.owner.id,
                                     user_name=project.owner.name,
                                     attribute='task_guidelines',
                                     old_value="old_task_guidelines1",
                                     new_value="new_task_guidelines2",
                                     created='2019-01-11T15:24:42.263980')

        AuditlogFactory.create_batch(size=3,
                                     project_id=project.id,
                                     project_short_name=project.short_name,
                                     user_id=project.owner.id,
                                     user_name=project.owner.name,
                                     attribute='task_guidelines',
                                     old_value="old_task_guidelines1",
                                     new_value="new_task_guidelines2",
                                     created='2020-01-11T15:24:42.263980')
 def test_update_delete_multiple_fields(self, delete):
     fields = {
         'hello': {
             'type': 'freetext',
             'config': {}
         },
         '你好': {
             'type': 'freetext',
             'config': {}
         },
         'ciao': {
             'type': 'freetext',
             'config': {}
         },
         'hola': {
             'type': 'freetext',
             'config': {}
         }
     }
     info = {'answer_fields': fields}
     project = ProjectFactory.create(published=True, info=info)
     url = '/project/%s/answerfieldsconfig?api_key=%s' % (
         project.short_name, project.owner.api_key)
     res = self.app_get_json(url)
     data = json.loads(res.data)
     csrf = data['csrf']
     fields.pop('hello')
     fields['Привет'] = {'type': 'freetext', 'config': {}}
     fields['hola']['type'] = 'categorical'
     res = self.app.post(url,
                         content_type='application/json',
                         data=json.dumps({'answer_fields': fields}),
                         headers={'X-CSRFToken': csrf})
     data = json.loads(res.data)
     assert delete.call_count == 2
     assert all(args[0] == project.id for args, _ in delete.call_args_list)
     deleted_fields = set(args[1] for args, _ in delete.call_args_list)
     assert deleted_fields == set(['hello', 'hola'])
Exemple #46
0
    def test_newtask_expired_cookie(self):
        """Test API project new_task expired cookie"""
        project = ProjectFactory.create(info={'timeout': 60})
        project.set_password('the_password')
        project_repo.save(project)
        TaskFactory.create_batch(2,
                                 project=project,
                                 info={'question': 'answer'})
        user = UserFactory.create()

        # simulate sending expired cookies
        with patch.dict(self.flask_app.config, {'PASSWD_COOKIE_TIMEOUT': -1}):
            url = '/project/%s/password?api_key=%s' % (project.short_name,
                                                       user.api_key)
            data = dict(password='******')
            res = self.app.post(url, data=data)

            c, v, e = get_pwd_cookie(project.short_name, res)

            assert c
            self.app.set_cookie('/', c, v)
            res = self.app.post(url, data=data)
            c, v, e = get_pwd_cookie(project.short_name, res)

            assert c

            url = '/project/%s/newtask?api_key=%s' % (project.short_name,
                                                      user.api_key)
            res = self.app.get(url)
            assert res.status_code == 302
            headers = {'Content-Type': 'application/json'}
            res = self.app.get(url, headers=headers)
            next_url = json.loads(res.data)['next']
            print next_url
            headers = {'Authorization': user.api_key}
            res = self.app.get(next_url, headers=headers)

            assert 'Enter the password to contribute to this project' in res.data, res.data
Exemple #47
0
    def test_taskrun_updates_task_state(self, guard, mock_request):
        """Test API TaskRun POST updates task state"""
        guard.return_value = mock_contributions_guard(True)
        project = ProjectFactory.create()
        task = TaskFactory.create(project=project, n_answers=2)
        url = '/api/taskrun?api_key=%s' % project.owner.api_key

        # Post first taskrun
        data = dict(project_id=task.project_id,
                    task_id=task.id,
                    user_id=project.owner.id,
                    info='my task result')
        datajson = json.dumps(data)
        mock_request.data = datajson

        tmp = self.app.post(url, data=datajson)
        r_taskrun = json.loads(tmp.data)

        assert tmp.status_code == 200, r_taskrun

        err_msg = "Task state should be different from completed"
        assert task.state == 'ongoing', err_msg

        # Post second taskrun
        mock_request.remote_addr = '127.0.0.0'
        admin = UserFactory.create()
        url = '/api/taskrun?api_key=%s' % admin.api_key
        data = dict(project_id=task.project_id,
                    task_id=task.id,
                    info='my task result anon')
        datajson = json.dumps(data)
        tmp = self.app.post(url, data=datajson)
        r_taskrun = json.loads(tmp.data)

        assert tmp.status_code == 200, r_taskrun
        assert r_taskrun['user_ip'] != '127.0.0.0', r_taskrun
        err_msg = "Task state should be equal to completed"
        assert task.state == 'completed', err_msg
Exemple #48
0
    def test_anonymous_03_respects_limit_tasks(self):
        """ Test SCHED newtask respects the limit of 10 TaskRuns per Task"""
        assigned_tasks = []
        project = ProjectFactory.create(owner=UserFactory.create(id=500),
                                        info=dict(sched='depth_first_all'))

        user = UserFactory.create()

        task = TaskFactory.create(project=project, n_answers=10)

        tasks = get_depth_first_all_task(project.id, user.id)
        assert len(tasks) == 1, len(tasks)
        assert tasks[0].id == task.id, tasks
        assert tasks[0].state == 'ongoing', tasks

        for i in range(10):
            tr = TaskRun(project_id=project.id,
                         task_id=task.id,
                         user_ip='127.0.0.%s' % i)
            db.session.add(tr)
            db.session.commit()

        tasks = get_depth_first_all_task(project.id, user.id)
        assert len(tasks) == 1, len(tasks)
        assert tasks[0].id == task.id, tasks
        assert tasks[0].state == 'completed', tasks

        for i in range(10):
            tasks = get_depth_first_all_task(project.id,
                                             user_id=None,
                                             user_ip='127.0.0.%s' % i)
            assert len(tasks) == 0, tasks

        tr = TaskRun(project_id=project.id, task_id=task.id, user_id=user.id)
        db.session.add(tr)
        db.session.commit()
        tasks = get_depth_first_all_task(project.id, user.id)
        assert len(tasks) == 0, tasks
    def test_orderby(self):
        """Test orderby."""
        project = ProjectFactory.create()
        task1 = TaskFactory.create(fav_user_ids=[1], project=project)
        task2 = TaskFactory.create(fav_user_ids=None, project=project)
        task3 = TaskFactory.create(fav_user_ids=[1, 2, 3], project=project)

        task = self.task_repo.filter_tasks_by(orderby='id',
                                              desc=True,
                                              project_id=project.id,
                                              limit=1)[0]
        assert task == task3, (task, task3)

        task = self.task_repo.filter_tasks_by(orderby='id',
                                              desc=False,
                                              project_id=project.id,
                                              limit=1)[0]
        assert task == task1, (task, task1)

        task = self.task_repo.filter_tasks_by(orderby='created',
                                              desc=True,
                                              project_id=project.id)[0]
        assert task == task3, (task.id, task3.id)

        task = self.task_repo.filter_tasks_by(orderby='created',
                                              desc=False,
                                              project_id=project.id)[0]
        assert task == task1, (task.created, task1.created)

        task = self.task_repo.filter_tasks_by(orderby='fav_user_ids',
                                              desc=True,
                                              project_id=project.id)[0][0]
        assert task == task3, (task.id, task3.id)

        task = self.task_repo.filter_tasks_by(orderby='fav_user_ids',
                                              desc=False,
                                              project_id=project.id)[0][0]
        assert task == task2, (task.fav_user_ids, task2.fav_user_ids)
    def test_project_contact_no_disabled_owner(self, enqueue):
        """Test Project Contact not emailing a disabled co-owner."""
        message = u'hello'

        admin, owner, user = UserFactory.create_batch(3)

        # Create a disabled user as a co-owner.
        coowner = UserFactory.create(name='My Disabled Co-Owner User',
                                     enabled=False,
                                     subadmin=True)

        # Create a project with a disabled co-owner.
        project = ProjectFactory.create(owner=owner,
                                        short_name='test-app',
                                        name='My New Project',
                                        owners_ids=[coowner.id])

        # Obtain a CSRF key.
        csrf = self.get_csrf('/account/signin')

        # Make a request to the api.
        url = '/project/' + project.short_name + '/contact?api_key=' + user.api_key
        data = dict(message=message)
        res = self.app.post(url,
                            headers={'X-CSRFToken': csrf},
                            content_type='application/json',
                            data=json.dumps(data))

        # Get contents of email.
        str_message = str(enqueue.call_args_list[0])

        # Verify recipient for project owner.
        recipients_index = str_message.find('recipients')
        assert recipients_index > -1
        assert str_message.find(owner.email_addr) > recipients_index

        # Verify no recipient for disabled co-owner.
        assert str_message.find(coowner.email_addr) == -1
Exemple #51
0
 def test_webhook_handler_auth(self):
     """Test WEBHOOK view works for authenticated not owner."""
     # Admin
     self.register()
     self.signout()
     # Owner
     self.register()
     self.signin()
     owner = user_repo.get(1)
     project = ProjectFactory.create(owner=owner)
     self.signout()
     # User
     self.register(name="juan")
     self.signin(email="*****@*****.**", password="******")
     url = "/project/%s/webhook" % project.short_name
     res = self.app.get(url)
     assert res.status_code == 403, res.status_code
     url = "/project/%s/webhook?all=true" % project.short_name
     res = self.app.get(url)
     assert res.status_code == 403, res.status_code
     url = "/project/%s/webhook?failed=true" % project.short_name
     res = self.app.get(url)
     assert res.status_code == 403, res.status_code
Exemple #52
0
    def test_blogpost_get_one_draft(self):
        """Test blogpost GET draft with id shows one blogpost"""
        user = self.create_users()[1]
        project = ProjectFactory.create(owner=user)
        blogpost = BlogpostFactory.create(project=project, title='title',
                                          published=False)
        url = "/project/%s/%s" % (project.short_name, blogpost.id)

        # As anonymous
        res = self.app.get(url, follow_redirects=True)
        assert res.status_code == 404, res.status_code

        # As authenticated
        self.register()
        res = self.app.get(url, follow_redirects=True)
        assert res.status_code == 404, res.status_code

        # As owner
        url = "/project/%s/%s?api_key=%s" % (project.short_name, blogpost.id,
                                             user.api_key)
        res = self.app.get(url, follow_redirects=True)
        assert res.status_code == 200, res.status_code
        assert 'title' in res.data
Exemple #53
0
    def test_blogpost_create_by_owner(self, mock_redirect):
        """Test blogposts, project owners can create"""
        self.register()
        user = user_repo.get(1)
        project = ProjectFactory.create(owner=user)
        url = "/project/%s/new-blogpost" % project.short_name

        res = self.app.get(url, follow_redirects=True)
        assert res.status_code == 200, res.status_code

        res = self.app.post(url,
                            data={
                                'title': 'blogpost title',
                                'body': 'body'
                            },
                            follow_redirects=True)
        assert res.status_code == 200, res.status_code
        mock_redirect.assert_called_with('/project/%E2%9C%93project1/blog')

        blogpost = blog_repo.get_by(title='blogpost title')
        assert blogpost.title == 'blogpost title', blogpost.title
        assert blogpost.project_id == project.id, blogpost.project.id
        assert blogpost.user_id == user.id, blogpost.user_id
    def test_query_projectstats_filter_project(self):
        owner = UserFactory.create()
        project1, project2 = ProjectFactory.create_batch(2, owner=owner)

        stats = PerformanceStatsFactory.create(user_id=owner.id,
                                               project_id=project1.id,
                                               info={'project': project1.id})
        stats = PerformanceStatsFactory.create(user_id=owner.id,
                                               project_id=project2.id,
                                               info={'project': project2.id})

        url = '/api/performancestats'
        res = self.app.get('{}?api_key={}&project_id={}'.format(
            url, owner.api_key, project1.id))
        data = json.loads(res.data)
        assert len(data) == 1
        assert data[0]['info']['project'] == project1.id

        res = self.app.get('{}?api_key={}&project_id={}'.format(
            url, owner.api_key, project2.id))
        data = json.loads(res.data)
        assert len(data) == 1
        assert data[0]['info']['project'] == project2.id
Exemple #55
0
    def test_blogpost_update_by_non_owner(self):
        """Test blogpost update by non owner of the project is forbidden"""
        self.register()
        self.signin()
        user = user_repo.get(1)
        project = ProjectFactory.create(owner=user)
        blogpost = BlogpostFactory.create(project=project, title='title', body='body')
        url = "/project/%s/new-blogpost" % project.short_name
        self.signout()
        self.register(name='notowner', email='*****@*****.**')
        self.signin(email='*****@*****.**', password='******')
        url = "/project/%s/%s/update" % (project.short_name, blogpost.id)

        res = self.app.get(url, follow_redirects=True)
        assert res.status_code == 403, res.status_code

        res = self.app.post(url,
                            data={'title':'new title', 'body':'body'},
                            follow_redirects=True)
        assert res.status_code == 403, res.status_code

        blogpost = blog_repo.get_by()
        assert blogpost.title == 'title', blogpost.title
    def test_query_projectstats_filter_user(self):
        owner, user = UserFactory.create_batch(2)
        project = ProjectFactory.create(owner=owner)

        stats = PerformanceStatsFactory.create(user_id=user.id,
                                               project_id=project.id,
                                               info={'user': user.id})
        stats = PerformanceStatsFactory.create(user_id=owner.id,
                                               project_id=project.id,
                                               info={'user': owner.id})

        url = '/api/performancestats'
        res = self.app.get('{}?api_key={}&user_id={}'.format(
            url, owner.api_key, user.id))
        data = json.loads(res.data)
        assert len(data) == 1
        assert data[0]['info']['user'] == user.id

        res = self.app.get('{}?api_key={}&user_id={}'.format(
            url, owner.api_key, owner.id))
        data = json.loads(res.data)
        assert len(data) == 1
        assert data[0]['info']['user'] == owner.id
Exemple #57
0
    def test_create_tasks_creates_them_correctly(self, importer_factory):
        mock_importer = Mock()
        mock_importer.tasks.return_value = [{
            'info': {
                'question': 'question',
                'url': 'url'
            },
            'n_answers': 20
        }]
        importer_factory.return_value = mock_importer
        project = ProjectFactory.create()
        form_data = dict(type='csv',
                         csv_url='http://fakecsv.com',
                         validate_tp=False)
        self.importer.create_tasks(task_repo, project, **form_data)
        task = task_repo.get_task(1)

        assert task is not None
        assert task.project_id == project.id, task.project_id
        assert task.n_answers == 20, task.n_answers
        assert task.info == {'question': 'question', 'url': 'url'}, task.info
        importer_factory.assert_called_with(**form_data)
        mock_importer.tasks.assert_called_with()
 def test_task_routing_2(self):
     '''
     task[0]: needs finance skill at least 0.8, should not be able to assign to the user
     task[1]: needs geography skill at least 0.5, should not be able to assign to the user
     task[3]: doesnt have filters, should be able to assign to the user
     '''
     user_info = dict(
         metadata={
             "profile": json.dumps({
                 "finance": 0.6,
                 "marketing": 0.4
             })
         })
     owner = UserFactory.create(id=500, info=user_info)
     user_repo.save(owner)
     project = ProjectFactory.create(owner=owner)
     project.info['sched'] = Schedulers.user_pref
     tasks = TaskFactory.create_batch(3, project=project, n_answers=10)
     tasks[0].worker_filter = {'finance': [0.8, '>=']}
     task_repo.save(tasks[0])
     tasks[1].worker_filter = {'geography': [0.5, '>=']}
     task_repo.save(tasks[1])
     assert n_available_tasks_for_user(project, 500) == 1
    def test_taskrun_post_requires_newtask_first_anonymous(self):
        """Test API TaskRun post fails if task was not previously requested for
        anonymous user"""
        project = ProjectFactory.create()
        task = TaskFactory.create(project=project)
        data = dict(project_id=project.id,
                    task_id=task.id,
                    info='my task result')
        datajson = json.dumps(data)
        fail = self.app.post('/api/taskrun', data=datajson)
        err = json.loads(fail.data)

        assert fail.status_code == 403, fail.status_code
        assert err['status'] == 'failed', err
        assert err['status_code'] == 403, err
        assert err['exception_msg'] == 'You must request a task first!', err
        assert err['exception_cls'] == 'Forbidden', err
        assert err['target'] == 'taskrun', err

        # Succeeds after requesting a task
        self.app.get('/api/project/%s/newtask' % project.id)
        success = self.app.post('/api/taskrun', data=datajson)
        assert success.status_code == 200, success.data
Exemple #60
0
    def test_get_locked_task(self):
        owner = UserFactory.create(id=500)
        project = ProjectFactory.create(owner=owner)
        project.info['sched'] = Schedulers.locked
        project_repo.save(project)

        task1 = TaskFactory.create(project=project, info='task 1', n_answers=2)
        task2 = TaskFactory.create(project=project, info='task 2', n_answers=2)

        t1 = get_locked_task(project.id, 11)
        t2 = get_locked_task(project.id, 1)
        assert t1[0].id == task1.id
        assert t2[0].id == task1.id
        t3 = get_locked_task(project.id, 2)
        t4 = get_locked_task(project.id, 3)
        assert t3[0].id == task2.id
        assert t4[0].id == task2.id

        t5 = get_locked_task(project.id, 11)
        assert t5[0].id == task1.id

        t6 = get_locked_task(project.id, 4)
        assert not t6