Esempio n. 1
0
 def test_new_draft_registration_on_registration(self):
     target = RegistrationFactory(user=self.user)
     payload = {
         'schema_name': self.meta_schema.name,
         'schema_version': self.meta_schema.schema_version
     }
     url = target.web_url_for('new_draft_registration')
     res = self.app.post(url, payload, auth=self.user.auth, expect_errors=True)
     assert_equal(res.status_code, http.FORBIDDEN)
Esempio n. 2
0
 def test_new_draft_registration_on_registration(self):
     target = RegistrationFactory(user=self.user)
     payload = {
         'schema_name': self.meta_schema.name,
         'schema_version': self.meta_schema.schema_version
     }
     url = target.web_url_for('new_draft_registration')
     res = self.app.post(url, payload, auth=self.user.auth, expect_errors=True)
     assert_equal(res.status_code, http.FORBIDDEN)
Esempio n. 3
0
 def test_is_public_node_register_page(self):
     self.node.is_public = True
     self.node.save()
     reg = RegistrationFactory(project=self.node)
     reg.is_public = True
     reg.save()
     url = reg.web_url_for('node_register_page')
     res = self.app.get(url, auth=None)
     assert_equal(res.status_code, http.OK)
Esempio n. 4
0
 def test_is_public_node_register_page(self):
     self.node.is_public = True
     self.node.save()
     reg = RegistrationFactory(project=self.node)
     reg.is_public = True
     reg.save()
     url = reg.web_url_for('node_register_page')
     res = self.app.get(url, auth=None)
     assert_equal(res.status_code, http.OK)
Esempio n. 5
0
 def test_non_admin_can_view_node_register_page(self):
     non_admin = AuthUserFactory()
     self.node.add_contributor(non_admin,
                               permissions.DEFAULT_CONTRIBUTOR_PERMISSIONS,
                               auth=self.auth,
                               save=True)
     reg = RegistrationFactory(project=self.node)
     url = reg.web_url_for('node_register_page')
     res = self.app.get(url, auth=non_admin.auth)
     assert_equal(res.status_code, http.OK)
Esempio n. 6
0
 def test_non_admin_can_view_node_register_page(self):
     non_admin = AuthUserFactory()
     self.node.add_contributor(
         non_admin,
         permissions.DEFAULT_CONTRIBUTOR_PERMISSIONS,
         auth=self.auth,
         save=True
     )
     reg = RegistrationFactory(project=self.node)
     url = reg.web_url_for('node_register_page')
     res = self.app.get(url, auth=non_admin.auth)
     assert_equal(res.status_code, http.OK)
    def test_GET_disapprove_with_valid_token_returns_redirect_to_parent(self):
        project = ProjectFactory(creator=self.user)
        registration = RegistrationFactory(project=project)
        registration.embargo_registration(self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10))
        registration.save()
        assert_true(registration.is_pending_embargo)

        rejection_token = registration.embargo.approval_state[self.user._id]["rejection_token"]
        res = self.app.get(registration.web_url_for("view_project", token=rejection_token), auth=self.user.auth)
        registration.embargo.reload()
        assert_equal(registration.embargo.state, Embargo.REJECTED)
        assert_false(registration.is_pending_embargo)
        assert_equal(res.status_code, 302)
Esempio n. 8
0
    def test_GET_disapprove_with_valid_token_returns_redirect_to_parent(self):
        project = ProjectFactory(creator=self.user)
        registration = RegistrationFactory(project=project)
        registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10))
        registration.save()
        assert_true(registration.is_pending_embargo)

        rejection_token = registration.embargo.approval_state[
            self.user._id]['rejection_token']
        res = self.app.get(
            registration.web_url_for('view_project', token=rejection_token),
            auth=self.user.auth,
        )
        registration.embargo.reload()
        assert_equal(registration.embargo.state, Embargo.REJECTED)
        assert_false(registration.is_pending_embargo)
        assert_equal(res.status_code, 302)
    def test_GET_disapprove_with_valid_token_returns_redirect_to_parent(self):
        project = ProjectFactory(creator=self.user)
        registration = RegistrationFactory(project=project)
        registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        registration.save()
        assert_true(registration.pending_embargo)

        disapproval_token = registration.embargo.approval_state[self.user._id]['disapproval_token']
        res = self.app.get(
            registration.web_url_for('node_registration_embargo_disapprove', token=disapproval_token),
            auth=self.user.auth,
        )
        registration.embargo.reload()
        assert_equal(registration.embargo.state, Embargo.CANCELLED)
        assert_false(registration.embargo_end_date)
        assert_false(registration.pending_embargo)
        assert_equal(res.status_code, 302)
        assert_true(project._id in res.location)
