Beispiel #1
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
    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
    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
    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
Beispiel #5
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
Beispiel #6
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_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_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_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
Beispiel #10
0
    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_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_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
Beispiel #13
0
    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
Beispiel #14
0
    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_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_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
Beispiel #19
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_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
    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_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_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_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
Beispiel #25
0
    def test_published_projects_only_returns_published(self):
        """Test CACHE USERS published_projects does not return draft
        or another user's projects"""
        user = UserFactory.create()
        another_user_published_project = ProjectFactory.create(published=True)
        draft_project = ProjectFactory.create(owner=user, published=False)

        projects_published = cached_users.published_projects(user.id)

        assert len(projects_published) == 0, projects_published
Beispiel #26
0
    def test_draft_projects_only_returns_drafts(self):
        """Test CACHE USERS draft_projects does not return any pubished projects
        or drafts that belong to another user"""
        user = UserFactory.create()
        published_project = ProjectFactory.create(owner=user, published=True)
        other_users_draft_project = ProjectFactory.create(published=False)

        draft_projects = cached_users.draft_projects(user.id)

        assert len(draft_projects) == 0, draft_projects
    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_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
Beispiel #29
0
    def test_n_count_with_published_projects(self):
        """Test CACHE PROJECTS n_count returns the number of published projects
        of a given category"""
        project = ProjectFactory.create(published=True)
        ProjectFactory.create(published=True)
        ProjectFactory.create(category=project.category, published=False)

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

        assert n_projects == 1, n_projects
    def test_get_from_pro_user_projects(self):
        """Test CACHE PROJECTS get_from_pro_user returns list of projects with
        'pro' owners only"""
        pro_user = UserFactory.create(pro=True)
        ProjectFactory.create()
        pro_project = ProjectFactory.create(owner=pro_user)

        pro_owned_projects = cached_projects.get_from_pro_user()

        assert len(pro_owned_projects) is 1, len(pro_owned_projects)
        assert pro_owned_projects[0]['short_name'] == pro_project.short_name
Beispiel #31
0
    def test_sync_L2_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="L2 - propriertary valid",
            output_data="L2 - propriertary valid")
        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"]
