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 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)
class TestNodeWikiList(ApiWikiTestCase): def _set_up_public_project_with_wiki_page(self): self.public_project = ProjectFactory(is_public=True, creator=self.user) self.public_wiki = self._add_project_wiki_page(self.public_project, self.user) self.public_url = '/{}nodes/{}/wikis/'.format(API_BASE, self.public_project._id) def _set_up_private_project_with_wiki_page(self): self.private_project = ProjectFactory(creator=self.user) self.private_wiki = self._add_project_wiki_page( self.private_project, self.user) self.private_url = '/{}nodes/{}/wikis/'.format( API_BASE, self.private_project._id) def _set_up_registration_with_wiki_page(self): self._set_up_private_project_with_wiki_page() self.registration = RegistrationFactory(project=self.private_project, user=self.user) self.registration_wiki_id = self.registration.wiki_pages_versions[ 'home'][0] self.registration.wiki_pages_current = { 'home': self.registration_wiki_id } self.registration.save() self.registration_url = '/{}registrations/{}/wikis/'.format( API_BASE, self.registration._id) def test_return_public_node_wikis_logged_out_user(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url) assert_equal(res.status_code, 200) wiki_ids = [wiki['id'] for wiki in res.json['data']] assert_in(self.public_wiki._id, wiki_ids) def test_return_public_node_wikis_logged_in_non_contributor(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url, auth=self.non_contributor.auth) assert_equal(res.status_code, 200) wiki_ids = [wiki['id'] for wiki in res.json['data']] assert_in(self.public_wiki._id, wiki_ids) def test_return_public_node_wikis_logged_in_contributor(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) wiki_ids = [wiki['id'] for wiki in res.json['data']] assert_in(self.public_wiki._id, wiki_ids) def test_return_private_node_wikis_logged_out_user(self): self._set_up_private_project_with_wiki_page() res = self.app.get(self.private_url, expect_errors=True) assert_equal(res.status_code, 401) assert_equal(res.json['errors'][0]['detail'], 'Authentication credentials were not provided.') def test_return_private_node_wikis_logged_in_non_contributor(self): self._set_up_private_project_with_wiki_page() res = self.app.get(self.private_url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.') def test_return_private_node_wikis_logged_in_contributor(self): self._set_up_private_project_with_wiki_page() res = self.app.get(self.private_url, auth=self.user.auth) assert_equal(res.status_code, 200) wiki_ids = [wiki['id'] for wiki in res.json['data']] assert_in(self.private_wiki._id, wiki_ids) def test_return_registration_wikis_logged_out_user(self): self._set_up_registration_with_wiki_page() res = self.app.get(self.registration_url, expect_errors=True) assert_equal(res.status_code, 401) assert_equal(res.json['errors'][0]['detail'], 'Authentication credentials were not provided.') def test_return_registration_wikis_logged_in_non_contributor(self): self._set_up_registration_with_wiki_page() res = self.app.get(self.registration_url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.') def test_return_registration_wikis_logged_in_contributor(self): self._set_up_registration_with_wiki_page() res = self.app.get(self.registration_url, auth=self.user.auth) assert_equal(res.status_code, 200) wiki_ids = [wiki['id'] for wiki in res.json['data']] assert_in(self.registration_wiki_id, wiki_ids) def test_wikis_not_returned_for_withdrawn_registration(self): self._set_up_registration_with_wiki_page() self.registration.is_public = True withdrawal = self.registration.retract_registration(user=self.user, save=True) token = withdrawal.approval_state.values()[0]['approval_token'] withdrawal.approve_retraction(self.user, token) withdrawal.save() res = self.app.get(self.registration_url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.')
class TestWikiDetailView(ApiWikiTestCase): def _set_up_public_project_with_wiki_page(self): self.public_project = ProjectFactory(is_public=True, creator=self.user) self.public_wiki = self._add_project_wiki_page(self.public_project, self.user) self.public_url = '/{}wikis/{}/'.format(API_BASE, self.public_wiki._id) def _set_up_private_project_with_wiki_page(self): self.private_project = ProjectFactory(creator=self.user) self.private_wiki = self._add_project_wiki_page(self.private_project, self.user) self.private_url = '/{}wikis/{}/'.format(API_BASE, self.private_wiki._id) def _set_up_public_registration_with_wiki_page(self): self._set_up_public_project_with_wiki_page() self.public_registration = RegistrationFactory(project=self.public_project, user=self.user, is_public=True) self.public_registration_wiki_id = self.public_registration.wiki_pages_versions['home'][0] self.public_registration.wiki_pages_current = {'home': self.public_registration_wiki_id} self.public_registration.save() self.public_registration_url = '/{}wikis/{}/'.format(API_BASE, self.public_registration_wiki_id) def _set_up_private_registration_with_wiki_page(self): self._set_up_private_project_with_wiki_page() self.private_registration = RegistrationFactory(project=self.private_project, user=self.user) self.private_registration_wiki_id = self.private_registration.wiki_pages_versions['home'][0] self.private_registration.wiki_pages_current = {'home': self.private_registration_wiki_id} self.private_registration.save() self.private_registration_url = '/{}wikis/{}/'.format(API_BASE, self.private_registration_wiki_id) def test_public_node_logged_out_user_can_view_wiki(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url) assert_equal(res.status_code, 200) assert_equal(res.json['data']['id'], self.public_wiki._id) def test_public_node_logged_in_non_contributor_can_view_wiki(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url, auth=self.non_contributor.auth) assert_equal(res.status_code, 200) assert_equal(res.json['data']['id'], self.public_wiki._id) def test_public_node_logged_in_contributor_can_view_wiki(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.json['data']['id'], self.public_wiki._id) def test_private_node_logged_out_user_cannot_view_wiki(self): self._set_up_private_project_with_wiki_page() res = self.app.get(self.private_url, expect_errors=True) assert_equal(res.status_code, 401) assert_equal(res.json['errors'][0]['detail'], 'Authentication credentials were not provided.') def test_private_node_logged_in_non_contributor_cannot_view_wiki(self): self._set_up_private_project_with_wiki_page() res = self.app.get(self.private_url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.') def test_private_node_logged_in_contributor_can_view_wiki(self): self._set_up_private_project_with_wiki_page() res = self.app.get(self.private_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.json['data']['id'], self.private_wiki._id) def test_private_node_user_with_anonymous_link_can_view_wiki(self): self._set_up_private_project_with_wiki_page() private_link = PrivateLinkFactory(anonymous=True) private_link.nodes.append(self.private_project) private_link.save() url = furl.furl(self.private_url).add(query_params={'view_only': private_link.key}).url res = self.app.get(url) assert_equal(res.status_code, 200) assert_equal(res.json['data']['id'], self.private_wiki._id) def test_private_node_user_with_view_only_link_can_view_wiki(self): self._set_up_private_project_with_wiki_page() private_link = PrivateLinkFactory(anonymous=False) private_link.nodes.append(self.private_project) private_link.save() url = furl.furl(self.private_url).add(query_params={'view_only': private_link.key}).url res = self.app.get(url) assert_equal(res.status_code, 200) assert_equal(res.json['data']['id'], self.private_wiki._id) def test_public_registration_logged_out_user_cannot_view_wiki(self): self._set_up_public_registration_with_wiki_page() res = self.app.get(self.public_registration_url, expect_errors=True) assert_equal(res.status_code, 200) assert_equal(res.json['data']['id'], self.public_registration_wiki_id) def test_public_registration_logged_in_non_contributor_cannot_view_wiki(self): self._set_up_public_registration_with_wiki_page() res = self.app.get(self.public_registration_url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 200) assert_equal(res.json['data']['id'], self.public_registration_wiki_id) def test_public_registration_contributor_can_view_wiki(self): self._set_up_public_registration_with_wiki_page() res = self.app.get(self.public_registration_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.json['data']['id'], self.public_registration_wiki_id) def test_user_cannot_view_withdrawn_registration_wikis(self): self._set_up_public_registration_with_wiki_page() withdrawal = self.public_registration.retract_registration(user=self.user, save=True) token = withdrawal.approval_state.values()[0]['approval_token'] withdrawal.approve_retraction(self.user, token) withdrawal.save() res = self.app.get(self.public_registration_url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.') def test_private_registration_logged_out_user_cannot_view_wiki(self): self._set_up_private_registration_with_wiki_page() res = self.app.get(self.private_registration_url, expect_errors=True) assert_equal(res.status_code, 401) assert_equal(res.json['errors'][0]['detail'], 'Authentication credentials were not provided.') def test_private_registration_logged_in_non_contributor_cannot_view_wiki(self): self._set_up_private_registration_with_wiki_page() res = self.app.get(self.private_registration_url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.') def test_private_registration_contributor_can_view_wiki(self): self._set_up_private_registration_with_wiki_page() res = self.app.get(self.private_registration_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.json['data']['id'], self.private_registration_wiki_id) def test_wiki_has_user_link(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url) url = res.json['data']['relationships']['user']['links']['related']['href'] expected_url = '/{}users/{}/'.format(API_BASE, self.user._id) assert_equal(res.status_code, 200) assert_equal(urlparse(url).path, expected_url) def test_wiki_has_node_link(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url) url = res.json['data']['relationships']['node']['links']['related']['href'] expected_url = '/{}nodes/{}/'.format(API_BASE, self.public_project._id) assert_equal(res.status_code, 200) assert_equal(urlparse(url).path, expected_url) def test_wiki_has_comments_link(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url) url = res.json['data']['relationships']['comments']['links']['related']['href'] expected_url = '/{}nodes/{}/comments/?filter[target]={}'.format(API_BASE, self.public_project._id, self.public_wiki._id) assert_equal(res.status_code, 200) assert_in(expected_url, url) def test_wiki_has_download_link(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url) url = res.json['data']['links']['download'] expected_url = '/{}wikis/{}/content/'.format(API_BASE, self.public_wiki._id) assert_equal(res.status_code, 200) assert_in(expected_url, url) def test_wiki_invalid_id_not_found(self): url = '/{}wikis/{}/'.format(API_BASE, 'abcde') res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 404) def test_old_wiki_versions_not_returned(self): self._set_up_public_project_with_wiki_page() current_wiki = NodeWikiFactory(node=self.public_project, user=self.user) old_version_id = self.public_project.wiki_pages_versions[current_wiki.page_name][-2] old_version = NodeWikiPage.load(old_version_id) url = '/{}wikis/{}/'.format(API_BASE, old_version._id) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 404)
class TestRetractRegistrations(OsfTestCase): def setUp(self): super(TestRetractRegistrations, self).setUp() self.user = UserFactory() self.registration = RegistrationFactory(creator=self.user) self.registration.is_public = True self.registration.retract_registration(self.user) self.registration.save() def test_new_retraction_should_not_be_retracted(self): assert_false(self.registration.is_retracted) main(dry_run=False) assert_false(self.registration.is_retracted) def test_should_not_retract_pending_retraction_less_than_48_hours_old(self): # Retraction#iniation_date is read only self.registration.retraction._fields['initiation_date'].__set__( self.registration.retraction, (timezone.now() - timedelta(hours=47)), safe=True ) # setattr(self.registration.retraction, 'initiation_date', (timezone.now() - timedelta(hours=47))) self.registration.retraction.save() assert_false(self.registration.is_retracted) main(dry_run=False) assert_false(self.registration.is_retracted) def test_should_retract_pending_retraction_that_is_48_hours_old(self): # Retraction#iniation_date is read only self.registration.retraction._fields['initiation_date'].__set__( self.registration.retraction, (timezone.now() - timedelta(hours=48)), safe=True ) self.registration.retraction.save() assert_false(self.registration.is_retracted) main(dry_run=False) assert_true(self.registration.is_retracted) def test_should_retract_pending_retraction_more_than_48_hours_old(self): # Retraction#iniation_date is read only self.registration.retraction._fields['initiation_date'].__set__( self.registration.retraction, (timezone.now() - timedelta(days=365)), safe=True ) self.registration.retraction.save() assert_false(self.registration.is_retracted) main(dry_run=False) assert_true(self.registration.is_retracted) def test_retraction_adds_to_parent_projects_log(self): initial_project_logs = len(self.registration.registered_from.logs) # Retraction#iniation_date is read only self.registration.retraction._fields['initiation_date'].__set__( self.registration.retraction, (timezone.now() - timedelta(days=365)), safe=True ) self.registration.retraction.save() assert_false(self.registration.is_retracted) main(dry_run=False) assert_true(self.registration.is_retracted) # Logs: Created, made public, retraction initiated, retracted approved assert_equal(len(self.registration.registered_from.logs), initial_project_logs + 1)
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 TestWikiContentView(ApiWikiTestCase): def _set_up_public_project_with_wiki_page(self): self.public_project = ProjectFactory(is_public=True, creator=self.user) self.public_wiki = self._add_project_wiki_page(self.public_project, self.user) self.public_url = '/{}wikis/{}/content/'.format(API_BASE, self.public_wiki._id) def _set_up_private_project_with_wiki_page(self): self.private_project = ProjectFactory(creator=self.user) self.private_wiki = self._add_project_wiki_page(self.private_project, self.user) self.private_url = '/{}wikis/{}/content/'.format(API_BASE, self.private_wiki._id) def _set_up_public_registration_with_wiki_page(self): self._set_up_public_project_with_wiki_page() self.public_registration = RegistrationFactory(project=self.public_project, user=self.user, is_public=True) self.public_registration_wiki_id = self.public_registration.wiki_pages_versions['home'][0] self.public_registration.wiki_pages_current = {'home': self.public_registration_wiki_id} self.public_registration.save() self.public_registration_url = '/{}wikis/{}/content/'.format(API_BASE, self.public_registration_wiki_id) def test_logged_out_user_can_get_public_wiki_content(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url) assert_equal(res.status_code, 200) assert_equal(res.content_type, 'text/markdown') assert_equal(res.body, self.public_wiki.content) def test_logged_in_non_contributor_can_get_public_wiki_content(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url, auth=self.non_contributor.auth) assert_equal(res.status_code, 200) assert_equal(res.content_type, 'text/markdown') assert_equal(res.body, self.public_wiki.content) def test_logged_in_contributor_can_get_public_wiki_content(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.content_type, 'text/markdown') assert_equal(res.body, self.public_wiki.content) def test_logged_out_user_cannot_get_private_wiki_content(self): self._set_up_private_project_with_wiki_page() res = self.app.get(self.private_url, expect_errors=True) assert_equal(res.status_code, 401) def test_logged_in_non_contributor_cannot_get_private_wiki_content(self): self._set_up_private_project_with_wiki_page() res = self.app.get(self.private_url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_logged_in_contributor_can_get_private_wiki_content(self): self._set_up_private_project_with_wiki_page() res = self.app.get(self.private_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.content_type, 'text/markdown') assert_equal(res.body, self.private_wiki.content) def test_user_cannot_get_withdrawn_registration_wiki_content(self): self._set_up_public_registration_with_wiki_page() withdrawal = self.public_registration.retract_registration(user=self.user, save=True) token = withdrawal.approval_state.values()[0]['approval_token'] withdrawal.approve_retraction(self.user, token) withdrawal.save() res = self.app.get(self.public_registration_url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 403)
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)
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 TestNodeWikiList(ApiWikiTestCase): def _set_up_public_project_with_wiki_page(self): self.public_project = ProjectFactory(is_public=True, creator=self.user) self.public_wiki = self._add_project_wiki_page(self.public_project, self.user) self.public_url = '/{}nodes/{}/wikis/'.format(API_BASE, self.public_project._id) def _set_up_private_project_with_wiki_page(self): self.private_project = ProjectFactory(creator=self.user) self.private_wiki = self._add_project_wiki_page(self.private_project, self.user) self.private_url = '/{}nodes/{}/wikis/'.format(API_BASE, self.private_project._id) def _set_up_public_registration_with_wiki_page(self): self._set_up_public_project_with_wiki_page() self.public_registration = RegistrationFactory(project=self.public_project, user=self.user, is_public=True) self.public_registration_wiki_id = self.public_registration.wiki_pages_versions['home'][0] self.public_registration.wiki_pages_current = {'home': self.public_registration_wiki_id} self.public_registration.save() self.public_registration_url = '/{}registrations/{}/wikis/'.format(API_BASE, self.public_registration._id) def _set_up_registration_with_wiki_page(self): self._set_up_private_project_with_wiki_page() self.registration = RegistrationFactory(project=self.private_project, user=self.user) self.registration_wiki_id = self.registration.wiki_pages_versions['home'][0] self.registration.wiki_pages_current = {'home': self.registration_wiki_id} self.registration.save() self.registration_url = '/{}registrations/{}/wikis/'.format(API_BASE, self.registration._id) def test_return_public_node_wikis_logged_out_user(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url) assert_equal(res.status_code, 200) wiki_ids = [wiki['id'] for wiki in res.json['data']] assert_in(self.public_wiki._id, wiki_ids) def test_return_public_node_wikis_logged_in_non_contributor(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url, auth=self.non_contributor.auth) assert_equal(res.status_code, 200) wiki_ids = [wiki['id'] for wiki in res.json['data']] assert_in(self.public_wiki._id, wiki_ids) def test_return_public_node_wikis_logged_in_contributor(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) wiki_ids = [wiki['id'] for wiki in res.json['data']] assert_in(self.public_wiki._id, wiki_ids) def test_return_private_node_wikis_logged_out_user(self): self._set_up_private_project_with_wiki_page() res = self.app.get(self.private_url, expect_errors=True) assert_equal(res.status_code, 401) assert_equal(res.json['errors'][0]['detail'], 'Authentication credentials were not provided.') def test_return_private_node_wikis_logged_in_non_contributor(self): self._set_up_private_project_with_wiki_page() res = self.app.get(self.private_url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.') def test_return_private_node_wikis_logged_in_contributor(self): self._set_up_private_project_with_wiki_page() res = self.app.get(self.private_url, auth=self.user.auth) assert_equal(res.status_code, 200) wiki_ids = [wiki['id'] for wiki in res.json['data']] assert_in(self.private_wiki._id, wiki_ids) def test_return_registration_wikis_logged_out_user(self): self._set_up_registration_with_wiki_page() res = self.app.get(self.registration_url, expect_errors=True) assert_equal(res.status_code, 401) assert_equal(res.json['errors'][0]['detail'], 'Authentication credentials were not provided.') def test_return_registration_wikis_logged_in_non_contributor(self): self._set_up_registration_with_wiki_page() res = self.app.get(self.registration_url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.') def test_return_registration_wikis_logged_in_contributor(self): self._set_up_registration_with_wiki_page() res = self.app.get(self.registration_url, auth=self.user.auth) assert_equal(res.status_code, 200) wiki_ids = [wiki['id'] for wiki in res.json['data']] assert_in(self.registration_wiki_id, wiki_ids) def test_wikis_not_returned_for_withdrawn_registration(self): self._set_up_registration_with_wiki_page() self.registration.is_public = True withdrawal = self.registration.retract_registration(user=self.user, save=True) token = withdrawal.approval_state.values()[0]['approval_token'] withdrawal.approve_retraction(self.user, token) withdrawal.save() res = self.app.get(self.registration_url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json['errors'][0]['detail'], 'You do not have permission to perform this action.') def test_public_node_wikis_relationship_links(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url) expected_nodes_relationship_url = '{}nodes/{}/'.format(API_BASE, self.public_project._id) expected_comments_relationship_url = '{}nodes/{}/comments/'.format(API_BASE, self.public_project._id) assert_in(expected_nodes_relationship_url, res.json['data'][0]['relationships']['node']['links']['related']['href']) assert_in(expected_comments_relationship_url, res.json['data'][0]['relationships']['comments']['links']['related']['href']) def test_private_node_wikis_relationship_links(self): self._set_up_private_project_with_wiki_page() res = self.app.get(self.private_url, auth=self.user.auth) expected_nodes_relationship_url = '{}nodes/{}/'.format(API_BASE, self.private_project._id) expected_comments_relationship_url = '{}nodes/{}/comments/'.format(API_BASE, self.private_project._id) assert_in(expected_nodes_relationship_url, res.json['data'][0]['relationships']['node']['links']['related']['href']) assert_in(expected_comments_relationship_url, res.json['data'][0]['relationships']['comments']['links']['related']['href']) def test_public_registration_wikis_relationship_links(self): self._set_up_public_registration_with_wiki_page() res = self.app.get(self.public_registration_url) expected_nodes_relationship_url = '{}registrations/{}/'.format(API_BASE, self.public_registration._id) expected_comments_relationship_url = '{}registrations/{}/comments/'.format(API_BASE, self.public_registration._id) assert_in(expected_nodes_relationship_url, res.json['data'][0]['relationships']['node']['links']['related']['href']) assert_in(expected_comments_relationship_url, res.json['data'][0]['relationships']['comments']['links']['related']['href']) def test_private_registration_wikis_relationship_links(self): self._set_up_registration_with_wiki_page() res = self.app.get(self.registration_url, auth=self.user.auth) expected_nodes_relationship_url = '{}registrations/{}/'.format(API_BASE, self.registration._id) expected_comments_relationship_url = '{}registrations/{}/comments/'.format(API_BASE, self.registration._id) assert_in(expected_nodes_relationship_url, res.json['data'][0]['relationships']['node']['links']['related']['href']) assert_in(expected_comments_relationship_url, res.json['data'][0]['relationships']['comments']['links']['related']['href']) def test_registration_wikis_not_returned_from_nodes_endpoint(self): self._set_up_public_project_with_wiki_page() self._set_up_public_registration_with_wiki_page() res = self.app.get(self.public_url) node_relationships = [ node_wiki['relationships']['node']['links']['related']['href'] for node_wiki in res.json['data'] ] assert_equal(res.status_code, 200) assert_equal(len(node_relationships), 1) assert_in(self.public_project._id, node_relationships[0]) def test_node_wikis_not_returned_from_registrations_endpoint(self): self._set_up_public_project_with_wiki_page() self._set_up_public_registration_with_wiki_page() res = self.app.get(self.public_registration_url) node_relationships = [ node_wiki['relationships']['node']['links']['related']['href'] for node_wiki in res.json['data'] ] assert_equal(res.status_code, 200) assert_equal(len(node_relationships), 1) assert_in(self.public_registration._id, node_relationships[0])
class TestNodeWikiList(ApiWikiTestCase): def _set_up_public_project_with_wiki_page(self): self.public_project = ProjectFactory(is_public=True, creator=self.user) self.public_wiki = self._add_project_wiki_page(self.public_project, self.user) self.public_url = "/{}nodes/{}/wikis/".format(API_BASE, self.public_project._id) def _set_up_private_project_with_wiki_page(self): self.private_project = ProjectFactory(creator=self.user) self.private_wiki = self._add_project_wiki_page(self.private_project, self.user) self.private_url = "/{}nodes/{}/wikis/".format(API_BASE, self.private_project._id) def _set_up_registration_with_wiki_page(self): self._set_up_private_project_with_wiki_page() self.registration = RegistrationFactory(project=self.private_project, user=self.user) self.registration_wiki_id = self.registration.wiki_pages_versions["home"][0] self.registration.wiki_pages_current = {"home": self.registration_wiki_id} self.registration.save() self.registration_url = "/{}registrations/{}/wikis/".format(API_BASE, self.registration._id) def test_return_public_node_wikis_logged_out_user(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url) assert_equal(res.status_code, 200) wiki_ids = [wiki["id"] for wiki in res.json["data"]] assert_in(self.public_wiki._id, wiki_ids) def test_return_public_node_wikis_logged_in_non_contributor(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url, auth=self.non_contributor.auth) assert_equal(res.status_code, 200) wiki_ids = [wiki["id"] for wiki in res.json["data"]] assert_in(self.public_wiki._id, wiki_ids) def test_return_public_node_wikis_logged_in_contributor(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) wiki_ids = [wiki["id"] for wiki in res.json["data"]] assert_in(self.public_wiki._id, wiki_ids) def test_return_private_node_wikis_logged_out_user(self): self._set_up_private_project_with_wiki_page() res = self.app.get(self.private_url, expect_errors=True) assert_equal(res.status_code, 401) assert_equal(res.json["errors"][0]["detail"], "Authentication credentials were not provided.") def test_return_private_node_wikis_logged_in_non_contributor(self): self._set_up_private_project_with_wiki_page() res = self.app.get(self.private_url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json["errors"][0]["detail"], "You do not have permission to perform this action.") def test_return_private_node_wikis_logged_in_contributor(self): self._set_up_private_project_with_wiki_page() res = self.app.get(self.private_url, auth=self.user.auth) assert_equal(res.status_code, 200) wiki_ids = [wiki["id"] for wiki in res.json["data"]] assert_in(self.private_wiki._id, wiki_ids) def test_return_registration_wikis_logged_out_user(self): self._set_up_registration_with_wiki_page() res = self.app.get(self.registration_url, expect_errors=True) assert_equal(res.status_code, 401) assert_equal(res.json["errors"][0]["detail"], "Authentication credentials were not provided.") def test_return_registration_wikis_logged_in_non_contributor(self): self._set_up_registration_with_wiki_page() res = self.app.get(self.registration_url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json["errors"][0]["detail"], "You do not have permission to perform this action.") def test_return_registration_wikis_logged_in_contributor(self): self._set_up_registration_with_wiki_page() res = self.app.get(self.registration_url, auth=self.user.auth) assert_equal(res.status_code, 200) wiki_ids = [wiki["id"] for wiki in res.json["data"]] assert_in(self.registration_wiki_id, wiki_ids) def test_wikis_not_returned_for_withdrawn_registration(self): self._set_up_registration_with_wiki_page() self.registration.is_public = True withdrawal = self.registration.retract_registration(user=self.user, save=True) token = withdrawal.approval_state.values()[0]["approval_token"] withdrawal.approve_retraction(self.user, token) withdrawal.save() res = self.app.get(self.registration_url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_equal(res.json["errors"][0]["detail"], "You do not have permission to perform this action.")
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)
class RegistrationRetractionApprovalDisapprovalViewsTestCase(OsfTestCase): def setUp(self): super(RegistrationRetractionApprovalDisapprovalViewsTestCase, self).setUp() self.user = AuthUserFactory() self.auth = self.user.auth self.registration = RegistrationFactory(is_public=True, creator=self.user) # node_registration_retraction_approve_tests def test_GET_approve_from_unauthorized_user_raises_HTTPForbidden(self): unauthorized_user = AuthUserFactory() res = self.app.get( self.registration.web_url_for('node_registration_retraction_approve', token=fake.sentence()), auth=unauthorized_user.auth, expect_errors=True ) assert_equal(res.status_code, 403) def test_GET_approve_registration_without_retraction_returns_HTTPBad_Request(self): assert_false(self.registration.pending_retraction) res = self.app.get( self.registration.web_url_for('node_registration_retraction_approve', token=fake.sentence()), auth=self.auth, expect_errors=True ) assert_equal(res.status_code, 400) def test_GET_approve_with_invalid_token_returns_HTTPBad_Request(self): self.registration.retract_registration(self.user) self.registration.save() assert_true(self.registration.pending_retraction) res = self.app.get( self.registration.web_url_for('node_registration_retraction_approve', token=fake.sentence()), auth=self.auth, expect_errors=True ) assert_equal(res.status_code, 400) def test_GET_approve_with_valid_token_returns_redirect(self): self.registration.retract_registration(self.user) self.registration.save() assert_true(self.registration.pending_retraction) approval_token = self.registration.retraction.approval_state[self.user._id]['approval_token'] res = self.app.get( self.registration.web_url_for('node_registration_retraction_approve', token=approval_token), auth=self.auth ) self.registration.retraction.reload() assert_true(self.registration.is_retracted) assert_false(self.registration.pending_retraction) assert_equal(res.status_code, 302) def test_GET_approve_with_wrong_admins_token_returns_HTTPBad_Request(self): user2 = AuthUserFactory() self.registration.contributors.append(user2) self.registration.add_permission(user2, 'admin', save=True) self.registration.retract_registration(self.user) self.registration.save() assert_true(self.registration.pending_retraction) assert_equal(len(self.registration.retraction.approval_state), 2) wrong_approval_token = self.registration.retraction.approval_state[user2._id]['approval_token'] res = self.app.get( self.registration.web_url_for('node_registration_retraction_approve', token=wrong_approval_token), auth=self.auth, expect_errors=True ) assert_true(self.registration.pending_retraction) assert_equal(res.status_code, 400) # node_registration_retraction_disapprove_tests def test_GET_disapprove_from_unauthorized_user_raises_HTTPForbidden(self): unauthorized_user = AuthUserFactory() res = self.app.get( self.registration.web_url_for('node_registration_retraction_disapprove', token=fake.sentence()), auth=unauthorized_user.auth, expect_errors=True ) assert_equal(res.status_code, 403) def test_GET_disapprove_registration_without_retraction_returns_HTTPBad_Request(self): assert_false(self.registration.pending_retraction) res = self.app.get( self.registration.web_url_for('node_registration_retraction_disapprove', token=fake.sentence()), auth=self.auth, expect_errors=True ) assert_equal(res.status_code, 400) def test_GET_disapprove_with_invalid_token_returns_HTTPBad_Request(self): self.registration.retract_registration(self.user) self.registration.save() assert_true(self.registration.pending_retraction) res = self.app.get( self.registration.web_url_for('node_registration_retraction_disapprove', token=fake.sentence()), auth=self.auth, expect_errors=True ) assert_equal(res.status_code, 400) def test_GET_disapprove_with_wrong_admins_token_returns_HTTPBad_Request(self): user2 = AuthUserFactory() self.registration.contributors.append(user2) self.registration.add_permission(user2, 'admin', save=True) self.registration.retract_registration(self.user) self.registration.save() assert_true(self.registration.pending_retraction) assert_equal(len(self.registration.retraction.approval_state), 2) wrong_disapproval_token = self.registration.retraction.approval_state[user2._id]['disapproval_token'] res = self.app.get( self.registration.web_url_for('node_registration_retraction_disapprove', token=wrong_disapproval_token), auth=self.auth, expect_errors=True ) assert_true(self.registration.pending_retraction) assert_equal(res.status_code, 400) def test_GET_disapprove_with_valid_token_returns_redirect(self): self.registration.retract_registration(self.user) self.registration.save() assert_true(self.registration.pending_retraction) disapproval_token = self.registration.retraction.approval_state[self.user._id]['disapproval_token'] res = self.app.get( self.registration.web_url_for('node_registration_retraction_disapprove', token=disapproval_token), auth=self.auth, ) self.registration.retraction.reload() assert_false(self.registration.is_retracted) assert_false(self.registration.pending_retraction) assert_equal(self.registration.retraction.state, Retraction.CANCELLED) assert_equal(res.status_code, 302)
class RegistrationRetractionApprovalDisapprovalViewsTestCase(OsfTestCase): def setUp(self): super(RegistrationRetractionApprovalDisapprovalViewsTestCase, self).setUp() self.user = AuthUserFactory() self.registered_from = ProjectFactory(is_public=True, creator=self.user) self.registration = RegistrationFactory(is_public=True, project=self.registered_from) self.registration.retract_registration(self.user) self.registration.save() self.approval_token = self.registration.retraction.approval_state[self.user._id]['approval_token'] self.rejection_token = self.registration.retraction.approval_state[self.user._id]['rejection_token'] self.corrupt_token = fake.sentence() self.token_without_sanction = tokens.encode({ 'action': 'approve_retraction', 'user_id': self.user._id, 'sanction_id': 'invalid id' }) # node_registration_retraction_approve_tests def test_GET_approve_from_unauthorized_user_returns_HTTPError_UNAUTHORIZED(self): unauthorized_user = AuthUserFactory() res = self.app.get( self.registration.web_url_for('view_project', token=self.approval_token), auth=unauthorized_user.auth, expect_errors=True ) assert_equal(res.status_code, http.UNAUTHORIZED) def test_GET_approve_registration_without_retraction_returns_HTTPError_BAD_REQUEST(self): assert_true(self.registration.is_pending_retraction) self.registration.retraction.reject(self.user, self.rejection_token) assert_false(self.registration.is_pending_retraction) self.registration.retraction.save() res = self.app.get( self.registration.web_url_for('view_project', token=self.approval_token), auth=self.user.auth, expect_errors=True ) assert_equal(res.status_code, http.BAD_REQUEST) def test_GET_approve_with_invalid_token_returns_HTTPError_BAD_REQUEST(self): res = self.app.get( self.registration.web_url_for('view_project', token=self.corrupt_token), auth=self.user.auth, expect_errors=True ) assert_equal(res.status_code, http.BAD_REQUEST) def test_GET_approve_with_non_existant_sanction_returns_HTTPError_BAD_REQUEST(self): res = self.app.get( self.registration.web_url_for('view_project', token=self.token_without_sanction), auth=self.user.auth, expect_errors=True ) assert_equal(res.status_code, http.BAD_REQUEST) def test_GET_approve_with_valid_token_returns_200(self): res = self.app.get( self.registration.web_url_for('view_project', token=self.approval_token), auth=self.user.auth ) self.registration.retraction.reload() assert_true(self.registration.is_retracted) assert_false(self.registration.is_pending_retraction) assert_equal(res.status_code, http.OK) # node_registration_retraction_disapprove_tests def test_GET_disapprove_from_unauthorized_user_returns_HTTPError_UNAUTHORIZED(self): unauthorized_user = AuthUserFactory() res = self.app.get( self.registration.web_url_for('view_project', token=self.rejection_token), auth=unauthorized_user.auth, expect_errors=True ) assert_equal(res.status_code, http.UNAUTHORIZED) def test_GET_disapprove_registration_without_retraction_returns_HTTPError_BAD_REQUEST(self): assert_true(self.registration.is_pending_retraction) self.registration.retraction.reject(self.user, self.rejection_token) assert_false(self.registration.is_pending_retraction) self.registration.retraction.save() res = self.app.get( self.registration.web_url_for('view_project', token=self.rejection_token), auth=self.user.auth, expect_errors=True ) assert_equal(res.status_code, http.BAD_REQUEST) def test_GET_disapprove_with_invalid_token_HTTPError_BAD_REQUEST(self): res = self.app.get( self.registration.web_url_for('view_project', token=self.corrupt_token), auth=self.user.auth, expect_errors=True ) assert_equal(res.status_code, http.BAD_REQUEST) def test_GET_disapprove_with_valid_token_returns_redirect(self): res = self.app.get( self.registration.web_url_for('view_project', token=self.rejection_token), auth=self.user.auth, ) self.registration.retraction.reload() assert_false(self.registration.is_retracted) assert_false(self.registration.is_pending_retraction) assert_true(self.registration.retraction.is_rejected) assert_equal(res.status_code, http.OK)
class TestWikiContentView(ApiWikiTestCase): def _set_up_public_project_with_wiki_page(self): self.public_project = ProjectFactory(is_public=True, creator=self.user) self.public_wiki = self._add_project_wiki_page(self.public_project, self.user) self.public_url = '/{}wikis/{}/content/'.format( API_BASE, self.public_wiki._id) def _set_up_private_project_with_wiki_page(self): self.private_project = ProjectFactory(creator=self.user) self.private_wiki = self._add_project_wiki_page( self.private_project, self.user) self.private_url = '/{}wikis/{}/content/'.format( API_BASE, self.private_wiki._id) def _set_up_public_registration_with_wiki_page(self): self._set_up_public_project_with_wiki_page() self.public_registration = RegistrationFactory( project=self.public_project, user=self.user, is_public=True) self.public_registration_wiki_id = self.public_registration.wiki_pages_versions[ 'home'][0] self.public_registration.wiki_pages_current = { 'home': self.public_registration_wiki_id } self.public_registration.save() self.public_registration_url = '/{}wikis/{}/content/'.format( API_BASE, self.public_registration_wiki_id) def test_logged_out_user_can_get_public_wiki_content(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url) assert_equal(res.status_code, 200) assert_equal(res.content_type, 'text/markdown') assert_equal(res.body, self.public_wiki.content) def test_logged_in_non_contributor_can_get_public_wiki_content(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url, auth=self.non_contributor.auth) assert_equal(res.status_code, 200) assert_equal(res.content_type, 'text/markdown') assert_equal(res.body, self.public_wiki.content) def test_logged_in_contributor_can_get_public_wiki_content(self): self._set_up_public_project_with_wiki_page() res = self.app.get(self.public_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.content_type, 'text/markdown') assert_equal(res.body, self.public_wiki.content) def test_logged_out_user_cannot_get_private_wiki_content(self): self._set_up_private_project_with_wiki_page() res = self.app.get(self.private_url, expect_errors=True) assert_equal(res.status_code, 401) def test_logged_in_non_contributor_cannot_get_private_wiki_content(self): self._set_up_private_project_with_wiki_page() res = self.app.get(self.private_url, auth=self.non_contributor.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_logged_in_contributor_can_get_private_wiki_content(self): self._set_up_private_project_with_wiki_page() res = self.app.get(self.private_url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(res.content_type, 'text/markdown') assert_equal(res.body, self.private_wiki.content) def test_user_cannot_get_withdrawn_registration_wiki_content(self): self._set_up_public_registration_with_wiki_page() withdrawal = self.public_registration.retract_registration( user=self.user, save=True) token = withdrawal.approval_state.values()[0]['approval_token'] withdrawal.approve_retraction(self.user, token) withdrawal.save() res = self.app.get(self.public_registration_url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 403)
class RegistrationRetractionViewsTestCase(OsfTestCase): def setUp(self): super(RegistrationRetractionViewsTestCase, self).setUp() self.user = AuthUserFactory() self.registered_from = ProjectFactory(creator=self.user, is_public=True) self.registration = RegistrationFactory(project=self.registered_from, is_public=True) self.retraction_post_url = self.registration.api_url_for('node_registration_retraction_post') self.retraction_get_url = self.registration.web_url_for('node_registration_retraction_get') self.justification = fake.sentence() def test_GET_retraction_page_when_pending_retraction_returns_HTTPError_BAD_REQUEST(self): self.registration.retract_registration(self.user) self.registration.save() res = self.app.get( self.retraction_get_url, auth=self.user.auth, expect_errors=True, ) assert_equal(res.status_code, http.BAD_REQUEST) def test_POST_retraction_to_private_registration_returns_HTTPError_FORBIDDEN(self): self.registration.is_public = False self.registration.save() res = self.app.post_json( self.retraction_post_url, {'justification': ''}, auth=self.user.auth, expect_errors=True, ) assert_equal(res.status_code, http.FORBIDDEN) self.registration.reload() assert_is_none(self.registration.retraction) @mock.patch('website.mails.send_mail') def test_POST_retraction_does_not_send_email_to_unregistered_admins(self, mock_send_mail): unreg = UnregUserFactory() self.registration.add_contributor( unreg, auth=Auth(self.user), permissions=['read', 'write', 'admin'] ) self.registration.save() self.app.post_json( self.retraction_post_url, {'justification': ''}, auth=self.user.auth, ) # Only the creator gets an email; the unreg user does not get emailed assert_equal(mock_send_mail.call_count, 1) def test_POST_pending_embargo_returns_HTTPError_HTTPOK(self): self.registration.embargo_registration( self.user, (datetime.datetime.utcnow() + datetime.timedelta(days=10)), for_existing_registration=True ) self.registration.save() assert_true(self.registration.is_pending_embargo) res = self.app.post_json( self.retraction_post_url, {'justification': ''}, auth=self.user.auth, expect_errors=True, ) assert_equal(res.status_code, http.OK) self.registration.reload() assert_true(self.registration.is_pending_retraction) def test_POST_active_embargo_returns_HTTPOK(self): self.registration.embargo_registration( self.user, (datetime.datetime.utcnow() + datetime.timedelta(days=10)), for_existing_registration=True ) self.registration.save() assert_true(self.registration.is_pending_embargo) approval_token = self.registration.embargo.approval_state[self.user._id]['approval_token'] self.registration.embargo.approve(self.user, approval_token) assert_true(self.registration.embargo_end_date) res = self.app.post_json( self.retraction_post_url, {'justification': ''}, auth=self.user.auth, expect_errors=True, ) assert_equal(res.status_code, http.OK) self.registration.reload() assert_true(self.registration.is_pending_retraction) def test_POST_retraction_by_non_admin_retract_HTTPError_UNAUTHORIZED(self): res = self.app.post_json(self.retraction_post_url, expect_errors=True) assert_equals(res.status_code, http.UNAUTHORIZED) self.registration.reload() assert_is_none(self.registration.retraction) @mock.patch('website.mails.send_mail') def test_POST_retraction_without_justification_returns_HTTPOK(self, mock_send): res = self.app.post_json( self.retraction_post_url, {'justification': ''}, auth=self.user.auth, ) assert_equal(res.status_code, http.OK) self.registration.reload() assert_false(self.registration.is_retracted) assert_true(self.registration.is_pending_retraction) assert_is_none(self.registration.retraction.justification) @mock.patch('website.mails.send_mail') def test_valid_POST_retraction_adds_to_parent_projects_log(self, mock_send): initial_project_logs = len(self.registration.registered_from.logs) self.app.post_json( self.retraction_post_url, {'justification': ''}, auth=self.user.auth, ) self.registration.registered_from.reload() # Logs: Created, registered, retraction initiated assert_equal(len(self.registration.registered_from.logs), initial_project_logs + 1) @mock.patch('website.mails.send_mail') def test_valid_POST_retraction_when_pending_retraction_raises_400(self, mock_send): self.app.post_json( self.retraction_post_url, {'justification': ''}, auth=self.user.auth, ) res = self.app.post_json( self.retraction_post_url, {'justification': ''}, auth=self.user.auth, expect_errors=True ) assert_equal(res.status_code, 400) @mock.patch('website.mails.send_mail') def test_valid_POST_calls_send_mail_with_username(self, mock_send): self.app.post_json( self.retraction_post_url, {'justification': ''}, auth=self.user.auth, ) assert_true(mock_send.called) args, kwargs = mock_send.call_args assert_true(self.user.username in args) def test_non_contributor_GET_approval_returns_HTTPError_UNAUTHORIZED(self): non_contributor = AuthUserFactory() self.registration.retract_registration(self.user) approval_token = self.registration.retraction.approval_state[self.user._id]['approval_token'] approval_url = self.registration.web_url_for('view_project', token=approval_token) res = self.app.get(approval_url, auth=non_contributor.auth, expect_errors=True) assert_equal(res.status_code, http.UNAUTHORIZED) assert_true(self.registration.is_pending_retraction) assert_false(self.registration.is_retracted) def test_non_contributor_GET_disapproval_returns_HTTPError_UNAUTHORIZED(self): non_contributor = AuthUserFactory() self.registration.retract_registration(self.user) rejection_token = self.registration.retraction.approval_state[self.user._id]['rejection_token'] disapproval_url = self.registration.web_url_for('view_project', token=rejection_token) res = self.app.get(disapproval_url, auth=non_contributor.auth, expect_errors=True) assert_equal(res.status_code, http.UNAUTHORIZED) assert_true(self.registration.is_pending_retraction) assert_false(self.registration.is_retracted)
class RegistrationRetractionApprovalDisapprovalViewsTestCase(OsfTestCase): def setUp(self): super(RegistrationRetractionApprovalDisapprovalViewsTestCase, self).setUp() self.user = AuthUserFactory() self.auth = self.user.auth self.registration = RegistrationFactory(is_public=True, creator=self.user) # node_registration_retraction_approve_tests def test_GET_approve_from_unauthorized_user_raises_HTTPForbidden(self): unauthorized_user = AuthUserFactory() res = self.app.get(self.registration.web_url_for( 'node_registration_retraction_approve', token=fake.sentence()), auth=unauthorized_user.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_GET_approve_registration_without_retraction_returns_HTTPBad_Request( self): assert_false(self.registration.pending_retraction) res = self.app.get(self.registration.web_url_for( 'node_registration_retraction_approve', token=fake.sentence()), auth=self.auth, expect_errors=True) assert_equal(res.status_code, 400) def test_GET_approve_with_invalid_token_returns_HTTPBad_Request(self): self.registration.retract_registration(self.user) self.registration.save() assert_true(self.registration.pending_retraction) res = self.app.get(self.registration.web_url_for( 'node_registration_retraction_approve', token=fake.sentence()), auth=self.auth, expect_errors=True) assert_equal(res.status_code, 400) def test_GET_approve_with_valid_token_returns_redirect(self): self.registration.retract_registration(self.user) self.registration.save() assert_true(self.registration.pending_retraction) approval_token = self.registration.retraction.approval_state[ self.user._id]['approval_token'] res = self.app.get(self.registration.web_url_for( 'node_registration_retraction_approve', token=approval_token), auth=self.auth) self.registration.retraction.reload() assert_true(self.registration.is_retracted) assert_false(self.registration.pending_retraction) assert_equal(res.status_code, 302) def test_GET_approve_with_wrong_admins_token_returns_HTTPBad_Request(self): user2 = AuthUserFactory() self.registration.contributors.append(user2) self.registration.add_permission(user2, 'admin', save=True) self.registration.retract_registration(self.user) self.registration.save() assert_true(self.registration.pending_retraction) assert_equal(len(self.registration.retraction.approval_state), 2) wrong_approval_token = self.registration.retraction.approval_state[ user2._id]['approval_token'] res = self.app.get(self.registration.web_url_for( 'node_registration_retraction_approve', token=wrong_approval_token), auth=self.auth, expect_errors=True) assert_true(self.registration.pending_retraction) assert_equal(res.status_code, 400) # node_registration_retraction_disapprove_tests def test_GET_disapprove_from_unauthorized_user_raises_HTTPForbidden(self): unauthorized_user = AuthUserFactory() res = self.app.get(self.registration.web_url_for( 'node_registration_retraction_disapprove', token=fake.sentence()), auth=unauthorized_user.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_GET_disapprove_registration_without_retraction_returns_HTTPBad_Request( self): assert_false(self.registration.pending_retraction) res = self.app.get(self.registration.web_url_for( 'node_registration_retraction_disapprove', token=fake.sentence()), auth=self.auth, expect_errors=True) assert_equal(res.status_code, 400) def test_GET_disapprove_with_invalid_token_returns_HTTPBad_Request(self): self.registration.retract_registration(self.user) self.registration.save() assert_true(self.registration.pending_retraction) res = self.app.get(self.registration.web_url_for( 'node_registration_retraction_disapprove', token=fake.sentence()), auth=self.auth, expect_errors=True) assert_equal(res.status_code, 400) def test_GET_disapprove_with_wrong_admins_token_returns_HTTPBad_Request( self): user2 = AuthUserFactory() self.registration.contributors.append(user2) self.registration.add_permission(user2, 'admin', save=True) self.registration.retract_registration(self.user) self.registration.save() assert_true(self.registration.pending_retraction) assert_equal(len(self.registration.retraction.approval_state), 2) wrong_disapproval_token = self.registration.retraction.approval_state[ user2._id]['disapproval_token'] res = self.app.get(self.registration.web_url_for( 'node_registration_retraction_disapprove', token=wrong_disapproval_token), auth=self.auth, expect_errors=True) assert_true(self.registration.pending_retraction) assert_equal(res.status_code, 400) def test_GET_disapprove_with_valid_token_returns_redirect(self): self.registration.retract_registration(self.user) self.registration.save() assert_true(self.registration.pending_retraction) disapproval_token = self.registration.retraction.approval_state[ self.user._id]['disapproval_token'] res = self.app.get( self.registration.web_url_for( 'node_registration_retraction_disapprove', token=disapproval_token), auth=self.auth, ) self.registration.retraction.reload() assert_false(self.registration.is_retracted) assert_false(self.registration.pending_retraction) assert_equal(self.registration.retraction.state, Retraction.CANCELLED) assert_equal(res.status_code, 302)