Esempio n. 10
0
class RegistrationEmbargoViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationEmbargoViewsTestCase, self).setUp()
        ensure_schemas()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user)
        self.registration = RegistrationFactory(project=self.project,
                                                creator=self.user)

        current_month = datetime.datetime.now().strftime("%B")
        current_year = datetime.datetime.now().strftime("%Y")

        self.valid_make_public_payload = json.dumps({
            u'embargoEndDate':
            u'Fri, 01, {month} {year} 00:00:00 GMT'.format(month=current_month,
                                                           year=current_year),
            u'registrationChoice':
            'immediate',
            u'summary':
            unicode(fake.sentence())
        })
        valid_date = datetime.datetime.now() + datetime.timedelta(days=180)
        self.valid_embargo_payload = json.dumps({
            u'embargoEndDate':
            unicode(valid_date.strftime('%a, %d, %B %Y %H:%M:%S')) + u' GMT',
            u'registrationChoice':
            'embargo',
            u'summary':
            unicode(fake.sentence())
        })
        self.invalid_embargo_date_payload = json.dumps({
            u'embargoEndDate':
            u"Thu, 01 {month} {year} 05:00:00 GMT".format(
                month=current_month, year=str(int(current_year) - 1)),
            u'registrationChoice':
            'embargo',
            u'summary':
            unicode(fake.sentence())
        })

    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_POST_register_make_public_immediately_creates_registration_approval(
            self, mock_enqueue):
        res = self.app.post(self.project.api_url_for(
            'node_register_template_page_post',
            template=u'Open-Ended_Registration'),
                            self.valid_make_public_payload,
                            content_type='application/json',
                            auth=self.user.auth)
        assert_equal(res.status_code, 201)

        registration = Node.find().sort('-registered_date')[0]

        assert_true(registration.is_registration)
        assert_not_equal(registration.registration_approval, None)

    # Regression test for https://openscience.atlassian.net/browse/OSF-5039
    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_POST_register_make_public_immediately_creates_private_pending_registration_for_public_project(
            self, mock_enqueue):
        public_project = ProjectFactory(is_public=True, creator=self.user)
        component = NodeFactory(creator=self.user,
                                parent=public_project,
                                title='Component',
                                is_public=True)
        subproject = ProjectFactory(creator=self.user,
                                    parent=public_project,
                                    title='Subproject',
                                    is_public=True)
        subproject_component = NodeFactory(creator=self.user,
                                           parent=subproject,
                                           title='Subcomponent',
                                           is_public=True)
        res = self.app.post(public_project.api_url_for(
            'node_register_template_page_post',
            template=u'Open-Ended_Registration'),
                            self.valid_make_public_payload,
                            content_type='application/json',
                            auth=self.user.auth)
        public_project.reload()
        assert_equal(res.status_code, 201)

        # Last node directly registered from self.project
        registration = Node.load(public_project.node__registrations[-1])

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)

    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_POST_register_make_public_does_not_make_children_public(
            self, mock_enqueue):
        component = NodeFactory(creator=self.user,
                                parent=self.project,
                                title='Component')
        subproject = ProjectFactory(creator=self.user,
                                    parent=self.project,
                                    title='Subproject')
        subproject_component = NodeFactory(creator=self.user,
                                           parent=subproject,
                                           title='Subcomponent')

        res = self.app.post(self.project.api_url_for(
            'node_register_template_page_post',
            template=u'Open-Ended_Registration'),
                            self.valid_make_public_payload,
                            content_type='application/json',
                            auth=self.user.auth)
        self.project.reload()
        # Last node directly registered from self.project
        registration = Node.load(self.project.node__registrations[-1])
        assert_false(registration.is_public)
        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)

    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_POST_register_embargo_is_not_public(self, mock_enqueue):
        res = self.app.post(self.project.api_url_for(
            'node_register_template_page_post',
            template=u'Open-Ended_Registration'),
                            self.valid_embargo_payload,
                            content_type='application/json',
                            auth=self.user.auth)

        assert_equal(res.status_code, 201)

        registration = Node.find().sort('-registered_date')[0]

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        assert_true(registration.is_pending_embargo_for_existing_registration)
        assert_is_not_none(registration.embargo)

    # Regression test for https://openscience.atlassian.net/browse/OSF-5071
    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_POST_register_embargo_does_not_make_project_or_children_public(
            self, mock_enqueue):
        public_project = ProjectFactory(creator=self.user, is_public=True)
        component = NodeFactory(creator=self.user,
                                parent=public_project,
                                title='Component',
                                is_public=True)
        subproject = ProjectFactory(creator=self.user,
                                    parent=public_project,
                                    title='Subproject',
                                    is_public=True)
        subproject_component = NodeFactory(creator=self.user,
                                           parent=subproject,
                                           title='Subcomponent',
                                           is_public=True)
        res = self.app.post(public_project.api_url_for(
            'node_register_template_page_post',
            template=u'Open-Ended_Registration'),
                            self.valid_embargo_payload,
                            content_type='application/json',
                            auth=self.user.auth)
        public_project.reload()
        assert_equal(res.status_code, 201)

        # Last node directly registered from self.project
        registration = Node.load(public_project.node__registrations[-1])

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        assert_true(registration.is_pending_embargo_for_existing_registration)
        assert_is_not_none(registration.embargo)

        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)

    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_POST_invalid_embargo_end_date_returns_HTTPBad_Request(
            self, mock_enqueue):
        res = self.app.post(self.project.api_url_for(
            'node_register_template_page_post',
            template=u'Open-Ended_Registration'),
                            self.invalid_embargo_date_payload,
                            content_type='application/json',
                            auth=self.user.auth,
                            expect_errors=True)

        assert_equal(res.status_code, 400)

    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_valid_POST_embargo_adds_to_parent_projects_log(
            self, mock_enquque):
        initial_project_logs = len(self.project.logs)
        res = self.app.post(self.project.api_url_for(
            'node_register_template_page_post',
            template=u'Open-Ended_Registration'),
                            self.valid_embargo_payload,
                            content_type='application/json',
                            auth=self.user.auth)
        self.project.reload()
        # Logs: Created, registered, embargo initiated
        assert_equal(len(self.project.logs), initial_project_logs + 1)

    def test_non_contributor_GET_approval_returns_HTTPError(self):
        non_contributor = AuthUserFactory()
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        approval_token = self.registration.embargo.approval_state[
            self.user._id]['approval_token']
        approval_url = self.registration.web_url_for('view_project',
                                                     token=approval_token)

        res = self.app.get(approval_url,
                           auth=non_contributor.auth,
                           expect_errors=True)
        assert_equal(http.FORBIDDEN, res.status_code)
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)

    def test_non_contributor_GET_disapproval_returns_HTTPError(self):
        non_contributor = AuthUserFactory()
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        rejection_token = self.registration.embargo.approval_state[
            self.user._id]['rejection_token']
        approval_url = self.registration.web_url_for('view_project',
                                                     token=rejection_token)

        res = self.app.get(approval_url,
                           auth=non_contributor.auth,
                           expect_errors=True)
        assert_equal(http.FORBIDDEN, res.status_code)
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)
Esempio n. 11
0
class RegistrationEmbargoApprovalDisapprovalViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationEmbargoApprovalDisapprovalViewsTestCase,
              self).setUp()
        self.user = AuthUserFactory()
        self.registration = RegistrationFactory(creator=self.user)

    # node_registration_embargo_approve tests
    def test_GET_from_unauthorized_user_raises_HTTPForbidden(self):
        unauthorized_user = AuthUserFactory()
        res = self.app.get(self.registration.web_url_for('view_project',
                                                         token=DUMMY_TOKEN),
                           auth=unauthorized_user.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_GET_approve_registration_without_embargo_raises_HTTPBad_Request(
            self):
        assert_false(self.registration.is_pending_embargo)
        res = self.app.get(self.registration.web_url_for('view_project',
                                                         token=DUMMY_TOKEN),
                           auth=self.user.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_GET_approve_with_invalid_token_returns_HTTPBad_Request(self):
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        res = self.app.get(self.registration.web_url_for('view_project',
                                                         token=DUMMY_TOKEN),
                           auth=self.user.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_GET_approve_with_wrong_token_returns_HTTPBad_Request(self):
        admin2 = UserFactory()
        self.registration.contributors.append(admin2)
        self.registration.add_permission(admin2, 'admin', save=True)
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        wrong_approval_token = self.registration.embargo.approval_state[
            admin2._id]['approval_token']
        res = self.app.get(self.registration.web_url_for(
            'view_project', token=wrong_approval_token),
                           auth=self.user.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_GET_approve_with_wrong_admins_token_returns_HTTPBad_Request(self):
        admin2 = UserFactory()
        self.registration.contributors.append(admin2)
        self.registration.add_permission(admin2, 'admin', save=True)
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        wrong_approval_token = self.registration.embargo.approval_state[
            admin2._id]['approval_token']
        res = self.app.get(self.registration.web_url_for(
            'view_project', token=wrong_approval_token),
                           auth=self.user.auth,
                           expect_errors=True)
        assert_true(self.registration.is_pending_embargo)
        assert_equal(res.status_code, 400)

    @mock.patch('flask.redirect')
    def test_GET_approve_with_valid_token_redirects(self, mock_redirect):
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        approval_token = self.registration.embargo.approval_state[
            self.user._id]['approval_token']
        self.app.get(
            self.registration.web_url_for('view_project',
                                          token=approval_token),
            auth=self.user.auth,
        )
        self.registration.embargo.reload()
        assert_true(self.registration.embargo_end_date)
        assert_false(self.registration.is_pending_embargo)
        assert_true(
            mock_redirect.called_with(
                self.registration.web_url_for('view_project')))

    def test_GET_from_unauthorized_user_returns_HTTPForbidden(self):
        unauthorized_user = AuthUserFactory()
        res = self.app.get(self.registration.web_url_for('view_project',
                                                         token=DUMMY_TOKEN),
                           auth=unauthorized_user.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_GET_disapprove_registration_without_embargo_HTTPBad_Request(self):
        assert_false(self.registration.is_pending_embargo)
        res = self.app.get(self.registration.web_url_for('view_project',
                                                         token=DUMMY_TOKEN),
                           auth=self.user.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_GET_disapprove_with_invalid_token_returns_HTTPBad_Request(self):
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        res = self.app.get(self.registration.web_url_for('view_project',
                                                         token=DUMMY_TOKEN),
                           auth=self.user.auth,
                           expect_errors=True)
        self.registration.embargo.reload()
        assert_true(self.registration.is_pending_embargo)
        assert_equal(res.status_code, 400)

    def test_GET_disapprove_with_wrong_admins_token_returns_HTTPBad_Request(
            self):
        admin2 = UserFactory()
        self.registration.contributors.append(admin2)
        self.registration.add_permission(admin2, 'admin', save=True)
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        wrong_rejection_token = self.registration.embargo.approval_state[
            admin2._id]['rejection_token']
        res = self.app.get(self.registration.web_url_for(
            'view_project', token=wrong_rejection_token),
                           auth=self.user.auth,
                           expect_errors=True)
        assert_true(self.registration.is_pending_embargo)
        assert_equal(res.status_code, 400)

    def test_GET_disapprove_with_valid_token_returns_redirect_to_parent(self):
        project = ProjectFactory(creator=self.user)
        registration = RegistrationFactory(project=project)
        registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10))
        registration.save()
        assert_true(registration.is_pending_embargo)

        rejection_token = registration.embargo.approval_state[
            self.user._id]['rejection_token']
        res = self.app.get(
            registration.web_url_for('view_project', token=rejection_token),
            auth=self.user.auth,
        )
        registration.embargo.reload()
        assert_equal(registration.embargo.state, Embargo.REJECTED)
        assert_false(registration.is_pending_embargo)
        assert_equal(res.status_code, 302)

    @mock.patch('flask.redirect')
    def test_GET_disapprove_for_existing_registration_with_valid_token_redirects_to_registration(
            self, mock_redirect):
        self.registration.embargo_registration(self.user,
                                               datetime.datetime.utcnow() +
                                               datetime.timedelta(days=10),
                                               for_existing_registration=True)
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        rejection_token = self.registration.embargo.approval_state[
            self.user._id]['rejection_token']
        res = self.app.get(
            self.registration.web_url_for('view_project',
                                          token=rejection_token),
            auth=self.user.auth,
        )
        self.registration.embargo.reload()
        assert_equal(self.registration.embargo.state, Embargo.REJECTED)
        assert_false(self.registration.is_pending_embargo)
        assert_true(
            mock_redirect.called_with(
                self.registration.web_url_for('view_project')))
class RegistrationEmbargoViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationEmbargoViewsTestCase, self).setUp()
        ensure_schemas()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user)
        self.registration = RegistrationFactory(project=self.project, creator=self.user)

        current_month = datetime.datetime.now().strftime("%B")
        current_year = datetime.datetime.now().strftime("%Y")

        self.valid_make_public_payload = json.dumps(
            {
                u"embargoEndDate": u"Fri, 01, {month} {year} 00:00:00 GMT".format(
                    month=current_month, year=current_year
                ),
                u"registrationChoice": "immediate",
                u"summary": unicode(fake.sentence()),
            }
        )
        valid_date = datetime.datetime.now() + datetime.timedelta(days=180)
        self.valid_embargo_payload = json.dumps(
            {
                u"embargoEndDate": unicode(valid_date.strftime("%a, %d, %B %Y %H:%M:%S")) + u" GMT",
                u"registrationChoice": "embargo",
                u"summary": unicode(fake.sentence()),
            }
        )
        self.invalid_embargo_date_payload = json.dumps(
            {
                u"embargoEndDate": u"Thu, 01 {month} {year} 05:00:00 GMT".format(
                    month=current_month, year=str(int(current_year) - 1)
                ),
                u"registrationChoice": "embargo",
                u"summary": unicode(fake.sentence()),
            }
        )

    @mock.patch("framework.tasks.handlers.enqueue_task")
    def test_POST_register_make_public_immediately_creates_registration_approval(self, mock_enqueue):
        res = self.app.post(
            self.project.api_url_for("node_register_template_page_post", template=u"Open-Ended_Registration"),
            self.valid_make_public_payload,
            content_type="application/json",
            auth=self.user.auth,
        )
        assert_equal(res.status_code, 201)

        registration = Node.find().sort("-registered_date")[0]

        assert_true(registration.is_registration)
        assert_not_equal(registration.registration_approval, None)

    # Regression test for https://openscience.atlassian.net/browse/OSF-5039
    @mock.patch("framework.tasks.handlers.enqueue_task")
    def test_POST_register_make_public_immediately_creates_private_pending_registration_for_public_project(
        self, mock_enqueue
    ):
        public_project = ProjectFactory(is_public=True, creator=self.user)
        component = NodeFactory(creator=self.user, parent=public_project, title="Component", is_public=True)
        subproject = ProjectFactory(creator=self.user, parent=public_project, title="Subproject", is_public=True)
        subproject_component = NodeFactory(creator=self.user, parent=subproject, title="Subcomponent", is_public=True)
        res = self.app.post(
            public_project.api_url_for("node_register_template_page_post", template=u"Open-Ended_Registration"),
            self.valid_make_public_payload,
            content_type="application/json",
            auth=self.user.auth,
        )
        public_project.reload()
        assert_equal(res.status_code, 201)

        # Last node directly registered from self.project
        registration = Node.load(public_project.node__registrations[-1])

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)

    @mock.patch("framework.tasks.handlers.enqueue_task")
    def test_POST_register_make_public_does_not_make_children_public(self, mock_enqueue):
        component = NodeFactory(creator=self.user, parent=self.project, title="Component")
        subproject = ProjectFactory(creator=self.user, parent=self.project, title="Subproject")
        subproject_component = NodeFactory(creator=self.user, parent=subproject, title="Subcomponent")

        res = self.app.post(
            self.project.api_url_for("node_register_template_page_post", template=u"Open-Ended_Registration"),
            self.valid_make_public_payload,
            content_type="application/json",
            auth=self.user.auth,
        )
        self.project.reload()
        # Last node directly registered from self.project
        registration = Node.load(self.project.node__registrations[-1])
        assert_false(registration.is_public)
        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)

    @mock.patch("framework.tasks.handlers.enqueue_task")
    def test_POST_register_embargo_is_not_public(self, mock_enqueue):
        res = self.app.post(
            self.project.api_url_for("node_register_template_page_post", template=u"Open-Ended_Registration"),
            self.valid_embargo_payload,
            content_type="application/json",
            auth=self.user.auth,
        )

        assert_equal(res.status_code, 201)

        registration = Node.find().sort("-registered_date")[0]

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        assert_true(registration.is_pending_embargo_for_existing_registration)
        assert_is_not_none(registration.embargo)

    # Regression test for https://openscience.atlassian.net/browse/OSF-5071
    @mock.patch("framework.tasks.handlers.enqueue_task")
    def test_POST_register_embargo_does_not_make_project_or_children_public(self, mock_enqueue):
        public_project = ProjectFactory(creator=self.user, is_public=True)
        component = NodeFactory(creator=self.user, parent=public_project, title="Component", is_public=True)
        subproject = ProjectFactory(creator=self.user, parent=public_project, title="Subproject", is_public=True)
        subproject_component = NodeFactory(creator=self.user, parent=subproject, title="Subcomponent", is_public=True)
        res = self.app.post(
            public_project.api_url_for("node_register_template_page_post", template=u"Open-Ended_Registration"),
            self.valid_embargo_payload,
            content_type="application/json",
            auth=self.user.auth,
        )
        public_project.reload()
        assert_equal(res.status_code, 201)

        # Last node directly registered from self.project
        registration = Node.load(public_project.node__registrations[-1])

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        assert_true(registration.is_pending_embargo_for_existing_registration)
        assert_is_not_none(registration.embargo)

        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)

    @mock.patch("framework.tasks.handlers.enqueue_task")
    def test_POST_invalid_embargo_end_date_returns_HTTPBad_Request(self, mock_enqueue):
        res = self.app.post(
            self.project.api_url_for("node_register_template_page_post", template=u"Open-Ended_Registration"),
            self.invalid_embargo_date_payload,
            content_type="application/json",
            auth=self.user.auth,
            expect_errors=True,
        )

        assert_equal(res.status_code, 400)

    @mock.patch("framework.tasks.handlers.enqueue_task")
    def test_valid_POST_embargo_adds_to_parent_projects_log(self, mock_enquque):
        initial_project_logs = len(self.project.logs)
        res = self.app.post(
            self.project.api_url_for("node_register_template_page_post", template=u"Open-Ended_Registration"),
            self.valid_embargo_payload,
            content_type="application/json",
            auth=self.user.auth,
        )
        self.project.reload()
        # Logs: Created, registered, embargo initiated
        assert_equal(len(self.project.logs), initial_project_logs + 1)

    def test_non_contributor_GET_approval_returns_HTTPError(self):
        non_contributor = AuthUserFactory()
        self.registration.embargo_registration(self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        approval_token = self.registration.embargo.approval_state[self.user._id]["approval_token"]
        approval_url = self.registration.web_url_for("view_project", token=approval_token)

        res = self.app.get(approval_url, auth=non_contributor.auth, expect_errors=True)
        assert_equal(http.FORBIDDEN, res.status_code)
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)

    def test_non_contributor_GET_disapproval_returns_HTTPError(self):
        non_contributor = AuthUserFactory()
        self.registration.embargo_registration(self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        rejection_token = self.registration.embargo.approval_state[self.user._id]["rejection_token"]
        approval_url = self.registration.web_url_for("view_project", token=rejection_token)

        res = self.app.get(approval_url, auth=non_contributor.auth, expect_errors=True)
        assert_equal(http.FORBIDDEN, res.status_code)
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)
class RegistrationEmbargoApprovalDisapprovalViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationEmbargoApprovalDisapprovalViewsTestCase, self).setUp()
        self.user = AuthUserFactory()
        self.registration = RegistrationFactory(creator=self.user)

    # node_registration_embargo_approve tests
    def test_GET_from_unauthorized_user_raises_HTTPForbidden(self):
        unauthorized_user = AuthUserFactory()
        res = self.app.get(
            self.registration.web_url_for("view_project", token=DUMMY_TOKEN),
            auth=unauthorized_user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 403)

    def test_GET_approve_registration_without_embargo_raises_HTTPBad_Request(self):
        assert_false(self.registration.is_pending_embargo)
        res = self.app.get(
            self.registration.web_url_for("view_project", token=DUMMY_TOKEN), auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_GET_approve_with_invalid_token_returns_HTTPBad_Request(self):
        self.registration.embargo_registration(self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        res = self.app.get(
            self.registration.web_url_for("view_project", token=DUMMY_TOKEN), auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_GET_approve_with_wrong_token_returns_HTTPBad_Request(self):
        admin2 = UserFactory()
        self.registration.contributors.append(admin2)
        self.registration.add_permission(admin2, "admin", save=True)
        self.registration.embargo_registration(self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        wrong_approval_token = self.registration.embargo.approval_state[admin2._id]["approval_token"]
        res = self.app.get(
            self.registration.web_url_for("view_project", token=wrong_approval_token),
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 400)

    def test_GET_approve_with_wrong_admins_token_returns_HTTPBad_Request(self):
        admin2 = UserFactory()
        self.registration.contributors.append(admin2)
        self.registration.add_permission(admin2, "admin", save=True)
        self.registration.embargo_registration(self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        wrong_approval_token = self.registration.embargo.approval_state[admin2._id]["approval_token"]
        res = self.app.get(
            self.registration.web_url_for("view_project", token=wrong_approval_token),
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_true(self.registration.is_pending_embargo)
        assert_equal(res.status_code, 400)

    @mock.patch("flask.redirect")
    def test_GET_approve_with_valid_token_redirects(self, mock_redirect):
        self.registration.embargo_registration(self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        approval_token = self.registration.embargo.approval_state[self.user._id]["approval_token"]
        self.app.get(self.registration.web_url_for("view_project", token=approval_token), auth=self.user.auth)
        self.registration.embargo.reload()
        assert_true(self.registration.embargo_end_date)
        assert_false(self.registration.is_pending_embargo)
        assert_true(mock_redirect.called_with(self.registration.web_url_for("view_project")))

    def test_GET_from_unauthorized_user_returns_HTTPForbidden(self):
        unauthorized_user = AuthUserFactory()
        res = self.app.get(
            self.registration.web_url_for("view_project", token=DUMMY_TOKEN),
            auth=unauthorized_user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 403)

    def test_GET_disapprove_registration_without_embargo_HTTPBad_Request(self):
        assert_false(self.registration.is_pending_embargo)
        res = self.app.get(
            self.registration.web_url_for("view_project", token=DUMMY_TOKEN), auth=self.user.auth, expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_GET_disapprove_with_invalid_token_returns_HTTPBad_Request(self):
        self.registration.embargo_registration(self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        res = self.app.get(
            self.registration.web_url_for("view_project", token=DUMMY_TOKEN), auth=self.user.auth, expect_errors=True
        )
        self.registration.embargo.reload()
        assert_true(self.registration.is_pending_embargo)
        assert_equal(res.status_code, 400)

    def test_GET_disapprove_with_wrong_admins_token_returns_HTTPBad_Request(self):
        admin2 = UserFactory()
        self.registration.contributors.append(admin2)
        self.registration.add_permission(admin2, "admin", save=True)
        self.registration.embargo_registration(self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        wrong_rejection_token = self.registration.embargo.approval_state[admin2._id]["rejection_token"]
        res = self.app.get(
            self.registration.web_url_for("view_project", token=wrong_rejection_token),
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_true(self.registration.is_pending_embargo)
        assert_equal(res.status_code, 400)

    def test_GET_disapprove_with_valid_token_returns_redirect_to_parent(self):
        project = ProjectFactory(creator=self.user)
        registration = RegistrationFactory(project=project)
        registration.embargo_registration(self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10))
        registration.save()
        assert_true(registration.is_pending_embargo)

        rejection_token = registration.embargo.approval_state[self.user._id]["rejection_token"]
        res = self.app.get(registration.web_url_for("view_project", token=rejection_token), auth=self.user.auth)
        registration.embargo.reload()
        assert_equal(registration.embargo.state, Embargo.REJECTED)
        assert_false(registration.is_pending_embargo)
        assert_equal(res.status_code, 302)

    @mock.patch("flask.redirect")
    def test_GET_disapprove_for_existing_registration_with_valid_token_redirects_to_registration(self, mock_redirect):
        self.registration.embargo_registration(
            self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10), for_existing_registration=True
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        rejection_token = self.registration.embargo.approval_state[self.user._id]["rejection_token"]
        res = self.app.get(self.registration.web_url_for("view_project", token=rejection_token), auth=self.user.auth)
        self.registration.embargo.reload()
        assert_equal(self.registration.embargo.state, Embargo.REJECTED)
        assert_false(self.registration.is_pending_embargo)
        assert_true(mock_redirect.called_with(self.registration.web_url_for("view_project")))
Esempio n. 14
0
class RegistrationEmbargoViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationEmbargoViewsTestCase, self).setUp()
        ensure_schemas()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user)
        self.draft = DraftRegistrationFactory(branched_from=self.project)
        self.registration = RegistrationFactory(project=self.project, creator=self.user)

        current_month = datetime.datetime.now().strftime("%B")
        current_year = datetime.datetime.now().strftime("%Y")

        self.valid_make_public_payload = json.dumps({
            u'embargoEndDate': u'Fri, 01, {month} {year} 00:00:00 GMT'.format(
                month=current_month,
                year=current_year
            ),
            u'registrationChoice': 'immediate',
            u'summary': unicode(fake.sentence())
        })
        valid_date = datetime.datetime.now() + datetime.timedelta(days=180)
        self.valid_embargo_payload = json.dumps({
            u'embargoEndDate': unicode(valid_date.strftime('%a, %d, %B %Y %H:%M:%S')) + u' GMT',
            u'registrationChoice': 'embargo',
            u'summary': unicode(fake.sentence())
        })
        self.invalid_embargo_date_payload = json.dumps({
            u'embargoEndDate': u"Thu, 01 {month} {year} 05:00:00 GMT".format(
                month=current_month,
                year=str(int(current_year)-1)
            ),
            u'registrationChoice': 'embargo',
            u'summary': unicode(fake.sentence())
        })

    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_register_draft_without_embargo_creates_registration_approval(self, mock_enqueue):
        res = self.app.post(
            self.project.api_url_for('register_draft_registration', draft_id=self.draft._id),
            self.valid_make_public_payload,
            content_type='application/json',
            auth=self.user.auth
        )
        assert_equal(res.status_code, 202)

        registration = Node.find().sort('-registered_date')[0]

        assert_true(registration.is_registration)
        assert_not_equal(registration.registration_approval, None)

    # Regression test for https://openscience.atlassian.net/browse/OSF-5039
    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_POST_register_make_public_immediately_creates_private_pending_registration_for_public_project(self, mock_enqueue):
        self.project.is_public = True
        self.project.save()
        component = NodeFactory(
            creator=self.user,
            parent=self.project,
            title='Component',
            is_public=True
        )
        subproject = ProjectFactory(
            creator=self.user,
            parent=self.project,
            title='Subproject',
            is_public=True
        )
        subproject_component = NodeFactory(
            creator=self.user,
            parent=subproject,
            title='Subcomponent',
            is_public=True
        )
        res = self.app.post(
            self.project.api_url_for('register_draft_registration', draft_id=self.draft._id),
            self.valid_make_public_payload,
            content_type='application/json',
            auth=self.user.auth
        )
        self.project.reload()
        assert_equal(res.status_code, 202)
        assert_equal(res.json['urls']['registrations'], self.project.web_url_for('node_registrations'))


        # Last node directly registered from self.project
        registration = Node.find(
            Q('registered_from', 'eq', self.project)
        ).sort('-registered_date')[0]

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)

    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_POST_register_make_public_does_not_make_children_public(self, mock_enqueue):
        component = NodeFactory(
            creator=self.user,
            parent=self.project,
            title='Component'
        )
        subproject = ProjectFactory(
            creator=self.user,
            parent=self.project,
            title='Subproject'
        )
        subproject_component = NodeFactory(
            creator=self.user,
            parent=subproject,
            title='Subcomponent'
        )

        res = self.app.post(
            self.project.api_url_for('register_draft_registration', draft_id=self.draft._id),
            self.valid_make_public_payload,
            content_type='application/json',
            auth=self.user.auth
        )
        self.project.reload()
        # Last node directly registered from self.project
        registration = Node.load(self.project.node__registrations[-1])
        assert_false(registration.is_public)
        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)

    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_POST_register_embargo_is_not_public(self, mock_enqueue):
        res = self.app.post(
            self.project.api_url_for('register_draft_registration', draft_id=self.draft._id),
            self.valid_embargo_payload,
            content_type='application/json',
            auth=self.user.auth
        )

        assert_equal(res.status_code, 202)

        registration = Node.find().sort('-registered_date')[0]

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        assert_true(registration.is_pending_embargo_for_existing_registration)
        assert_is_not_none(registration.embargo)

    # Regression test for https://openscience.atlassian.net/browse/OSF-5071
    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_POST_register_embargo_does_not_make_project_or_children_public(self, mock_enqueue):
        self.project.is_public = True
        self.project.save()
        component = NodeFactory(
            creator=self.user,
            parent=self.project,
            title='Component',
            is_public=True
        )
        subproject = ProjectFactory(
            creator=self.user,
            parent=self.project,
            title='Subproject',
            is_public=True
        )
        subproject_component = NodeFactory(
            creator=self.user,
            parent=subproject,
            title='Subcomponent',
            is_public=True
        )
        res = self.app.post(
            self.project.api_url_for('register_draft_registration', draft_id=self.draft._id),
            self.valid_embargo_payload,
            content_type='application/json',
            auth=self.user.auth
        )
        self.project.reload()
        assert_equal(res.status_code, 202)
        assert_equal(res.json['urls']['registrations'], self.project.web_url_for('node_registrations'))

        # Last node directly registered from self.project
        registration = Node.find(
            Q('registered_from', 'eq', self.project)
        ).sort('-registered_date')[0]

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        assert_true(registration.is_pending_embargo_for_existing_registration)
        assert_is_not_none(registration.embargo)

        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)

    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_POST_invalid_embargo_end_date_returns_HTTPBad_Request(self, mock_enqueue):
        res = self.app.post(
            self.project.api_url_for('register_draft_registration', draft_id=self.draft._id),
            self.invalid_embargo_date_payload,
            content_type='application/json',
            auth=self.user.auth,
            expect_errors=True
        )

        assert_equal(res.status_code, 400)

    @mock.patch('framework.tasks.handlers.enqueue_task')
    def test_valid_POST_embargo_adds_to_parent_projects_log(self, mock_enquque):
        initial_project_logs = len(self.project.logs)
        res = self.app.post(
            self.project.api_url_for('register_draft_registration', draft_id=self.draft._id),
            self.valid_embargo_payload,
            content_type='application/json',
            auth=self.user.auth
        )
        self.project.reload()
        # Logs: Created, registered, embargo initiated
        assert_equal(len(self.project.logs), initial_project_logs + 1)

    def test_non_contributor_GET_approval_returns_HTTPError(self):
        non_contributor = AuthUserFactory()
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        approval_token = self.registration.embargo.approval_state[self.user._id]['approval_token']
        approval_url = self.registration.web_url_for('view_project', token=approval_token)

        res = self.app.get(approval_url, auth=non_contributor.auth, expect_errors=True)
        assert_equal(http.FORBIDDEN, res.status_code)
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)

    def test_non_contributor_GET_disapproval_returns_HTTPError(self):
        non_contributor = AuthUserFactory()
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        rejection_token = self.registration.embargo.approval_state[self.user._id]['rejection_token']
        approval_url = self.registration.web_url_for('view_project', token=rejection_token)

        res = self.app.get(approval_url, auth=non_contributor.auth, expect_errors=True)
        assert_equal(http.FORBIDDEN, res.status_code)
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)
class RegistrationEmbargoApprovalDisapprovalViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationEmbargoApprovalDisapprovalViewsTestCase, self).setUp()
        self.user = AuthUserFactory()
        self.registration = RegistrationFactory(creator=self.user)

    # node_registration_embargo_approve tests
    def test_GET_from_unauthorized_user_raises_HTTPForbidden(self):
        unauthorized_user = AuthUserFactory()
        res = self.app.get(
            self.registration.web_url_for('node_registration_embargo_approve', token=fake.sentence()),
            auth=unauthorized_user.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, 403)

    def test_GET_approve_registration_without_embargo_raises_HTTPBad_Request(self):
        assert_false(self.registration.pending_embargo)
        res = self.app.get(
            self.registration.web_url_for('node_registration_embargo_approve', token=fake.sentence()),
            auth=self.user.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_GET_approve_with_invalid_token_returns_HTTPBad_Request(self):
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.pending_embargo)

        res = self.app.get(
            self.registration.web_url_for('node_registration_embargo_approve', token=fake.sentence()),
            auth=self.user.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_GET_approve_with_wrong_token_returns_HTTPBad_Request(self):
        admin2 = UserFactory()
        self.registration.contributors.append(admin2)
        self.registration.add_permission(admin2, 'admin', save=True)
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.pending_embargo)

        wrong_approval_token = self.registration.embargo.approval_state[admin2._id]['approval_token']
        res = self.app.get(
            self.registration.web_url_for('node_registration_embargo_approve', token=wrong_approval_token),
            auth=self.user.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_GET_approve_with_wrong_admins_token_returns_HTTPBad_Request(self):
        admin2 = UserFactory()
        self.registration.contributors.append(admin2)
        self.registration.add_permission(admin2, 'admin', save=True)
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.pending_embargo)

        wrong_approval_token = self.registration.embargo.approval_state[admin2._id]['approval_token']
        res = self.app.get(
            self.registration.web_url_for('node_registration_embargo_approve', token=wrong_approval_token),
            auth=self.user.auth,
            expect_errors=True
        )
        assert_true(self.registration.pending_embargo)
        assert_equal(res.status_code, 400)

    def test_GET_approve_with_valid_token_returns_redirect(self):
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.pending_embargo)

        approval_token = self.registration.embargo.approval_state[self.user._id]['approval_token']
        res = self.app.get(
            self.registration.web_url_for('node_registration_embargo_approve', token=approval_token),
            auth=self.user.auth,
        )
        self.registration.embargo.reload()
        assert_true(self.registration.embargo_end_date)
        assert_false(self.registration.pending_embargo)
        assert_equal(res.status_code, 302)

    # node_registration_embargo_disapprove tests
    def test_GET_from_unauthorized_user_returns_HTTPForbidden(self):
        unauthorized_user = AuthUserFactory()
        res = self.app.get(
            self.registration.web_url_for('node_registration_embargo_disapprove', token=fake.sentence()),
            auth=unauthorized_user.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, 403)

    def test_GET_disapprove_registration_without_embargo_HTTPBad_Request(self):
        assert_false(self.registration.pending_embargo)
        res = self.app.get(
            self.registration.web_url_for('node_registration_embargo_disapprove', token=fake.sentence()),
            auth=self.user.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_GET_disapprove_with_invalid_token_returns_HTTPBad_Request(self):
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.pending_embargo)

        res = self.app.get(
            self.registration.web_url_for('node_registration_embargo_disapprove', token=fake.sentence()),
            auth=self.user.auth,
            expect_errors=True
        )
        self.registration.embargo.reload()
        assert_true(self.registration.pending_embargo)
        assert_equal(res.status_code, 400)

    def test_GET_disapprove_with_wrong_admins_token_returns_HTTPBad_Request(self):
        admin2 = UserFactory()
        self.registration.contributors.append(admin2)
        self.registration.add_permission(admin2, 'admin', save=True)
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.pending_embargo)

        wrong_disapproval_token = self.registration.embargo.approval_state[admin2._id]['disapproval_token']
        res = self.app.get(
            self.registration.web_url_for('node_registration_embargo_disapprove', token=wrong_disapproval_token),
            auth=self.user.auth,
            expect_errors=True
        )
        assert_true(self.registration.pending_embargo)
        assert_equal(res.status_code, 400)

    def test_GET_disapprove_with_valid_token_returns_redirect_to_parent(self):
        project = ProjectFactory(creator=self.user)
        registration = RegistrationFactory(project=project)
        registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        registration.save()
        assert_true(registration.pending_embargo)

        disapproval_token = registration.embargo.approval_state[self.user._id]['disapproval_token']
        res = self.app.get(
            registration.web_url_for('node_registration_embargo_disapprove', token=disapproval_token),
            auth=self.user.auth,
        )
        registration.embargo.reload()
        assert_equal(registration.embargo.state, Embargo.CANCELLED)
        assert_false(registration.embargo_end_date)
        assert_false(registration.pending_embargo)
        assert_equal(res.status_code, 302)
        assert_true(project._id in res.location)

    def test_GET_disapprove_for_existing_registration_with_valid_token_returns_redirect_to_registration(self):
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10),
            for_existing_registration=True
        )
        self.registration.save()
        assert_true(self.registration.pending_embargo)

        disapproval_token = self.registration.embargo.approval_state[self.user._id]['disapproval_token']
        res = self.app.get(
            self.registration.web_url_for('node_registration_embargo_disapprove', token=disapproval_token),
            auth=self.user.auth,
        )
        self.registration.embargo.reload()
        assert_equal(self.registration.embargo.state, Embargo.CANCELLED)
        assert_false(self.registration.embargo_end_date)
        assert_false(self.registration.pending_embargo)
        assert_equal(res.status_code, 302)
        assert_true(self.registration._id in res.location)
