Example #1
0
    def test_rejecting_embargo_for_existing_registration_does_not_deleted_component_registrations(self):
        component = NodeFactory(
            creator=self.user,
            parent=self.project,
            title='Component'
        )
        NodeFactory(  # subcomponent
            creator=self.user,
            parent=component,
            title='Subcomponent'
        )
        project_registration = RegistrationFactory(project=self.project)
        component_registration = project_registration._nodes.first()
        subcomponent_registration = component_registration._nodes.first()
        project_registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10),
            for_existing_registration=True
        )

        rejection_token = project_registration.embargo.approval_state[self.user._id]['rejection_token']
        project_registration.embargo.disapprove_embargo(self.user, rejection_token)
        project_registration.save()
        assert_equal(project_registration.embargo.state, Embargo.REJECTED)
        assert_false(project_registration.is_deleted)
        assert_false(component_registration.is_deleted)
        assert_false(subcomponent_registration.is_deleted)
Example #2
0
    def test_make_child_embargoed_registration_public_asks_all_admins_in_tree(
            self, mock_ask):
        # Initiate and approve embargo
        node = NodeFactory(creator=self.user)
        c1 = AuthUserFactory()
        child = NodeFactory(parent=node, creator=c1)
        c2 = AuthUserFactory()
        NodeFactory(parent=child, creator=c2)
        registration = RegistrationFactory(project=node)

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

        res = self.app.post(registration.api_url_for('project_set_privacy',
                                                     permissions='public'),
                            auth=self.user.auth)
        assert_equal(res.status_code, 200)
        asked_admins = [(admin._id, n._id)
                        for admin, n in mock_ask.call_args[0][0]]
        for admin, node in registration.get_admin_contributors_recursive():
            assert_in((admin._id, node._id), asked_admins)
    def test_rejecting_embargo_for_existing_registration_does_not_deleted_component_registrations(self):
        component = NodeFactory(
            creator=self.user,
            parent=self.project,
            title='Component'
        )
        NodeFactory(  # subcomponent
            creator=self.user,
            parent=component,
            title='Subcomponent'
        )
        project_registration = RegistrationFactory(project=self.project)
        component_registration = project_registration._nodes.first()
        subcomponent_registration = component_registration._nodes.first()
        project_registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10),
            for_existing_registration=True
        )

        rejection_token = project_registration.embargo.approval_state[self.user._id]['rejection_token']
        project_registration.embargo.disapprove_embargo(self.user, rejection_token)
        project_registration.save()
        assert_equal(project_registration.embargo.state, Embargo.REJECTED)
        assert_false(project_registration.is_deleted)
        assert_false(component_registration.is_deleted)
        assert_false(subcomponent_registration.is_deleted)
Example #4
0
    def test_GET_disapprove_with_valid(self):
        project = ProjectFactory(creator=self.user)
        registration = RegistrationFactory(project=project)
        registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        registration.save()
        assert_true(registration.is_pending_embargo)

        rejection_token = registration.embargo.approval_state[self.user._id]['rejection_token']

        res = self.app.get(
            registration.registered_from.web_url_for('view_project', token=rejection_token),
            auth=self.user.auth,
        )
        registration.embargo.reload()
        assert_equal(registration.embargo.state, Embargo.REJECTED)
        assert_false(registration.is_pending_embargo)
        assert_equal(res.status_code, 200)
        assert_equal(project.web_url_for('view_project'), res.request.path)
    def test_GET_disapprove_with_valid(self):
        project = ProjectFactory(creator=self.user)
        registration = RegistrationFactory(project=project)
        registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        registration.save()
        assert_true(registration.is_pending_embargo)

        rejection_token = registration.embargo.approval_state[self.user._id]['rejection_token']

        res = self.app.get(
            registration.registered_from.web_url_for('view_project', token=rejection_token),
            auth=self.user.auth,
        )
        registration.embargo.reload()
        assert_equal(registration.embargo.state, Embargo.REJECTED)
        assert_false(registration.is_pending_embargo)
        assert_equal(res.status_code, 200)
        assert_equal(project.web_url_for('view_project'), res.request.path)
Example #6
0
    def test_make_child_embargoed_registration_public_asks_all_admins_in_tree(self, mock_ask):
        # Initiate and approve embargo
        node = NodeFactory(creator=self.user)
        c1 = AuthUserFactory()
        child = NodeFactory(parent=node, creator=c1)
        c2 = AuthUserFactory()
        NodeFactory(parent=child, creator=c2)
        registration = RegistrationFactory(project=node)

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

        registration.set_privacy('public', Auth(self.registration.creator))
        asked_admins = [(admin._id, n._id) for admin, n in mock_ask.call_args[0][0]]
        for admin, node in registration.get_admin_contributors_recursive():
            assert_in((admin._id, node._id), asked_admins)
