Beispiel #1
0
 def test_cannot_update_a_retraction(self):
     registration = RegistrationFactory(creator=self.user, project=self.public_project)
     url = "/{}nodes/{}/".format(API_BASE, registration._id)
     retraction = RetractedRegistrationFactory(registration=registration, user=registration.creator)
     res = self.app.put_json_api(
         url,
         {
             "data": {
                 "id": registration._id,
                 "type": "nodes",
                 "attributes": {
                     "title": fake.catch_phrase(),
                     "description": fake.bs(),
                     "category": "hypothesis",
                     "public": True,
                 },
             }
         },
         auth=self.user.auth,
         expect_errors=True,
     )
     registration.reload()
     assert_equal(res.status_code, 404)
     assert_equal(registration.title, registration.title)
     assert_equal(registration.description, registration.description)
class RegistrationWithChildNodesEmbargoModelTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationWithChildNodesEmbargoModelTestCase, self).setUp()
        self.user = AuthUserFactory()
        self.auth = self.user.auth
        self.valid_embargo_end_date = datetime.datetime.utcnow() + 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:
            assert_false(node.is_pending_embargo)
            assert_false(node.embargo_end_date)
Beispiel #3
0
 def test_cannot_delete_a_retraction(self):
     registration = RegistrationFactory(creator=self.user, project=self.public_project)
     url = '/{}nodes/{}/'.format(API_BASE, registration._id)
     retraction = RetractedRegistrationFactory(registration=registration, user=registration.creator)
     res = self.app.delete_json_api(url, auth=self.user.auth, expect_errors=True)
     registration.reload()
     assert_equal(res.status_code, 404)
     assert_equal(registration.title, registration.title)
     assert_equal(registration.description, registration.description)
Beispiel #4
0
 def test_cannot_delete_a_retraction(self):
     registration = RegistrationFactory(creator=self.user, project=self.public_project)
     url = '/{}nodes/{}/'.format(API_BASE, registration._id)
     retraction = RetractedRegistrationFactory(registration=registration, user=registration.creator)
     res = self.app.delete_json_api(url, auth=self.user.auth, expect_errors=True)
     registration.reload()
     assert_equal(res.status_code, 404)
     assert_equal(registration.title, registration.title)
     assert_equal(registration.description, registration.description)
Beispiel #5
0
 def test_cannot_update_a_retraction(self):
     registration = RegistrationFactory(creator=self.user, project=self.public_project)
     url = '/{}nodes/{}/'.format(API_BASE, registration._id)
     retraction = RetractedRegistrationFactory(registration=registration, user=registration.creator)
     res = self.app.put_json_api(url, {
         'data': {
             'id': registration._id,
             'type': 'nodes',
             'attributes': {
                 'title': fake.catch_phrase(),
                 'description': fake.bs(),
                 'category': 'hypothesis',
                 'public': True
             }
         }
     }, auth=self.user.auth, expect_errors=True)
     registration.reload()
     assert_equal(res.status_code, 404)
     assert_equal(registration.title, registration.title)
     assert_equal(registration.description, registration.description)
Beispiel #6
0
 def test_cannot_update_a_retraction(self):
     registration = RegistrationFactory(creator=self.user, project=self.public_project)
     url = '/{}nodes/{}/'.format(API_BASE, registration._id)
     retraction = RetractedRegistrationFactory(registration=registration, user=registration.creator)
     res = self.app.put_json_api(url, {
         'data': {
             'id': registration._id,
             'type': 'nodes',
             'attributes': {
                 'title': fake.catch_phrase(),
                 'description': fake.bs(),
                 'category': 'hypothesis',
                 'public': True
             }
         }
     }, auth=self.user.auth, expect_errors=True)
     registration.reload()
     assert_equal(res.status_code, 404)
     assert_equal(registration.title, registration.title)
     assert_equal(registration.description, registration.description)