Beispiel #32
0
 def test_trigger_fails_webhook_with_no_url(self, mock_post,
                                            mock_send_mail):
     """Test WEBHOOK fails and sends email is triggered when no URL or failed connection."""
     mock_post.side_effect = requests.exceptions.ConnectionError('Not URL')
     project = ProjectFactory.create(published=True)
     payload = dict(
         event='task_completed',
         project_short_name=project.short_name,
         project_id=project.id,
         task_id=1,
         result_id=1,
         fired_at=datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S"))
     wbh = WebhookFactory.create()
     tmp = webhook(None, payload=payload, oid=wbh.id)
     headers = {'Content-type': 'application/json', 'Accept': 'text/plain'}
     #mock_post.assert_called_with('url', data=json.dumps(payload), headers=headers)
     subject = "Broken: %s webhook failed" % project.name
     body = 'Sorry, but the webhook failed'
     mail_dict = dict(recipients=self.flask_app.config.get('ADMINS'),
                      subject=subject,
                      body=body,
                      html=tmp.response)
     mock_send_mail.assert_called_with(mail_dict)
Beispiel #33
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 str(res.data)
    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
Beispiel #35
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
Beispiel #36
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
Beispiel #37
0
    def test_get_active_users_lock(self):
        """ Test number of locked tasks"""
        user = UserFactory.create(id=500)
        project = ProjectFactory.create(owner=user, info={'sched': 'default'})
        TaskFactory.create_batch(2, project=project, n_answers=2)

        # Register the active user as a locked task.
        register_active_user(project.id, user.id, sentinel.master)
        # Verify the count of locked tasks for this project equals 1.
        count = get_active_user_count(project.id, sentinel.master)
        assert count == 1

        # Unregister the active user as a locked task.
        unregister_active_user(project.id, user.id, sentinel.master)
        # Verify the count of locked tasks for this project equals 1.
        # There is a delay before the lock is released.
        count = get_active_user_count(project.id, sentinel.master)
        assert count == 1

        # Confirm lock released after a delay.
        time.sleep(EXPIRE_LOCK_DELAY + 1)
        count = get_active_user_count(project.id, sentinel.master)
        assert not count
 def test_update_add_field_does_not_delete_stats(self, delete):
     fields = {
         'hello': {
             'type': 'categorical',
             'config': {
                 'labels': ['A', 'B', 'C']
             }
         }
     }
     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['bye'] = {'config': {}, 'type': 'freetext'}
     res = self.app.post(url,
                         content_type='application/json',
                         data=json.dumps(info),
                         headers={'X-CSRFToken': csrf})
     data = json.loads(res.data)
     delete.assert_not_called()
Beispiel #39
0
    def test_warn_project_owner(self, mail):
        """Test JOB email is sent to warn project owner."""
        # Mock for the send method
        send_mock = MagicMock()
        send_mock.send.return_value = True
        # Mock for the connection method
        connection = MagicMock()
        connection.__enter__.return_value = send_mock
        # Join them
        mail.connect.return_value = connection

        date = '2010-10-22T11:02:00.000000'
        project = ProjectFactory.create(updated=date)
        project_id = project.id
        warn_old_project_owners()
        err_msg = "mail.connect() should be called"
        assert mail.connect.called, err_msg
        err_msg = "conn.send() should be called"
        assert send_mock.send.called, err_msg
        err_msg = "project.contacted field should be True"
        assert project.contacted, err_msg
        err_msg = "The update date should be different"
        assert project.updated != date, err_msg
Beispiel #40
0
    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
Beispiel #41
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
Beispiel #42
0
 def test_ensure_task_assignment_to_project(self):
     project = ProjectFactory.create(info={})
     task = TaskFactory.create(info={})
     patched_levels = self.patched_levels(
         valid_project_levels_for_task_level={'A': ['A']},
         valid_task_levels_for_project_level={'A': ['A']}
     )
     with patch.dict(data_access.data_access_levels, patched_levels):
         with assert_raises(Exception):
             data_access.ensure_task_assignment_to_project(task, project)
         project.info['data_access'] = ['A']
         with assert_raises(Exception):
             data_access.ensure_task_assignment_to_project(task, project)
         project.info['data_access'] = []
         task.info['data_access'] = ['A']
         with assert_raises(Exception):
             data_access.ensure_task_assignment_to_project(task, project)
         project.info['data_access'] = ['A', 'B']
         task.info['data_access'] = ['A']
         with assert_raises(Exception):
             data_access.ensure_task_assignment_to_project(task, project)
         project.info['ext_config'] = {'data_access': {'tracking_id': '123'}}
         data_access.ensure_task_assignment_to_project(task, project)
    def test_org_revoke_invitation(self):
        user_a = UserFactory.create(email="*****@*****.**")
        user_b = UserFactory.create(email="*****@*****.**", full_name="User B")
        org = create_sample_organization(user_a,
                                         org_kwargs={
                                             'name': u"My first org",
                                         })
        project = ProjectFactory.create(name=u"my project", org=org)
        org.add_user(user_b)
        project.add_user(user_b)
        self.assertTrue(project.can_read(user_b))

        url = reverse("dashboard")
        response = self.app.get(url, user=user_b)
        self.assertContains(response, u"My first org")

        auth = AuthorizationAssociation.objects.get(org=org, user=user_b)

        url = reverse("org_auth_delete", args=(org.pk, auth.pk))
        self.app.get(url, user=user_b, status=403)
        response = self.app.get(url, user=user_a)
        self.assertContains(
            response, u"Are you sure you want to revoke "
            u"'User B' from the organization "
            u"'My first org'")
        form = response.forms['delete_form']
        response = form.submit().follow()
        self.assertContains(
            response,
            'User {0} has been revoked.'.format(user_b.email),
        )
        url = reverse("dashboard")
        response = self.app.get(url, user=user_b)
        self.assertNotContains(response, u"My first org")
        # ensure we revoked the rights for project too
        project = Project.objects.get(pk=project.pk)
        self.assertFalse(project.can_read(user_b))
Beispiel #44
0
    def test_taskrun_multipart(self, set_content):
        with patch.dict(self.flask_app.config, self.patch_config):
            project = ProjectFactory.create()
            task = TaskFactory.create(project=project)
            self.app.get('/api/project/%s/newtask?api_key=%s' %
                         (project.id, project.owner.api_key))

            data = dict(project_id=project.id,
                        task_id=task.id,
                        info={'field': 'value'})
            datajson = json.dumps(data)

            form = {
                'request_json': datajson,
                'test__upload_url': (StringIO('Hi there'), 'hello.txt')
            }

            url = '/api/taskrun?api_key=%s' % project.owner.api_key
            success = self.app.post(url,
                                    content_type='multipart/form-data',
                                    data=form)

            assert success.status_code == 200, success.data
            set_content.assert_called()
            res = json.loads(success.data)
            url = res['info']['pyb_answer_url']
            args = {
                'host': self.host,
                'bucket': self.bucket,
                'project_id': project.id,
                'task_id': task.id,
                'user_id': project.owner.id,
                'filename': 'pyb_answer.json'
            }
            expected = 'https://{host}/{bucket}/{project_id}/{task_id}/{user_id}/{filename}'.format(
                **args)
            assert url == expected, url
    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
        err_msg = "Task state should be equal to completed"
        assert task.state == 'completed', err_msg
Beispiel #46
0
    def test_task_priority_limit(self):
        """Test SCHED respects priority_0 field with limit"""
        project = ProjectFactory.create(info=dict(sched='depth_first_all'),
                                        owner=UserFactory.create(id=500))

        TaskFactory.create_batch(10, project=project)

        # Register
        self.register()
        self.signin()

        # By default, tasks without priority should be ordered by task.id (FIFO)
        tasks = db.session.query(Task).filter_by(
            project_id=project.id).order_by('id').all()
        url = 'api/project/%s/newtask?limit=2' % project.id
        self.set_proj_passwd_cookie(project, username='******')
        res = self.app.get(url)
        tasks1 = json.loads(res.data)
        # Check that we received a Task
        err_msg = "Task.id should be the same"
        assert tasks1[0].get('id') == tasks[0].id, err_msg

        # Now let's change the priority to a random task
        import random
        t = random.choice(tasks)
        # Increase priority to maximum
        t.priority_0 = 1
        db.session.add(t)
        db.session.commit()
        # Request again a new task
        res = self.app.get(url + '&orderby=priority_0&desc=true')
        tasks1 = json.loads(res.data)
        # Check that we received a Task
        err_msg = "Task.id should be the same"
        assert tasks1[0].get('id') == t.id, (err_msg, tasks1[0])
        err_msg = "Task.priority_0 should be the 1"
        assert tasks1[0].get('priority_0') == 1, err_msg
Beispiel #47
0
    def test_newtask(self):
        """Test API project new_task method and authentication"""
        project = ProjectFactory.create()
        TaskFactory.create_batch(2, project=project)
        user = UserFactory.create()

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

        # The output should have a mime-type: application/json
        assert res.mimetype == 'application/json', res

        # as a real user
        url = '/api/project/%s/newtask?api_key=%s' % (project.id, user.api_key)
        res = self.app.get(url)
        assert res, res
        task = json.loads(res.data)
        assert_equal(task['project_id'], project.id)

        # Get NotFound for an non-existing project
        url = '/api/project/5000/newtask'
        res = self.app.get(url)
        err = json.loads(res.data)
        err_msg = "The project does not exist"
        assert err['status'] == 'failed', err_msg
        assert err['status_code'] == 404, err
        assert err['exception_cls'] == 'NotFound', err_msg
        assert err['target'] == 'project', err_msg

        # Get an empty task
        url = '/api/project/%s/newtask?offset=1000' % project.id
        res = self.app.get(url)
        assert res.data == '{}', res.data
    def test_taskrun_post_with_bad_data(self):
        """Test API TaskRun error messages."""
        project = ProjectFactory.create()
        task = TaskFactory.create(project=project)
        project_id = project.id
        task_run = dict(project_id=project.id,
                        task_id=task.id,
                        info='my task result')
        url = '/api/taskrun?api_key=%s' % project.owner.api_key

        # POST with not JSON data
        res = self.app.post(url, data=task_run)
        err = json.loads(res.data)
        assert res.status_code == 415, err
        assert err['status'] == 'failed', err
        assert err['target'] == 'taskrun', err
        assert err['action'] == 'POST', err
        assert err['exception_cls'] == 'ValueError', err

        # POST with not allowed args
        res = self.app.post(url + '&foo=bar', data=task_run)
        err = json.loads(res.data)
        assert res.status_code == 415, err
        assert err['status'] == 'failed', err
        assert err['target'] == 'taskrun', err
        assert err['action'] == 'POST', err
        assert err['exception_cls'] == 'AttributeError', err

        # POST with fake data
        task_run['wrongfield'] = 13
        res = self.app.post(url, data=json.dumps(task_run))
        err = json.loads(res.data)
        assert res.status_code == 415, err
        assert err['status'] == 'failed', err
        assert err['target'] == 'taskrun', err
        assert err['action'] == 'POST', err
        assert err['exception_cls'] == 'TypeError', err
Beispiel #49
0
 def test_project_update_attributes(self):
     """Test Auditlog API project update attributes works."""
     project = ProjectFactory.create(
         info=dict(list=[0],
                   data_classification=dict(input_data="L4 - public",
                                            output_data="L4 - public")))
     data = {
         'name': 'New Name',
         'short_name': project.short_name,
         'description': 'new_description',
         'long_description': 'new_long_description',
         'allow_anonymous_contributors': False,
         'info': {
             u'list': [1]
         }
     }
     attributes = data.keys()
     attributes.append('list')
     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) == 5, (len(logs), logs)
     for log in logs:
         assert log.user_id == project.owner_id, log.user_id
         assert log.user_name == project.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, attributes)
         if log.attribute != 'list':
             msg = "%s != %s" % (data[log.attribute], log.new_value)
             assert unicode(data[log.attribute]) == log.new_value, msg
         else:
             msg = "%s != %s" % (data['info'][log.attribute], log.new_value)
             assert data['info'][log.attribute] == json.loads(
                 log.new_value), msg