Example #7
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_unregistered_contributor(
            unreg.fullname,
            unreg.email,
            auth=Auth(self.user),
            permissions=['read', 'write', 'admin'],
            existing_user=unreg)
        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, (timezone.now() + 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, (timezone.now() + 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 = self.registration.registered_from.logs.count()
        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(self.registration.registered_from.logs.count(),
                     initial_project_logs + 1)

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

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

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

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

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

        disapproval_url = self.registration.web_url_for('view_project',
                                                        token=rejection_token)
        res = self.app.get(disapproval_url,
                           auth=non_contributor.auth,
                           expect_errors=True)
        assert_equal(res.status_code, http.UNAUTHORIZED)
        assert_true(self.registration.is_pending_retraction)
        assert_false(self.registration.is_retracted)
class RegistrationEmbargoModelsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationEmbargoModelsTestCase, self).setUp()
        self.user = UserFactory()
        self.project = ProjectFactory(creator=self.user)
        self.registration = RegistrationFactory(project=self.project)
        self.embargo = EmbargoFactory(user=self.user)
        self.valid_embargo_end_date = timezone.now() + datetime.timedelta(days=3)

    # Node#_initiate_embargo tests
    def test__initiate_embargo_saves_embargo(self):
        initial_count = Embargo.find().count()
        self.registration._initiate_embargo(
            self.user,
            self.valid_embargo_end_date,
            for_existing_registration=True
        )
        assert_equal(Embargo.find().count(), initial_count + 1)

    def test_state_can_be_set_to_complete(self):
        embargo = EmbargoFactory()
        embargo.state = Embargo.COMPLETED
        embargo.save()  # should pass validation
        assert_equal(embargo.state, Embargo.COMPLETED)

    def test__initiate_embargo_does_not_create_tokens_for_unregistered_admin(self):
        unconfirmed_user = UnconfirmedUserFactory()
        Contributor.objects.create(user=unconfirmed_user, node=self.registration)
        self.registration.add_permission(unconfirmed_user, 'admin', save=True)
        assert_true(self.registration.has_permission(unconfirmed_user, 'admin'))

        embargo = self.registration._initiate_embargo(
            self.user,
            self.valid_embargo_end_date,
            for_existing_registration=True
        )
        assert_true(self.user._id in embargo.approval_state)
        assert_false(unconfirmed_user._id in embargo.approval_state)

    def test__initiate_embargo_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)

        embargo = registration._initiate_embargo(
            project.creator,
            self.valid_embargo_end_date,
            for_existing_registration=True
        )
        assert_in(project_admin._id, embargo.approval_state)
        assert_in(child_admin._id, embargo.approval_state)
        assert_in(grandchild_admin._id, embargo.approval_state)

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

    def test__initiate_embargo_with_save_does_save_embargo(self):
        initial_count = Embargo.find().count()
        self.registration._initiate_embargo(
            self.user,
            self.valid_embargo_end_date,
            for_existing_registration=True,
        )
        assert_equal(Embargo.find().count(), initial_count + 1)

    # Node#embargo_registration tests
    def test_embargo_from_non_admin_raises_PermissionsError(self):
        self.registration.remove_permission(self.user, 'admin')
        self.registration.save()
        self.registration.reload()
        with assert_raises(PermissionsError):
            self.registration.embargo_registration(self.user, self.valid_embargo_end_date)

    def test_embargo_end_date_in_past_raises_ValueError(self):
        with assert_raises(ValidationError):
            self.registration.embargo_registration(
                self.user,
                datetime.datetime(1999, 1, 1, tzinfo=pytz.utc)
            )

    def test_embargo_end_date_today_raises_ValueError(self):
        with assert_raises(ValidationError):
            self.registration.embargo_registration(
                self.user,
                timezone.now()
            )

    def test_embargo_end_date_in_far_future_raises_ValidationError(self):
        with assert_raises(ValidationError):
            self.registration.embargo_registration(
                self.user,
                datetime.datetime(2099, 1, 1, tzinfo=pytz.utc)
            )

    def test_embargo_with_valid_end_date_starts_pending_embargo(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

    def test_embargo_public_project_makes_private_pending_embargo(self):
        self.registration.is_public = True
        assert_true(self.registration.is_public)
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.is_public)

    # Embargo#approve_embargo tests
    def test_invalid_approval_token_raises_InvalidSanctionApprovalToken(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        invalid_approval_token = 'not a real token'
        with assert_raises(InvalidSanctionApprovalToken):
            self.registration.embargo.approve_embargo(self.user, invalid_approval_token)
        assert_true(self.registration.is_pending_embargo)

    def test_non_admin_approval_token_raises_PermissionsError(self):
        non_admin = UserFactory()
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        approval_token = self.registration.embargo.approval_state[self.user._id]['approval_token']
        with assert_raises(PermissionsError):
            self.registration.embargo.approve_embargo(non_admin, approval_token)
        assert_true(self.registration.is_pending_embargo)

    def test_one_approval_with_one_admin_embargoes(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

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

    def test_approval_adds_to_parent_projects_log(self):
        initial_project_logs = self.registration.registered_from.logs.count()
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()

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

    def test_one_approval_with_two_admins_stays_pending(self):
        admin2 = UserFactory()
        Contributor.objects.create(user=admin2, node=self.registration)
        self.registration.add_permission(admin2, 'admin', save=True)
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()

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

        # Second admin approves
        approval_token = self.registration.embargo.approval_state[admin2._id]['approval_token']
        self.registration.embargo.approve_embargo(admin2, approval_token)
        assert_true(self.registration.embargo_end_date)
        assert_false(self.registration.is_pending_embargo)
        num_of_approvals = sum([val['has_approved'] for val in self.registration.embargo.approval_state.values()])
        assert_equal(num_of_approvals, 2)

    # Embargo#disapprove_embargo tests
    def test_invalid_rejection_token_raises_InvalidSanctionRejectionToken(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)
        with assert_raises(InvalidSanctionRejectionToken):
            self.registration.embargo.disapprove_embargo(self.user, fake.sentence())
        assert_true(self.registration.is_pending_embargo)

    def test_non_admin_rejection_token_raises_PermissionsError(self):
        non_admin = UserFactory()
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        rejection_token = self.registration.embargo.approval_state[self.user._id]['rejection_token']
        with assert_raises(PermissionsError):
            self.registration.embargo.disapprove_embargo(non_admin, rejection_token)
        assert_true(self.registration.is_pending_embargo)

    def test_one_disapproval_cancels_embargo(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        rejection_token = self.registration.embargo.approval_state[self.user._id]['rejection_token']
        self.registration.embargo.disapprove_embargo(self.user, rejection_token)
        assert_equal(self.registration.embargo.state, Embargo.REJECTED)
        assert_false(self.registration.is_pending_embargo)

    def test_disapproval_adds_to_parent_projects_log(self):
        initial_project_logs = self.registration.registered_from.logs.count()
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()

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

    def test_cancelling_embargo_deletes_parent_registration(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()

        rejection_token = self.registration.embargo.approval_state[self.user._id]['rejection_token']
        self.registration.embargo.disapprove_embargo(self.user, rejection_token)
        self.registration.reload()
        assert_equal(self.registration.embargo.state, Embargo.REJECTED)
        assert_true(self.registration.is_deleted)

    def test_cancelling_embargo_deletes_component_registrations(self):
        component = NodeFactory(
            creator=self.user,
            parent=self.project,
            title='Component'
        )
        NodeFactory(  # subcomponent
            creator=self.user,
            parent=component,
            title='Subcomponent'
        )
        project_registration = RegistrationFactory(project=self.project)
        component_registration = project_registration._nodes.first()
        subcomponent_registration = component_registration._nodes.first()
        project_registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        project_registration.save()

        rejection_token = project_registration.embargo.approval_state[self.user._id]['rejection_token']
        project_registration.embargo.disapprove_embargo(self.user, rejection_token)
        assert_equal(project_registration.embargo.state, Embargo.REJECTED)
        project_registration.reload()
        assert_true(project_registration.is_deleted)
        component_registration.reload()
        assert_true(component_registration.is_deleted)
        subcomponent_registration.reload()
        assert_true(subcomponent_registration.is_deleted)

    def test_cancelling_embargo_for_existing_registration_does_not_delete_registration(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10),
            for_existing_registration=True
        )
        self.registration.save()

        rejection_token = self.registration.embargo.approval_state[self.user._id]['rejection_token']
        self.registration.embargo.disapprove_embargo(self.user, rejection_token)
        assert_equal(self.registration.embargo.state, Embargo.REJECTED)
        assert_false(self.registration.is_deleted)

    def test_rejecting_embargo_for_existing_registration_does_not_deleted_component_registrations(self):
        component = NodeFactory(
            creator=self.user,
            parent=self.project,
            title='Component'
        )
        NodeFactory(  # subcomponent
            creator=self.user,
            parent=component,
            title='Subcomponent'
        )
        project_registration = RegistrationFactory(project=self.project)
        component_registration = project_registration._nodes.first()
        subcomponent_registration = component_registration._nodes.first()
        project_registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10),
            for_existing_registration=True
        )

        rejection_token = project_registration.embargo.approval_state[self.user._id]['rejection_token']
        project_registration.embargo.disapprove_embargo(self.user, rejection_token)
        project_registration.save()
        assert_equal(project_registration.embargo.state, Embargo.REJECTED)
        assert_false(project_registration.is_deleted)
        assert_false(component_registration.is_deleted)
        assert_false(subcomponent_registration.is_deleted)

    # Embargo property tests
    def test_new_registration_is_pending_registration(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo_for_existing_registration)

    def test_existing_registration_is_not_pending_registration(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10),
            for_existing_registration=True
        )
        self.registration.save()
        assert_false(self.registration.is_pending_embargo_for_existing_registration)

    def test_on_complete_notify_initiator(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10),
            notify_initiator_on_complete=True
        )
        self.registration.save()
        with mock.patch.object(PreregCallbackMixin, '_notify_initiator') as mock_notify:
            self.registration.embargo._on_complete(self.user)
        assert_equal(mock_notify.call_count, 1)

    def test_on_complete_raises_error_if_registration_is_spam(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10),
            notify_initiator_on_complete=True
        )
        self.registration.spam_status = SpamStatus.FLAGGED
        self.registration.save()
        with mock.patch.object(PreregCallbackMixin, '_notify_initiator') as mock_notify:
            with assert_raises(NodeStateError):
                self.registration.embargo._on_complete(self.user)
        assert_equal(mock_notify.call_count, 0)

    # Regression for OSF-8840
    def test_public_embargo_cannot_be_deleted_with_initial_token(self):
        embargo_termination_approval = EmbargoTerminationApprovalFactory()
        registration = Registration.objects.get(embargo_termination_approval=embargo_termination_approval)
        user = registration.contributors.first()

        registration.terminate_embargo(Auth(user))  

        rejection_token = registration.embargo.approval_state[user._id]['rejection_token']
        with assert_raises(HTTPError) as e:
            registration.embargo.disapprove_embargo(user, rejection_token)

        registration.refresh_from_db()
        assert registration.is_deleted is False
