Ejemplo n.º 1
0
class RegistrationRetractionModelsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationRetractionModelsTestCase, self).setUp()
        self.user = UserFactory()
        self.registration = RegistrationFactory(creator=self.user, is_public=True)
        self.valid_justification = fake.sentence()
        self.invalid_justification = fake.text(max_nb_chars=3000)

    def test_set_public_registration_to_private_raises_NodeStateException(self):
        self.registration.save()
        with assert_raises(NodeStateError):
            self.registration.set_privacy('private')
        self.registration.reload()

        assert_true(self.registration.is_public)

    def test_initiate_retraction_saves_retraction(self):
        initial_count = Retraction.find().count()
        self.registration._initiate_retraction(self.user)
        assert_equal(Retraction.find().count(), initial_count + 1)

    def test__initiate_retraction_does_not_create_tokens_for_unregistered_admin(self):
        unconfirmed_user = UnconfirmedUserFactory()
        self.registration.contributors.append(unconfirmed_user)
        self.registration.add_permission(unconfirmed_user, 'admin', save=True)
        assert_true(self.registration.has_permission(unconfirmed_user, 'admin'))

        retraction = self.registration._initiate_retraction(self.user)
        assert_true(self.user._id in retraction.approval_state)
        assert_false(unconfirmed_user._id in retraction.approval_state)

    def test__initiate_retraction_adds_admins_on_child_nodes(self):
        project_admin = UserFactory()
        project_non_admin = UserFactory()
        child_admin = UserFactory()
        child_non_admin = UserFactory()
        grandchild_admin = UserFactory()

        project = ProjectFactory(creator=project_admin)
        project.add_contributor(project_non_admin, auth=Auth(project.creator), save=True)

        child = NodeFactory(creator=child_admin, parent=project)
        child.add_contributor(child_non_admin, auth=Auth(child.creator), save=True)

        grandchild = NodeFactory(creator=grandchild_admin, parent=child)  # noqa

        registration = RegistrationFactory(project=project)

        retraction = registration._initiate_retraction(registration.creator)
        assert_in(project_admin._id, retraction.approval_state)
        assert_in(child_admin._id, retraction.approval_state)
        assert_in(grandchild_admin._id, retraction.approval_state)

        assert_not_in(project_non_admin._id, retraction.approval_state)
        assert_not_in(child_non_admin._id, retraction.approval_state)

    # Backref tests
    def test_retraction_initiator_has_backref(self):
        self.registration.retract_registration(self.user, self.valid_justification)
        self.registration.save()
        self.registration.reload()
        assert_equal(Retraction.find(Q('initiated_by', 'eq', self.user)).count(), 1)

    # Node#retract_registration tests
    def test_pending_retract(self):
        self.registration.retract_registration(self.user, self.valid_justification)
        self.registration.save()
        self.registration.reload()

        assert_false(self.registration.is_retracted)
        assert_equal(self.registration.retraction.state, Retraction.UNAPPROVED)
        assert_equal(self.registration.retraction.justification, self.valid_justification)
        assert_equal(self.registration.retraction.initiated_by, self.user)
        assert_equal(
            self.registration.retraction.initiation_date.date(),
            datetime.datetime.utcnow().date()
        )

    def test_retract_component_raises_NodeStateError(self):
        project = ProjectFactory(is_public=True, creator=self.user)
        component = NodeFactory(is_public=True, creator=self.user, parent=project)
        registration = RegistrationFactory(is_public=True, project=project)

        with assert_raises(NodeStateError):
            registration.nodes[0].retract_registration(self.user, self.valid_justification)

    def test_long_justification_raises_ValidationValueError(self):
        with assert_raises(ValidationValueError):
            self.registration.retract_registration(self.user, self.invalid_justification)
            self.registration.save()
        self.registration.reload()
        assert_is_none(self.registration.retraction)

    def test_retract_private_registration_raises_NodeStateError(self):
        self.registration.is_public = False
        with assert_raises(NodeStateError):
            self.registration.retract_registration(self.user, self.valid_justification)
            self.registration.save()
        self.registration.reload()
        assert_is_none(self.registration.retraction)

    def test_retract_public_non_registration_raises_NodeStateError(self):
        project = ProjectFactory(is_public=True, creator=self.user)
        project.save()
        with assert_raises(NodeStateError):
            project.retract_registration(self.user, self.valid_justification)

        project.reload()
        assert_is_none(project.retraction)

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

        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.is_pending_retraction)

        approval_token = self.registration.retraction.approval_state[self.user._id]['approval_token']
        self.registration.retraction.approve_retraction(self.user, approval_token)
        assert_false(self.registration.is_pending_retraction)
        assert_true(self.registration.is_retracted)
        assert_false(self.registration.is_pending_embargo)
        assert_true(self.registration.embargo.is_rejected)

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

        embargo_approval_token = self.registration.embargo.approval_state[self.user._id]['approval_token']
        self.registration.embargo.approve_embargo(self.user, embargo_approval_token)
        assert_false(self.registration.is_pending_embargo)
        assert_true(self.registration.embargo_end_date)

        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.is_pending_retraction)

        retraction_approval_token = self.registration.retraction.approval_state[self.user._id]['approval_token']
        self.registration.retraction.approve_retraction(self.user, retraction_approval_token)
        assert_false(self.registration.is_pending_retraction)
        assert_true(self.registration.is_retracted)
        assert_false(self.registration.is_pending_embargo)
        assert_true(self.registration.embargo.is_rejected)

    # Retraction#approve_retraction_tests
    def test_invalid_approval_token_raises_InvalidSanctionApprovalToken(self):
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.is_pending_retraction)

        with assert_raises(InvalidSanctionApprovalToken):
            self.registration.retraction.approve_retraction(self.user, fake.sentence())
        assert_true(self.registration.is_pending_retraction)
        assert_false(self.registration.is_retracted)

    def test_non_admin_approval_token_raises_PermissionsError(self):
        non_admin = UserFactory()
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.is_pending_retraction)

        approval_token = self.registration.retraction.approval_state[self.user._id]['approval_token']
        with assert_raises(PermissionsError):
            self.registration.retraction.approve_retraction(non_admin, approval_token)
        assert_true(self.registration.is_pending_retraction)
        assert_false(self.registration.is_retracted)

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

        approval_token = self.registration.retraction.approval_state[self.user._id]['approval_token']
        assert_true(self.registration.is_pending_retraction)
        self.registration.retraction.approve_retraction(self.user, approval_token)
        assert_true(self.registration.is_retracted)
        num_of_approvals = sum([val['has_approved'] for val in self.registration.retraction.approval_state.values()])
        assert_equal(num_of_approvals, 1)

    def test_approval_adds_to_parent_projects_log(self):
        initial_project_logs = len(self.registration.registered_from.logs)
        self.registration.retract_registration(self.user)
        self.registration.save()

        approval_token = self.registration.retraction.approval_state[self.user._id]['approval_token']
        self.registration.retraction.approve_retraction(self.user, approval_token)
        # Logs: Created, registered, retraction initiated, retraction approved
        assert_equal(len(self.registration.registered_from.logs), initial_project_logs + 2)

    def test_retraction_of_registration_pending_embargo_cancels_embargo(self):
        self.registration.is_public = True
        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)

        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.is_pending_retraction)

        approval_token = self.registration.retraction.approval_state[self.user._id]['approval_token']
        self.registration.retraction.approve_retraction(self.user, approval_token)
        assert_false(self.registration.is_pending_retraction)
        assert_true(self.registration.is_retracted)
        assert_false(self.registration.is_pending_embargo)
        assert_true(self.registration.embargo.is_rejected)

    def test_approval_of_registration_with_embargo_adds_to_parent_projects_log(self):
        initial_project_logs = len(self.registration.registered_from.logs)
        self.registration.is_public = True
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10),
            for_existing_registration=True
        )
        self.registration.save()

        self.registration.retract_registration(self.user)
        self.registration.save()

        approval_token = self.registration.retraction.approval_state[self.user._id]['approval_token']
        self.registration.retraction.approve_retraction(self.user, approval_token)
        # Logs: Created, registered, embargo initiated, retraction initiated, retraction approved, embargo cancelled
        assert_equal(len(self.registration.registered_from.logs), initial_project_logs + 4)

    def test_retraction_of_registration_in_active_embargo_cancels_embargo(self):
        self.registration.is_public = True
        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)

        embargo_approval_token = self.registration.embargo.approval_state[self.user._id]['approval_token']
        self.registration.embargo.approve_embargo(self.user, embargo_approval_token)
        assert_false(self.registration.is_pending_embargo)
        assert_true(self.registration.embargo_end_date)

        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.is_pending_retraction)

        retraction_approval_token = self.registration.retraction.approval_state[self.user._id]['approval_token']
        self.registration.retraction.approve_retraction(self.user, retraction_approval_token)
        assert_false(self.registration.is_pending_retraction)
        assert_true(self.registration.is_retracted)
        assert_false(self.registration.is_pending_embargo)
        assert_true(self.registration.embargo.is_rejected)

    def test_two_approvals_with_two_admins_retracts(self):
        self.admin2 = UserFactory()
        self.registration.contributors.append(self.admin2)
        self.registration.add_permission(self.admin2, 'admin', save=True)
        self.registration.retract_registration(self.user)
        self.registration.save()
        self.registration.reload()

        # First admin approves
        approval_token = self.registration.retraction.approval_state[self.user._id]['approval_token']
        self.registration.retraction.approve_retraction(self.user, approval_token)
        assert_true(self.registration.is_pending_retraction)
        num_of_approvals = sum([val['has_approved'] for val in self.registration.retraction.approval_state.values()])
        assert_equal(num_of_approvals, 1)

        # Second admin approves
        approval_token = self.registration.retraction.approval_state[self.admin2._id]['approval_token']
        self.registration.retraction.approve_retraction(self.admin2, approval_token)
        num_of_approvals = sum([val['has_approved'] for val in self.registration.retraction.approval_state.values()])
        assert_equal(num_of_approvals, 2)
        assert_true(self.registration.is_retracted)

    def test_one_approval_with_two_admins_stays_pending(self):
        self.admin2 = UserFactory()
        self.registration.contributors.append(self.admin2)
        self.registration.add_permission(self.admin2, 'admin', save=True)

        self.registration.retract_registration(self.user)
        self.registration.save()
        self.registration.reload()

        approval_token = self.registration.retraction.approval_state[self.user._id]['approval_token']
        assert_equal(self.registration.retraction.state, Retraction.UNAPPROVED)
        self.registration.retraction.approve_retraction(self.user, approval_token)
        assert_true(self.registration.is_pending_retraction)
        num_of_approvals = sum([val['has_approved'] for val in self.registration.retraction.approval_state.values()])
        assert_equal(num_of_approvals, 1)

    # Retraction#disapprove_retraction tests
    def test_invalid_rejection_token_raises_InvalidSanctionRejectionToken(self):
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.is_pending_retraction)

        with assert_raises(InvalidSanctionRejectionToken):
            self.registration.retraction.disapprove_retraction(self.user, fake.sentence())
        assert_true(self.registration.is_pending_retraction)
        assert_false(self.registration.is_retracted)

    def test_non_admin_rejection_token_raises_PermissionsError(self):
        non_admin = UserFactory()
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.is_pending_retraction)

        rejection_token = self.registration.retraction.approval_state[self.user._id]['rejection_token']
        with assert_raises(PermissionsError):
            self.registration.retraction.disapprove_retraction(non_admin, rejection_token)
        assert_true(self.registration.is_pending_retraction)
        assert_false(self.registration.is_retracted)

    def test_one_disapproval_cancels_retraction(self):
        self.registration.retract_registration(self.user)
        self.registration.save()
        self.registration.reload()

        rejection_token = self.registration.retraction.approval_state[self.user._id]['rejection_token']
        assert_equal(self.registration.retraction.state, Retraction.UNAPPROVED)
        self.registration.retraction.disapprove_retraction(self.user, rejection_token)
        assert_true(self.registration.retraction.is_rejected)

    def test_disapproval_adds_to_parent_projects_log(self):
        initial_project_logs = len(self.registration.registered_from.logs)
        self.registration.retract_registration(self.user)
        self.registration.save()
        self.registration.reload()

        rejection_token = self.registration.retraction.approval_state[self.user._id]['rejection_token']
        self.registration.retraction.disapprove_retraction(self.user, rejection_token)
        # Logs: Created, registered, retraction initiated, retraction cancelled
        assert_equal(len(self.registration.registered_from.logs), initial_project_logs + 2)

    def test__on_complete_makes_project_and_components_public(self):
        project_admin = UserFactory()
        child_admin = UserFactory()
        grandchild_admin = UserFactory()

        project = ProjectFactory(creator=project_admin, is_public=False)
        child = NodeFactory(creator=child_admin, parent=project, is_public=False)
        grandchild = NodeFactory(creator=grandchild_admin, parent=child, is_public=False)  # noqa

        registration = RegistrationFactory(project=project)
        registration._initiate_retraction(self.user)
        registration.retraction._on_complete(self.user)
        for each in registration.node_and_primary_descendants():
            assert_true(each.is_public)

    # Retraction property tests
    def test_new_retraction_is_pending_retraction(self):
        self.registration.retract_registration(self.user)
        assert_true(self.registration.is_pending_retraction)
        assert_false(self.registration.is_retracted)