Beispiel #50
0
    def test_enrich_task_requires_enrichment_config(self, mock_del,
                                                    upload_from_string,
                                                    importer_factory):
        mock_importer = Mock()
        mock_importer.tasks.return_value = [{
            'info': {
                u'Foo': u'a'
            },
            'private_fields': {
                u'Bar2': u'd',
                u'Bar': u'c'
            },
            'gold_answers': {
                u'ans2': u'e',
                u'ans': u'b'
            },
            'calibration': 1,
            'exported': True,
            'state': u'enrich'
        }]

        importer_factory.return_value = mock_importer
        project = ProjectFactory.create()
        form_data = dict(type='localCSV',
                         csv_filename='fakefile.csv',
                         validate_tp=False)

        with patch.dict(
                self.flask_app.config, {
                    'S3_REQUEST_BUCKET': 'mybucket',
                    'S3_CONN_TYPE': 'dev',
                    'ENABLE_ENCRYPTION': True
                }):
            import_report = self.importer.create_tasks(task_repo, project,
                                                       **form_data)
            print import_report.message
            assert 'task import failed' in import_report.message
Beispiel #51
0
    def test_newtask_default_orderby(self):
        """Test SCHED depth first works with orderby."""
        project = ProjectFactory.create(info=dict(sched="depth_first"))
        task1 = TaskFactory.create(project=project, fav_user_ids=None)
        task2 = TaskFactory.create(project=project, fav_user_ids=[1,2,3])
        api_key = project.owner.api_key

        url = "/api/project/%s/newtask?orderby=%s&desc=%s&api_key=%s" % (project.id, 'id', False, api_key)
        res = self.app.get(url)
        data = json.loads(res.data)
        assert data['id'] == task1.id, data

        url = "/api/project/%s/newtask?orderby=%s&desc=%s&api_key=%s" % (project.id, 'id', True, api_key)
        res = self.app.get(url)
        data = json.loads(res.data)
        assert data['id'] == task2.id, data

        url = "/api/project/%s/newtask?orderby=%s&desc=%s&api_key=%s" % (project.id, 'created', False, api_key)
        res = self.app.get(url)
        data = json.loads(res.data)
        assert data['id'] == task1.id, data

        url = "/api/project/%s/newtask?orderby=%s&desc=%s&api_key=%s" % (project.id, 'created', True, api_key)
        res = self.app.get(url)
        data = json.loads(res.data)
        assert data['id'] == task2.id, data

        url = "/api/project/%s/newtask?orderby=%s&desc=%s&api_key=%s" % (project.id, 'fav_user_ids', False, api_key)
        res = self.app.get(url)
        data = json.loads(res.data)
        assert data['id'] == task1.id, data

        url = "/api/project/%s/newtask?orderby=%s&desc=%s&api_key=%s" % (project.id, 'fav_user_ids', True, api_key)
        res = self.app.get(url)
        data = json.loads(res.data)
        assert data['id'] == task2.id, data
        assert data['fav_user_ids'] == task2.fav_user_ids, data