Example #9
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.objects.all().count()
        self.registration._initiate_retraction(self.user)
        assert_equal(Retraction.objects.all().count(), initial_count + 1)

    def test__initiate_retraction_does_not_create_tokens_for_unregistered_admin(
            self):
        unconfirmed_user = UnconfirmedUserFactory()
        Contributor.objects.create(node=self.registration,
                                   user=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.objects.filter(initiated_by=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(),
                     timezone.now().date())

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

        with assert_raises(NodeStateError):
            registration._nodes.first().retract_registration(
                self.user, self.valid_justification)

    def test_long_justification_raises_ValidationValueError(self):
        with assert_raises(DataError):
            self.registration.retract_registration(self.user,
                                                   self.invalid_justification)
            self.registration.save()
        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_retraction_of_registration_pending_embargo_cancels_embargo(self):
        self.registration.embargo_registration(
            self.user, (timezone.now() + 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)
        self.registration.embargo.reload()
        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, (timezone.now() + 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)
        self.registration.embargo.reload()
        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 = self.registration.registered_from.logs.count()
        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(self.registration.registered_from.logs.count(),
                     initial_project_logs + 2)

    def test_retraction_of_registration_pending_embargo_cancels_embargo_public(
            self):
        self.registration.is_public = True
        self.registration.embargo_registration(self.user,
                                               timezone.now() +
                                               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)
        self.registration.embargo.reload()
        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 = self.registration.registered_from.logs.count()
        self.registration.is_public = True
        self.registration.embargo_registration(self.user,
                                               timezone.now() +
                                               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(self.registration.registered_from.logs.count(),
                     initial_project_logs + 4)

    def test_retraction_of_public_registration_in_active_embargo_cancels_embargo(
            self):
        self.registration.is_public = True
        self.registration.embargo_registration(self.user,
                                               timezone.now() +
                                               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)
        self.registration.embargo.reload()
        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()
        Contributor.objects.create(node=self.registration, user=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()
        Contributor.objects.create(node=self.registration, user=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 = self.registration.registered_from.logs.count()
        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(self.registration.registered_from.logs.count(),
                     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():
            each.reload()
            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)
Example #10
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()

    @mock.patch('website.project.tasks.format_node')
    @mock.patch('website.project.tasks.format_registration')
    @mock.patch('website.project.tasks.settings.SHARE_URL', 'ima_real_website')
    @mock.patch('website.project.tasks.settings.SHARE_API_TOKEN',
                'totaly_real_token')
    @mock.patch('website.project.tasks.send_share_node_data')
    def test_approval_retracts_descendant_nodes(self, mock_update_share,
                                                mock_format_registration,
                                                mock_format_node):
        # 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)

        assert mock_update_share.called
        assert mock_format_registration.called
        assert not mock_format_node.called

    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)

    @mock.patch('website.project.tasks.settings.SHARE_URL', 'ima_real_website')
    @mock.patch('website.project.tasks.settings.SHARE_API_TOKEN',
                'totaly_real_token')
    @mock.patch('website.project.tasks.send_share_node_data')
    def test_approval_cancels_pending_embargoes_on_descendant_nodes(
            self, mock_update_share):
        # Initiate embargo for registration
        self.registration.embargo_registration(self.user,
                                               timezone.now() +
                                               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)
        self.registration.embargo.reload()
        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)

        assert mock_update_share.called

    @mock.patch('website.project.tasks.settings.SHARE_URL', 'ima_real_website')
    @mock.patch('website.project.tasks.settings.SHARE_API_TOKEN',
                'totaly_real_token')
    @mock.patch('website.project.tasks.send_share_node_data')
    def test_approval_cancels_active_embargoes_on_descendant_nodes(
            self, mock_update_share):
        # Initiate embargo for registration
        self.registration.embargo_registration(self.user,
                                               timezone.now() +
                                               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)

        assert mock_update_share.called
Example #11
0
class TestNodeCount(OsfTestCase):

    def setUp(self):
        super(TestNodeCount, self).setUp()

        self.user = UserFactory()

        # 3 Projects - Public, Private, Private Component
        self.public_project = ProjectFactory(is_public=True)
        self.private_project = ProjectFactory(is_public=False)
        self.private_component = ProjectFactory(parent=self.private_project)

        # 5 Registrations - Public, Public Registrations of Private Proj + Component, Embargoed, Withdrawn
        self.public_registration = RegistrationFactory(project=self.public_project, is_public=True)
        self.registration_of_components = RegistrationFactory(project=self.private_project, is_public=True)
        registration_of_component = self.private_component.registrations_all[0]
        registration_of_component.is_public = True
        registration_of_component.save()

        self.embargoed_registration = RegistrationFactory(project=self.public_project, creator=self.public_project.creator)
        self.embargoed_registration.embargo_registration(
            self.embargoed_registration.creator,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.embargoed_registration.save()

        self.reg_to_be_withdrawn = RegistrationFactory(project=self.public_project)
        self.withdrawn_registration = WithdrawnRegistrationFactory(
            registration=self.reg_to_be_withdrawn,
            user=self.reg_to_be_withdrawn.creator
        )

        # Add Deleted Nodes
        self.deleted_node = ProjectFactory(is_deleted=True)
        self.deleted_node2 = ProjectFactory(is_deleted=True)

        self.date = timezone.now() - datetime.timedelta(days=1)

        for node in AbstractNode.objects.all():
            node.created = self.date
            node.save()
        # modify_node_dates_in_mongo(self.date - datetime.timedelta(0.1))

        self.results = NodeSummary().get_events(self.date.date())[0]

    def test_counts(self):

    # test_get_node_count
        nodes = self.results['nodes']

        assert_equal(nodes['total'], 3)  # 2 Projects, 1 component
        assert_equal(nodes['public'], 1)  # 1 Project
        assert_equal(nodes['private'], 2)  # 1 Project, 1 Component
        assert_equal(nodes['total_daily'], 3)  # 2 Projects, 1 component
        assert_equal(nodes['public_daily'], 1)  # 1 Project
        assert_equal(nodes['private_daily'], 2)  # 1 Project, 1 Component

    # test_get_project_count
        projects = self.results['projects']

        assert_equal(projects['total'], 2)
        assert_equal(projects['public'], 1)
        assert_equal(projects['private'], 1)
        assert_equal(projects['total_daily'], 2)
        assert_equal(projects['public_daily'], 1)
        assert_equal(projects['private_daily'], 1)


    # test_get_registered_nodes_count
        registered_nodes = self.results['registered_nodes']

        assert_equal(registered_nodes['total'], 5)
        assert_equal(registered_nodes['public'], 4)  # 3 Registrations, 1 Withdrawn registration
        assert_equal(registered_nodes['withdrawn'], 1)
        assert_equal(registered_nodes['embargoed'], 1)
        assert_equal(registered_nodes['embargoed_v2'], 1)
        assert_equal(registered_nodes['total_daily'], 5)
        assert_equal(registered_nodes['public_daily'], 4)  # 3 Registrations, 1 Withdrawn registration
        assert_equal(registered_nodes['withdrawn_daily'], 1)
        assert_equal(registered_nodes['embargoed_daily'], 1)
        assert_equal(registered_nodes['embargoed_v2_daily'], 1)

    # test_get_registered_projects_count
        registered_projects = self.results['registered_projects']

        assert_equal(registered_projects['total'], 4)  # Not including a Registration Component
        assert_equal(registered_projects['public'], 3)
        assert_equal(registered_projects['withdrawn'], 1)
        assert_equal(registered_projects['embargoed'], 1)
        assert_equal(registered_projects['embargoed_v2'], 1)

        assert_equal(registered_projects['total_daily'], 4)
        assert_equal(registered_projects['public_daily'], 3)
        assert_equal(registered_projects['withdrawn_daily'], 1)
        assert_equal(registered_projects['embargoed_daily'], 1)
        assert_equal(registered_projects['embargoed_v2_daily'], 1)

        # Modify date to zero out dailies
        for node in AbstractNode.objects.all():
            node.created = self.date - datetime.timedelta(days=1)
            node.save()

        self.results = NodeSummary().get_events(self.date.date())[0]

    # test_get_node_count daily zero
        nodes = self.results['nodes']

        assert_equal(nodes['total'], 3)  # 2 Projects, 1 component
        assert_equal(nodes['public'], 1)  # 1 Project
        assert_equal(nodes['private'], 2)  # 1 Project, 1 Component

        assert_equal(nodes['total_daily'], 0)  # 2 Projects, 1 component
        assert_equal(nodes['public_daily'], 0)  # 1 Project
        assert_equal(nodes['private_daily'], 0)  # 1 Project, 1 Component

    # test_get_project_count daily zero
        projects = self.results['projects']

        assert_equal(projects['total'], 2)
        assert_equal(projects['public'], 1)
        assert_equal(projects['private'], 1)

        assert_equal(projects['total_daily'], 0)
        assert_equal(projects['public_daily'], 0)
        assert_equal(projects['private_daily'], 0)

    # test_get_registered_nodes_count daily zero
        registered_nodes = self.results['registered_nodes']

        assert_equal(registered_nodes['total'], 5)
        assert_equal(registered_nodes['public'], 4)  # 3 Registrations, 1 Withdrawn registration
        assert_equal(registered_nodes['withdrawn'], 1)
        assert_equal(registered_nodes['embargoed'], 1)
        assert_equal(registered_nodes['embargoed_v2'], 1)

        assert_equal(registered_nodes['total_daily'], 0)
        assert_equal(registered_nodes['public_daily'], 0)  # 3 Registrations, 1 Withdrawn registration
        assert_equal(registered_nodes['withdrawn_daily'], 0)
        assert_equal(registered_nodes['embargoed_daily'], 0)
        assert_equal(registered_nodes['embargoed_v2_daily'], 0)

    # test_get_registered_projects_count daily zero
        registered_projects = self.results['registered_projects']

        assert_equal(registered_projects['total'], 4)  # Not including a Registration Component
        assert_equal(registered_projects['public'], 3)
        assert_equal(registered_projects['withdrawn'], 1)
        assert_equal(registered_projects['embargoed'], 1)
        assert_equal(registered_projects['embargoed_v2'], 1)

        assert_equal(registered_projects['total_daily'], 0)
        assert_equal(registered_projects['public_daily'], 0)
        assert_equal(registered_projects['withdrawn_daily'], 0)
        assert_equal(registered_projects['embargoed_daily'], 0)
        assert_equal(registered_projects['embargoed_v2_daily'], 0)
Example #12
0
class RegistrationEmbargoViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationEmbargoViewsTestCase, self).setUp()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user)
        self.draft = DraftRegistrationFactory(branched_from=self.project)
        self.registration = RegistrationFactory(project=self.project, creator=self.user)

        current_month = timezone.now().strftime('%B')
        current_year = timezone.now().strftime('%Y')

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

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

        registration = Registration.find().order_by('-registered_date').first()
        assert_not_equal(registration.registration_approval, None)

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

        # Last node directly registered from self.project
        registration = AbstractNode.objects.filter(registered_from=self.project).order_by('-registered_date')[0]

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

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

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

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

        assert_equal(res.status_code, 202)

        registration = Registration.find().order_by('-registered_date').first()

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

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

        # Last node directly registered from self.project
        registration = AbstractNode.objects.filter(registered_from=self.project).order_by('-registered_date')[0]

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

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

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

        assert_equal(res.status_code, 400)

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

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

        self.registration.set_privacy('public', Auth(self.registration.creator))
        for reg in self.registration.node_and_primary_descendants():
            reg.reload()
            assert_false(reg.is_public)
        assert_true(reg.embargo_termination_approval)
        assert_true(reg.embargo_termination_approval.is_pending_approval)

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

        with utils.mock_archive(node, embargo=True, autocomplete=True, autoapprove=True) as reg:
            with assert_raises(NodeStateError):
                reg._nodes.first().request_embargo_termination(Auth(node.creator))

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

        self.registration.set_privacy('public', Auth(self.registration.creator))
        for admin in self.registration.admin_contributors:
            assert_true(any([each[0][0] == admin.username for each in mock_send_mail.call_args_list]))

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

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

        registration.set_privacy('public', Auth(self.registration.creator))
        asked_admins = [(admin._id, n._id) for admin, n in mock_ask.call_args[0][0]]
        for admin, node in registration.get_admin_contributors_recursive():
            assert_in((admin._id, node._id), asked_admins)

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

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

        res = self.app.get(approval_url, auth=non_contributor.auth, expect_errors=True)
        self.registration.reload()
        assert_equal(http.UNAUTHORIZED, res.status_code)
        assert_true(self.registration.is_pending_embargo)
        assert_equal(self.registration.embargo.state, Embargo.UNAPPROVED)

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

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

        res = self.app.get(approval_url, auth=non_contributor.auth, expect_errors=True)
        assert_equal(http.UNAUTHORIZED, res.status_code)
        assert_true(self.registration.is_pending_embargo)
        assert_equal(self.registration.embargo.state, Embargo.UNAPPROVED)
Example #13
0
class RegistrationRetractionModelsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationRetractionModelsTestCase, self).setUp()
        self.mock_registration_update = mock.patch('website.project.tasks.on_registration_updated')
        self.mock_registration_update.start()

        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 tearDown(self):
        self.mock_registration_update.stop()
        super(RegistrationRetractionModelsTestCase, self).tearDown()

    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()
        Contributor.objects.create(node=self.registration, user=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(),
            timezone.now().date()
        )

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

        with assert_raises(NodeStateError):
            registration._nodes.first().retract_registration(self.user, self.valid_justification)

    def test_long_justification_raises_ValidationValueError(self):
        with assert_raises(DataError):
            self.registration.retract_registration(self.user, self.invalid_justification)
            self.registration.save()
        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_retraction_of_registration_pending_embargo_cancels_embargo(self):
        self.registration.embargo_registration(
            self.user,
            (timezone.now() + 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)
        self.registration.embargo.reload()
        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,
            (timezone.now() + 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)
        self.registration.embargo.reload()
        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 = self.registration.registered_from.logs.count()
        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(self.registration.registered_from.logs.count(), initial_project_logs + 2)

    def test_retraction_of_registration_pending_embargo_cancels_embargo_public(self):
        self.registration.is_public = True
        self.registration.embargo_registration(
            self.user,
            timezone.now() + 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)
        self.registration.embargo.reload()
        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 = self.registration.registered_from.logs.count()
        self.registration.is_public = True
        self.registration.embargo_registration(
            self.user,
            timezone.now() + 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(self.registration.registered_from.logs.count(), initial_project_logs + 4)

    def test_retraction_of_public_registration_in_active_embargo_cancels_embargo(self):
        self.registration.is_public = True
        self.registration.embargo_registration(
            self.user,
            timezone.now() + 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)
        self.registration.embargo.reload()
        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()
        Contributor.objects.create(node=self.registration, user=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()
        Contributor.objects.create(node=self.registration, user=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 = self.registration.registered_from.logs.count()
        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(self.registration.registered_from.logs.count(), 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():
            each.reload()
            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)
Example #14
0
class TestRetractRegistrations(OsfTestCase):
    def setUp(self):
        super(TestRetractRegistrations, self).setUp()
        self.user = UserFactory()
        self.registration = RegistrationFactory(creator=self.user)
        self.registration.embargo_registration(
            self.user,
            timezone.now() + timedelta(days=10))
        self.registration.save()

    def test_new_embargo_should_be_unapproved(self):
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)

        main(dry_run=False)
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)

    def test_should_not_activate_pending_embargo_less_than_48_hours_old(self):
        # Embargo#iniation_date is read only
        self.registration.embargo._fields['initiation_date'].__set__(
            self.registration.embargo, (timezone.now() - timedelta(hours=47)),
            safe=True)
        self.registration.embargo.save()
        assert_false(self.registration.embargo_end_date)

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

    def test_should_activate_pending_embargo_that_is_48_hours_old(self):
        # Embargo#iniation_date is read only
        self.registration.embargo._fields['initiation_date'].__set__(
            self.registration.embargo, (timezone.now() - timedelta(hours=48)),
            safe=True)
        self.registration.embargo.save()
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)

        main(dry_run=False)
        assert_false(self.registration.is_pending_embargo)
        assert_true(self.registration.embargo_end_date)

    def test_should_activate_pending_embargo_more_than_48_hours_old(self):
        # Embargo#iniation_date is read only
        self.registration.embargo._fields['initiation_date'].__set__(
            self.registration.embargo, (timezone.now() - timedelta(days=365)),
            safe=True)
        self.registration.embargo.save()
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)

        main(dry_run=False)
        assert_false(self.registration.is_pending_embargo)
        assert_true(self.registration.embargo_end_date)

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

        # Embargo#iniation_date is read only
        self.registration.embargo._fields['end_date'].__set__(
            self.registration.embargo, (timezone.now() - timedelta(days=1)),
            safe=True)
        self.registration.embargo.save()

        assert_false(self.registration.is_public)
        main(dry_run=False)
        assert_true(self.registration.is_public)
        assert_false(self.registration.embargo_end_date)
        assert_false(self.registration.is_pending_embargo)
        assert_equal(self.registration.embargo.state, 'completed')

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

        # Embargo#iniation_date is read only
        self.registration.embargo._fields['end_date'].__set__(
            self.registration.embargo, (timezone.now() + timedelta(days=1)),
            safe=True)
        self.registration.embargo.save()

        assert_false(self.registration.is_public)
        main(dry_run=False)
        assert_false(self.registration.is_public)
        assert_true(self.registration.embargo_end_date)
        assert_false(self.registration.is_pending_embargo)

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

        main(dry_run=False)
        # Logs: Created, made public, registered, embargo initiated, embargo approved
        embargo_approved_log = self.registration.registered_from.logs[
            initial_project_logs + 1]
        assert_equal(len(self.registration.registered_from.logs),
                     initial_project_logs + 1)
        assert_equal(embargo_approved_log.params['node'],
                     self.registration.registered_from._id)

    def test_embargo_completion_adds_to_parent_projects_log(self):
        initial_project_logs = len(self.registration.registered_from.logs)
        approval_token = self.registration.embargo.approval_state[
            self.user._id]['approval_token']
        self.registration.embargo.approve_embargo(self.user, approval_token)
        self.registration.save()

        # Embargo#iniation_date is read only
        self.registration.embargo._fields['end_date'].__set__(
            self.registration.embargo, (timezone.now() - timedelta(days=1)),
            safe=True)
        self.registration.embargo.save()

        main(dry_run=False)
        # Logs: Created, made public, registered, embargo initiated, embargo approved, embargo completed
        embargo_completed_log = self.registration.registered_from.logs[
            initial_project_logs + 1]
        assert_equal(len(self.registration.registered_from.logs),
                     initial_project_logs + 2)
        assert_equal(embargo_completed_log.params['node'],
                     self.registration.registered_from._id)
Example #15
0
class RegistrationWithChildNodesEmbargoModelTestCase(OsfTestCase):

    def setUp(self):
        super(RegistrationWithChildNodesEmbargoModelTestCase, self).setUp()
        self.user = AuthUserFactory()
        self.auth = self.user.auth
        self.valid_embargo_end_date = timezone.now() + datetime.timedelta(days=3)
        self.project = ProjectFactory(title='Root', is_public=False, 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)
        # Reload the registration; else tests won't catch failures to save
        self.registration.reload()

    def test_approval_embargoes_descendant_nodes(self):
        # Initiate embargo for parent registration
        self.registration.embargo_registration(
            self.user,
            self.valid_embargo_end_date
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

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

        # Approve parent registration's embargo
        approval_token = self.registration.embargo.approval_state[self.user._id]['approval_token']
        self.registration.embargo.approve_embargo(self.user, approval_token)
        assert_true(self.registration.embargo.embargo_end_date)

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

    def test_disapproval_cancels_embargo_on_descendant_nodes(self):
        # Initiate embargo on parent registration
        self.registration.embargo_registration(
            self.user,
            self.valid_embargo_end_date
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

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

        # Disapprove parent registration's embargo
        rejection_token = self.registration.embargo.approval_state[self.user._id]['rejection_token']
        self.registration.embargo.disapprove_embargo(self.user, rejection_token)
        assert_false(self.registration.is_pending_embargo)
        assert_equal(self.registration.embargo.state, Embargo.REJECTED)

        # Ensure descendant nodes' embargoes are cancelled
        descendants = self.registration.get_descendants_recursive()
        for node in descendants:
            node.reload()
            assert_false(node.is_pending_embargo)
            assert_false(node.embargo_end_date)
Example #16
0
class RegistrationWithChildNodesRetractionModelTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationWithChildNodesRetractionModelTestCase, self).setUp()
        self.mock_registration_update = mock.patch('website.project.tasks.on_registration_updated')
        self.mock_registration_update.start()

        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 tearDown(self):
        self.mock_registration_update.stop()
        super(RegistrationWithChildNodesRetractionModelTestCase, self).tearDown()

    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,
            timezone.now() + 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)
        self.registration.embargo.reload()
        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,
            timezone.now() + 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)