Ejemplo n.º 2
0
class RegistrationWithChildNodesRetractionModelTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationWithChildNodesRetractionModelTestCase, self).setUp()
        self.user = AuthUserFactory()
        self.auth = self.user.auth
        self.project = ProjectFactory(is_public=True, creator=self.user)
        self.component = NodeFactory(
            creator=self.user,
            parent=self.project,
            title='Component'
        )
        self.subproject = ProjectFactory(
            creator=self.user,
            parent=self.project,
            title='Subproject'
        )
        self.subproject_component = NodeFactory(
            creator=self.user,
            parent=self.subproject,
            title='Subcomponent'
        )
        self.registration = RegistrationFactory(project=self.project, is_public=True)
        # Reload the registration; else tests won't catch failures to svae
        self.registration.reload()

    def test_approval_retracts_descendant_nodes(self):
        # Initiate retraction for parent registration
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.is_pending_retraction)

        # Ensure descendant nodes are pending registration
        descendants = self.registration.get_descendants_recursive()
        for node in descendants:
            node.save()
            assert_true(node.is_pending_retraction)

        # Approve parent registration's retraction
        approval_token = self.registration.retraction.approval_state[self.user._id]['approval_token']
        self.registration.retraction.approve_retraction(self.user, approval_token)
        assert_true(self.registration.is_retracted)

        # Ensure descendant nodes are retracted
        descendants = self.registration.get_descendants_recursive()
        for node in descendants:
            assert_true(node.is_retracted)

    def test_disapproval_cancels_retraction_on_descendant_nodes(self):
        # Initiate retraction for parent registration
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.is_pending_retraction)

        # Ensure descendant nodes are pending registration
        descendants = self.registration.get_descendants_recursive()
        for node in descendants:
            node.save()
            assert_true(node.is_pending_retraction)

        # Disapprove parent registration's retraction
        rejection_token = self.registration.retraction.approval_state[self.user._id]['rejection_token']
        self.registration.retraction.disapprove_retraction(self.user, rejection_token)
        assert_false(self.registration.is_pending_retraction)
        assert_false(self.registration.is_retracted)
        assert_true(self.registration.retraction.is_rejected)

        # Ensure descendant nodes' retractions are cancelled
        descendants = self.registration.get_descendants_recursive()
        for node in descendants:
            assert_false(node.is_pending_retraction)
            assert_false(node.is_retracted)

    def test_approval_cancels_pending_embargoes_on_descendant_nodes(self):
        # Initiate embargo for registration
        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)

        # Initiate retraction for parent registration
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.is_pending_retraction)

        # Ensure descendant nodes are pending embargo
        descendants = self.registration.get_descendants_recursive()
        for node in descendants:
            assert_true(node.is_pending_retraction)
            assert_true(node.is_pending_embargo)

        # Approve parent registration's retraction
        approval_token = self.registration.retraction.approval_state[self.user._id]['approval_token']
        self.registration.retraction.approve_retraction(self.user, approval_token)
        assert_true(self.registration.is_retracted)
        assert_false(self.registration.is_pending_embargo)

        # Ensure descendant nodes are not pending embargo
        descendants = self.registration.get_descendants_recursive()
        for node in descendants:
            assert_true(node.is_retracted)
            assert_false(node.is_pending_embargo)

    def test_approval_cancels_active_embargoes_on_descendant_nodes(self):
        # Initiate embargo for registration
        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)

        # Approve embargo for registration
        embargo_approval_token = self.registration.embargo.approval_state[self.user._id]['approval_token']
        self.registration.embargo.approve_embargo(self.user, embargo_approval_token)
        assert_false(self.registration.is_pending_embargo)
        assert_true(self.registration.embargo_end_date)

        # Initiate retraction for parent registration
        self.registration.retract_registration(self.user)
        self.registration.save()
        assert_true(self.registration.is_pending_retraction)

        # Ensure descendant nodes are not pending embargo
        descendants = self.registration.get_descendants_recursive()
        for node in descendants:
            assert_true(node.is_pending_retraction)
            assert_true(node.embargo_end_date)

        # Approve parent registration's retraction
        approval_token = self.registration.retraction.approval_state[self.user._id]['approval_token']
        self.registration.retraction.approve_retraction(self.user, approval_token)
        assert_true(self.registration.is_retracted)

        # Ensure descendant nodes are not pending embargo
        descendants = self.registration.get_descendants_recursive()
        for node in descendants:
            assert_true(node.is_retracted)