Esempio n. 16
0
class RegistrationRetractionApprovalDisapprovalViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationRetractionApprovalDisapprovalViewsTestCase, self).setUp()
        self.user = AuthUserFactory()
        self.registered_from = ProjectFactory(is_public=True, creator=self.user)
        self.registration = RegistrationFactory(is_public=True, project=self.registered_from)
        self.registration.retract_registration(self.user)
        self.registration.save()
        self.approval_token = self.registration.retraction.approval_state[self.user._id]['approval_token']
        self.rejection_token = self.registration.retraction.approval_state[self.user._id]['rejection_token']
        self.corrupt_token = fake.sentence()
        self.token_without_sanction = tokens.encode({
            'action': 'approve_retraction',
            'user_id': self.user._id,
            'sanction_id': 'invalid id'
        })

    # node_registration_retraction_approve_tests
    def test_GET_approve_from_unauthorized_user_returns_HTTPError_UNAUTHORIZED(self):
        unauthorized_user = AuthUserFactory()
        res = self.app.get(
            self.registration.web_url_for('view_project', token=self.approval_token),
            auth=unauthorized_user.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, http.UNAUTHORIZED)

    def test_GET_approve_registration_without_retraction_returns_HTTPError_BAD_REQUEST(self):
        assert_true(self.registration.is_pending_retraction)
        self.registration.retraction.reject(self.user, self.rejection_token)
        assert_false(self.registration.is_pending_retraction)
        self.registration.retraction.save()

        res = self.app.get(
            self.registration.web_url_for('view_project', token=self.approval_token),
            auth=self.user.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, http.BAD_REQUEST)

    def test_GET_approve_with_invalid_token_returns_HTTPError_BAD_REQUEST(self):
        res = self.app.get(
            self.registration.web_url_for('view_project', token=self.corrupt_token),
            auth=self.user.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, http.BAD_REQUEST)

    def test_GET_approve_with_non_existant_sanction_returns_HTTPError_BAD_REQUEST(self):
        res = self.app.get(
            self.registration.web_url_for('view_project', token=self.token_without_sanction),
            auth=self.user.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, http.BAD_REQUEST)

    def test_GET_approve_with_valid_token_returns_200(self):
        res = self.app.get(
            self.registration.web_url_for('view_project', token=self.approval_token),
            auth=self.user.auth
        )
        self.registration.retraction.reload()
        assert_true(self.registration.is_retracted)
        assert_false(self.registration.is_pending_retraction)
        assert_equal(res.status_code, http.OK)

    # node_registration_retraction_disapprove_tests
    def test_GET_disapprove_from_unauthorized_user_returns_HTTPError_UNAUTHORIZED(self):
        unauthorized_user = AuthUserFactory()

        res = self.app.get(
            self.registration.web_url_for('view_project', token=self.rejection_token),
            auth=unauthorized_user.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, http.UNAUTHORIZED)

    def test_GET_disapprove_registration_without_retraction_returns_HTTPError_BAD_REQUEST(self):
        assert_true(self.registration.is_pending_retraction)
        self.registration.retraction.reject(self.user, self.rejection_token)
        assert_false(self.registration.is_pending_retraction)
        self.registration.retraction.save()

        res = self.app.get(
            self.registration.web_url_for('view_project', token=self.rejection_token),
            auth=self.user.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, http.BAD_REQUEST)

    def test_GET_disapprove_with_invalid_token_HTTPError_BAD_REQUEST(self):
        res = self.app.get(
            self.registration.web_url_for('view_project', token=self.corrupt_token),
            auth=self.user.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, http.BAD_REQUEST)

    def test_GET_disapprove_with_valid_token_returns_redirect(self):
        res = self.app.get(
            self.registration.web_url_for('view_project', token=self.rejection_token),
            auth=self.user.auth,
        )
        self.registration.retraction.reload()
        assert_false(self.registration.is_retracted)
        assert_false(self.registration.is_pending_retraction)
        assert_true(self.registration.retraction.is_rejected)
        assert_equal(res.status_code, http.OK)
class RegistrationRetractionViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationRetractionViewsTestCase, self).setUp()
        self.user = AuthUserFactory()
        self.auth = self.user.auth
        self.registration = RegistrationFactory(creator=self.user,
                                                is_public=True)

        self.retraction_post_url = self.registration.api_url_for(
            'node_registration_retraction_post')
        self.retraction_get_url = self.registration.web_url_for(
            'node_registration_retraction_get')
        self.justification = fake.sentence()

    def test_GET_retraction_page_when_pending_retraction_returns_HTTPBad_Request(
            self):
        self.registration.retract_registration(self.user)
        self.registration.save()

        res = self.app.get(
            self.retraction_get_url,
            auth=self.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 400)

    def test_POST_retraction_to_private_registration_returns_HTTPBad_request(
            self):
        self.registration.is_public = False
        self.registration.save()

        res = self.app.post_json(
            self.retraction_post_url,
            auth=self.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 400)
        self.registration.reload()
        assert_is_none(self.registration.retraction)

    # https://trello.com/c/bYyt6nYT/89-clicking-retract-registration-with-unregistered-users-as-project-admins-gives-500-error
    @mock.patch('website.project.views.register.mails.send_mail')
    def test_POST_retraction_does_not_send_email_to_unregistered_admins(
            self, mock_send_mail):
        unreg = UnregUserFactory()
        self.registration.add_contributor(unreg,
                                          auth=Auth(self.user),
                                          permissions=('read', 'write',
                                                       'admin'))
        self.registration.save()
        self.app.post_json(
            self.retraction_post_url,
            {'justification': ''},
            auth=self.auth,
        )
        # Only the creator gets an email; the unreg user does not get emailed
        assert_equal(mock_send_mail.call_count, 1)

    def test_POST_pending_embargo_returns_HTTPBad_request(self):
        self.registration.embargo_registration(
            self.user,
            (datetime.datetime.utcnow() + datetime.timedelta(days=10)),
            for_existing_registration=True)
        self.registration.save()
        assert_true(self.registration.pending_embargo)

        res = self.app.post_json(
            self.retraction_post_url,
            auth=self.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 400)
        self.registration.reload()
        assert_is_none(self.registration.retraction)

    def test_POST_retraction_by_non_admin_retract_HTTPUnauthorized(self):
        res = self.app.post_json(self.retraction_post_url, expect_errors=True)
        assert_equals(res.status_code, 401)
        self.registration.reload()
        assert_is_none(self.registration.retraction)

    def test_POST_retraction_without_justification_returns_HTTPOK(self):
        res = self.app.post_json(
            self.retraction_post_url,
            {'justification': ''},
            auth=self.auth,
        )
        assert_equal(res.status_code, 200)
        self.registration.reload()
        assert_false(self.registration.retraction.is_retracted)
        assert_equal(self.registration.retraction.state, Retraction.PENDING)
        assert_is_none(self.registration.retraction.justification)

    def test_valid_POST_retraction_adds_to_parent_projects_log(self):
        initial_project_logs = len(self.registration.registered_from.logs)
        self.app.post_json(
            self.retraction_post_url,
            {'justification': ''},
            auth=self.auth,
        )
        self.registration.registered_from.reload()
        # Logs: Created, registered, retraction initiated
        assert_equal(len(self.registration.registered_from.logs),
                     initial_project_logs + 1)