Example #17
0
class RegistrationRetractionViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationRetractionViewsTestCase, self).setUp()
        self.mock_registration_update = mock.patch('website.project.tasks.on_registration_updated')
        self.mock_registration_update.start()

        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 tearDown(self):
        self.mock_registration_update.stop()
        super(RegistrationRetractionViewsTestCase, self).tearDown()

    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,
            (timezone.now() + 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,
            (timezone.now() + 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 = self.registration.registered_from.logs.count()
        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(self.registration.registered_from.logs.count(), 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)
Example #18
0
class TestNodeCount(OsfTestCase):
    def setUp(self):
        super(TestNodeCount, self).setUp()

        self.user = UserFactory()

        # 3 Projects - Public, Private, Private Component
        self.public_project = ProjectFactory(is_public=True)
        self.private_project = ProjectFactory(is_public=False)
        self.private_component = ProjectFactory(parent=self.private_project)

        # 5 Registrations - Public, Public Registrations of Private Proj + Component, Embargoed, Withdrawn
        self.public_registration = RegistrationFactory(
            project=self.public_project, is_public=True)
        self.registration_of_components = RegistrationFactory(
            project=self.private_project, is_public=True)
        registration_of_component = self.private_component.registrations_all[0]
        registration_of_component.is_public = True
        registration_of_component.save()

        self.embargoed_registration = RegistrationFactory(
            project=self.public_project, creator=self.public_project.creator)
        self.embargoed_registration.embargo_registration(
            self.embargoed_registration.creator,
            timezone.now() + datetime.timedelta(days=10))
        self.embargoed_registration.save()

        self.reg_to_be_withdrawn = RegistrationFactory(
            project=self.public_project)
        self.withdrawn_registration = WithdrawnRegistrationFactory(
            registration=self.reg_to_be_withdrawn,
            user=self.reg_to_be_withdrawn.creator)

        # Add Deleted Nodes
        self.deleted_node = ProjectFactory(is_deleted=True)
        self.deleted_node2 = ProjectFactory(is_deleted=True)

        # Add Spam
        self.spam_node = ProjectFactory(spam_status=2)

        self.date = timezone.now() - datetime.timedelta(days=1)

        for node in AbstractNode.objects.all():
            node.created = self.date
            node.save()
        # modify_node_dates_in_mongo(self.date - datetime.timedelta(0.1))

        self.results = NodeSummary().get_events(self.date.date())[0]

    def test_counts(self):

        # test_get_node_count
        nodes = self.results['nodes']

        assert_equal(nodes['total'], 4)  # 2 Projects, 1 component, 1 spam node
        assert_equal(nodes['total_excluding_spam'],
                     3)  # 2 Projects, 1 component
        assert_equal(nodes['public'], 1)  # 1 Project
        assert_equal(
            nodes['private'],
            3)  # 1 Project, 1 Component, 1 spam node (spam is always private)
        assert_equal(nodes['total_daily'],
                     4)  # 2 Projects, 1 component,  1 spam node
        assert_equal(nodes['total_daily_excluding_spam'],
                     3)  # 2 Projects, 1 component
        assert_equal(nodes['public_daily'], 1)  # 1 Project
        assert_equal(nodes['private_daily'],
                     3)  # 1 Project, 1 Component, 1 spam node

        # test_get_project_count
        projects = self.results['projects']

        assert_equal(projects['total'], 3)
        assert_equal(projects['total_excluding_spam'], 2)
        assert_equal(projects['public'], 1)
        assert_equal(projects['private'], 2)
        assert_equal(projects['total_daily'], 3)
        assert_equal(projects['total_daily_excluding_spam'], 2)
        assert_equal(projects['public_daily'], 1)
        assert_equal(projects['private_daily'], 2)

        # test_get_registered_nodes_count
        registered_nodes = self.results['registered_nodes']

        assert_equal(registered_nodes['total'], 5)
        assert_equal(registered_nodes['public'],
                     4)  # 3 Registrations, 1 Withdrawn registration
        assert_equal(registered_nodes['withdrawn'], 1)
        assert_equal(registered_nodes['embargoed'], 1)
        assert_equal(registered_nodes['embargoed_v2'], 1)
        assert_equal(registered_nodes['total_daily'], 5)
        assert_equal(registered_nodes['public_daily'],
                     4)  # 3 Registrations, 1 Withdrawn registration
        assert_equal(registered_nodes['withdrawn_daily'], 1)
        assert_equal(registered_nodes['embargoed_daily'], 1)
        assert_equal(registered_nodes['embargoed_v2_daily'], 1)

        # test_get_registered_projects_count
        registered_projects = self.results['registered_projects']

        assert_equal(registered_projects['total'],
                     4)  # Not including a Registration Component
        assert_equal(registered_projects['public'], 3)
        assert_equal(registered_projects['withdrawn'], 1)
        assert_equal(registered_projects['embargoed'], 1)
        assert_equal(registered_projects['embargoed_v2'], 1)

        assert_equal(registered_projects['total_daily'], 4)
        assert_equal(registered_projects['public_daily'], 3)
        assert_equal(registered_projects['withdrawn_daily'], 1)
        assert_equal(registered_projects['embargoed_daily'], 1)
        assert_equal(registered_projects['embargoed_v2_daily'], 1)

        # Modify date to zero out dailies
        for node in AbstractNode.objects.all():
            node.created = self.date - datetime.timedelta(days=1)
            node.save()

        self.results = NodeSummary().get_events(self.date.date())[0]

        # test_get_node_count daily zero
        nodes = self.results['nodes']

        assert_equal(nodes['total'], 4)  # 2 Projects, 1 component, 1 spam node
        assert_equal(nodes['public'], 1)  # 1 Project
        assert_equal(nodes['private'],
                     3)  # 1 Project, 1 Component, 1 spam node

        assert_equal(nodes['total_daily'], 0)  # 2 Projects, 1 component
        assert_equal(nodes['total_daily_excluding_spam'], 0)
        assert_equal(nodes['public_daily'], 0)  # 1 Project
        assert_equal(nodes['private_daily'], 0)  # 1 Project, 1 Component

        # test_get_project_count daily zero
        projects = self.results['projects']

        assert_equal(projects['total'], 3)
        assert_equal(projects['public'], 1)
        assert_equal(projects['private'], 2)

        assert_equal(projects['total_daily'], 0)
        assert_equal(projects['total_daily_excluding_spam'], 0)
        assert_equal(projects['public_daily'], 0)
        assert_equal(projects['private_daily'], 0)

        # test_get_registered_nodes_count daily zero
        registered_nodes = self.results['registered_nodes']

        assert_equal(registered_nodes['total'], 5)
        assert_equal(registered_nodes['public'],
                     4)  # 3 Registrations, 1 Withdrawn registration
        assert_equal(registered_nodes['withdrawn'], 1)
        assert_equal(registered_nodes['embargoed'], 1)
        assert_equal(registered_nodes['embargoed_v2'], 1)

        assert_equal(registered_nodes['total_daily'], 0)
        assert_equal(registered_nodes['public_daily'],
                     0)  # 3 Registrations, 1 Withdrawn registration
        assert_equal(registered_nodes['withdrawn_daily'], 0)
        assert_equal(registered_nodes['embargoed_daily'], 0)
        assert_equal(registered_nodes['embargoed_v2_daily'], 0)

        # test_get_registered_projects_count daily zero
        registered_projects = self.results['registered_projects']

        assert_equal(registered_projects['total'],
                     4)  # Not including a Registration Component
        assert_equal(registered_projects['public'], 3)
        assert_equal(registered_projects['withdrawn'], 1)
        assert_equal(registered_projects['embargoed'], 1)
        assert_equal(registered_projects['embargoed_v2'], 1)

        assert_equal(registered_projects['total_daily'], 0)
        assert_equal(registered_projects['public_daily'], 0)
        assert_equal(registered_projects['withdrawn_daily'], 0)
        assert_equal(registered_projects['embargoed_daily'], 0)
        assert_equal(registered_projects['embargoed_v2_daily'], 0)
Example #19
0
class TestRetractRegistrations(OsfTestCase):
    def setUp(self):
        super(TestRetractRegistrations, self).setUp()
        self.user = UserFactory()
        self.registration = RegistrationFactory(creator=self.user)
        self.registration.embargo_registration(
            self.user,
            timezone.now() + timedelta(days=10))
        self.registration.save()

    def test_new_embargo_should_be_unapproved(self):
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)

        main(dry_run=False)
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)

    def test_should_not_activate_pending_embargo_less_than_48_hours_old(self):
        self.registration.embargo.initiation_date = timezone.now() - timedelta(
            hours=47)
        self.registration.embargo.save()
        assert_false(self.registration.embargo_end_date)

        main(dry_run=False)
        self.registration.embargo.refresh_from_db()
        self.registration.refresh_from_db()
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)

    def test_should_activate_pending_embargo_that_is_48_hours_old(self):
        self.registration.embargo.initiation_date = timezone.now() - timedelta(
            hours=48)
        self.registration.embargo.save()
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)

        main(dry_run=False)
        self.registration.embargo.refresh_from_db()
        self.registration.refresh_from_db()
        assert_true(self.registration.is_embargoed)
        assert_true(self.registration.embargo_end_date)

    def test_should_activate_pending_embargo_more_than_48_hours_old(self):
        self.registration.embargo.initiation_date = timezone.now() - timedelta(
            days=365)
        self.registration.embargo.save()
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)

        main(dry_run=False)
        self.registration.embargo.refresh_from_db()
        self.registration.refresh_from_db()
        assert_true(self.registration.is_embargoed)
        assert_false(self.registration.is_pending_embargo)
        assert_true(self.registration.embargo_end_date)

    def test_embargo_past_end_date_should_be_completed(self):
        self.registration.embargo.accept()
        assert_true(self.registration.embargo_end_date)
        assert_false(self.registration.is_pending_embargo)

        self.registration.embargo.end_date = timezone.now() - timedelta(days=1)
        self.registration.embargo.save()

        assert_false(self.registration.is_public)
        main(dry_run=False)
        self.registration.embargo.refresh_from_db()
        self.registration.refresh_from_db()
        assert_true(self.registration.is_public)
        assert_false(self.registration.embargo_end_date)
        assert_false(self.registration.is_pending_embargo)
        assert_equal(self.registration.embargo.state, 'completed')

    def test_embargo_before_end_date_should_not_be_completed(self):
        self.registration.embargo.accept()
        assert_true(self.registration.embargo_end_date)
        assert_false(self.registration.is_pending_embargo)

        self.registration.embargo.end_date = timezone.now() + timedelta(days=1)
        self.registration.embargo.save()

        assert_false(self.registration.is_public)
        main(dry_run=False)
        self.registration.embargo.refresh_from_db()
        assert_false(self.registration.is_public)
        assert_true(self.registration.embargo_end_date)
        assert_false(self.registration.is_pending_embargo)

    def test_embargo_approval_adds_to_parent_projects_log(self):
        assert_false(
            self.registration.registered_from.logs.filter(
                action=NodeLog.EMBARGO_APPROVED).exists())

        self.registration.embargo.initiation_date = timezone.now() - timedelta(
            days=365)
        self.registration.embargo.save()
        main(dry_run=False)

        assert_true(
            self.registration.registered_from.logs.filter(
                action=NodeLog.EMBARGO_APPROVED).exists())

    def test_embargo_completion_adds_to_parent_projects_log(self):
        assert_false(
            self.registration.registered_from.logs.filter(
                action=NodeLog.EMBARGO_COMPLETED).exists())

        self.registration.embargo.accept()
        self.registration.embargo.end_date = timezone.now() - timedelta(days=1)
        self.registration.embargo.save()

        main(dry_run=False)
        assert_true(
            self.registration.registered_from.logs.filter(
                action=NodeLog.EMBARGO_COMPLETED).exists())
