def test_remove_errors(self, app, user, user_write_contrib, user_non_contrib, project, url_user, url_user_write_contrib, url_user_non_contrib): # test_remove_contributor_non_contributor res = app.delete(url_user_write_contrib, auth=user_non_contrib.auth, expect_errors=True) assert res.status_code == 403 # test_remove_contributor_osf_group_member_read group_mem = AuthUserFactory() group = OSFGroupFactory(creator=group_mem) project.add_osf_group(group, permissions.READ) res = app.delete(url_user_write_contrib, auth=group_mem.auth, expect_errors=True) assert res.status_code == 403 # test_remove_contributor_not_logged_in res = app.delete(url_user_write_contrib, expect_errors=True) assert res.status_code == 401 project.reload() assert user_write_contrib in project.contributors # test_remove_non_contributor_admin assert user_non_contrib not in project.contributors res = app.delete(url_user_non_contrib, auth=user.auth, expect_errors=True) assert res.status_code == 404 project.reload() assert user_non_contrib not in project.contributors # test_remove_non_existing_user_admin url_user_fake = '/{}nodes/{}/contributors/{}/'.format( API_BASE, project._id, 'fake') # Disconnect contributor_removed so that we don't check in files # We can remove this when StoredFileNode is implemented in osf-models with disconnected_from_listeners(contributor_removed): res = app.delete(url_user_fake, auth=user.auth, expect_errors=True) assert res.status_code == 404 # test_remove_self_contributor_unique_admin # Disconnect contributor_removed so that we don't check in files # We can remove this when StoredFileNode is implemented in osf-models with disconnected_from_listeners(contributor_removed): res = app.delete(url_user, auth=user.auth, expect_errors=True) assert res.status_code == 400 project.reload() assert user in project.contributors
def test_remove_errors( self, app, user, user_write_contrib, user_non_contrib, preprint, url_user, url_user_write_contrib, url_user_non_contrib): # test_remove_contributor_non_contributor res = app.delete( url_user_write_contrib, auth=user_non_contrib.auth, expect_errors=True) assert res.status_code == 403 preprint.reload() assert user_write_contrib in preprint.contributors # test_remove_contributor_not_logged_in res = app.delete(url_user_write_contrib, expect_errors=True) assert res.status_code == 401 preprint.reload() assert user_write_contrib in preprint.contributors # test_remove_non_contributor_admin assert user_non_contrib not in preprint.contributors res = app.delete( url_user_non_contrib, auth=user.auth, expect_errors=True) assert res.status_code == 404 preprint.reload() assert user_non_contrib not in preprint.contributors # test_remove_non_existing_user_admin url_user_fake = '/{}preprints/{}/contributors/{}/'.format( API_BASE, preprint._id, 'fake') # Disconnect contributor_removed so that we don't check in files # We can remove this when StoredFileNode is implemented in osf-models with disconnected_from_listeners(contributor_removed): res = app.delete(url_user_fake, auth=user.auth, expect_errors=True) assert res.status_code == 404 # test_remove_self_contributor_unique_admin # Disconnect contributor_removed so that we don't check in files # We can remove this when StoredFileNode is implemented in osf-models with disconnected_from_listeners(contributor_removed): res = app.delete(url_user, auth=user.auth, expect_errors=True) assert res.status_code == 400 preprint.reload() assert user in preprint.contributors
def test_remove_errors( self, app, user, user_write_contrib, user_non_contrib, project, url_user, url_user_write_contrib, url_user_non_contrib): # test_remove_contributor_non_contributor res = app.delete( url_user_write_contrib, auth=user_non_contrib.auth, expect_errors=True) assert res.status_code == 403 project.reload() assert user_write_contrib in project.contributors # test_remove_contributor_not_logged_in res = app.delete(url_user_write_contrib, expect_errors=True) assert res.status_code == 401 project.reload() assert user_write_contrib in project.contributors # test_remove_non_contributor_admin assert user_non_contrib not in project.contributors res = app.delete( url_user_non_contrib, auth=user.auth, expect_errors=True) assert res.status_code == 404 project.reload() assert user_non_contrib not in project.contributors # test_remove_non_existing_user_admin url_user_fake = '/{}nodes/{}/contributors/{}/'.format( API_BASE, project._id, 'fake') # Disconnect contributor_removed so that we don't check in files # We can remove this when StoredFileNode is implemented in osf-models with disconnected_from_listeners(contributor_removed): res = app.delete(url_user_fake, auth=user.auth, expect_errors=True) assert res.status_code == 404 # test_remove_self_contributor_unique_admin # Disconnect contributor_removed so that we don't check in files # We can remove this when StoredFileNode is implemented in osf-models with disconnected_from_listeners(contributor_removed): res = app.delete(url_user, auth=user.auth, expect_errors=True) assert res.status_code == 400 project.reload() assert user in project.contributors
def test_draft_registration_fields_are_copied_back_to_draft_node(self, user, institution, subject, write_contrib, title, description, category, license, make_complex_draft_registration): draft_registration = make_complex_draft_registration() draft_node = draft_registration.branched_from with disconnected_from_listeners(after_create_registration): draft_registration.register(auth=Auth(user), save=True) draft_node.reload() assert draft_node.type == 'osf.node' assert draft_node.title == title assert draft_node.description == description assert draft_node.category == category assert user in draft_node.contributors.all() assert write_contrib in draft_node.contributors.all() assert draft_node.get_permissions(user) == [READ, WRITE, ADMIN] assert draft_node.get_permissions(write_contrib) == [READ, WRITE] assert draft_node.node_license.license_id == license.license_id assert draft_node.node_license.name == license.name assert draft_node.node_license.copyright_holders == COPYLEFT_HOLDERS draft_tags = draft_node.tags.values_list('name', flat=True) assert 'savanna' in draft_tags assert 'taxonomy' in draft_tags assert subject in draft_node.subjects.all() assert institution in draft_node.affiliated_institutions.all()
def test_register_draft_node(self, user, draft_node, draft_registration): assert draft_node.type == 'osf.draftnode' with disconnected_from_listeners(after_create_registration): registration = draft_node.register_node(get_default_metaschema(), Auth(user), draft_registration, None) assert type(registration) is Registration assert draft_node._id != registration._id draft_node.reload() assert draft_node.type == 'osf.node' assert len(draft_node.logs.all()) == 1 assert draft_node.logs.first().action == NodeLog.PROJECT_CREATED_FROM_DRAFT_REG
def test_remove_contributor_admin(self, app, user, user_write_contrib, project, url_user_write_contrib): with assert_latest_log(NodeLog.CONTRIB_REMOVED, project): # Disconnect contributor_removed so that we don't check in files # We can remove this when StoredFileNode is implemented in # osf-models with disconnected_from_listeners(contributor_removed): res = app.delete(url_user_write_contrib, auth=user.auth) assert res.status_code == 204 project.reload() assert user_write_contrib not in project.contributors
def test_remove_contributor_admin( self, app, user, user_write_contrib, project, url_user_write_contrib): with assert_latest_log(NodeLog.CONTRIB_REMOVED, project): # Disconnect contributor_removed so that we don't check in files # We can remove this when StoredFileNode is implemented in # osf-models with disconnected_from_listeners(contributor_removed): res = app.delete(url_user_write_contrib, auth=user.auth) assert res.status_code == 204 project.reload() assert user_write_contrib not in project.contributors
def test_project_add_remove_contributor( self, app, user, contrib, user_auth, public_project, public_url): public_project.add_contributor(contrib, auth=user_auth) assert public_project.logs.latest().action == 'contributor_added' # Disconnect contributor_removed so that we don't check in files # We can remove this when StoredFileNode is implemented in osf-models with disconnected_from_listeners(contributor_removed): public_project.remove_contributor(contrib, auth=user_auth) assert public_project.logs.latest().action == 'contributor_removed' res = app.get(public_url, auth=user.auth) assert res.status_code == 200 assert len(res.json['data']) == public_project.logs.count() assert res.json['data'][API_LATEST]['attributes']['action'] == 'contributor_removed' assert res.json['data'][1]['attributes']['action'] == 'contributor_added'
def test_linked_nodes_only_return_viewable_nodes(self, app, auth, private_node_one, private_node_two, public_node, node_ids): user = AuthUserFactory() new_linking_node = NodeFactory(creator=user) private_node_one.add_contributor(user, auth=auth, save=True) private_node_two.add_contributor(user, auth=auth, save=True) public_node.add_contributor(user, auth=auth, save=True) new_linking_node.add_pointer(private_node_one, auth=Auth(user)) new_linking_node.add_pointer(private_node_two, auth=Auth(user)) new_linking_node.add_pointer(public_node, auth=Auth(user)) new_linking_node.save() new_linking_registration = RegistrationFactory( project=new_linking_node, creator=user) res = app.get('/{}registrations/{}/linked_nodes/'.format( API_BASE, new_linking_registration._id), auth=user.auth) assert res.status_code == 200 nodes_returned = [ linked_node['id'] for linked_node in res.json['data'] ] assert len(nodes_returned) == len(node_ids) for node_id in node_ids: assert node_id in nodes_returned # Disconnect contributor_removed so that we don't check in files # We can remove this when StoredFileNode is implemented in osf-models with disconnected_from_listeners(contributor_removed): private_node_two.remove_contributor(user, auth=auth) public_node.remove_contributor(user, auth=auth) res = app.get('/{}registrations/{}/linked_nodes/'.format( API_BASE, new_linking_registration._id), auth=user.auth) nodes_returned = [ linked_node['id'] for linked_node in res.json['data'] ] assert len(nodes_returned) == len(node_ids) - 1 assert private_node_one._id in nodes_returned assert public_node._id in nodes_returned assert private_node_two._id not in nodes_returned
def test_linked_nodes_only_return_viewable_nodes( self, app, user, node_one, node_two, node_public, node_ids): user_two = AuthUserFactory() node_linking_two = NodeFactory(creator=user_two) node_one.add_contributor(user_two, auth=Auth(user), save=True) node_two.add_contributor(user_two, auth=Auth(user), save=True) node_public.add_contributor(user_two, auth=Auth(user), save=True) node_linking_two.add_pointer(node_one, auth=Auth(user_two)) node_linking_two.add_pointer(node_two, auth=Auth(user_two)) node_linking_two.add_pointer(node_public, auth=Auth(user_two)) node_linking_two.save() res = app.get( '/{}nodes/{}/linked_nodes/'.format(API_BASE, node_linking_two._id), auth=user_two.auth ) assert res.status_code == 200 nodes_returned = [ linked_node['id']for linked_node in res.json['data'] ] assert len(nodes_returned) == len(node_ids) for node_id in node_ids: assert node_id in nodes_returned # Disconnect contributor_removed so that we don't check in files # We can remove this when StoredFileNode is implemented in osf-models with disconnected_from_listeners(contributor_removed): node_two.remove_contributor(user_two, auth=Auth(user)) node_public.remove_contributor(user_two, auth=Auth(user)) res = app.get( '/{}nodes/{}/linked_nodes/'.format( API_BASE, node_linking_two._id ), auth=user_two.auth ) nodes_returned = [ linked_node['id']for linked_node in res.json['data'] ] assert len(nodes_returned) == len(node_ids) - 1 assert node_one._id in nodes_returned assert node_public._id in nodes_returned assert node_two._id not in nodes_returned
def test_linked_nodes_only_return_viewable_nodes( self, app, user, node_one, node_two, node_public, node_ids): user_two = AuthUserFactory() node_linking_two = NodeFactory(creator=user_two) node_one.add_contributor(user_two, auth=Auth(user), save=True) node_two.add_contributor(user_two, auth=Auth(user), save=True) node_public.add_contributor(user_two, auth=Auth(user), save=True) node_linking_two.add_pointer(node_one, auth=Auth(user_two)) node_linking_two.add_pointer(node_two, auth=Auth(user_two)) node_linking_two.add_pointer(node_public, auth=Auth(user_two)) node_linking_two.save() res = app.get( '/{}nodes/{}/linked_nodes/'.format(API_BASE, node_linking_two._id), auth=user_two.auth ) assert res.status_code == 200 nodes_returned = [ linked_node['id']for linked_node in res.json['data'] ] assert len(nodes_returned) == len(node_ids) for node_id in node_ids: assert node_id in nodes_returned # Disconnect contributor_removed so that we don't check in files # We can remove this when StoredFileNode is implemented in osf-models with disconnected_from_listeners(contributor_removed): node_two.remove_contributor(user_two, auth=Auth(user)) node_public.remove_contributor(user_two, auth=Auth(user)) res = app.get( '/{}nodes/{}/linked_nodes/'.format( API_BASE, node_linking_two._id ), auth=user_two.auth ) nodes_returned = [ linked_node['id']for linked_node in res.json['data'] ] assert len(nodes_returned) == len(node_ids) - 1 assert node_one._id in nodes_returned assert node_public._id in nodes_returned assert node_two._id not in nodes_returned
def test_remove_contributor_osf_group_member_admin(self, app, user, user_write_contrib, project, url_user_write_contrib): with assert_latest_log(NodeLog.CONTRIB_REMOVED, project): # Disconnect contributor_removed so that we don't check in files # We can remove this when StoredFileNode is implemented in # osf-models group_mem = AuthUserFactory() group = OSFGroupFactory(creator=group_mem) project.add_osf_group(group, permissions.ADMIN) with disconnected_from_listeners(contributor_removed): res = app.delete(url_user_write_contrib, auth=group_mem.auth) assert res.status_code == 204 project.reload() assert user_write_contrib not in project.contributors
def test_project_add_remove_contributor(self, app, user, contrib, user_auth, public_project, public_url): public_project.add_contributor(contrib, auth=user_auth) assert public_project.logs.latest().action == 'contributor_added' # Disconnect contributor_removed so that we don't check in files # We can remove this when StoredFileNode is implemented in osf-models with disconnected_from_listeners(contributor_removed): public_project.remove_contributor(contrib, auth=user_auth) assert public_project.logs.latest().action == 'contributor_removed' res = app.get(public_url, auth=user.auth) assert res.status_code == 200 assert len(res.json['data']) == public_project.logs.count() assert res.json['data'][API_LATEST]['attributes'][ 'action'] == 'contributor_removed' assert res.json['data'][1]['attributes'][ 'action'] == 'contributor_added'
def test_linked_nodes_only_return_viewable_nodes( self, app, auth, private_node_one, private_node_two, public_node, node_ids): user = AuthUserFactory() new_linking_node = NodeFactory(creator=user) private_node_one.add_contributor(user, auth=auth, save=True) private_node_two.add_contributor(user, auth=auth, save=True) public_node.add_contributor(user, auth=auth, save=True) new_linking_node.add_pointer(private_node_one, auth=Auth(user)) new_linking_node.add_pointer(private_node_two, auth=Auth(user)) new_linking_node.add_pointer(public_node, auth=Auth(user)) new_linking_node.save() new_linking_registration = RegistrationFactory( project=new_linking_node, creator=user) res = app.get( '/{}registrations/{}/linked_nodes/'.format(API_BASE, new_linking_registration._id), auth=user.auth ) assert res.status_code == 200 nodes_returned = [linked_node['id'] for linked_node in res.json['data']] assert len(nodes_returned) == len(node_ids) for node_id in node_ids: assert node_id in nodes_returned # Disconnect contributor_removed so that we don't check in files # We can remove this when StoredFileNode is implemented in osf-models with disconnected_from_listeners(contributor_removed): private_node_two.remove_contributor(user, auth=auth) public_node.remove_contributor(user, auth=auth) res = app.get( '/{}registrations/{}/linked_nodes/'.format(API_BASE, new_linking_registration._id), auth=user.auth ) nodes_returned = [ linked_node['id'] for linked_node in res.json['data'] ] assert len(nodes_returned) == len(node_ids) - 1 assert private_node_one._id in nodes_returned assert public_node._id in nodes_returned assert private_node_two._id not in nodes_returned
def test_remove_self_non_admin(self, app, user_non_contrib, project, url_user_non_contrib): with assert_latest_log(NodeLog.CONTRIB_REMOVED, project): project.add_contributor(user_non_contrib, permissions=permissions.WRITE, visible=True, save=True) # Disconnect contributor_removed so that we don't check in files # We can remove this when StoredFileNode is implemented in # osf-models with disconnected_from_listeners(contributor_removed): res = app.delete(url_user_non_contrib, auth=user_non_contrib.auth) assert res.status_code == 204 project.reload() assert user_non_contrib not in project.contributors
def test_withdraw_request_does_not_send_email_to_unregistered_admins( self, mock_send_mail, app, user, public_registration, public_url, public_payload): unreg = UnregUserFactory() with disconnected_from_listeners(contributor_added): public_registration.add_unregistered_contributor( unreg.fullname, unreg.email, auth=Auth(user), permissions=permissions.ADMIN, existing_user=unreg, save=True) res = app.put_json_api(public_url, public_payload, auth=user.auth) assert res.status_code == 200 # Only the creator gets an email; the unreg user does not get emailed assert public_registration._contributors.count() == 2 assert mock_send_mail.call_count == 1
def test_withdraw_request_does_not_send_email_to_unregistered_admins( self, mock_send_mail, app, user, public_registration, public_url, public_payload): unreg = UnregUserFactory() with disconnected_from_listeners(contributor_added): public_registration.add_unregistered_contributor( unreg.fullname, unreg.email, auth=Auth(user), permissions=['read', 'write', 'admin'], existing_user=unreg, save=True ) res = app.put_json_api(public_url, public_payload, auth=user.auth) assert res.status_code == 200 # Only the creator gets an email; the unreg user does not get emailed assert public_registration._contributors.count() == 2 assert mock_send_mail.call_count == 1
def test_remove_self_non_admin( self, app, user_non_contrib, project, url_user_non_contrib): with assert_latest_log(NodeLog.CONTRIB_REMOVED, project): project.add_contributor( user_non_contrib, permissions=[ permissions.READ, permissions.WRITE], visible=True, save=True) # Disconnect contributor_removed so that we don't check in files # We can remove this when StoredFileNode is implemented in # osf-models with disconnected_from_listeners(contributor_removed): res = app.delete( url_user_non_contrib, auth=user_non_contrib.auth) assert res.status_code == 204 project.reload() assert user_non_contrib not in project.contributors
def test_draft_registration_fields_are_not_copied_back_to_original_node(self, user, institution, project, subject, write_contrib, title, description, category, license, make_complex_draft_registration): draft_registration = make_complex_draft_registration(node=project) with disconnected_from_listeners(after_create_registration): draft_registration.register(auth=Auth(user), save=True) project.reload() assert project.type == 'osf.node' assert project.title != title assert project.description != description assert project.category != category assert user in project.contributors.all() assert write_contrib not in project.contributors.all() assert project.get_permissions(user) == [READ, WRITE, ADMIN] assert project.node_license is None project_tags = project.tags.values_list('name', flat=True) assert 'savanna' not in project_tags assert 'taxonomy' not in project_tags assert subject not in project.subjects.all() assert institution not in project.affiliated_institutions.all()