Esempio n. 18
0
class TestIdentifierViews(OsfTestCase):

    def setUp(self):
        super(TestIdentifierViews, self).setUp()
        self.user = AuthUserFactory()
        self.node = RegistrationFactory(creator=self.user, is_public=True)

    def test_get_identifiers(self):
        self.node.set_identifier_value('doi', 'FK424601')
        self.node.set_identifier_value('ark', 'fk224601')
        res = self.app.get(self.node.api_url_for('node_identifiers_get'))
        assert_equal(res.json['doi'], 'FK424601')
        assert_equal(res.json['ark'], 'fk224601')

    @httpretty.activate
    def test_create_identifiers_not_exists(self):
        identifier = self.node._id
        url = furl.furl('https://ezid.cdlib.org/id')
        doi = settings.EZID_FORMAT.format(namespace=settings.DOI_NAMESPACE, guid=identifier)
        url.path.segments.append(doi)
        httpretty.register_uri(
            httpretty.PUT,
            url.url,
            body=to_anvl({
                'success': '{doi}osf.io/{ident} | {ark}osf.io/{ident}'.format(
                    doi=settings.DOI_NAMESPACE,
                    ark=settings.ARK_NAMESPACE,
                    ident=identifier,
                ),
            }),
            status=201,
            priority=1,
        )
        res = self.app.post(
            self.node.api_url_for('node_identifiers_post'),
            auth=self.user.auth,
        )
        self.node.reload()
        assert_equal(
            res.json['doi'],
            self.node.get_identifier_value('doi')
        )
        assert_equal(
            res.json['ark'],
            self.node.get_identifier_value('ark')
        )
        assert_equal(res.status_code, 201)


    @httpretty.activate
    def test_create_identifiers_exists(self):
        identifier = self.node._id
        doi = settings.EZID_FORMAT.format(namespace=settings.DOI_NAMESPACE, guid=identifier)
        url = furl.furl('https://ezid.cdlib.org/id')
        url.path.segments.append(doi)
        httpretty.register_uri(
            httpretty.PUT,
            url.url,
            body='identifier already exists',
            status=400,
        )
        httpretty.register_uri(
            httpretty.GET,
            url.url,
            body=to_anvl({
                'success': doi,
            }),
            status=200,
        )
        res = self.app.post(
            self.node.api_url_for('node_identifiers_post'),
            auth=self.user.auth,
        )
        self.node.reload()
        assert_equal(
            res.json['doi'],
            self.node.get_identifier_value('doi')
        )
        assert_equal(
            res.json['ark'],
            self.node.get_identifier_value('ark')
        )
        assert_equal(res.status_code, 201)

    def test_get_by_identifier(self):
        self.node.set_identifier_value('doi', 'FK424601')
        self.node.set_identifier_value('ark', 'fk224601')
        res_doi = self.app.get(
            self.node.web_url_for(
                'get_referent_by_identifier',
                category='doi',
                value=self.node.get_identifier_value('doi'),
            ),
        )
        assert_equal(res_doi.status_code, 302)
        assert_urls_equal(res_doi.headers['Location'], self.node.absolute_url)
        res_ark = self.app.get(
            self.node.web_url_for(
                'get_referent_by_identifier',
                category='ark',
                value=self.node.get_identifier_value('ark'),
            ),
        )
        assert_equal(res_ark.status_code, 302)
        assert_urls_equal(res_ark.headers['Location'], self.node.absolute_url)

    def test_get_by_identifier_not_found(self):
        self.node.set_identifier_value('doi', 'FK424601')
        res = self.app.get(
            self.node.web_url_for(
                'get_referent_by_identifier',
                category='doi',
                value='fakedoi',
            ),
            expect_errors=True,
        )
        assert_equal(res.status_code, 404)
class RegistrationRetractionApprovalDisapprovalViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationRetractionApprovalDisapprovalViewsTestCase, self).setUp()
        self.user = AuthUserFactory()
        self.auth = self.user.auth
        self.registration = RegistrationFactory(is_public=True, creator=self.user)

    # node_registration_retraction_approve_tests
    def test_GET_approve_from_unauthorized_user_raises_HTTPForbidden(self):
        unauthorized_user = AuthUserFactory()

        res = self.app.get(
            self.registration.web_url_for('node_registration_retraction_approve', token=fake.sentence()),
            auth=unauthorized_user.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, 403)

    def test_GET_approve_registration_without_retraction_returns_HTTPBad_Request(self):
        assert_false(self.registration.pending_retraction)

        res = self.app.get(
            self.registration.web_url_for('node_registration_retraction_approve', token=fake.sentence()),
            auth=self.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_GET_approve_with_invalid_token_returns_HTTPBad_Request(self):
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.pending_retraction)

        res = self.app.get(
            self.registration.web_url_for('node_registration_retraction_approve', token=fake.sentence()),
            auth=self.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_GET_approve_with_valid_token_returns_redirect(self):
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.pending_retraction)

        approval_token = self.registration.retraction.approval_state[self.user._id]['approval_token']
        res = self.app.get(
            self.registration.web_url_for('node_registration_retraction_approve', token=approval_token),
            auth=self.auth
        )
        self.registration.retraction.reload()
        assert_true(self.registration.is_retracted)
        assert_false(self.registration.pending_retraction)
        assert_equal(res.status_code, 302)

    def test_GET_approve_with_wrong_admins_token_returns_HTTPBad_Request(self):
        user2 = AuthUserFactory()
        self.registration.contributors.append(user2)
        self.registration.add_permission(user2, 'admin', save=True)
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.pending_retraction)
        assert_equal(len(self.registration.retraction.approval_state), 2)

        wrong_approval_token = self.registration.retraction.approval_state[user2._id]['approval_token']
        res = self.app.get(
            self.registration.web_url_for('node_registration_retraction_approve', token=wrong_approval_token),
            auth=self.auth,
            expect_errors=True
        )
        assert_true(self.registration.pending_retraction)
        assert_equal(res.status_code, 400)

    # node_registration_retraction_disapprove_tests
    def test_GET_disapprove_from_unauthorized_user_raises_HTTPForbidden(self):
        unauthorized_user = AuthUserFactory()

        res = self.app.get(
            self.registration.web_url_for('node_registration_retraction_disapprove', token=fake.sentence()),
            auth=unauthorized_user.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, 403)

    def test_GET_disapprove_registration_without_retraction_returns_HTTPBad_Request(self):
        assert_false(self.registration.pending_retraction)

        res = self.app.get(
            self.registration.web_url_for('node_registration_retraction_disapprove', token=fake.sentence()),
            auth=self.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_GET_disapprove_with_invalid_token_returns_HTTPBad_Request(self):
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.pending_retraction)

        res = self.app.get(
            self.registration.web_url_for('node_registration_retraction_disapprove', token=fake.sentence()),
            auth=self.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, 400)

    def test_GET_disapprove_with_wrong_admins_token_returns_HTTPBad_Request(self):
        user2 = AuthUserFactory()
        self.registration.contributors.append(user2)
        self.registration.add_permission(user2, 'admin', save=True)
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.pending_retraction)
        assert_equal(len(self.registration.retraction.approval_state), 2)

        wrong_disapproval_token = self.registration.retraction.approval_state[user2._id]['disapproval_token']
        res = self.app.get(
            self.registration.web_url_for('node_registration_retraction_disapprove', token=wrong_disapproval_token),
            auth=self.auth,
            expect_errors=True
        )
        assert_true(self.registration.pending_retraction)
        assert_equal(res.status_code, 400)

    def test_GET_disapprove_with_valid_token_returns_redirect(self):
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.pending_retraction)

        disapproval_token = self.registration.retraction.approval_state[self.user._id]['disapproval_token']
        res = self.app.get(
            self.registration.web_url_for('node_registration_retraction_disapprove', token=disapproval_token),
            auth=self.auth,
        )
        self.registration.retraction.reload()
        assert_false(self.registration.is_retracted)
        assert_false(self.registration.pending_retraction)
        assert_equal(self.registration.retraction.state, Retraction.CANCELLED)
        assert_equal(res.status_code, 302)
Esempio n. 20
0
class TestIdentifierViews(OsfTestCase):
    def setUp(self):
        super(TestIdentifierViews, self).setUp()
        self.user = AuthUserFactory()
        self.node = RegistrationFactory(creator=self.user, is_public=True)

    def test_get_identifiers(self):
        self.node.set_identifier_value('doi', 'FK424601')
        self.node.set_identifier_value('ark', 'fk224601')
        res = self.app.get(self.node.api_url_for('node_identifiers_get'))
        assert_equal(res.json['doi'], 'FK424601')
        assert_equal(res.json['ark'], 'fk224601')

    def test_create_identifiers_not_exists(self):
        identifier = self.node._id
        url = furl.furl('https://ezid.cdlib.org/id')
        doi = settings.EZID_FORMAT.format(namespace=settings.DOI_NAMESPACE,
                                          guid=identifier)
        url.path.segments.append(doi)
        httpretty.register_uri(
            httpretty.PUT,
            url.url,
            body=to_anvl({
                'success':
                '{doi}osf.io/{ident} | {ark}osf.io/{ident}'.format(
                    doi=settings.DOI_NAMESPACE,
                    ark=settings.ARK_NAMESPACE,
                    ident=identifier,
                ),
            }),
            status=201,
            priority=1,
        )
        res = self.app.post(
            self.node.api_url_for('node_identifiers_post'),
            auth=self.user.auth,
        )
        self.node.reload()
        assert_equal(res.json['doi'], self.node.get_identifier_value('doi'))
        assert_equal(res.json['ark'], self.node.get_identifier_value('ark'))
        assert_equal(res.status_code, 201)

    def test_create_identifiers_exists(self):
        identifier = self.node._id
        doi = settings.EZID_FORMAT.format(namespace=settings.DOI_NAMESPACE,
                                          guid=identifier)
        url = furl.furl('https://ezid.cdlib.org/id')
        url.path.segments.append(doi)
        httpretty.register_uri(
            httpretty.PUT,
            url.url,
            body='identifier already exists',
            status=400,
        )
        httpretty.register_uri(
            httpretty.GET,
            url.url,
            body=to_anvl({
                'success': doi,
            }),
            status=200,
        )
        res = self.app.post(
            self.node.api_url_for('node_identifiers_post'),
            auth=self.user.auth,
        )
        self.node.reload()
        assert_equal(res.json['doi'], self.node.get_identifier_value('doi'))
        assert_equal(res.json['ark'], self.node.get_identifier_value('ark'))
        assert_equal(res.status_code, 201)

    def test_get_by_identifier(self):
        self.node.set_identifier_value('doi', 'FK424601')
        self.node.set_identifier_value('ark', 'fk224601')
        res_doi = self.app.get(
            self.node.web_url_for(
                'get_referent_by_identifier',
                category='doi',
                value=self.node.get_identifier_value('doi'),
            ), )
        assert_equal(res_doi.status_code, 302)
        assert_urls_equal(res_doi.headers['Location'], self.node.absolute_url)
        res_ark = self.app.get(
            self.node.web_url_for(
                'get_referent_by_identifier',
                category='ark',
                value=self.node.get_identifier_value('ark'),
            ), )
        assert_equal(res_ark.status_code, 302)
        assert_urls_equal(res_ark.headers['Location'], self.node.absolute_url)

    def test_get_by_identifier_not_found(self):
        self.node.set_identifier_value('doi', 'FK424601')
        res = self.app.get(
            self.node.web_url_for(
                'get_referent_by_identifier',
                category='doi',
                value='fakedoi',
            ),
            expect_errors=True,
        )
        assert_equal(res.status_code, 404)