Example #20
0
class RegistrationEmbargoModelsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationEmbargoModelsTestCase, self).setUp()
        self.user = UserFactory()
        self.project = ProjectFactory(creator=self.user)
        self.registration = RegistrationFactory(project=self.project)
        self.embargo = EmbargoFactory(user=self.user)
        self.valid_embargo_end_date = timezone.now() + datetime.timedelta(days=3)

    # Node#_initiate_embargo tests
    def test__initiate_embargo_saves_embargo(self):
        initial_count = Embargo.objects.all().count()
        self.registration._initiate_embargo(
            self.user,
            self.valid_embargo_end_date,
            for_existing_registration=True
        )
        assert_equal(Embargo.objects.all().count(), initial_count + 1)

    def test_state_can_be_set_to_complete(self):
        embargo = EmbargoFactory()
        embargo.state = Embargo.COMPLETED
        embargo.save()  # should pass validation
        assert_equal(embargo.state, Embargo.COMPLETED)

    def test__initiate_embargo_does_not_create_tokens_for_unregistered_admin(self):
        unconfirmed_user = UnconfirmedUserFactory()
        Contributor.objects.create(user=unconfirmed_user, node=self.registration)
        self.registration.add_permission(unconfirmed_user, 'admin', save=True)
        assert_true(self.registration.has_permission(unconfirmed_user, 'admin'))

        embargo = self.registration._initiate_embargo(
            self.user,
            self.valid_embargo_end_date,
            for_existing_registration=True
        )
        assert_true(self.user._id in embargo.approval_state)
        assert_false(unconfirmed_user._id in embargo.approval_state)

    def test__initiate_embargo_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)

        embargo = registration._initiate_embargo(
            project.creator,
            self.valid_embargo_end_date,
            for_existing_registration=True
        )
        assert_in(project_admin._id, embargo.approval_state)
        assert_in(child_admin._id, embargo.approval_state)
        assert_in(grandchild_admin._id, embargo.approval_state)

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

    def test__initiate_embargo_with_save_does_save_embargo(self):
        initial_count = Embargo.objects.all().count()
        self.registration._initiate_embargo(
            self.user,
            self.valid_embargo_end_date,
            for_existing_registration=True,
        )
        assert_equal(Embargo.objects.all().count(), initial_count + 1)

    # Node#embargo_registration tests
    def test_embargo_from_non_admin_raises_PermissionsError(self):
        self.registration.remove_permission(self.user, 'admin')
        self.registration.save()
        self.registration.reload()
        with assert_raises(PermissionsError):
            self.registration.embargo_registration(self.user, self.valid_embargo_end_date)

    def test_embargo_end_date_in_past_raises_ValueError(self):
        with assert_raises(ValidationError):
            self.registration.embargo_registration(
                self.user,
                datetime.datetime(1999, 1, 1, tzinfo=pytz.utc)
            )

    def test_embargo_end_date_today_raises_ValueError(self):
        with assert_raises(ValidationError):
            self.registration.embargo_registration(
                self.user,
                timezone.now()
            )

    def test_embargo_end_date_in_far_future_raises_ValidationError(self):
        with assert_raises(ValidationError):
            self.registration.embargo_registration(
                self.user,
                datetime.datetime(2099, 1, 1, tzinfo=pytz.utc)
            )

    def test_embargo_with_valid_end_date_starts_pending_embargo(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

    def test_embargo_public_project_makes_private_pending_embargo(self):
        self.registration.is_public = True
        assert_true(self.registration.is_public)
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.is_public)

    # Embargo#approve_embargo tests
    def test_invalid_approval_token_raises_InvalidSanctionApprovalToken(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        invalid_approval_token = 'not a real token'
        with assert_raises(InvalidSanctionApprovalToken):
            self.registration.embargo.approve_embargo(self.user, invalid_approval_token)
        assert_true(self.registration.is_pending_embargo)

    def test_non_admin_approval_token_raises_PermissionsError(self):
        non_admin = UserFactory()
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        approval_token = self.registration.embargo.approval_state[self.user._id]['approval_token']
        with assert_raises(PermissionsError):
            self.registration.embargo.approve_embargo(non_admin, approval_token)
        assert_true(self.registration.is_pending_embargo)

    def test_one_approval_with_one_admin_embargoes(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

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

    def test_approval_adds_to_parent_projects_log(self):
        initial_project_logs = self.registration.registered_from.logs.count()
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()

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

    def test_one_approval_with_two_admins_stays_pending(self):
        admin2 = UserFactory()
        Contributor.objects.create(user=admin2, node=self.registration)
        self.registration.add_permission(admin2, 'admin', save=True)
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()

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

        # Second admin approves
        approval_token = self.registration.embargo.approval_state[admin2._id]['approval_token']
        self.registration.embargo.approve_embargo(admin2, approval_token)
        assert_true(self.registration.embargo_end_date)
        assert_false(self.registration.is_pending_embargo)
        num_of_approvals = sum([val['has_approved'] for val in self.registration.embargo.approval_state.values()])
        assert_equal(num_of_approvals, 2)

    # Embargo#disapprove_embargo tests
    def test_invalid_rejection_token_raises_InvalidSanctionRejectionToken(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)
        with assert_raises(InvalidSanctionRejectionToken):
            self.registration.embargo.disapprove_embargo(self.user, fake.sentence())
        assert_true(self.registration.is_pending_embargo)

    def test_non_admin_rejection_token_raises_PermissionsError(self):
        non_admin = UserFactory()
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        rejection_token = self.registration.embargo.approval_state[self.user._id]['rejection_token']
        with assert_raises(PermissionsError):
            self.registration.embargo.disapprove_embargo(non_admin, rejection_token)
        assert_true(self.registration.is_pending_embargo)

    def test_one_disapproval_cancels_embargo(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        rejection_token = self.registration.embargo.approval_state[self.user._id]['rejection_token']
        self.registration.embargo.disapprove_embargo(self.user, rejection_token)
        assert_equal(self.registration.embargo.state, Embargo.REJECTED)
        assert_false(self.registration.is_pending_embargo)

    def test_disapproval_adds_to_parent_projects_log(self):
        initial_project_logs = self.registration.registered_from.logs.count()
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()

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

    def test_cancelling_embargo_deletes_parent_registration(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()

        rejection_token = self.registration.embargo.approval_state[self.user._id]['rejection_token']
        self.registration.embargo.disapprove_embargo(self.user, rejection_token)
        self.registration.reload()
        assert_equal(self.registration.embargo.state, Embargo.REJECTED)
        assert_true(self.registration.is_deleted)

    def test_cancelling_embargo_deletes_component_registrations(self):
        component = NodeFactory(
            creator=self.user,
            parent=self.project,
            title='Component'
        )
        NodeFactory(  # subcomponent
            creator=self.user,
            parent=component,
            title='Subcomponent'
        )
        project_registration = RegistrationFactory(project=self.project)
        component_registration = project_registration._nodes.first()
        subcomponent_registration = component_registration._nodes.first()
        project_registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        project_registration.save()

        rejection_token = project_registration.embargo.approval_state[self.user._id]['rejection_token']
        project_registration.embargo.disapprove_embargo(self.user, rejection_token)
        assert_equal(project_registration.embargo.state, Embargo.REJECTED)
        project_registration.reload()
        assert_true(project_registration.is_deleted)
        component_registration.reload()
        assert_true(component_registration.is_deleted)
        subcomponent_registration.reload()
        assert_true(subcomponent_registration.is_deleted)

    def test_cancelling_embargo_for_existing_registration_does_not_delete_registration(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10),
            for_existing_registration=True
        )
        self.registration.save()

        rejection_token = self.registration.embargo.approval_state[self.user._id]['rejection_token']
        self.registration.embargo.disapprove_embargo(self.user, rejection_token)
        assert_equal(self.registration.embargo.state, Embargo.REJECTED)
        assert_false(self.registration.is_deleted)

    def test_rejecting_embargo_for_existing_registration_does_not_deleted_component_registrations(self):
        component = NodeFactory(
            creator=self.user,
            parent=self.project,
            title='Component'
        )
        NodeFactory(  # subcomponent
            creator=self.user,
            parent=component,
            title='Subcomponent'
        )
        project_registration = RegistrationFactory(project=self.project)
        component_registration = project_registration._nodes.first()
        subcomponent_registration = component_registration._nodes.first()
        project_registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10),
            for_existing_registration=True
        )

        rejection_token = project_registration.embargo.approval_state[self.user._id]['rejection_token']
        project_registration.embargo.disapprove_embargo(self.user, rejection_token)
        project_registration.save()
        assert_equal(project_registration.embargo.state, Embargo.REJECTED)
        assert_false(project_registration.is_deleted)
        assert_false(component_registration.is_deleted)
        assert_false(subcomponent_registration.is_deleted)

    # Embargo property tests
    def test_new_registration_is_pending_registration(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo_for_existing_registration)

    def test_existing_registration_is_not_pending_registration(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10),
            for_existing_registration=True
        )
        self.registration.save()
        assert_false(self.registration.is_pending_embargo_for_existing_registration)

    def test_on_complete_notify_initiator(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10),
            notify_initiator_on_complete=True
        )
        self.registration.save()
        with mock.patch.object(PreregCallbackMixin, '_notify_initiator') as mock_notify:
            self.registration.embargo._on_complete(self.user)
        assert_equal(mock_notify.call_count, 1)

    def test_on_complete_raises_error_if_registration_is_spam(self):
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10),
            notify_initiator_on_complete=True
        )
        self.registration.spam_status = SpamStatus.FLAGGED
        self.registration.save()
        with mock.patch.object(PreregCallbackMixin, '_notify_initiator') as mock_notify:
            with assert_raises(NodeStateError):
                self.registration.embargo._on_complete(self.user)
        assert_equal(mock_notify.call_count, 0)

    # Regression for OSF-8840
    def test_public_embargo_cannot_be_deleted_with_initial_token(self):
        embargo_termination_approval = EmbargoTerminationApprovalFactory()
        registration = Registration.objects.get(embargo_termination_approval=embargo_termination_approval)
        user = registration.contributors.first()

        registration.terminate_embargo(Auth(user))  

        rejection_token = registration.embargo.approval_state[user._id]['rejection_token']
        with assert_raises(HTTPError) as e:
            registration.embargo.disapprove_embargo(user, rejection_token)

        registration.refresh_from_db()
        assert registration.is_deleted is False