Ejemplo n.º 3
0
class TestNodeWikiList(ApiWikiTestCase):
    def _set_up_public_project_with_wiki_page(self):
        self.public_project = ProjectFactory(is_public=True, creator=self.user)
        self.public_wiki = self._add_project_wiki_page(self.public_project,
                                                       self.user)
        self.public_url = '/{}nodes/{}/wikis/'.format(API_BASE,
                                                      self.public_project._id)

    def _set_up_private_project_with_wiki_page(self):
        self.private_project = ProjectFactory(creator=self.user)
        self.private_wiki = self._add_project_wiki_page(
            self.private_project, self.user)
        self.private_url = '/{}nodes/{}/wikis/'.format(
            API_BASE, self.private_project._id)

    def _set_up_registration_with_wiki_page(self):
        self._set_up_private_project_with_wiki_page()
        self.registration = RegistrationFactory(project=self.private_project,
                                                user=self.user)
        self.registration_wiki_id = self.registration.wiki_pages_versions[
            'home'][0]
        self.registration.wiki_pages_current = {
            'home': self.registration_wiki_id
        }
        self.registration.save()
        self.registration_url = '/{}registrations/{}/wikis/'.format(
            API_BASE, self.registration._id)

    def test_return_public_node_wikis_logged_out_user(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url)
        assert_equal(res.status_code, 200)
        wiki_ids = [wiki['id'] for wiki in res.json['data']]
        assert_in(self.public_wiki._id, wiki_ids)

    def test_return_public_node_wikis_logged_in_non_contributor(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url, auth=self.non_contributor.auth)
        assert_equal(res.status_code, 200)
        wiki_ids = [wiki['id'] for wiki in res.json['data']]
        assert_in(self.public_wiki._id, wiki_ids)

    def test_return_public_node_wikis_logged_in_contributor(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        wiki_ids = [wiki['id'] for wiki in res.json['data']]
        assert_in(self.public_wiki._id, wiki_ids)

    def test_return_private_node_wikis_logged_out_user(self):
        self._set_up_private_project_with_wiki_page()
        res = self.app.get(self.private_url, expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_equal(res.json['errors'][0]['detail'],
                     'Authentication credentials were not provided.')

    def test_return_private_node_wikis_logged_in_non_contributor(self):
        self._set_up_private_project_with_wiki_page()
        res = self.app.get(self.private_url,
                           auth=self.non_contributor.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_equal(res.json['errors'][0]['detail'],
                     'You do not have permission to perform this action.')

    def test_return_private_node_wikis_logged_in_contributor(self):
        self._set_up_private_project_with_wiki_page()
        res = self.app.get(self.private_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        wiki_ids = [wiki['id'] for wiki in res.json['data']]
        assert_in(self.private_wiki._id, wiki_ids)

    def test_return_registration_wikis_logged_out_user(self):
        self._set_up_registration_with_wiki_page()
        res = self.app.get(self.registration_url, expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_equal(res.json['errors'][0]['detail'],
                     'Authentication credentials were not provided.')

    def test_return_registration_wikis_logged_in_non_contributor(self):
        self._set_up_registration_with_wiki_page()
        res = self.app.get(self.registration_url,
                           auth=self.non_contributor.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_equal(res.json['errors'][0]['detail'],
                     'You do not have permission to perform this action.')

    def test_return_registration_wikis_logged_in_contributor(self):
        self._set_up_registration_with_wiki_page()
        res = self.app.get(self.registration_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        wiki_ids = [wiki['id'] for wiki in res.json['data']]
        assert_in(self.registration_wiki_id, wiki_ids)

    def test_wikis_not_returned_for_withdrawn_registration(self):
        self._set_up_registration_with_wiki_page()
        self.registration.is_public = True
        withdrawal = self.registration.retract_registration(user=self.user,
                                                            save=True)
        token = withdrawal.approval_state.values()[0]['approval_token']
        withdrawal.approve_retraction(self.user, token)
        withdrawal.save()
        res = self.app.get(self.registration_url,
                           auth=self.user.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_equal(res.json['errors'][0]['detail'],
                     'You do not have permission to perform this action.')
Ejemplo n.º 4
0
class TestWikiDetailView(ApiWikiTestCase):

    def _set_up_public_project_with_wiki_page(self):
        self.public_project = ProjectFactory(is_public=True, creator=self.user)
        self.public_wiki = self._add_project_wiki_page(self.public_project, self.user)
        self.public_url = '/{}wikis/{}/'.format(API_BASE, self.public_wiki._id)

    def _set_up_private_project_with_wiki_page(self):
        self.private_project = ProjectFactory(creator=self.user)
        self.private_wiki = self._add_project_wiki_page(self.private_project, self.user)
        self.private_url = '/{}wikis/{}/'.format(API_BASE, self.private_wiki._id)

    def _set_up_public_registration_with_wiki_page(self):
        self._set_up_public_project_with_wiki_page()
        self.public_registration = RegistrationFactory(project=self.public_project, user=self.user, is_public=True)
        self.public_registration_wiki_id = self.public_registration.wiki_pages_versions['home'][0]
        self.public_registration.wiki_pages_current = {'home': self.public_registration_wiki_id}
        self.public_registration.save()
        self.public_registration_url = '/{}wikis/{}/'.format(API_BASE, self.public_registration_wiki_id)

    def _set_up_private_registration_with_wiki_page(self):
        self._set_up_private_project_with_wiki_page()
        self.private_registration = RegistrationFactory(project=self.private_project, user=self.user)
        self.private_registration_wiki_id = self.private_registration.wiki_pages_versions['home'][0]
        self.private_registration.wiki_pages_current = {'home': self.private_registration_wiki_id}
        self.private_registration.save()
        self.private_registration_url = '/{}wikis/{}/'.format(API_BASE, self.private_registration_wiki_id)

    def test_public_node_logged_out_user_can_view_wiki(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url)
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['id'], self.public_wiki._id)

    def test_public_node_logged_in_non_contributor_can_view_wiki(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url, auth=self.non_contributor.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['id'], self.public_wiki._id)

    def test_public_node_logged_in_contributor_can_view_wiki(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['id'], self.public_wiki._id)

    def test_private_node_logged_out_user_cannot_view_wiki(self):
        self._set_up_private_project_with_wiki_page()
        res = self.app.get(self.private_url, expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_equal(res.json['errors'][0]['detail'], 'Authentication credentials were not provided.')

    def test_private_node_logged_in_non_contributor_cannot_view_wiki(self):
        self._set_up_private_project_with_wiki_page()
        res = self.app.get(self.private_url, auth=self.non_contributor.auth, expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.')

    def test_private_node_logged_in_contributor_can_view_wiki(self):
        self._set_up_private_project_with_wiki_page()
        res = self.app.get(self.private_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['id'], self.private_wiki._id)

    def test_private_node_user_with_anonymous_link_can_view_wiki(self):
        self._set_up_private_project_with_wiki_page()
        private_link = PrivateLinkFactory(anonymous=True)
        private_link.nodes.append(self.private_project)
        private_link.save()
        url = furl.furl(self.private_url).add(query_params={'view_only': private_link.key}).url
        res = self.app.get(url)
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['id'], self.private_wiki._id)

    def test_private_node_user_with_view_only_link_can_view_wiki(self):
        self._set_up_private_project_with_wiki_page()
        private_link = PrivateLinkFactory(anonymous=False)
        private_link.nodes.append(self.private_project)
        private_link.save()
        url = furl.furl(self.private_url).add(query_params={'view_only': private_link.key}).url
        res = self.app.get(url)
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['id'], self.private_wiki._id)

    def test_public_registration_logged_out_user_cannot_view_wiki(self):
        self._set_up_public_registration_with_wiki_page()
        res = self.app.get(self.public_registration_url, expect_errors=True)
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['id'], self.public_registration_wiki_id)

    def test_public_registration_logged_in_non_contributor_cannot_view_wiki(self):
        self._set_up_public_registration_with_wiki_page()
        res = self.app.get(self.public_registration_url, auth=self.non_contributor.auth, expect_errors=True)
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['id'], self.public_registration_wiki_id)

    def test_public_registration_contributor_can_view_wiki(self):
        self._set_up_public_registration_with_wiki_page()
        res = self.app.get(self.public_registration_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['id'], self.public_registration_wiki_id)

    def test_user_cannot_view_withdrawn_registration_wikis(self):
        self._set_up_public_registration_with_wiki_page()
        withdrawal = self.public_registration.retract_registration(user=self.user, save=True)
        token = withdrawal.approval_state.values()[0]['approval_token']
        withdrawal.approve_retraction(self.user, token)
        withdrawal.save()
        res = self.app.get(self.public_registration_url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.')

    def test_private_registration_logged_out_user_cannot_view_wiki(self):
        self._set_up_private_registration_with_wiki_page()
        res = self.app.get(self.private_registration_url, expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_equal(res.json['errors'][0]['detail'], 'Authentication credentials were not provided.')

    def test_private_registration_logged_in_non_contributor_cannot_view_wiki(self):
        self._set_up_private_registration_with_wiki_page()
        res = self.app.get(self.private_registration_url, auth=self.non_contributor.auth, expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.')

    def test_private_registration_contributor_can_view_wiki(self):
        self._set_up_private_registration_with_wiki_page()
        res = self.app.get(self.private_registration_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['id'], self.private_registration_wiki_id)

    def test_wiki_has_user_link(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url)
        url = res.json['data']['relationships']['user']['links']['related']['href']
        expected_url = '/{}users/{}/'.format(API_BASE, self.user._id)
        assert_equal(res.status_code, 200)
        assert_equal(urlparse(url).path, expected_url)

    def test_wiki_has_node_link(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url)
        url = res.json['data']['relationships']['node']['links']['related']['href']
        expected_url = '/{}nodes/{}/'.format(API_BASE, self.public_project._id)
        assert_equal(res.status_code, 200)
        assert_equal(urlparse(url).path, expected_url)

    def test_wiki_has_comments_link(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url)
        url = res.json['data']['relationships']['comments']['links']['related']['href']
        expected_url = '/{}nodes/{}/comments/?filter[target]={}'.format(API_BASE, self.public_project._id, self.public_wiki._id)
        assert_equal(res.status_code, 200)
        assert_in(expected_url, url)

    def test_wiki_has_download_link(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url)
        url = res.json['data']['links']['download']
        expected_url = '/{}wikis/{}/content/'.format(API_BASE, self.public_wiki._id)
        assert_equal(res.status_code, 200)
        assert_in(expected_url, url)

    def test_wiki_invalid_id_not_found(self):
        url = '/{}wikis/{}/'.format(API_BASE, 'abcde')
        res = self.app.get(url, expect_errors=True)
        assert_equal(res.status_code, 404)

    def test_old_wiki_versions_not_returned(self):
        self._set_up_public_project_with_wiki_page()
        current_wiki = NodeWikiFactory(node=self.public_project, user=self.user)
        old_version_id = self.public_project.wiki_pages_versions[current_wiki.page_name][-2]
        old_version = NodeWikiPage.load(old_version_id)
        url = '/{}wikis/{}/'.format(API_BASE, old_version._id)
        res = self.app.get(url, expect_errors=True)
        assert_equal(res.status_code, 404)
Ejemplo n.º 5
0
class TestRetractRegistrations(OsfTestCase):

    def setUp(self):
        super(TestRetractRegistrations, self).setUp()
        self.user = UserFactory()
        self.registration = RegistrationFactory(creator=self.user)
        self.registration.is_public = True
        self.registration.retract_registration(self.user)
        self.registration.save()

    def test_new_retraction_should_not_be_retracted(self):
        assert_false(self.registration.is_retracted)

        main(dry_run=False)
        assert_false(self.registration.is_retracted)

    def test_should_not_retract_pending_retraction_less_than_48_hours_old(self):
        # Retraction#iniation_date is read only
        self.registration.retraction._fields['initiation_date'].__set__(
            self.registration.retraction,
            (timezone.now() - timedelta(hours=47)),
            safe=True
        )
        # setattr(self.registration.retraction, 'initiation_date', (timezone.now() - timedelta(hours=47)))
        self.registration.retraction.save()
        assert_false(self.registration.is_retracted)

        main(dry_run=False)
        assert_false(self.registration.is_retracted)

    def test_should_retract_pending_retraction_that_is_48_hours_old(self):
        # Retraction#iniation_date is read only
        self.registration.retraction._fields['initiation_date'].__set__(
            self.registration.retraction,
            (timezone.now() - timedelta(hours=48)),
            safe=True
        )
        self.registration.retraction.save()
        assert_false(self.registration.is_retracted)

        main(dry_run=False)
        assert_true(self.registration.is_retracted)

    def test_should_retract_pending_retraction_more_than_48_hours_old(self):
        # Retraction#iniation_date is read only
        self.registration.retraction._fields['initiation_date'].__set__(
            self.registration.retraction,
            (timezone.now() - timedelta(days=365)),
            safe=True
        )
        self.registration.retraction.save()
        assert_false(self.registration.is_retracted)

        main(dry_run=False)
        assert_true(self.registration.is_retracted)

    def test_retraction_adds_to_parent_projects_log(self):
        initial_project_logs = len(self.registration.registered_from.logs)
        # Retraction#iniation_date is read only
        self.registration.retraction._fields['initiation_date'].__set__(
            self.registration.retraction,
            (timezone.now() - timedelta(days=365)),
            safe=True
        )
        self.registration.retraction.save()
        assert_false(self.registration.is_retracted)

        main(dry_run=False)
        assert_true(self.registration.is_retracted)
        # Logs: Created, made public, retraction initiated, retracted approved
        assert_equal(len(self.registration.registered_from.logs), initial_project_logs + 1)
Ejemplo n.º 6
0
class TestRegistrationRetractions(SearchTestCase):
    def setUp(self):
        super(TestRegistrationRetractions, self).setUp()
        self.user = UserFactory(usename='Doug Bogie')
        self.title = 'Red Special'
        self.consolidate_auth = Auth(user=self.user)
        self.project = ProjectFactory(
            title=self.title,
            creator=self.user,
            is_public=True,
        )
        self.registration = RegistrationFactory(project=self.project,
                                                title=self.title,
                                                creator=self.user,
                                                is_public=True,
                                                is_registration=True)

    def test_retraction_is_searchable(self):

        self.registration.retract_registration(self.user)
        docs = query('category:registration AND ' + self.title)['results']
        assert_equal(len(docs), 1)

    @mock.patch('website.project.model.Node.archiving',
                mock.PropertyMock(return_value=False))
    def test_pending_retraction_wiki_content_is_searchable(self):
        # Add unique string to wiki
        wiki_content = {'home': 'public retraction test'}
        for key, value in wiki_content.items():
            docs = query(value)['results']
            assert_equal(len(docs), 0)
            self.registration.update_node_wiki(
                key,
                value,
                self.consolidate_auth,
            )
            # Query and ensure unique string shows up
            docs = query(value)['results']
            assert_equal(len(docs), 1)

        # Query and ensure registration does show up
        docs = query('category:registration AND ' + self.title)['results']
        assert_equal(len(docs), 1)

        # Retract registration
        self.registration.retract_registration(self.user, '')
        self.registration.save()
        self.registration.reload()

        # Query and ensure unique string in wiki doesn't show up
        docs = query('category:registration AND "{}"'.format(
            wiki_content['home']))['results']
        assert_equal(len(docs), 1)

        # Query and ensure registration does show up
        docs = query('category:registration AND ' + self.title)['results']
        assert_equal(len(docs), 1)

    @mock.patch('website.project.model.Node.archiving',
                mock.PropertyMock(return_value=False))
    def test_retraction_wiki_content_is_not_searchable(self):
        # Add unique string to wiki
        wiki_content = {'home': 'public retraction test'}
        for key, value in wiki_content.items():
            docs = query(value)['results']
            assert_equal(len(docs), 0)
            self.registration.update_node_wiki(
                key,
                value,
                self.consolidate_auth,
            )
            # Query and ensure unique string shows up
            docs = query(value)['results']
            assert_equal(len(docs), 1)

        # Query and ensure registration does show up
        docs = query('category:registration AND ' + self.title)['results']
        assert_equal(len(docs), 1)

        # Retract registration
        self.registration.retract_registration(self.user, '')
        self.registration.retraction.state = 'retracted'
        self.registration.retraction.save()
        self.registration.save()
        self.registration.update_search()

        # Query and ensure unique string in wiki doesn't show up
        docs = query('category:registration AND "{}"'.format(
            wiki_content['home']))['results']
        assert_equal(len(docs), 0)

        # Query and ensure registration does show up
        docs = query('category:registration AND ' + self.title)['results']
        assert_equal(len(docs), 1)
Ejemplo n.º 7
0
class TestWikiContentView(ApiWikiTestCase):

    def _set_up_public_project_with_wiki_page(self):
        self.public_project = ProjectFactory(is_public=True, creator=self.user)
        self.public_wiki = self._add_project_wiki_page(self.public_project, self.user)
        self.public_url = '/{}wikis/{}/content/'.format(API_BASE, self.public_wiki._id)

    def _set_up_private_project_with_wiki_page(self):
        self.private_project = ProjectFactory(creator=self.user)
        self.private_wiki = self._add_project_wiki_page(self.private_project, self.user)
        self.private_url = '/{}wikis/{}/content/'.format(API_BASE, self.private_wiki._id)

    def _set_up_public_registration_with_wiki_page(self):
        self._set_up_public_project_with_wiki_page()
        self.public_registration = RegistrationFactory(project=self.public_project, user=self.user, is_public=True)
        self.public_registration_wiki_id = self.public_registration.wiki_pages_versions['home'][0]
        self.public_registration.wiki_pages_current = {'home': self.public_registration_wiki_id}
        self.public_registration.save()
        self.public_registration_url = '/{}wikis/{}/content/'.format(API_BASE, self.public_registration_wiki_id)

    def test_logged_out_user_can_get_public_wiki_content(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url)
        assert_equal(res.status_code, 200)
        assert_equal(res.content_type, 'text/markdown')
        assert_equal(res.body, self.public_wiki.content)

    def test_logged_in_non_contributor_can_get_public_wiki_content(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url, auth=self.non_contributor.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.content_type, 'text/markdown')
        assert_equal(res.body, self.public_wiki.content)

    def test_logged_in_contributor_can_get_public_wiki_content(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.content_type, 'text/markdown')
        assert_equal(res.body, self.public_wiki.content)

    def test_logged_out_user_cannot_get_private_wiki_content(self):
        self._set_up_private_project_with_wiki_page()
        res = self.app.get(self.private_url, expect_errors=True)
        assert_equal(res.status_code, 401)

    def test_logged_in_non_contributor_cannot_get_private_wiki_content(self):
        self._set_up_private_project_with_wiki_page()
        res = self.app.get(self.private_url, auth=self.non_contributor.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_logged_in_contributor_can_get_private_wiki_content(self):
        self._set_up_private_project_with_wiki_page()
        res = self.app.get(self.private_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.content_type, 'text/markdown')
        assert_equal(res.body, self.private_wiki.content)

    def test_user_cannot_get_withdrawn_registration_wiki_content(self):
        self._set_up_public_registration_with_wiki_page()
        withdrawal = self.public_registration.retract_registration(user=self.user, save=True)
        token = withdrawal.approval_state.values()[0]['approval_token']
        withdrawal.approve_retraction(self.user, token)
        withdrawal.save()
        res = self.app.get(self.public_registration_url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
class TestRegistrationRetractions(SearchTestCase):

    def setUp(self):
        super(TestRegistrationRetractions, self).setUp()
        self.user = UserFactory(usename='Doug Bogie')
        self.title = 'Red Special'
        self.consolidate_auth = Auth(user=self.user)
        self.project = ProjectFactory(
            title=self.title,
            creator=self.user,
            is_public=True,
        )
        self.registration = RegistrationFactory(
            project=self.project,
            title=self.title,
            creator=self.user,
            is_public=True,
            is_registration=True
        )

    def test_retraction_is_searchable(self):

        self.registration.retract_registration(self.user)
        docs = query('category:registration AND ' + self.title)['results']
        assert_equal(len(docs), 1)

    @mock.patch('website.project.model.Node.archiving', mock.PropertyMock(return_value=False))
    def test_pending_retraction_wiki_content_is_searchable(self):
        # Add unique string to wiki
        wiki_content = {'home': 'public retraction test'}
        for key, value in wiki_content.items():
            docs = query(value)['results']
            assert_equal(len(docs), 0)
            self.registration.update_node_wiki(
                key, value, self.consolidate_auth,
            )
            # Query and ensure unique string shows up
            docs = query(value)['results']
            assert_equal(len(docs), 1)

        # Query and ensure registration does show up
        docs = query('category:registration AND ' + self.title)['results']
        assert_equal(len(docs), 1)

        # Retract registration
        self.registration.retract_registration(self.user, '')
        self.registration.save()
        self.registration.reload()

        # Query and ensure unique string in wiki doesn't show up
        docs = query('category:registration AND "{}"'.format(wiki_content['home']))['results']
        assert_equal(len(docs), 1)

        # Query and ensure registration does show up
        docs = query('category:registration AND ' + self.title)['results']
        assert_equal(len(docs), 1)

    @mock.patch('website.project.model.Node.archiving', mock.PropertyMock(return_value=False))
    def test_retraction_wiki_content_is_not_searchable(self):
        # Add unique string to wiki
        wiki_content = {'home': 'public retraction test'}
        for key, value in wiki_content.items():
            docs = query(value)['results']
            assert_equal(len(docs), 0)
            self.registration.update_node_wiki(
                key, value, self.consolidate_auth,
            )
            # Query and ensure unique string shows up
            docs = query(value)['results']
            assert_equal(len(docs), 1)

        # Query and ensure registration does show up
        docs = query('category:registration AND ' + self.title)['results']
        assert_equal(len(docs), 1)

        # Retract registration
        self.registration.retract_registration(self.user, '')
        self.registration.retraction.state = Retraction.APPROVED
        self.registration.retraction.save()
        self.registration.save()
        self.registration.update_search()

        # Query and ensure unique string in wiki doesn't show up
        docs = query('category:registration AND "{}"'.format(wiki_content['home']))['results']
        assert_equal(len(docs), 0)

        # Query and ensure registration does show up
        docs = query('category:registration AND ' + self.title)['results']
        assert_equal(len(docs), 1)
Ejemplo n.º 10
0
class TestNodeWikiList(ApiWikiTestCase):

    def _set_up_public_project_with_wiki_page(self):
        self.public_project = ProjectFactory(is_public=True, creator=self.user)
        self.public_wiki = self._add_project_wiki_page(self.public_project, self.user)
        self.public_url = '/{}nodes/{}/wikis/'.format(API_BASE, self.public_project._id)

    def _set_up_private_project_with_wiki_page(self):
        self.private_project = ProjectFactory(creator=self.user)
        self.private_wiki = self._add_project_wiki_page(self.private_project, self.user)
        self.private_url = '/{}nodes/{}/wikis/'.format(API_BASE, self.private_project._id)

    def _set_up_public_registration_with_wiki_page(self):
        self._set_up_public_project_with_wiki_page()
        self.public_registration = RegistrationFactory(project=self.public_project, user=self.user, is_public=True)
        self.public_registration_wiki_id = self.public_registration.wiki_pages_versions['home'][0]
        self.public_registration.wiki_pages_current = {'home': self.public_registration_wiki_id}
        self.public_registration.save()
        self.public_registration_url = '/{}registrations/{}/wikis/'.format(API_BASE, self.public_registration._id)

    def _set_up_registration_with_wiki_page(self):
        self._set_up_private_project_with_wiki_page()
        self.registration = RegistrationFactory(project=self.private_project, user=self.user)
        self.registration_wiki_id = self.registration.wiki_pages_versions['home'][0]
        self.registration.wiki_pages_current = {'home': self.registration_wiki_id}
        self.registration.save()
        self.registration_url = '/{}registrations/{}/wikis/'.format(API_BASE, self.registration._id)

    def test_return_public_node_wikis_logged_out_user(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url)
        assert_equal(res.status_code, 200)
        wiki_ids = [wiki['id'] for wiki in res.json['data']]
        assert_in(self.public_wiki._id, wiki_ids)

    def test_return_public_node_wikis_logged_in_non_contributor(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url, auth=self.non_contributor.auth)
        assert_equal(res.status_code, 200)
        wiki_ids = [wiki['id'] for wiki in res.json['data']]
        assert_in(self.public_wiki._id, wiki_ids)

    def test_return_public_node_wikis_logged_in_contributor(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        wiki_ids = [wiki['id'] for wiki in res.json['data']]
        assert_in(self.public_wiki._id, wiki_ids)

    def test_return_private_node_wikis_logged_out_user(self):
        self._set_up_private_project_with_wiki_page()
        res = self.app.get(self.private_url, expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_equal(res.json['errors'][0]['detail'], 'Authentication credentials were not provided.')

    def test_return_private_node_wikis_logged_in_non_contributor(self):
        self._set_up_private_project_with_wiki_page()
        res = self.app.get(self.private_url, auth=self.non_contributor.auth, expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.')

    def test_return_private_node_wikis_logged_in_contributor(self):
        self._set_up_private_project_with_wiki_page()
        res = self.app.get(self.private_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        wiki_ids = [wiki['id'] for wiki in res.json['data']]
        assert_in(self.private_wiki._id, wiki_ids)

    def test_return_registration_wikis_logged_out_user(self):
        self._set_up_registration_with_wiki_page()
        res = self.app.get(self.registration_url, expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_equal(res.json['errors'][0]['detail'], 'Authentication credentials were not provided.')

    def test_return_registration_wikis_logged_in_non_contributor(self):
        self._set_up_registration_with_wiki_page()
        res = self.app.get(self.registration_url, auth=self.non_contributor.auth, expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.')

    def test_return_registration_wikis_logged_in_contributor(self):
        self._set_up_registration_with_wiki_page()
        res = self.app.get(self.registration_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        wiki_ids = [wiki['id'] for wiki in res.json['data']]
        assert_in(self.registration_wiki_id, wiki_ids)

    def test_wikis_not_returned_for_withdrawn_registration(self):
        self._set_up_registration_with_wiki_page()
        self.registration.is_public = True
        withdrawal = self.registration.retract_registration(user=self.user, save=True)
        token = withdrawal.approval_state.values()[0]['approval_token']
        withdrawal.approve_retraction(self.user, token)
        withdrawal.save()
        res = self.app.get(self.registration_url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.')

    def test_public_node_wikis_relationship_links(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url)
        expected_nodes_relationship_url = '{}nodes/{}/'.format(API_BASE, self.public_project._id)
        expected_comments_relationship_url = '{}nodes/{}/comments/'.format(API_BASE, self.public_project._id)
        assert_in(expected_nodes_relationship_url, res.json['data'][0]['relationships']['node']['links']['related']['href'])
        assert_in(expected_comments_relationship_url, res.json['data'][0]['relationships']['comments']['links']['related']['href'])

    def test_private_node_wikis_relationship_links(self):
        self._set_up_private_project_with_wiki_page()
        res = self.app.get(self.private_url, auth=self.user.auth)
        expected_nodes_relationship_url = '{}nodes/{}/'.format(API_BASE, self.private_project._id)
        expected_comments_relationship_url = '{}nodes/{}/comments/'.format(API_BASE, self.private_project._id)
        assert_in(expected_nodes_relationship_url, res.json['data'][0]['relationships']['node']['links']['related']['href'])
        assert_in(expected_comments_relationship_url, res.json['data'][0]['relationships']['comments']['links']['related']['href'])

    def test_public_registration_wikis_relationship_links(self):
        self._set_up_public_registration_with_wiki_page()
        res = self.app.get(self.public_registration_url)
        expected_nodes_relationship_url = '{}registrations/{}/'.format(API_BASE, self.public_registration._id)
        expected_comments_relationship_url = '{}registrations/{}/comments/'.format(API_BASE, self.public_registration._id)
        assert_in(expected_nodes_relationship_url, res.json['data'][0]['relationships']['node']['links']['related']['href'])
        assert_in(expected_comments_relationship_url, res.json['data'][0]['relationships']['comments']['links']['related']['href'])

    def test_private_registration_wikis_relationship_links(self):
        self._set_up_registration_with_wiki_page()
        res = self.app.get(self.registration_url, auth=self.user.auth)
        expected_nodes_relationship_url = '{}registrations/{}/'.format(API_BASE, self.registration._id)
        expected_comments_relationship_url = '{}registrations/{}/comments/'.format(API_BASE, self.registration._id)
        assert_in(expected_nodes_relationship_url, res.json['data'][0]['relationships']['node']['links']['related']['href'])
        assert_in(expected_comments_relationship_url, res.json['data'][0]['relationships']['comments']['links']['related']['href'])

    def test_registration_wikis_not_returned_from_nodes_endpoint(self):
        self._set_up_public_project_with_wiki_page()
        self._set_up_public_registration_with_wiki_page()
        res = self.app.get(self.public_url)
        node_relationships = [
            node_wiki['relationships']['node']['links']['related']['href']
            for node_wiki in res.json['data']
        ]
        assert_equal(res.status_code, 200)
        assert_equal(len(node_relationships), 1)
        assert_in(self.public_project._id, node_relationships[0])

    def test_node_wikis_not_returned_from_registrations_endpoint(self):
        self._set_up_public_project_with_wiki_page()
        self._set_up_public_registration_with_wiki_page()
        res = self.app.get(self.public_registration_url)
        node_relationships = [
            node_wiki['relationships']['node']['links']['related']['href']
            for node_wiki in res.json['data']
            ]
        assert_equal(res.status_code, 200)
        assert_equal(len(node_relationships), 1)
        assert_in(self.public_registration._id, node_relationships[0])
Ejemplo n.º 11
0
class TestNodeWikiList(ApiWikiTestCase):
    def _set_up_public_project_with_wiki_page(self):
        self.public_project = ProjectFactory(is_public=True, creator=self.user)
        self.public_wiki = self._add_project_wiki_page(self.public_project, self.user)
        self.public_url = "/{}nodes/{}/wikis/".format(API_BASE, self.public_project._id)

    def _set_up_private_project_with_wiki_page(self):
        self.private_project = ProjectFactory(creator=self.user)
        self.private_wiki = self._add_project_wiki_page(self.private_project, self.user)
        self.private_url = "/{}nodes/{}/wikis/".format(API_BASE, self.private_project._id)

    def _set_up_registration_with_wiki_page(self):
        self._set_up_private_project_with_wiki_page()
        self.registration = RegistrationFactory(project=self.private_project, user=self.user)
        self.registration_wiki_id = self.registration.wiki_pages_versions["home"][0]
        self.registration.wiki_pages_current = {"home": self.registration_wiki_id}
        self.registration.save()
        self.registration_url = "/{}registrations/{}/wikis/".format(API_BASE, self.registration._id)

    def test_return_public_node_wikis_logged_out_user(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url)
        assert_equal(res.status_code, 200)
        wiki_ids = [wiki["id"] for wiki in res.json["data"]]
        assert_in(self.public_wiki._id, wiki_ids)

    def test_return_public_node_wikis_logged_in_non_contributor(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url, auth=self.non_contributor.auth)
        assert_equal(res.status_code, 200)
        wiki_ids = [wiki["id"] for wiki in res.json["data"]]
        assert_in(self.public_wiki._id, wiki_ids)

    def test_return_public_node_wikis_logged_in_contributor(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        wiki_ids = [wiki["id"] for wiki in res.json["data"]]
        assert_in(self.public_wiki._id, wiki_ids)

    def test_return_private_node_wikis_logged_out_user(self):
        self._set_up_private_project_with_wiki_page()
        res = self.app.get(self.private_url, expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_equal(res.json["errors"][0]["detail"], "Authentication credentials were not provided.")

    def test_return_private_node_wikis_logged_in_non_contributor(self):
        self._set_up_private_project_with_wiki_page()
        res = self.app.get(self.private_url, auth=self.non_contributor.auth, expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_equal(res.json["errors"][0]["detail"], "You do not have permission to perform this action.")

    def test_return_private_node_wikis_logged_in_contributor(self):
        self._set_up_private_project_with_wiki_page()
        res = self.app.get(self.private_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        wiki_ids = [wiki["id"] for wiki in res.json["data"]]
        assert_in(self.private_wiki._id, wiki_ids)

    def test_return_registration_wikis_logged_out_user(self):
        self._set_up_registration_with_wiki_page()
        res = self.app.get(self.registration_url, expect_errors=True)
        assert_equal(res.status_code, 401)
        assert_equal(res.json["errors"][0]["detail"], "Authentication credentials were not provided.")

    def test_return_registration_wikis_logged_in_non_contributor(self):
        self._set_up_registration_with_wiki_page()
        res = self.app.get(self.registration_url, auth=self.non_contributor.auth, expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_equal(res.json["errors"][0]["detail"], "You do not have permission to perform this action.")

    def test_return_registration_wikis_logged_in_contributor(self):
        self._set_up_registration_with_wiki_page()
        res = self.app.get(self.registration_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        wiki_ids = [wiki["id"] for wiki in res.json["data"]]
        assert_in(self.registration_wiki_id, wiki_ids)

    def test_wikis_not_returned_for_withdrawn_registration(self):
        self._set_up_registration_with_wiki_page()
        self.registration.is_public = True
        withdrawal = self.registration.retract_registration(user=self.user, save=True)
        token = withdrawal.approval_state.values()[0]["approval_token"]
        withdrawal.approve_retraction(self.user, token)
        withdrawal.save()
        res = self.app.get(self.registration_url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)
        assert_equal(res.json["errors"][0]["detail"], "You do not have permission to perform this action.")
Ejemplo n.º 12
0
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)
Ejemplo n.º 13
0
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)
Ejemplo n.º 14
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)
Ejemplo n.º 15
0
class TestWikiContentView(ApiWikiTestCase):
    def _set_up_public_project_with_wiki_page(self):
        self.public_project = ProjectFactory(is_public=True, creator=self.user)
        self.public_wiki = self._add_project_wiki_page(self.public_project,
                                                       self.user)
        self.public_url = '/{}wikis/{}/content/'.format(
            API_BASE, self.public_wiki._id)

    def _set_up_private_project_with_wiki_page(self):
        self.private_project = ProjectFactory(creator=self.user)
        self.private_wiki = self._add_project_wiki_page(
            self.private_project, self.user)
        self.private_url = '/{}wikis/{}/content/'.format(
            API_BASE, self.private_wiki._id)

    def _set_up_public_registration_with_wiki_page(self):
        self._set_up_public_project_with_wiki_page()
        self.public_registration = RegistrationFactory(
            project=self.public_project, user=self.user, is_public=True)
        self.public_registration_wiki_id = self.public_registration.wiki_pages_versions[
            'home'][0]
        self.public_registration.wiki_pages_current = {
            'home': self.public_registration_wiki_id
        }
        self.public_registration.save()
        self.public_registration_url = '/{}wikis/{}/content/'.format(
            API_BASE, self.public_registration_wiki_id)

    def test_logged_out_user_can_get_public_wiki_content(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url)
        assert_equal(res.status_code, 200)
        assert_equal(res.content_type, 'text/markdown')
        assert_equal(res.body, self.public_wiki.content)

    def test_logged_in_non_contributor_can_get_public_wiki_content(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url, auth=self.non_contributor.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.content_type, 'text/markdown')
        assert_equal(res.body, self.public_wiki.content)

    def test_logged_in_contributor_can_get_public_wiki_content(self):
        self._set_up_public_project_with_wiki_page()
        res = self.app.get(self.public_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.content_type, 'text/markdown')
        assert_equal(res.body, self.public_wiki.content)

    def test_logged_out_user_cannot_get_private_wiki_content(self):
        self._set_up_private_project_with_wiki_page()
        res = self.app.get(self.private_url, expect_errors=True)
        assert_equal(res.status_code, 401)

    def test_logged_in_non_contributor_cannot_get_private_wiki_content(self):
        self._set_up_private_project_with_wiki_page()
        res = self.app.get(self.private_url,
                           auth=self.non_contributor.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_logged_in_contributor_can_get_private_wiki_content(self):
        self._set_up_private_project_with_wiki_page()
        res = self.app.get(self.private_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.content_type, 'text/markdown')
        assert_equal(res.body, self.private_wiki.content)

    def test_user_cannot_get_withdrawn_registration_wiki_content(self):
        self._set_up_public_registration_with_wiki_page()
        withdrawal = self.public_registration.retract_registration(
            user=self.user, save=True)
        token = withdrawal.approval_state.values()[0]['approval_token']
        withdrawal.approve_retraction(self.user, token)
        withdrawal.save()
        res = self.app.get(self.public_registration_url,
                           auth=self.user.auth,
                           expect_errors=True)
        assert_equal(res.status_code, 403)
Ejemplo n.º 16
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)
Ejemplo n.º 17
0
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)