Esempio n. 21
0
class RegistrationEmbargoViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationEmbargoViewsTestCase, self).setUp()
        ensure_schemas()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user)
        self.draft = DraftRegistrationFactory(branched_from=self.project)
        self.registration = RegistrationFactory(project=self.project, creator=self.user)

        current_month = datetime.datetime.now().strftime("%B")
        current_year = datetime.datetime.now().strftime("%Y")

        self.valid_make_public_payload = json.dumps({
            u'embargoEndDate': u'Fri, 01, {month} {year} 00:00:00 GMT'.format(
                month=current_month,
                year=current_year
            ),
            u'registrationChoice': 'immediate',
            u'summary': unicode(fake.sentence())
        })
        valid_date = datetime.datetime.now() + datetime.timedelta(days=180)
        self.valid_embargo_payload = json.dumps({
            u'embargoEndDate': unicode(valid_date.strftime('%a, %d, %B %Y %H:%M:%S')) + u' GMT',
            u'registrationChoice': 'embargo',
            u'summary': unicode(fake.sentence())
        })
        self.invalid_embargo_date_payload = json.dumps({
            u'embargoEndDate': u"Thu, 01 {month} {year} 05:00:00 GMT".format(
                month=current_month,
                year=str(int(current_year)-1)
            ),
            u'registrationChoice': 'embargo',
            u'summary': unicode(fake.sentence())
        })

    @mock.patch('framework.celery_tasks.handlers.enqueue_task')
    def test_register_draft_without_embargo_creates_registration_approval(self, mock_enqueue):
        res = self.app.post(
            self.project.api_url_for('register_draft_registration', draft_id=self.draft._id),
            self.valid_make_public_payload,
            content_type='application/json',
            auth=self.user.auth
        )
        assert_equal(res.status_code, 202)

        registration = Node.find().sort('-registered_date')[0]

        assert_true(registration.is_registration)
        assert_not_equal(registration.registration_approval, None)

    # Regression test for https://openscience.atlassian.net/browse/OSF-5039
    @mock.patch('framework.celery_tasks.handlers.enqueue_task')
    def test_POST_register_make_public_immediately_creates_private_pending_registration_for_public_project(self, mock_enqueue):
        self.project.is_public = True
        self.project.save()
        component = NodeFactory(
            creator=self.user,
            parent=self.project,
            title='Component',
            is_public=True
        )
        subproject = ProjectFactory(
            creator=self.user,
            parent=self.project,
            title='Subproject',
            is_public=True
        )
        subproject_component = NodeFactory(
            creator=self.user,
            parent=subproject,
            title='Subcomponent',
            is_public=True
        )
        res = self.app.post(
            self.project.api_url_for('register_draft_registration', draft_id=self.draft._id),
            self.valid_make_public_payload,
            content_type='application/json',
            auth=self.user.auth
        )
        self.project.reload()
        assert_equal(res.status_code, 202)
        assert_equal(res.json['urls']['registrations'], self.project.web_url_for('node_registrations'))


        # Last node directly registered from self.project
        registration = Node.find(
            Q('registered_from', 'eq', self.project)
        ).sort('-registered_date')[0]

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)

    @mock.patch('framework.celery_tasks.handlers.enqueue_task')
    def test_POST_register_make_public_does_not_make_children_public(self, mock_enqueue):
        component = NodeFactory(
            creator=self.user,
            parent=self.project,
            title='Component'
        )
        subproject = ProjectFactory(
            creator=self.user,
            parent=self.project,
            title='Subproject'
        )
        subproject_component = NodeFactory(
            creator=self.user,
            parent=subproject,
            title='Subcomponent'
        )

        res = self.app.post(
            self.project.api_url_for('register_draft_registration', draft_id=self.draft._id),
            self.valid_make_public_payload,
            content_type='application/json',
            auth=self.user.auth
        )
        self.project.reload()
        # Last node directly registered from self.project
        registration = self.project.registrations_all[-1]
        assert_false(registration.is_public)
        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)

    @mock.patch('framework.celery_tasks.handlers.enqueue_task')
    def test_POST_register_embargo_is_not_public(self, mock_enqueue):
        res = self.app.post(
            self.project.api_url_for('register_draft_registration', draft_id=self.draft._id),
            self.valid_embargo_payload,
            content_type='application/json',
            auth=self.user.auth
        )

        assert_equal(res.status_code, 202)

        registration = Node.find().sort('-registered_date')[0]

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        assert_true(registration.is_pending_embargo_for_existing_registration)
        assert_is_not_none(registration.embargo)

    # Regression test for https://openscience.atlassian.net/browse/OSF-5071
    @mock.patch('framework.celery_tasks.handlers.enqueue_task')
    def test_POST_register_embargo_does_not_make_project_or_children_public(self, mock_enqueue):
        self.project.is_public = True
        self.project.save()
        component = NodeFactory(
            creator=self.user,
            parent=self.project,
            title='Component',
            is_public=True
        )
        subproject = ProjectFactory(
            creator=self.user,
            parent=self.project,
            title='Subproject',
            is_public=True
        )
        subproject_component = NodeFactory(
            creator=self.user,
            parent=subproject,
            title='Subcomponent',
            is_public=True
        )
        res = self.app.post(
            self.project.api_url_for('register_draft_registration', draft_id=self.draft._id),
            self.valid_embargo_payload,
            content_type='application/json',
            auth=self.user.auth
        )
        self.project.reload()
        assert_equal(res.status_code, 202)
        assert_equal(res.json['urls']['registrations'], self.project.web_url_for('node_registrations'))

        # Last node directly registered from self.project
        registration = Node.find(
            Q('registered_from', 'eq', self.project)
        ).sort('-registered_date')[0]

        assert_true(registration.is_registration)
        assert_false(registration.is_public)
        assert_true(registration.is_pending_embargo_for_existing_registration)
        assert_is_not_none(registration.embargo)

        for node in registration.get_descendants_recursive():
            assert_true(node.is_registration)
            assert_false(node.is_public)

    @mock.patch('framework.celery_tasks.handlers.enqueue_task')
    def test_POST_invalid_embargo_end_date_returns_HTTPBad_Request(self, mock_enqueue):
        res = self.app.post(
            self.project.api_url_for('register_draft_registration', draft_id=self.draft._id),
            self.invalid_embargo_date_payload,
            content_type='application/json',
            auth=self.user.auth,
            expect_errors=True
        )

        assert_equal(res.status_code, 400)

    @mock.patch('framework.celery_tasks.handlers.enqueue_task')
    def test_valid_POST_embargo_adds_to_parent_projects_log(self, mock_enquque):
        initial_project_logs = len(self.project.logs)
        self.app.post(
            self.project.api_url_for('register_draft_registration', draft_id=self.draft._id),
            self.valid_embargo_payload,
            content_type='application/json',
            auth=self.user.auth
        )
        self.project.reload()
        # Logs: Created, registered, embargo initiated
        assert_equal(len(self.project.logs), initial_project_logs + 1)

    @mock.patch('website.project.sanctions.TokenApprovableSanction.ask')
    def test_embargoed_registration_set_privacy_requests_embargo_termination(self, mock_ask):
        # Initiate and approve embargo
        for i in range(3):
            c = AuthUserFactory()
            self.registration.add_contributor(c, [permissions.ADMIN], auth=Auth(self.user))
        self.registration.save()
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        for user_id, embargo_tokens in self.registration.embargo.approval_state.iteritems():
            approval_token = embargo_tokens['approval_token']
            self.registration.embargo.approve_embargo(User.load(user_id), approval_token)
        self.registration.save()

        res = self.app.post(
            self.registration.api_url_for('project_set_privacy', permissions='public'),
            auth=self.user.auth,
        )
        assert_equal(res.status_code, 200)
        for reg in self.registration.node_and_primary_descendants():
            reg.reload()
            assert_false(reg.is_public)
        assert_true(reg.embargo_termination_approval)
        assert_true(reg.embargo_termination_approval.is_pending_approval)

    def test_cannot_request_termination_on_component_of_embargo(self):
        node = ProjectFactory()
        child = ProjectFactory(parent=node, creator=node.creator)

        with utils.mock_archive(node, embargo=True, autocomplete=True, autoapprove=True) as reg:
            with assert_raises(NodeStateError):
                reg.nodes[0].request_embargo_termination(Auth(node.creator))

    @mock.patch('website.mails.send_mail')
    def test_embargoed_registration_set_privacy_sends_mail(self, mock_send_mail):
        """
        Integration test for https://github.com/CenterForOpenScience/osf.io/pull/5294#issuecomment-212613668
        """
        # Initiate and approve embargo
        for i in range(3):
            c = AuthUserFactory()
            self.registration.add_contributor(c, [permissions.ADMIN], auth=Auth(self.user))
        self.registration.save()
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        for user_id, embargo_tokens in self.registration.embargo.approval_state.iteritems():
            approval_token = embargo_tokens['approval_token']
            self.registration.embargo.approve_embargo(User.load(user_id), approval_token)
        self.registration.save()

        res = self.app.post(
            self.registration.api_url_for('project_set_privacy', permissions='public'),
            auth=self.user.auth,
        )
        assert_equal(res.status_code, 200)
        for admin in self.registration.admin_contributors:
            assert_true(any([c[0][0] == admin.username for c in mock_send_mail.call_args_list]))

    @mock.patch('website.project.sanctions.TokenApprovableSanction.ask')
    def test_make_child_embargoed_registration_public_asks_all_admins_in_tree(self, mock_ask):
        # Initiate and approve embargo
        node = NodeFactory(creator=self.user)
        c1 = AuthUserFactory()
        child = NodeFactory(parent=node, creator=c1)
        c2 = AuthUserFactory()
        NodeFactory(parent=child, creator=c2)
        registration = RegistrationFactory(project=node)

        registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        for user_id, embargo_tokens in registration.embargo.approval_state.iteritems():
            approval_token = embargo_tokens['approval_token']
            registration.embargo.approve_embargo(User.load(user_id), approval_token)
        self.registration.save()

        res = self.app.post(
            registration.api_url_for('project_set_privacy', permissions='public'),
            auth=self.user.auth
        )
        assert_equal(res.status_code, 200)
        asked_admins = [(admin._id, n._id) for admin, n in mock_ask.call_args[0][0]]
        for admin, node in registration.get_admin_contributors_recursive():
            assert_in((admin._id, node._id), asked_admins)

    def test_non_contributor_GET_approval_returns_HTTPError(self):
        non_contributor = AuthUserFactory()
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        approval_token = self.registration.embargo.approval_state[self.user._id]['approval_token']
        approval_url = self.registration.web_url_for('view_project', token=approval_token)

        res = self.app.get(approval_url, auth=non_contributor.auth, expect_errors=True)
        assert_equal(http.FORBIDDEN, res.status_code)
        assert_true(self.registration.is_pending_embargo)
        assert_true(self.registration.embargo_end_date)

    def test_non_contributor_GET_disapproval_returns_HTTPError(self):
        non_contributor = AuthUserFactory()
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        rejection_token = self.registration.embargo.approval_state[self.user._id]['rejection_token']
        approval_url = self.registration.web_url_for('view_project', token=rejection_token)

        res = self.app.get(approval_url, auth=non_contributor.auth, expect_errors=True)
        assert_equal(http.FORBIDDEN, res.status_code)
        assert_true(self.registration.is_pending_embargo)
        assert_true(self.registration.embargo_end_date)
class RegistrationRetractionViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationRetractionViewsTestCase, self).setUp()
        self.user = AuthUserFactory()
        self.auth = self.user.auth
        self.registration = RegistrationFactory(creator=self.user, is_public=True)

        self.retraction_post_url = self.registration.api_url_for('node_registration_retraction_post')
        self.retraction_get_url = self.registration.web_url_for('node_registration_retraction_get')
        self.justification = fake.sentence()

    def test_GET_retraction_page_when_pending_retraction_returns_HTTPBad_Request(self):
        self.registration.retract_registration(self.user)
        self.registration.save()

        res = self.app.get(
            self.retraction_get_url,
            auth=self.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 400)

    def test_POST_retraction_to_private_registration_returns_HTTPBad_request(self):
        self.registration.is_public = False
        self.registration.save()

        res = self.app.post_json(
            self.retraction_post_url,
            auth=self.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 400)
        self.registration.reload()
        assert_is_none(self.registration.retraction)

    # https://trello.com/c/bYyt6nYT/89-clicking-retract-registration-with-unregistered-users-as-project-admins-gives-500-error
    @mock.patch('website.project.views.register.mails.send_mail')
    def test_POST_retraction_does_not_send_email_to_unregistered_admins(self, mock_send_mail):
        unreg = UnregUserFactory()
        self.registration.add_contributor(
            unreg,
            auth=Auth(self.user),
            permissions=('read', 'write', 'admin')
        )
        self.registration.save()
        self.app.post_json(
            self.retraction_post_url,
            {'justification': ''},
            auth=self.auth,
        )
        # Only the creator gets an email; the unreg user does not get emailed
        assert_equal(mock_send_mail.call_count, 1)

    def test_POST_pending_embargo_returns_HTTPBad_request(self):
        self.registration.embargo_registration(
            self.user,
            (datetime.datetime.utcnow() + datetime.timedelta(days=10)),
            for_existing_registration=True
        )
        self.registration.save()
        assert_true(self.registration.pending_embargo)

        res = self.app.post_json(
            self.retraction_post_url,
            auth=self.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 400)
        self.registration.reload()
        assert_is_none(self.registration.retraction)

    def test_POST_retraction_by_non_admin_retract_HTTPUnauthorized(self):
        res = self.app.post_json(self.retraction_post_url, expect_errors=True)
        assert_equals(res.status_code, 401)
        self.registration.reload()
        assert_is_none(self.registration.retraction)

    def test_POST_retraction_without_justification_returns_HTTPOK(self):
        res = self.app.post_json(
            self.retraction_post_url,
            {'justification': ''},
            auth=self.auth,
        )
        assert_equal(res.status_code, 200)
        self.registration.reload()
        assert_false(self.registration.retraction.is_retracted)
        assert_equal(self.registration.retraction.state, Retraction.PENDING)
        assert_is_none(self.registration.retraction.justification)

    def test_valid_POST_retraction_adds_to_parent_projects_log(self):
        initial_project_logs = len(self.registration.registered_from.logs)
        self.app.post_json(
            self.retraction_post_url,
            {'justification': ''},
            auth=self.auth,
        )
        self.registration.registered_from.reload()
        # Logs: Created, registered, retraction initiated
        assert_equal(len(self.registration.registered_from.logs), initial_project_logs + 1)