class TestWithdrawnRegistrations(NodeCRUDTestCase):

    def setUp(self):
        super(TestWithdrawnRegistrations, self).setUp()
        self.registration = RegistrationFactory(creator=self.user, project=self.public_project)
        self.withdrawn_registration = WithdrawnRegistrationFactory(registration=self.registration, user=self.registration.creator)

        self.public_pointer_project = ProjectFactory(is_public=True)
        self.public_pointer = self.public_project.add_pointer(self.public_pointer_project,
                                                              auth=Auth(self.user),
                                                              save=True)
        self.withdrawn_url = '/{}registrations/{}/'.format(API_BASE, self.registration._id)
        self.withdrawn_registration.justification = 'We made a major error.'
        self.withdrawn_registration.save()

    def test_can_access_withdrawn_contributors(self):
        url = '/{}registrations/{}/contributors/'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 200)

    def test_cannot_access_withdrawn_children(self):
        url = '/{}registrations/{}/children/'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_cannot_access_withdrawn_comments(self):
        self.public_project = ProjectFactory(is_public=True, creator=self.user)
        self.public_comment = CommentFactory(node=self.public_project, user=self.user)
        url = '/{}registrations/{}/comments/'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_can_access_withdrawn_contributor_detail(self):
        url = '/{}registrations/{}/contributors/{}/'.format(API_BASE, self.registration._id, self.user._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 200)

    def test_cannot_return_a_withdrawn_registration_at_node_detail_endpoint(self):
        url = '/{}nodes/{}/'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 404)

    def test_cannot_delete_a_withdrawn_registration(self):
        url = '/{}registrations/{}/'.format(API_BASE, self.registration._id)
        res = self.app.delete_json_api(url, auth=self.user.auth, expect_errors=True)
        self.registration.reload()
        assert_equal(res.status_code, 405)

    def test_cannot_access_withdrawn_files_list(self):
        url = '/{}registrations/{}/files/'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_cannot_access_withdrawn_node_links_detail(self):
        url = '/{}registrations/{}/node_links/{}/'.format(API_BASE, self.registration._id, self.public_pointer._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_cannot_access_withdrawn_node_links_list(self):
        url = '/{}registrations/{}/node_links/'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_cannot_access_withdrawn_node_logs(self):
        self.public_project = ProjectFactory(is_public=True, creator=self.user)
        url = '/{}registrations/{}/logs/'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_cannot_access_withdrawn_registrations_list(self):
        self.registration.save()
        url = '/{}registrations/{}/registrations/'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_withdrawn_registrations_display_limited_fields(self):
        registration = self.registration
        res = self.app.get(self.withdrawn_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        attributes = res.json['data']['attributes']
        expected_attributes = {
            'title': registration.title,
            'description': registration.description,
            'date_created': registration.date_created.isoformat(),
            'date_registered': registration.registered_date.isoformat(),
            'withdrawal_justification': registration.retraction.justification,
            'public': None,
            'category': None,
            'date_modified': None,
            'registration': True,
            'fork': None,
            'collection': None,
            'tags': None,
            'withdrawn': True,
            'pending_withdrawal': None,
            'pending_registration_approval': None,
            'pending_embargo_approval': None,
            'embargo_end_date': None,
            'registered_meta': None,
            'current_user_permissions': None,
            'registration_supplement': registration.registered_schema[0].name
        }

        for attribute in expected_attributes:
            assert_equal(expected_attributes[attribute], attributes[attribute])

        contributors = urlparse(res.json['data']['relationships']['contributors']['links']['related']['href']).path
        assert_equal(contributors, '/{}registrations/{}/contributors/'.format(API_BASE, registration._id))

        assert_not_in('children', res.json['data']['relationships'])
        assert_not_in('comments', res.json['data']['relationships'])
        assert_not_in('node_links', res.json['data']['relationships'])
        assert_not_in('registrations', res.json['data']['relationships'])
        assert_not_in('parent', res.json['data']['relationships'])
        assert_not_in('forked_from', res.json['data']['relationships'])
        assert_not_in('files', res.json['data']['relationships'])
        assert_not_in('logs', res.json['data']['relationships'])
        assert_not_in('primary_institution', res.json['data']['relationships'])
        assert_not_in('registered_by', res.json['data']['relationships'])
        assert_not_in('registered_from', res.json['data']['relationships'])
        assert_not_in('root', res.json['data']['relationships'])

    def test_field_specific_related_counts_ignored_if_hidden_field_on_withdrawn_registration(self):
        url = '/{}registrations/{}/?related_counts=children'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_not_in('children', res.json['data']['relationships'])
        assert_in('contributors', res.json['data']['relationships'])

    def test_field_specific_related_counts_retrieved_if_visible_field_on_withdrawn_registration(self):
        url = '/{}registrations/{}/?related_counts=contributors'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['relationships']['contributors']['links']['related']['meta']['count'], 1)
Beispiel #8
0
class TestRegistrationRetractions(SearchTestCase):
    def setUp(self):
        super(TestRegistrationRetractions, self).setUp()
        self.user = UserFactory(usename='Doug Bogie')
        self.title = 'Red Special'
        self.consolidate_auth = Auth(user=self.user)
        self.project = ProjectFactory(
            title=self.title,
            creator=self.user,
            is_public=True,
        )
        self.registration = RegistrationFactory(project=self.project,
                                                title=self.title,
                                                creator=self.user,
                                                is_public=True,
                                                is_registration=True)

    def test_retraction_is_searchable(self):

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

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

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

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

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

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

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

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

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

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

        # Query and ensure registration does show up
        docs = query('category:registration AND ' + self.title)['results']
        assert_equal(len(docs), 1)
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 = datetime.datetime.utcnow() + 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__initiate_embargo_does_not_create_tokens_for_unregistered_admin(self):
        unconfirmed_user = UnconfirmedUserFactory()
        self.registration.contributors.append(unconfirmed_user)
        self.registration.add_permission(unconfirmed_user, "admin", save=True)
        assert_true(self.registration.has_permission(unconfirmed_user, "admin"))

        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_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)

    # Backref tests
    def test_embargo_initiator_has_backref(self):
        self.registration.embargo_registration(self.user, self.valid_embargo_end_date)
        self.registration.save()
        self.registration.reload()
        assert_equal(len(self.user.embargo__embargoed), Embargo.find(Q("initiated_by", "eq", self.user)).count())

    # 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_ValidationValueError(self):
        with assert_raises(ValidationValueError):
            self.registration.embargo_registration(self.user, datetime.datetime(1999, 1, 1))

    def test_embargo_end_date_today_raises_ValidationValueError(self):
        with assert_raises(ValidationValueError):
            self.registration.embargo_registration(self.user, datetime.datetime.utcnow())

    def test_embargo_end_date_in_far_future_raises_ValidationValueError(self):
        with assert_raises(ValidationValueError):
            self.registration.embargo_registration(self.user, datetime.datetime(2099, 1, 1))

    def test_embargo_with_valid_end_date_starts_pending_embargo(self):
        self.registration.embargo_registration(self.user, datetime.datetime.utcnow() + 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, datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.is_public)

    def test_embargo_non_registration_raises_NodeStateError(self):
        self.registration.is_registration = False
        self.registration.save()
        with assert_raises(NodeStateError):
            self.registration.embargo_registration(self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10))
        assert_false(self.registration.is_pending_embargo)

    # Embargo#approve_embargo tests
    def test_invalid_approval_token_raises_InvalidSanctionApprovalToken(self):
        self.registration.embargo_registration(self.user, datetime.datetime.utcnow() + 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, datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        approval_token = self.registration.embargo.approval_state[self.user._id]["approval_token"]
        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, datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        approval_token = self.registration.embargo.approval_state[self.user._id]["approval_token"]
        self.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 = len(self.registration.registered_from.logs)
        self.registration.embargo_registration(self.user, datetime.datetime.utcnow() + 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(len(self.registration.registered_from.logs), initial_project_logs + 2)

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

        # 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, datetime.datetime.utcnow() + 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, datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        rejection_token = self.registration.embargo.approval_state[self.user._id]["rejection_token"]
        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, datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        rejection_token = self.registration.embargo.approval_state[self.user._id]["rejection_token"]
        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 = len(self.registration.registered_from.logs)
        self.registration.embargo_registration(self.user, datetime.datetime.utcnow() + 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(len(registered_from.logs), initial_project_logs + 2)

    def test_cancelling_embargo_deletes_parent_registration(self):
        self.registration.embargo_registration(self.user, datetime.datetime.utcnow() + 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)
        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")
        subcomponent = NodeFactory(creator=self.user, parent=component, title="Subcomponent")
        project_registration = RegistrationFactory(project=self.project)
        component_registration = project_registration.nodes[0]
        subcomponent_registration = component_registration.nodes[0]
        project_registration.embargo_registration(self.user, datetime.datetime.utcnow() + 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)
        assert_true(project_registration.is_deleted)
        assert_true(component_registration.is_deleted)
        assert_true(subcomponent_registration.is_deleted)

    def test_cancelling_embargo_for_existing_registration_does_not_delete_registration(self):
        self.registration.embargo_registration(
            self.user, datetime.datetime.utcnow() + 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")
        subcomponent = NodeFactory(creator=self.user, parent=component, title="Subcomponent")
        project_registration = RegistrationFactory(project=self.project)
        component_registration = project_registration.nodes[0]
        subcomponent_registration = component_registration.nodes[0]
        project_registration.embargo_registration(
            self.user, datetime.datetime.utcnow() + 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, datetime.datetime.utcnow() + 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, datetime.datetime.utcnow() + datetime.timedelta(days=10), for_existing_registration=True
        )
        self.registration.save()
        assert_false(self.registration.is_pending_embargo_for_existing_registration)
Beispiel #10
0
class TestIdentifierViews(OsfTestCase):
    def setUp(self):
        super(TestIdentifierViews, self).setUp()
        self.user = AuthUserFactory()
        self.node = RegistrationFactory(creator=self.user, is_public=True)

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

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

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

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

    def test_get_by_identifier_not_found(self):
        self.node.set_identifier_value('doi', 'FK424601')
        res = self.app.get(
            self.node.web_url_for(
                'get_referent_by_identifier',
                category='doi',
                value='fakedoi',
            ),
            expect_errors=True,
        )
        assert_equal(res.status_code, 404)
class TestWithdrawnRegistrations(NodeCRUDTestCase):

    def setUp(self):
        super(TestWithdrawnRegistrations, self).setUp()
        self.registration = RegistrationFactory(creator=self.user, project=self.public_project)
        self.withdrawn_registration = WithdrawnRegistrationFactory(registration=self.registration, user=self.registration.creator)

        self.public_pointer_project = ProjectFactory(is_public=True)
        self.public_pointer = self.public_project.add_pointer(self.public_pointer_project,
                                                              auth=Auth(self.user),
                                                              save=True)
        self.withdrawn_url = '/{}registrations/{}/'.format(API_BASE, self.registration._id)
        self.withdrawn_registration.justification = 'We made a major error.'
        self.withdrawn_registration.save()

    def test_can_access_withdrawn_contributors(self):
        url = '/{}registrations/{}/contributors/'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 200)

    def test_cannot_access_withdrawn_children(self):
        url = '/{}registrations/{}/children/'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_cannot_access_withdrawn_comments(self):
        self.public_project = ProjectFactory(is_public=True, creator=self.user)
        self.public_comment = CommentFactory(node=self.public_project, user=self.user)
        url = '/{}registrations/{}/comments/'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_can_access_withdrawn_contributor_detail(self):
        url = '/{}registrations/{}/contributors/{}/'.format(API_BASE, self.registration._id, self.user._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 200)

    def test_cannot_return_a_withdrawn_registration_at_node_detail_endpoint(self):
        url = '/{}nodes/{}/'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 404)

    def test_cannot_delete_a_withdrawn_registration(self):
        url = '/{}registrations/{}/'.format(API_BASE, self.registration._id)
        res = self.app.delete_json_api(url, auth=self.user.auth, expect_errors=True)
        self.registration.reload()
        assert_equal(res.status_code, 405)

    def test_cannot_access_withdrawn_files_list(self):
        url = '/{}registrations/{}/files/'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_cannot_access_withdrawn_node_links_detail(self):
        url = '/{}registrations/{}/node_links/{}/'.format(API_BASE, self.registration._id, self.public_pointer._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 404)

    def test_cannot_access_withdrawn_node_links_list(self):
        url = '/{}registrations/{}/node_links/'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_cannot_access_withdrawn_node_logs(self):
        self.public_project = ProjectFactory(is_public=True, creator=self.user)
        url = '/{}registrations/{}/logs/'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_cannot_access_withdrawn_registrations_list(self):
        self.registration.save()
        url = '/{}registrations/{}/registrations/'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth, expect_errors=True)
        assert_equal(res.status_code, 403)

    def test_withdrawn_registrations_display_limited_fields(self):
        registration = self.registration
        res = self.app.get(self.withdrawn_url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        attributes = res.json['data']['attributes']
        expected_attributes = {
            'title': registration.title,
            'description': registration.description,
            'date_created': registration.date_created.isoformat(),
            'date_registered': registration.registered_date.isoformat(),
            'withdrawal_justification': registration.retraction.justification,
            'public': None,
            'category': None,
            'date_modified': None,
            'registration': True,
            'fork': None,
            'collection': None,
            'tags': None,
            'withdrawn': True,
            'pending_withdrawal': None,
            'pending_registration_approval': None,
            'pending_embargo_approval': None,
            'embargo_end_date': None,
            'registered_meta': None,
            'current_user_permissions': None,
            'registration_supplement': registration.registered_schema[0].name
        }

        for attribute in expected_attributes:
            assert_equal(expected_attributes[attribute], attributes[attribute])

        contributors = urlparse(res.json['data']['relationships']['contributors']['links']['related']['href']).path
        assert_equal(contributors, '/{}registrations/{}/contributors/'.format(API_BASE, registration._id))

        assert_not_in('children', res.json['data']['relationships'])
        assert_not_in('comments', res.json['data']['relationships'])
        assert_not_in('node_links', res.json['data']['relationships'])
        assert_not_in('registrations', res.json['data']['relationships'])
        assert_not_in('parent', res.json['data']['relationships'])
        assert_not_in('forked_from', res.json['data']['relationships'])
        assert_not_in('files', res.json['data']['relationships'])
        assert_not_in('logs', res.json['data']['relationships'])
        assert_not_in('registered_by', res.json['data']['relationships'])
        assert_not_in('registered_from', res.json['data']['relationships'])
        assert_not_in('root', res.json['data']['relationships'])

    def test_field_specific_related_counts_ignored_if_hidden_field_on_withdrawn_registration(self):
        url = '/{}registrations/{}/?related_counts=children'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_not_in('children', res.json['data']['relationships'])
        assert_in('contributors', res.json['data']['relationships'])

    def test_field_specific_related_counts_retrieved_if_visible_field_on_withdrawn_registration(self):
        url = '/{}registrations/{}/?related_counts=contributors'.format(API_BASE, self.registration._id)
        res = self.app.get(url, auth=self.user.auth)
        assert_equal(res.status_code, 200)
        assert_equal(res.json['data']['relationships']['contributors']['links']['related']['meta']['count'], 1)
Beispiel #12
0
class RegistrationApprovalModelTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationApprovalModelTestCase, 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 = datetime.datetime.utcnow(
        ) + datetime.timedelta(days=3)

    def test__require_approval_saves_approval(self):
        initial_count = RegistrationApproval.find().count()
        self.registration._initiate_approval(self.user)
        assert_equal(RegistrationApproval.find().count(), initial_count + 1)

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

        approval = self.registration._initiate_approval(self.user)
        assert_true(self.user._id in approval.approval_state)
        assert_false(unconfirmed_user._id in approval.approval_state)

    def test_require_approval_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.require_approval(self.user)

    def test_require_approval_non_registration_raises_NodeStateError(self):
        self.registration.is_registration = False
        self.registration.save()
        with assert_raises(NodeStateError):
            self.registration.require_approval(self.user, )
        assert_false(self.registration.is_pending_registration)

    def test_invalid_approval_token_raises_InvalidSanctionApprovalToken(self):
        self.registration.require_approval(self.user)
        self.registration.save()
        assert_true(self.registration.is_pending_registration)

        invalid_approval_token = 'not a real token'
        with assert_raises(InvalidSanctionApprovalToken):
            self.registration.registration_approval.approve(
                self.user, invalid_approval_token)
        assert_true(self.registration.is_pending_registration)

    def test_non_admin_approval_token_raises_PermissionsError(self):
        non_admin = UserFactory()
        self.registration.require_approval(self.user, )
        self.registration.save()
        assert_true(self.registration.is_pending_registration)

        approval_token = self.registration.registration_approval.approval_state[
            self.user._id]['approval_token']
        with assert_raises(PermissionsError):
            self.registration.registration_approval.approve(
                non_admin, approval_token)
        assert_true(self.registration.is_pending_registration)

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

        approval_token = self.registration.registration_approval.approval_state[
            self.user._id]['approval_token']
        self.registration.registration_approval.approve(
            self.user, approval_token)
        # adds initiated, approved, and registered logs
        assert_equal(len(self.registration.registered_from.logs),
                     initial_project_logs + 3)

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

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

        # Second admin approves
        approval_token = self.registration.registration_approval.approval_state[
            admin2._id]['approval_token']
        self.registration.registration_approval.approve(admin2, approval_token)
        assert_false(self.registration.is_pending_registration)
        num_of_approvals = sum([
            val['has_approved'] for val in
            self.registration.registration_approval.approval_state.values()
        ])
        assert_equal(num_of_approvals, 2)

    def test_invalid_rejection_token_raises_InvalidSanctionRejectionToken(
            self):
        self.registration.require_approval(self.user)
        self.registration.save()
        assert_true(self.registration.is_pending_registration)
        with assert_raises(InvalidSanctionRejectionToken):
            self.registration.registration_approval.reject(
                self.user, fake.sentence())
        assert_true(self.registration.is_pending_registration)

    def test_non_admin_rejection_token_raises_PermissionsError(self):
        non_admin = UserFactory()
        self.registration.require_approval(self.user)
        self.registration.save()
        assert_true(self.registration.is_pending_registration)

        rejection_token = self.registration.registration_approval.approval_state[
            self.user._id]['rejection_token']
        with assert_raises(PermissionsError):
            self.registration.registration_approval.reject(
                non_admin, rejection_token)
        assert_true(self.registration.is_pending_registration)

    def test_one_disapproval_cancels_registration_approval(self):
        self.registration.require_approval(self.user)
        self.registration.save()
        assert_true(self.registration.is_pending_registration)

        rejection_token = self.registration.registration_approval.approval_state[
            self.user._id]['rejection_token']
        self.registration.registration_approval.reject(self.user,
                                                       rejection_token)
        assert_equal(self.registration.registration_approval.state,
                     Sanction.REJECTED)
        assert_false(self.registration.is_pending_registration)

    def test_disapproval_adds_to_parent_projects_log(self):
        initial_project_logs = len(self.registration.registered_from.logs)
        self.registration.require_approval(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()

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

    def test_cancelling_registration_approval_deletes_parent_registration(
            self):
        self.registration.require_approval(self.user)
        self.registration.save()

        rejection_token = self.registration.registration_approval.approval_state[
            self.user._id]['rejection_token']
        self.registration.registration_approval.reject(self.user,
                                                       rejection_token)
        assert_equal(self.registration.registration_approval.state,
                     Sanction.REJECTED)
        assert_true(self.registration.is_deleted)

    def test_cancelling_registration_approval_deletes_component_registrations(
            self):
        component = NodeFactory(creator=self.user,
                                parent=self.project,
                                title='Component')
        NodeFactory(creator=self.user, parent=component, title='Subcomponent')
        project_registration = RegistrationFactory(project=self.project)
        component_registration = project_registration.nodes[0]
        subcomponent_registration = component_registration.nodes[0]
        project_registration.require_approval(self.user)
        project_registration.save()

        rejection_token = project_registration.registration_approval.approval_state[
            self.user._id]['rejection_token']
        project_registration.registration_approval.reject(
            self.user, rejection_token)
        assert_equal(project_registration.registration_approval.state,
                     Sanction.REJECTED)
        assert_true(project_registration.is_deleted)
        assert_true(component_registration.is_deleted)
        assert_true(subcomponent_registration.is_deleted)

    def test_new_registration_is_pending_registration(self):
        self.registration.require_approval(self.user)
        self.registration.save()
        assert_true(self.registration.is_pending_registration)

    def test_on_complete_notify_initiator(self):
        self.registration.require_approval(self.user,
                                           notify_initiator_on_complete=True)
        self.registration.save()
        with mock.patch.object(PreregCallbackMixin,
                               '_notify_initiator') as mock_notify:
            self.registration.registration_approval._on_complete(self.user)
        mock_notify.assert_called()
Beispiel #13
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 = datetime.datetime.utcnow() + 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()
        self.registration.contributors.append(unconfirmed_user)
        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(project.creator), save=True)

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

        embargo = project._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)

    # Backref tests
    def test_embargo_initiator_has_backref(self):
        self.registration.embargo_registration(
            self.user,
            self.valid_embargo_end_date
        )
        self.registration.save()
        self.registration.reload()
        assert_equal(len(self.user.embargo__embargoed),
            Embargo.find(Q('initiated_by', 'eq', self.user)).count())

    # 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_ValidationValueError(self):
        with assert_raises(ValidationValueError):
            self.registration.embargo_registration(
                self.user,
                datetime.datetime(1999, 1, 1)
            )

    def test_embargo_end_date_today_raises_ValidationValueError(self):
        with assert_raises(ValidationValueError):
            self.registration.embargo_registration(
                self.user,
                datetime.datetime.utcnow()
            )

    def test_embargo_end_date_in_far_future_raises_ValidationValueError(self):
        with assert_raises(ValidationValueError):
            self.registration.embargo_registration(
                self.user,
                datetime.datetime(2099, 1, 1)
            )

    def test_embargo_with_valid_end_date_starts_pending_embargo(self):
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + 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,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.is_public)

    def test_embargo_non_registration_raises_NodeStateError(self):
        self.registration.is_registration = False
        self.registration.save()
        with assert_raises(NodeStateError):
            self.registration.embargo_registration(
                self.user,
                datetime.datetime.utcnow() + datetime.timedelta(days=10)
            )
        assert_false(self.registration.is_pending_embargo)

    # Embargo#approve_embargo tests
    def test_invalid_approval_token_raises_InvalidSanctionApprovalToken(self):
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + 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,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        approval_token = self.registration.embargo.approval_state[self.user._id]['approval_token']
        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,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        approval_token = self.registration.embargo.approval_state[self.user._id]['approval_token']
        self.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 = len(self.registration.registered_from.logs)
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + 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(len(self.registration.registered_from.logs), initial_project_logs + 2)

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

        # 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,
            datetime.datetime.utcnow() + 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,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        rejection_token = self.registration.embargo.approval_state[self.user._id]['rejection_token']
        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,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        rejection_token = self.registration.embargo.approval_state[self.user._id]['rejection_token']
        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 = len(self.registration.registered_from.logs)
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + 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(len(registered_from.logs), initial_project_logs + 2)

    def test_cancelling_embargo_deletes_parent_registration(self):
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + 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)
        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'
        )
        subcomponent = NodeFactory(
            creator=self.user,
            parent=component,
            title='Subcomponent'
        )
        project_registration = RegistrationFactory(project=self.project)
        component_registration = project_registration.nodes[0]
        subcomponent_registration = component_registration.nodes[0]
        project_registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + 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)
        assert_true(project_registration.is_deleted)
        assert_true(component_registration.is_deleted)
        assert_true(subcomponent_registration.is_deleted)

    def test_cancelling_embargo_for_existing_registration_does_not_delete_registration(self):
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + 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'
        )
        subcomponent = NodeFactory(
            creator=self.user,
            parent=component,
            title='Subcomponent'
        )
        project_registration = RegistrationFactory(project=self.project)
        component_registration = project_registration.nodes[0]
        subcomponent_registration = component_registration.nodes[0]
        project_registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + 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,
            datetime.datetime.utcnow() + 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,
            datetime.datetime.utcnow() + 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,
            datetime.datetime.utcnow() + 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)
        mock_notify.assert_called()