Example #21
0
class RegistrationWithChildNodesEmbargoModelTestCase(OsfTestCase):

    def setUp(self):
        super(RegistrationWithChildNodesEmbargoModelTestCase, self).setUp()
        self.user = AuthUserFactory()
        self.auth = self.user.auth
        self.valid_embargo_end_date = timezone.now() + datetime.timedelta(days=3)
        self.project = ProjectFactory(title='Root', is_public=False, 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)
        # Reload the registration; else tests won't catch failures to save
        self.registration.reload()

    def test_approval_embargoes_descendant_nodes(self):
        # Initiate embargo for parent registration
        self.registration.embargo_registration(
            self.user,
            self.valid_embargo_end_date
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

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

        # Approve parent registration's embargo
        approval_token = self.registration.embargo.approval_state[self.user._id]['approval_token']
        self.registration.embargo.approve_embargo(self.user, approval_token)
        assert_true(self.registration.embargo.embargo_end_date)

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

    def test_disapproval_cancels_embargo_on_descendant_nodes(self):
        # Initiate embargo on parent registration
        self.registration.embargo_registration(
            self.user,
            self.valid_embargo_end_date
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

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

        # Disapprove parent registration's embargo
        rejection_token = self.registration.embargo.approval_state[self.user._id]['rejection_token']
        self.registration.embargo.disapprove_embargo(self.user, rejection_token)
        assert_false(self.registration.is_pending_embargo)
        assert_equal(self.registration.embargo.state, Embargo.REJECTED)

        # Ensure descendant nodes' embargoes are cancelled
        descendants = self.registration.get_descendants_recursive()
        for node in descendants:
            node.reload()
            assert_false(node.is_pending_embargo)
            assert_false(node.embargo_end_date)
Example #22
0
class RegistrationEmbargoApprovalDisapprovalViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationEmbargoApprovalDisapprovalViewsTestCase, self).setUp()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user)
        self.registration = RegistrationFactory(creator=self.user, project=self.project)

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

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

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

    def test_GET_approve_with_wrong_token_returns_HTTPBad_Request(self):
        admin2 = UserFactory()
        Contributor.objects.create(user=admin2, node=self.registration)
        self.registration.add_permission(admin2, 'admin', save=True)
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

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

    def test_GET_approve_with_wrong_admins_token_returns_HTTPBad_Request(self):
        admin2 = UserFactory()
        Contributor.objects.create(user=admin2, node=self.registration)
        self.registration.add_permission(admin2, 'admin', save=True)
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

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

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

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

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

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

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

    def test_GET_disapprove_with_wrong_admins_token_returns_HTTPBad_Request(self):
        admin2 = UserFactory()
        Contributor.objects.create(user=admin2, node=self.registration)
        self.registration.add_permission(admin2, 'admin', save=True)
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

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

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

        rejection_token = registration.embargo.approval_state[self.user._id]['rejection_token']

        res = self.app.get(
            registration.registered_from.web_url_for('view_project', token=rejection_token),
            auth=self.user.auth,
        )
        registration.embargo.reload()
        assert_equal(registration.embargo.state, Embargo.REJECTED)
        assert_false(registration.is_pending_embargo)
        assert_equal(res.status_code, 200)
        assert_equal(project.web_url_for('view_project'), res.request.path)

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

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

    def test_GET_from_unauthorized_user_with_registration_token(self):
        unauthorized_user = AuthUserFactory()

        self.registration.require_approval(self.user)
        self.registration.save()

        app_token = self.registration.registration_approval.approval_state[self.user._id]['approval_token']
        rej_token = self.registration.registration_approval.approval_state[self.user._id]['rejection_token']

        # Test unauth user cannot approve
        res = self.app.get(
            # approval token goes through registration
            self.registration.web_url_for('view_project', token=app_token),
            auth=unauthorized_user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 401)

        # Test unauth user cannot reject
        res = self.app.get(
            # rejection token goes through registration parent
            self.project.web_url_for('view_project', token=rej_token),
            auth=unauthorized_user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 401)

        # Delete Node and try again
        self.project.is_deleted = True
        self.project.save()

        # Test unauth user cannot approve deleted node
        res = self.app.get(
            self.registration.web_url_for('view_project', token=app_token),
            auth=unauthorized_user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 401)

        # Test unauth user cannot reject
        res = self.app.get(
            self.project.web_url_for('view_project', token=rej_token),
            auth=unauthorized_user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 401)

        # Test auth user can approve registration with deleted parent
        res = self.app.get(
            self.registration.web_url_for('view_project', token=app_token),
            auth=self.user.auth,
        )
        assert_equal(res.status_code, 200)

    def test_GET_from_authorized_user_with_registration_app_token(self):
        self.registration.require_approval(self.user)
        self.registration.save()
        app_token = self.registration.registration_approval.approval_state[self.user._id]['approval_token']

        res = self.app.get(
            self.registration.web_url_for('view_project', token=app_token),
            auth=self.user.auth,
        )
        assert_equal(res.status_code, 200)

    def test_GET_from_authorized_user_with_registration_rej_token(self):
        self.registration.require_approval(self.user)
        self.registration.save()
        rej_token = self.registration.registration_approval.approval_state[self.user._id]['rejection_token']

        res = self.app.get(
            self.project.web_url_for('view_project', token=rej_token),
            auth=self.user.auth,
        )
        assert_equal(res.status_code, 200)

    def test_GET_from_authorized_user_with_registration_rej_token_deleted_node(self):
        self.registration.require_approval(self.user)
        self.registration.save()
        rej_token = self.registration.registration_approval.approval_state[self.user._id]['rejection_token']

        self.project.is_deleted = True
        self.project.save()

        res = self.app.get(
            self.project.web_url_for('view_project', token=rej_token),
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 410)
        res = self.app.get(
            self.registration.web_url_for('view_project'),
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 410)
Example #23
0
class RegistrationEmbargoApprovalDisapprovalViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationEmbargoApprovalDisapprovalViewsTestCase, self).setUp()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user)
        self.registration = RegistrationFactory(creator=self.user, project=self.project)

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

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

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

    def test_GET_approve_with_wrong_token_returns_HTTPBad_Request(self):
        admin2 = UserFactory()
        Contributor.objects.create(user=admin2, node=self.registration)
        self.registration.add_permission(admin2, 'admin', save=True)
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

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

    def test_GET_approve_with_wrong_admins_token_returns_HTTPBad_Request(self):
        admin2 = UserFactory()
        Contributor.objects.create(user=admin2, node=self.registration)
        self.registration.add_permission(admin2, 'admin', save=True)
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

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

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

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

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

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

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

    def test_GET_disapprove_with_wrong_admins_token_returns_HTTPBad_Request(self):
        admin2 = UserFactory()
        Contributor.objects.create(user=admin2, node=self.registration)
        self.registration.add_permission(admin2, 'admin', save=True)
        self.registration.embargo_registration(
            self.user,
            timezone.now() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

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

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

        rejection_token = registration.embargo.approval_state[self.user._id]['rejection_token']

        res = self.app.get(
            registration.registered_from.web_url_for('view_project', token=rejection_token),
            auth=self.user.auth,
        )
        registration.embargo.reload()
        assert_equal(registration.embargo.state, Embargo.REJECTED)
        assert_false(registration.is_pending_embargo)
        assert_equal(res.status_code, 200)
        assert_equal(project.web_url_for('view_project'), res.request.path)

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

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

    def test_GET_from_unauthorized_user_with_registration_token(self):
        unauthorized_user = AuthUserFactory()

        self.registration.require_approval(self.user)
        self.registration.save()

        app_token = self.registration.registration_approval.approval_state[self.user._id]['approval_token']
        rej_token = self.registration.registration_approval.approval_state[self.user._id]['rejection_token']

        # Test unauth user cannot approve
        res = self.app.get(
            # approval token goes through registration
            self.registration.web_url_for('view_project', token=app_token),
            auth=unauthorized_user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 401)

        # Test unauth user cannot reject
        res = self.app.get(
            # rejection token goes through registration parent
            self.project.web_url_for('view_project', token=rej_token),
            auth=unauthorized_user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 401)

        # Delete Node and try again
        self.project.is_deleted = True
        self.project.save()

        # Test unauth user cannot approve deleted node
        res = self.app.get(
            self.registration.web_url_for('view_project', token=app_token),
            auth=unauthorized_user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 401)

        # Test unauth user cannot reject
        res = self.app.get(
            self.project.web_url_for('view_project', token=rej_token),
            auth=unauthorized_user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 401)

        # Test auth user can approve registration with deleted parent
        res = self.app.get(
            self.registration.web_url_for('view_project', token=app_token),
            auth=self.user.auth,
        )
        assert_equal(res.status_code, 200)

    def test_GET_from_authorized_user_with_registration_app_token(self):
        self.registration.require_approval(self.user)
        self.registration.save()
        app_token = self.registration.registration_approval.approval_state[self.user._id]['approval_token']

        res = self.app.get(
            self.registration.web_url_for('view_project', token=app_token),
            auth=self.user.auth,
        )
        assert_equal(res.status_code, 200)

    def test_GET_from_authorized_user_with_registration_rej_token(self):
        self.registration.require_approval(self.user)
        self.registration.save()
        rej_token = self.registration.registration_approval.approval_state[self.user._id]['rejection_token']

        res = self.app.get(
            self.project.web_url_for('view_project', token=rej_token),
            auth=self.user.auth,
        )
        assert_equal(res.status_code, 200)

    def test_GET_from_authorized_user_with_registration_rej_token_deleted_node(self):
        self.registration.require_approval(self.user)
        self.registration.save()
        rej_token = self.registration.registration_approval.approval_state[self.user._id]['rejection_token']

        self.project.is_deleted = True
        self.project.save()

        res = self.app.get(
            self.project.web_url_for('view_project', token=rej_token),
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 410)
        res = self.app.get(
            self.registration.web_url_for('view_project'),
            auth=self.user.auth,
            expect_errors=True,
        )
        assert_equal(res.status_code, 410)
Example #24
0
class RegistrationEmbargoViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationEmbargoViewsTestCase, self).setUp()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user)
        self.draft = DraftRegistrationFactory(branched_from=self.project)
        self.registration = RegistrationFactory(project=self.project, creator=self.user)

        current_month = timezone.now().strftime('%B')
        current_year = timezone.now().strftime('%Y')

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

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

        registration = Registration.objects.all().order_by('-registered_date').first()
        assert_not_equal(registration.registration_approval, None)

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

        # Last node directly registered from self.project
        registration = AbstractNode.objects.filter(registered_from=self.project).order_by('-registered_date')[0]

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

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

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

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

        assert_equal(res.status_code, 202)

        registration = Registration.objects.order_by('-registered_date').first()

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

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

        # Last node directly registered from self.project
        registration = AbstractNode.objects.filter(registered_from=self.project).order_by('-registered_date')[0]

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

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

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

        assert_equal(res.status_code, 400)

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

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

        self.registration.set_privacy('public', Auth(self.registration.creator))
        for reg in self.registration.node_and_primary_descendants():
            reg.reload()
            assert_false(reg.is_public)
        assert_true(reg.embargo_termination_approval)
        assert_true(reg.embargo_termination_approval.is_pending_approval)

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

        with utils.mock_archive(node, embargo=True, autocomplete=True, autoapprove=True) as reg:
            with assert_raises(NodeStateError):
                reg._nodes.first().request_embargo_termination(Auth(node.creator))

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

        self.registration.set_privacy('public', Auth(self.registration.creator))
        for admin in self.registration.admin_contributors:
            assert_true(any([each[0][0] == admin.username for each in mock_send_mail.call_args_list]))

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

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

        registration.set_privacy('public', Auth(self.registration.creator))
        asked_admins = [(admin._id, n._id) for admin, n in mock_ask.call_args[0][0]]
        for admin, node in registration.get_admin_contributors_recursive():
            assert_in((admin._id, node._id), asked_admins)

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

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

        res = self.app.get(approval_url, auth=non_contributor.auth, expect_errors=True)
        self.registration.reload()
        assert_equal(http.UNAUTHORIZED, res.status_code)
        assert_true(self.registration.is_pending_embargo)
        assert_equal(self.registration.embargo.state, Embargo.UNAPPROVED)

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

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

        res = self.app.get(approval_url, auth=non_contributor.auth, expect_errors=True)
        assert_equal(http.UNAUTHORIZED, res.status_code)
        assert_true(self.registration.is_pending_embargo)
        assert_equal(self.registration.embargo.state, Embargo.UNAPPROVED)