Esempio n. 23
0
class RegistrationRetractionViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationRetractionViewsTestCase, self).setUp()
        self.user = AuthUserFactory()
        self.registered_from = ProjectFactory(creator=self.user, is_public=True)
        self.registration = RegistrationFactory(project=self.registered_from, is_public=True)

        self.retraction_post_url = self.registration.api_url_for('node_registration_retraction_post')
        self.retraction_get_url = self.registration.web_url_for('node_registration_retraction_get')
        self.justification = fake.sentence()

    def test_GET_retraction_page_when_pending_retraction_returns_HTTPError_BAD_REQUEST(self):
        self.registration.retract_registration(self.user)
        self.registration.save()

        res = self.app.get(
            self.retraction_get_url,
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, http.BAD_REQUEST)

    def test_POST_retraction_to_private_registration_returns_HTTPError_FORBIDDEN(self):
        self.registration.is_public = False
        self.registration.save()

        res = self.app.post_json(
            self.retraction_post_url,
            {'justification': ''},
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, http.FORBIDDEN)
        self.registration.reload()
        assert_is_none(self.registration.retraction)

    @mock.patch('website.mails.send_mail')
    def test_POST_retraction_does_not_send_email_to_unregistered_admins(self, mock_send_mail):
        unreg = UnregUserFactory()
        self.registration.add_contributor(
            unreg,
            auth=Auth(self.user),
            permissions=['read', 'write', 'admin']
        )
        self.registration.save()
        self.app.post_json(
            self.retraction_post_url,
            {'justification': ''},
            auth=self.user.auth,
        )
        # Only the creator gets an email; the unreg user does not get emailed
        assert_equal(mock_send_mail.call_count, 1)

    def test_POST_pending_embargo_returns_HTTPError_HTTPOK(self):
        self.registration.embargo_registration(
            self.user,
            (datetime.datetime.utcnow() + datetime.timedelta(days=10)),
            for_existing_registration=True
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        res = self.app.post_json(
            self.retraction_post_url,
            {'justification': ''},
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, http.OK)
        self.registration.reload()
        assert_true(self.registration.is_pending_retraction)

    def test_POST_active_embargo_returns_HTTPOK(self):
        self.registration.embargo_registration(
            self.user,
            (datetime.datetime.utcnow() + datetime.timedelta(days=10)),
            for_existing_registration=True
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        approval_token = self.registration.embargo.approval_state[self.user._id]['approval_token']
        self.registration.embargo.approve(self.user, approval_token)
        assert_true(self.registration.embargo_end_date)

        res = self.app.post_json(
            self.retraction_post_url,
            {'justification': ''},
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, http.OK)
        self.registration.reload()
        assert_true(self.registration.is_pending_retraction)

    def test_POST_retraction_by_non_admin_retract_HTTPError_UNAUTHORIZED(self):
        res = self.app.post_json(self.retraction_post_url, expect_errors=True)
        assert_equals(res.status_code, http.UNAUTHORIZED)
        self.registration.reload()
        assert_is_none(self.registration.retraction)

    @mock.patch('website.mails.send_mail')
    def test_POST_retraction_without_justification_returns_HTTPOK(self, mock_send):
        res = self.app.post_json(
            self.retraction_post_url,
            {'justification': ''},
            auth=self.user.auth,
        )
        assert_equal(res.status_code, http.OK)
        self.registration.reload()
        assert_false(self.registration.is_retracted)
        assert_true(self.registration.is_pending_retraction)
        assert_is_none(self.registration.retraction.justification)

    @mock.patch('website.mails.send_mail')
    def test_valid_POST_retraction_adds_to_parent_projects_log(self, mock_send):
        initial_project_logs = len(self.registration.registered_from.logs)
        self.app.post_json(
            self.retraction_post_url,
            {'justification': ''},
            auth=self.user.auth,
        )
        self.registration.registered_from.reload()
        # Logs: Created, registered, retraction initiated
        assert_equal(len(self.registration.registered_from.logs), initial_project_logs + 1)

    @mock.patch('website.mails.send_mail')
    def test_valid_POST_retraction_when_pending_retraction_raises_400(self, mock_send):
        self.app.post_json(
            self.retraction_post_url,
            {'justification': ''},
            auth=self.user.auth,
        )
        res = self.app.post_json(
            self.retraction_post_url,
            {'justification': ''},
            auth=self.user.auth,
            expect_errors=True
        )
        assert_equal(res.status_code, 400)

    @mock.patch('website.mails.send_mail')
    def test_valid_POST_calls_send_mail_with_username(self, mock_send):
        self.app.post_json(
            self.retraction_post_url,
            {'justification': ''},
            auth=self.user.auth,
        )
        assert_true(mock_send.called)
        args, kwargs = mock_send.call_args
        assert_true(self.user.username in args)

    def test_non_contributor_GET_approval_returns_HTTPError_UNAUTHORIZED(self):
        non_contributor = AuthUserFactory()
        self.registration.retract_registration(self.user)
        approval_token = self.registration.retraction.approval_state[self.user._id]['approval_token']

        approval_url = self.registration.web_url_for('view_project', token=approval_token)
        res = self.app.get(approval_url, auth=non_contributor.auth, expect_errors=True)
        assert_equal(res.status_code, http.UNAUTHORIZED)
        assert_true(self.registration.is_pending_retraction)
        assert_false(self.registration.is_retracted)

    def test_non_contributor_GET_disapproval_returns_HTTPError_UNAUTHORIZED(self):
        non_contributor = AuthUserFactory()
        self.registration.retract_registration(self.user)
        rejection_token = self.registration.retraction.approval_state[self.user._id]['rejection_token']

        disapproval_url = self.registration.web_url_for('view_project', token=rejection_token)
        res = self.app.get(disapproval_url, auth=non_contributor.auth, expect_errors=True)
        assert_equal(res.status_code, http.UNAUTHORIZED)
        assert_true(self.registration.is_pending_retraction)
        assert_false(self.registration.is_retracted)
class RegistrationRetractionApprovalDisapprovalViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationRetractionApprovalDisapprovalViewsTestCase,
              self).setUp()
        self.user = AuthUserFactory()
        self.auth = self.user.auth
        self.registration = RegistrationFactory(is_public=True,
                                                creator=self.user)

    # node_registration_retraction_approve_tests
    def test_GET_approve_from_unauthorized_user_raises_HTTPForbidden(self):
        unauthorized_user = AuthUserFactory()

        res = self.app.get(self.registration.web_url_for(
            'node_registration_retraction_approve', token=fake.sentence()),
                           auth=unauthorized_user.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_GET_approve_registration_without_retraction_returns_HTTPBad_Request(
            self):
        assert_false(self.registration.pending_retraction)

        res = self.app.get(self.registration.web_url_for(
            'node_registration_retraction_approve', token=fake.sentence()),
                           auth=self.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_GET_approve_with_invalid_token_returns_HTTPBad_Request(self):
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.pending_retraction)

        res = self.app.get(self.registration.web_url_for(
            'node_registration_retraction_approve', token=fake.sentence()),
                           auth=self.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_GET_approve_with_valid_token_returns_redirect(self):
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.pending_retraction)

        approval_token = self.registration.retraction.approval_state[
            self.user._id]['approval_token']
        res = self.app.get(self.registration.web_url_for(
            'node_registration_retraction_approve', token=approval_token),
                           auth=self.auth)
        self.registration.retraction.reload()
        assert_true(self.registration.is_retracted)
        assert_false(self.registration.pending_retraction)
        assert_equal(res.status_code, 302)

    def test_GET_approve_with_wrong_admins_token_returns_HTTPBad_Request(self):
        user2 = AuthUserFactory()
        self.registration.contributors.append(user2)
        self.registration.add_permission(user2, 'admin', save=True)
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.pending_retraction)
        assert_equal(len(self.registration.retraction.approval_state), 2)

        wrong_approval_token = self.registration.retraction.approval_state[
            user2._id]['approval_token']
        res = self.app.get(self.registration.web_url_for(
            'node_registration_retraction_approve',
            token=wrong_approval_token),
                           auth=self.auth,
                           expect_errors=True)
        assert_true(self.registration.pending_retraction)
        assert_equal(res.status_code, 400)

    # node_registration_retraction_disapprove_tests
    def test_GET_disapprove_from_unauthorized_user_raises_HTTPForbidden(self):
        unauthorized_user = AuthUserFactory()

        res = self.app.get(self.registration.web_url_for(
            'node_registration_retraction_disapprove', token=fake.sentence()),
                           auth=unauthorized_user.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_GET_disapprove_registration_without_retraction_returns_HTTPBad_Request(
            self):
        assert_false(self.registration.pending_retraction)

        res = self.app.get(self.registration.web_url_for(
            'node_registration_retraction_disapprove', token=fake.sentence()),
                           auth=self.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_GET_disapprove_with_invalid_token_returns_HTTPBad_Request(self):
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.pending_retraction)

        res = self.app.get(self.registration.web_url_for(
            'node_registration_retraction_disapprove', token=fake.sentence()),
                           auth=self.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 400)

    def test_GET_disapprove_with_wrong_admins_token_returns_HTTPBad_Request(
            self):
        user2 = AuthUserFactory()
        self.registration.contributors.append(user2)
        self.registration.add_permission(user2, 'admin', save=True)
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.pending_retraction)
        assert_equal(len(self.registration.retraction.approval_state), 2)

        wrong_disapproval_token = self.registration.retraction.approval_state[
            user2._id]['disapproval_token']
        res = self.app.get(self.registration.web_url_for(
            'node_registration_retraction_disapprove',
            token=wrong_disapproval_token),
                           auth=self.auth,
                           expect_errors=True)
        assert_true(self.registration.pending_retraction)
        assert_equal(res.status_code, 400)

    def test_GET_disapprove_with_valid_token_returns_redirect(self):
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.pending_retraction)

        disapproval_token = self.registration.retraction.approval_state[
            self.user._id]['disapproval_token']
        res = self.app.get(
            self.registration.web_url_for(
                'node_registration_retraction_disapprove',
                token=disapproval_token),
            auth=self.auth,
        )
        self.registration.retraction.reload()
        assert_false(self.registration.is_retracted)
        assert_false(self.registration.pending_retraction)
        assert_equal(self.registration.retraction.state, Retraction.CANCELLED)
        assert_equal(res.status_code, 302)