Beispiel #52
0
    def test_counter_table_api(self):
        """Test API Counter table is updated accordingly via api."""
        project = ProjectFactory.create()

        task = dict(project_id=project.id, info=dict(foo=1))

        url = '/api/task?api_key=%s' % project.owner.api_key

        res = self.app.post(url, data=json.dumps(task))

        data = json.loads(res.data)

        assert data.get('id') is not None, res.data

        items = db.session.query(Counter).filter_by(
            project_id=project.id).all()
        assert len(items) == 1
        items = db.session.query(Counter).filter_by(
            task_id=data.get('id')).all()
        assert len(items) == 1
        assert items[0].task_id == data.get('id')

        for i in range(9):
            res = self.app.post(url, data=json.dumps(task))
            created_task = json.loads(res.data)
        items = db.session.query(Counter).filter_by(
            project_id=project.id).all()
        assert len(items) == 10, len(items)

        res = self.app.delete('/api/task/%s?api_key=%s' %
                              (created_task['id'], project.owner.api_key))
        items = db.session.query(Counter).filter_by(
            project_id=project.id).all()
        assert len(items) == 9
        items = db.session.query(Counter).filter_by(
            task_id=created_task.get('id')).all()
        assert len(items) == 0
Beispiel #53
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
Beispiel #54
0
    def test_get_query_with_api_key_and_all(self):
        """ Test API GET query with an API-KEY requesting all results"""
        users = UserFactory.create_batch(3)
        project = ProjectFactory.create(owner=users[0], info={'total': 150})
        task = TaskFactory.create(project=project, info={'url': 'my url'})
        taskrun = TaskRunFactory.create(task=task,
                                        user=users[0],
                                        info={'answer': 'annakarenina'})
        for endpoint in self.endpoints:
            url = '/api/' + endpoint + '?api_key=' + users[1].api_key + '&all=1'
            res = self.app.get(url)
            data = json.loads(res.data)

            if endpoint == 'project':
                assert len(data) == 1, data
                project = data[0]
                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['info']['url'] == 'my url', data
                assert res.mimetype == 'application/json', res

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

            if endpoint == 'user':
                assert len(data) == 3, data
                user = data[0]
                assert user['name'] == 'user1', data
                assert res.mimetype == 'application/json', res