Beispiel #14
0
class TestRegistrationRetractions(SearchTestCase):

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

    def test_retraction_is_searchable(self):

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

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

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

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

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

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

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

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

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

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

        # Query and ensure registration does show up
        docs = query('category:registration AND ' + self.title)['results']
        assert_equal(len(docs), 1)
class RegistrationApprovalModelTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationApprovalModelTestCase, 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 = datetime.datetime.utcnow() + datetime.timedelta(days=3)

    def test__require_approval_saves_approval(self):
        initial_count = RegistrationApproval.find().count()
        self.registration._initiate_approval(
            self.user
        )
        assert_equal(RegistrationApproval.find().count(), initial_count + 1)

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

        approval = self.registration._initiate_approval(
            self.user
        )
        assert_true(self.user._id in approval.approval_state)
        assert_false(unconfirmed_user._id in approval.approval_state)

    def test_require_approval_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.require_approval(self.user)

    def test_require_approval_non_registration_raises_NodeStateError(self):
        self.registration.is_registration = False
        self.registration.save()
        with assert_raises(NodeStateError):
            self.registration.require_approval(
                self.user,
            )
        assert_false(self.registration.is_pending_registration)

    def test_invalid_approval_token_raises_InvalidSanctionApprovalToken(self):
        self.registration.require_approval(
            self.user
        )
        self.registration.save()
        assert_true(self.registration.is_pending_registration)

        invalid_approval_token = 'not a real token'
        with assert_raises(InvalidSanctionApprovalToken):
            self.registration.registration_approval.approve(self.user, invalid_approval_token)
        assert_true(self.registration.is_pending_registration)

    def test_non_admin_approval_token_raises_PermissionsError(self):
        non_admin = UserFactory()
        self.registration.require_approval(
            self.user,
        )
        self.registration.save()
        assert_true(self.registration.is_pending_registration)

        approval_token = self.registration.registration_approval.approval_state[self.user._id]['approval_token']
        with assert_raises(PermissionsError):
            self.registration.registration_approval.approve(non_admin, approval_token)
        assert_true(self.registration.is_pending_registration)

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

        approval_token = self.registration.registration_approval.approval_state[self.user._id]['approval_token']
        self.registration.registration_approval.approve(self.user, approval_token)
        # adds initiated, approved, and registered logs
        assert_equal(len(self.registration.registered_from.logs), initial_project_logs + 3)

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

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

        # Second admin approves
        approval_token = self.registration.registration_approval.approval_state[admin2._id]['approval_token']
        self.registration.registration_approval.approve(admin2, approval_token)
        assert_false(self.registration.is_pending_registration)
        num_of_approvals = sum([val['has_approved'] for val in self.registration.registration_approval.approval_state.values()])
        assert_equal(num_of_approvals, 2)

    def test_invalid_rejection_token_raises_InvalidSanctionRejectionToken(self):
        self.registration.require_approval(
            self.user
        )
        self.registration.save()
        assert_true(self.registration.is_pending_registration)
        with assert_raises(InvalidSanctionRejectionToken):
            self.registration.registration_approval.reject(self.user, fake.sentence())
        assert_true(self.registration.is_pending_registration)

    def test_non_admin_rejection_token_raises_PermissionsError(self):
        non_admin = UserFactory()
        self.registration.require_approval(
            self.user
        )
        self.registration.save()
        assert_true(self.registration.is_pending_registration)

        rejection_token = self.registration.registration_approval.approval_state[self.user._id]['rejection_token']
        with assert_raises(PermissionsError):
            self.registration.registration_approval.reject(non_admin, rejection_token)
        assert_true(self.registration.is_pending_registration)

    def test_one_disapproval_cancels_registration_approval(self):
        self.registration.require_approval(
            self.user
        )
        self.registration.save()
        assert_true(self.registration.is_pending_registration)

        rejection_token = self.registration.registration_approval.approval_state[self.user._id]['rejection_token']
        self.registration.registration_approval.reject(self.user, rejection_token)
        assert_equal(self.registration.registration_approval.state, Sanction.REJECTED)
        assert_false(self.registration.is_pending_registration)

    def test_disapproval_adds_to_parent_projects_log(self):
        initial_project_logs = len(self.registration.registered_from.logs)
        self.registration.require_approval(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10)
        )
        self.registration.save()

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

    def test_cancelling_registration_approval_deletes_parent_registration(self):
        self.registration.require_approval(
            self.user
        )
        self.registration.save()

        rejection_token = self.registration.registration_approval.approval_state[self.user._id]['rejection_token']
        self.registration.registration_approval.reject(self.user, rejection_token)
        assert_equal(self.registration.registration_approval.state, Sanction.REJECTED)
        assert_true(self.registration.is_deleted)

    def test_cancelling_registration_approval_deletes_component_registrations(self):
        component = NodeFactory(
            creator=self.user,
            parent=self.project,
            title='Component'
        )
        NodeFactory(
            creator=self.user,
            parent=component,
            title='Subcomponent'
        )
        project_registration = RegistrationFactory(project=self.project)
        component_registration = project_registration.nodes[0]
        subcomponent_registration = component_registration.nodes[0]
        project_registration.require_approval(
            self.user
        )
        project_registration.save()

        rejection_token = project_registration.registration_approval.approval_state[self.user._id]['rejection_token']
        project_registration.registration_approval.reject(self.user, rejection_token)
        assert_equal(project_registration.registration_approval.state, Sanction.REJECTED)
        assert_true(project_registration.is_deleted)
        assert_true(component_registration.is_deleted)
        assert_true(subcomponent_registration.is_deleted)

    def test_new_registration_is_pending_registration(self):
        self.registration.require_approval(
            self.user
        )
        self.registration.save()
        assert_true(self.registration.is_pending_registration)

    def test_on_complete_notify_initiator(self):
        self.registration.require_approval(
            self.user,
            notify_initiator_on_complete=True
        )
        self.registration.save()
        with mock.patch.object(PreregCallbackMixin, '_notify_initiator') as mock_notify:
            self.registration.registration_approval._on_complete(self.user)
        mock_notify.assert_called()