class TestRetractRegistrations(OsfTestCase):

    def setUp(self):
        super(TestRetractRegistrations, self).setUp()
        self.user = UserFactory()
        self.registration = RegistrationFactory(creator=self.user)
        self.registration.embargo_registration(
            self.user,
            timezone.now() + timedelta(days=10)
        )
        self.registration.save()

    def test_new_embargo_should_be_unapproved(self):
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)

        main(dry_run=False)
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)

    def test_should_not_activate_pending_embargo_less_than_48_hours_old(self):
        # Embargo#iniation_date is read only
        self.registration.embargo._fields['initiation_date'].__set__(
            self.registration.embargo,
            (timezone.now() - timedelta(hours=47)),
            safe=True
        )
        self.registration.embargo.save()
        assert_false(self.registration.embargo_end_date)

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

    def test_should_activate_pending_embargo_that_is_48_hours_old(self):
        # Embargo#iniation_date is read only
        self.registration.embargo._fields['initiation_date'].__set__(
            self.registration.embargo,
            (timezone.now() - timedelta(hours=48)),
            safe=True
        )
        self.registration.embargo.save()
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)

        main(dry_run=False)
        assert_false(self.registration.is_pending_embargo)
        assert_true(self.registration.embargo_end_date)

    def test_should_activate_pending_embargo_more_than_48_hours_old(self):
        # Embargo#iniation_date is read only
        self.registration.embargo._fields['initiation_date'].__set__(
            self.registration.embargo,
            (timezone.now() - timedelta(days=365)),
            safe=True
        )
        self.registration.embargo.save()
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.embargo_end_date)

        main(dry_run=False)
        assert_false(self.registration.is_pending_embargo)
        assert_true(self.registration.embargo_end_date)

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

        # Embargo#iniation_date is read only
        self.registration.embargo._fields['end_date'].__set__(
            self.registration.embargo,
            (timezone.now() - timedelta(days=1)),
            safe=True
        )
        self.registration.embargo.save()

        assert_false(self.registration.is_public)
        main(dry_run=False)
        assert_true(self.registration.is_public)
        assert_false(self.registration.embargo_end_date)
        assert_false(self.registration.is_pending_embargo)
        assert_equal(self.registration.embargo.state, 'completed')

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

        # Embargo#iniation_date is read only
        self.registration.embargo._fields['end_date'].__set__(
            self.registration.embargo,
            (timezone.now() + timedelta(days=1)),
            safe=True
        )
        self.registration.embargo.save()

        assert_false(self.registration.is_public)
        main(dry_run=False)
        assert_false(self.registration.is_public)
        assert_true(self.registration.embargo_end_date)
        assert_false(self.registration.is_pending_embargo)

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

        main(dry_run=False)
        # Logs: Created, made public, registered, embargo initiated, embargo approved
        embargo_approved_log = self.registration.registered_from.logs[initial_project_logs + 1]
        assert_equal(len(self.registration.registered_from.logs), initial_project_logs + 1)
        assert_equal(embargo_approved_log.params['node'], self.registration.registered_from._id)

    def test_embargo_completion_adds_to_parent_projects_log(self):
        initial_project_logs = len(self.registration.registered_from.logs)
        approval_token = self.registration.embargo.approval_state[self.user._id]['approval_token']
        self.registration.embargo.approve_embargo(self.user, approval_token)
        self.registration.save()

        # Embargo#iniation_date is read only
        self.registration.embargo._fields['end_date'].__set__(
            self.registration.embargo,
            (timezone.now() - timedelta(days=1)),
            safe=True
        )
        self.registration.embargo.save()

        main(dry_run=False)
        # Logs: Created, made public, registered, embargo initiated, embargo approved, embargo completed
        embargo_completed_log = self.registration.registered_from.logs[initial_project_logs + 1]
        assert_equal(len(self.registration.registered_from.logs), initial_project_logs + 2)
        assert_equal(embargo_completed_log.params['node'], self.registration.registered_from._id)