Beispiel #55
0
    def test_project_contact_no_non_admin_subadmin_owner(self, enqueue):
        """Test Project Contact not emailing a co-owner who is not an admin nor subadmin."""
        message = u'hello'

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

        # Create a user as a co-owner that is not an admin nor subadmin.
        coowner = UserFactory.create(name='My Non-Admin-Subadmin User')

        # 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 co-owner that is not an admin nor subadmin.
        assert str_message.find(coowner.email_addr) == -1
Beispiel #56
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
    def test_update_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': 'B'})
        stat = PerformanceStatsFactory.create(
            user_id=task_run.user_id,
            project_id=project.id,
            field='hello',
            info={'matrix': [[1, 4], [2, 3]]})

        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, 5], [2, 3]]
Beispiel #58
0
    def test_user_01_newtask(self):
        """ Test SCHED newtask returns a Task for John Doe User"""
        project = ProjectFactory.create(owner=UserFactory.create(id=500))
        TaskFactory.create_batch(2, project=project, n_answers=2)

        # Register
        self.register()
        self.signin()
        url = 'api/project/%s/newtask' % project.id
        self.set_proj_passwd_cookie(project, username='******')
        res = self.app.get(url)
        data = json.loads(res.data)
        task_id = data['id']
        assert data['id'], data

        taskrun = dict(project_id=data['project_id'], task_id=data['id'], info="hola")
        res = self.app.post('api/taskrun', data=json.dumps(taskrun))

        res = self.app.get(url)
        data = json.loads(res.data)
        assert data['id'], data
        assert data['id'] != task_id, data

        self.signout()
Beispiel #59
0
    def test_no_more_tasks(self):
        """Test that a users gets always tasks"""
        owner = UserFactory.create()
        project = ProjectFactory.create(owner=owner, short_name='egil', name='egil',
                  description='egil')

        project_id = project.id

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

        for t in tasks[0:10]:
            TaskRunFactory.create_batch(10, task=t, project=project)

        tasks = db.session.query(Task).filter_by(project_id=project.id, state='ongoing').all()
        assert tasks[0].n_answers == 10

        url = 'api/project/%s/newtask?api_key=%s' % (project.id, owner.api_key)
        res = self.app.get(url)
        data = json.loads(res.data)

        err_msg = "User should get a task"
        assert 'project_id' in data.keys(), err_msg
        assert data['project_id'] == project_id, err_msg
        assert data['id'] == tasks[0].id, err_msg
Beispiel #60
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'