Beispiel #16
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 = datetime.datetime.utcnow(
        ) + 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__initiate_embargo_does_not_create_tokens_for_unregistered_admin(
            self):
        unconfirmed_user = UnconfirmedUserFactory()
        self.registration.contributors.append(unconfirmed_user)
        self.registration.add_permission(unconfirmed_user, 'admin', save=True)
        assert_true(self.registration.has_permission(unconfirmed_user,
                                                     'admin'))

        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_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)

    # Backref tests
    def test_embargo_initiator_has_backref(self):
        self.registration.embargo_registration(self.user,
                                               self.valid_embargo_end_date)
        self.registration.save()
        self.registration.reload()
        assert_equal(len(self.user.embargo__embargoed),
                     Embargo.find(Q('initiated_by', 'eq', self.user)).count())

    # 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_ValidationValueError(self):
        with assert_raises(ValidationValueError):
            self.registration.embargo_registration(
                self.user, datetime.datetime(1999, 1, 1))

    def test_embargo_end_date_today_raises_ValidationValueError(self):
        with assert_raises(ValidationValueError):
            self.registration.embargo_registration(self.user,
                                                   datetime.datetime.utcnow())

    def test_embargo_end_date_in_far_future_raises_ValidationValueError(self):
        with assert_raises(ValidationValueError):
            self.registration.embargo_registration(
                self.user, datetime.datetime(2099, 1, 1))

    def test_embargo_with_valid_end_date_starts_pending_embargo(self):
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + 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,
            datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)
        assert_false(self.registration.is_public)

    def test_embargo_non_registration_raises_NodeStateError(self):
        self.registration.is_registration = False
        self.registration.save()
        with assert_raises(NodeStateError):
            self.registration.embargo_registration(
                self.user,
                datetime.datetime.utcnow() + datetime.timedelta(days=10))
        assert_false(self.registration.is_pending_embargo)

    # Embargo#approve_embargo tests
    def test_invalid_approval_token_raises_InvalidSanctionApprovalToken(self):
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + 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,
            datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        approval_token = self.registration.embargo.approval_state[
            self.user._id]['approval_token']
        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,
            datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        approval_token = self.registration.embargo.approval_state[
            self.user._id]['approval_token']
        self.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 = len(self.registration.registered_from.logs)
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + 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(len(self.registration.registered_from.logs),
                     initial_project_logs + 2)

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

        # 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,
            datetime.datetime.utcnow() + 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,
            datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        rejection_token = self.registration.embargo.approval_state[
            self.user._id]['rejection_token']
        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,
            datetime.datetime.utcnow() + datetime.timedelta(days=10))
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

        rejection_token = self.registration.embargo.approval_state[
            self.user._id]['rejection_token']
        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 = len(self.registration.registered_from.logs)
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + 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(len(registered_from.logs), initial_project_logs + 2)

    def test_cancelling_embargo_deletes_parent_registration(self):
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + 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)
        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')
        subcomponent = NodeFactory(creator=self.user,
                                   parent=component,
                                   title='Subcomponent')
        project_registration = RegistrationFactory(project=self.project)
        component_registration = project_registration.nodes[0]
        subcomponent_registration = component_registration.nodes[0]
        project_registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + 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)
        assert_true(project_registration.is_deleted)
        assert_true(component_registration.is_deleted)
        assert_true(subcomponent_registration.is_deleted)

    def test_cancelling_embargo_for_existing_registration_does_not_delete_registration(
            self):
        self.registration.embargo_registration(self.user,
                                               datetime.datetime.utcnow() +
                                               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')
        subcomponent = NodeFactory(creator=self.user,
                                   parent=component,
                                   title='Subcomponent')
        project_registration = RegistrationFactory(project=self.project)
        component_registration = project_registration.nodes[0]
        subcomponent_registration = component_registration.nodes[0]
        project_registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + 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,
            datetime.datetime.utcnow() + 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,
                                               datetime.datetime.utcnow() +
                                               datetime.timedelta(days=10),
                                               for_existing_registration=True)
        self.registration.save()
        assert_false(
            self.registration.is_pending_embargo_for_existing_registration)
Beispiel #17
0
class RegistrationWithChildNodesRetractionModelTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationWithChildNodesRetractionModelTestCase, self).setUp()
        self.user = AuthUserFactory()
        self.auth = self.user.auth
        self.project = ProjectFactory(is_public=True, creator=self.user)
        self.component = NodeFactory(
            creator=self.user,
            parent=self.project,
            title='Component'
        )
        self.subproject = ProjectFactory(
            creator=self.user,
            parent=self.project,
            title='Subproject'
        )
        self.subproject_component = NodeFactory(
            creator=self.user,
            parent=self.subproject,
            title='Subcomponent'
        )
        self.registration = RegistrationFactory(project=self.project, is_public=True)
        # Reload the registration; else tests won't catch failures to svae
        self.registration.reload()

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

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

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

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

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

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

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

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

    def test_approval_cancels_pending_embargoes_on_descendant_nodes(self):
        # Initiate embargo for registration
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10),
            for_existing_registration=True
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

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

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

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

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

    def test_approval_cancels_active_embargoes_on_descendant_nodes(self):
        # Initiate embargo for registration
        self.registration.embargo_registration(
            self.user,
            datetime.datetime.utcnow() + datetime.timedelta(days=10),
            for_existing_registration=True
        )
        self.registration.save()
        assert_true(self.registration.is_pending_embargo)

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

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

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

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

        # Ensure descendant nodes are not pending embargo
        descendants = self.registration.get_descendants_recursive()
        for node in descendants:
            assert_true(node.is_retracted)
Beispiel #18
0
class RegistrationWithChildNodesEmbargoModelTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationWithChildNodesEmbargoModelTestCase, self).setUp()
        self.user = AuthUserFactory()
        self.auth = self.user.auth
        self.valid_embargo_end_date = datetime.datetime.utcnow(
        ) + 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:
            assert_false(node.is_pending_embargo)
            assert_false(node.embargo_end_date)
class TestIdentifierViews(OsfTestCase):

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

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

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


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

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

    def test_get_by_identifier_not_found(self):
        self.node.set_identifier_value('doi', 'FK424601')
        res = self.app.get(
            self.node.web_url_for(
                'get_referent_by_identifier',
                category='doi',
                value='fakedoi',
            ),
            expect_errors=True,
        )
        assert_equal(res.status_code, 404)
Beispiel #20
0
class RegistrationRetractionModelsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationRetractionModelsTestCase, self).setUp()
        self.user = UserFactory()
        self.registration = RegistrationFactory(creator=self.user, is_public=True)
        self.valid_justification = fake.sentence()
        self.invalid_justification = fake.text(max_nb_chars=3000)

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

        assert_true(self.registration.is_public)

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

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

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

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

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

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

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

        registration = RegistrationFactory(project=project)

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

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

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

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

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

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

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

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

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

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

        project.reload()
        assert_is_none(project.retraction)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    # Retraction property tests
    def test_new_retraction_is_pending_retraction(self):
        self.registration.retract_registration(self.user)
        assert_true(self.registration.is_pending_retraction)
        assert_false(self.registration.is_retracted)
class RegistrationRetractionViewsTestCase(OsfTestCase):
    def setUp(self):
        super(RegistrationRetractionViewsTestCase, self).setUp()
        self.user = AuthUserFactory()
        self.auth = self.user.auth
        self.registration = RegistrationFactory(creator=self.user, is_public=True)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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