class TestClaimingAsARegisteredUser(OsfTestCase): def setUp(self): super(TestClaimingAsARegisteredUser, self).setUp() self.referrer = AuthUserFactory() self.project = ProjectFactory(creator=self.referrer, is_public=True) name, email = fake.name(), fake.email() self.user = self.project.add_unregistered_contributor(fullname=name, email=email, auth=Auth(user=self.referrer)) self.project.save() def test_claim_user_registered_with_correct_password(self): reg_user = AuthUserFactory() # NOTE: AuthUserFactory sets password as 'password' url = self.user.get_claim_url(self.project._primary_key) # Follow to password re-enter page res = self.app.get(url, auth=reg_user.auth).follow(auth=reg_user.auth) # verify that the "Claim Account" form is returned assert_in("Claim Contributor", res.body) form = res.forms["claimContributorForm"] form["password"] = "******" res = form.submit(auth=reg_user.auth).follow(auth=reg_user.auth) self.project.reload() self.user.reload() # user is now a contributor to the project assert_in(reg_user._primary_key, self.project.contributors) # the unregistered user (self.user) is removed as a contributor, and their assert_not_in(self.user._primary_key, self.project.contributors) # unclaimed record for the project has been deleted assert_not_in(self.project._primary_key, self.user.unclaimed_records)
class TestNodeDeleteView(AdminTestCase): def setUp(self): super(TestNodeDeleteView, self).setUp() self.node = ProjectFactory() self.request = RequestFactory().post('/fake_path') self.view = NodeDeleteView() self.view = setup_log_view(self.view, self.request, guid=self.node._id) def test_get_object(self): obj = self.view.get_object() nt.assert_is_instance(obj, Node) def test_get_context(self): res = self.view.get_context_data(object=self.node) nt.assert_in('guid', res) nt.assert_equal(res.get('guid'), self.node._id) def test_remove_node(self): count = OSFLogEntry.objects.count() self.view.delete(self.request) self.node.reload() nt.assert_true(self.node.is_deleted) nt.assert_equal(OSFLogEntry.objects.count(), count + 1) def test_restore_node(self): self.view.delete(self.request) nt.assert_true(self.node.is_deleted) count = OSFLogEntry.objects.count() self.view.delete(self.request) self.node.reload() nt.assert_false(self.node.is_deleted) nt.assert_equal(OSFLogEntry.objects.count(), count + 1)
def test_get_most_in_common_contributors(self): # project 1 (contrib 1, contrib 2, unreg_contrib 3) # - component 1 (contrib 1) # project 2 - add should show contrib 1 first (2 links), contrib 2 second (1 link) contributor_1 = AuthUserFactory() contributor_2 = AuthUserFactory() self.project.add_contributor(contributor_1, auth=self.auth) self.project.add_contributor(contributor_2, auth=self.auth) # has one unregistered contributor self.project.add_unregistered_contributor( fullname=fake.name(), email=fake.email(), auth=self.auth, ) self.project.save() component = NodeFactory(parent=self.project, creator=self.user) component.add_contributor(contributor_1, auth=self.auth) component.save() project_2 = ProjectFactory(creator=self.user) project_2.add_contributor(contributor_1, auth=self.auth) url = project_2.api_url_for('get_most_in_common_contributors') res = self.app.get(url, auth=self.user.auth) project_2.reload() res_contribs = res.json['contributors'] assert_equal(len(res.json['contributors']), 2) assert_equal(contributor_1._id, res_contribs[0]['id']) assert_equal(res_contribs[0]['n_projects_in_common'], 2) assert_equal(contributor_2._id, res_contribs[1]['id']) assert_equal(res_contribs[1]['n_projects_in_common'], 1)
class TestClaimingAsARegisteredUser(OsfTestCase): def setUp(self): super(TestClaimingAsARegisteredUser, self).setUp() self.referrer = AuthUserFactory() self.project = ProjectFactory(creator=self.referrer, is_public=True) name, email = fake.name(), fake.email() self.user = self.project.add_unregistered_contributor( fullname=name, email=email, auth=Auth(user=self.referrer)) self.project.save() def test_claim_user_registered_with_correct_password(self): reg_user = AuthUserFactory() reg_user.set_password('killerqueen') reg_user.save() url = self.user.get_claim_url(self.project._primary_key) # Follow to password re-enter page res = self.app.get(url, auth=reg_user.auth).follow(auth=reg_user.auth) # verify that the "Claim Account" form is returned assert_in('Claim Contributor', res.body) form = res.forms['claimContributorForm'] form['password'] = '******' res = form.submit(auth=reg_user.auth).follow(auth=reg_user.auth) self.project.reload() self.user.reload() # user is now a contributor to the project assert_in(reg_user._primary_key, self.project.contributors) # the unregistered user (self.user) is removed as a contributor, and their assert_not_in(self.user._primary_key, self.project.contributors) # unclaimed record for the project has been deleted assert_not_in(self.project._primary_key, self.user.unclaimed_records)
def test_POST_register_embargo_does_not_make_project_or_children_public(self, mock_enqueue): public_project = ProjectFactory(creator=self.user, is_public=True) component = NodeFactory(creator=self.user, parent=public_project, title="Component", is_public=True) subproject = ProjectFactory(creator=self.user, parent=public_project, title="Subproject", is_public=True) subproject_component = NodeFactory(creator=self.user, parent=subproject, title="Subcomponent", is_public=True) res = self.app.post( public_project.api_url_for("node_register_template_page_post", template=u"Open-Ended_Registration"), self.valid_embargo_payload, content_type="application/json", auth=self.user.auth, ) public_project.reload() assert_equal(res.status_code, 201) # Last node directly registered from self.project registration = Node.load(public_project.node__registrations[-1]) assert_true(registration.is_registration) assert_false(registration.is_public) assert_true(registration.is_pending_embargo_for_existing_registration) assert_is_not_none(registration.embargo) for node in registration.get_descendants_recursive(): assert_true(node.is_registration) assert_false(node.is_public)
class TestDisableSpamUser(AdminTestCase): def setUp(self): self.user = UserFactory() self.public_node = ProjectFactory(creator=self.user, is_public=True) self.public_node = ProjectFactory(creator=self.user, is_public=False) self.request = RequestFactory().post('/fake_path') self.view = SpamUserDeleteView() self.view = setup_log_view(self.view, self.request, guid=self.user._id) def test_get_object(self): obj = self.view.get_object() nt.assert_is_instance(obj, User) def test_get_context(self): res = self.view.get_context_data(object=self.user) nt.assert_in('guid', res) nt.assert_equal(res.get('guid'), self.user._id) def test_disable_spam_user(self): settings.ENABLE_EMAIL_SUBSCRIPTIONS = False count = OSFLogEntry.objects.count() self.view.delete(self.request) self.user.reload() self.public_node.reload() nt.assert_true(self.user.is_disabled) nt.assert_false(self.public_node.is_public) nt.assert_equal(OSFLogEntry.objects.count(), count + 3) def test_no_user(self): view = setup_view(UserDeleteView(), self.request, guid='meh') with nt.assert_raises(Http404): view.delete(self.request)
def test_POST_register_embargo_does_not_make_project_or_children_public( self, mock_enqueue): public_project = ProjectFactory(creator=self.user, is_public=True) component = NodeFactory(creator=self.user, parent=public_project, title='Component', is_public=True) subproject = ProjectFactory(creator=self.user, parent=public_project, title='Subproject', is_public=True) subproject_component = NodeFactory(creator=self.user, parent=subproject, title='Subcomponent', is_public=True) res = self.app.post(public_project.api_url_for( 'node_register_template_page_post', template=u'Open-Ended_Registration'), self.valid_embargo_payload, content_type='application/json', auth=self.user.auth) public_project.reload() assert_equal(res.status_code, 201) # Last node directly registered from self.project registration = Node.load(public_project.node__registrations[-1]) assert_true(registration.is_registration) assert_false(registration.is_public) assert_true(registration.is_pending_embargo_for_existing_registration) assert_is_not_none(registration.embargo) for node in registration.get_descendants_recursive(): assert_true(node.is_registration) assert_false(node.is_public)
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)
class TestRemoveContributor(AdminTestCase): def setUp(self): super(TestRemoveContributor, self).setUp() self.user = AuthUserFactory() self.node = ProjectFactory(creator=self.user) self.user_2 = AuthUserFactory() self.node.add_contributor(self.user_2) self.node.save() self.view = NodeRemoveContributorView() self.request = RequestFactory().post('/fake_path') def test_get_object(self): view = setup_log_view(self.view, self.request, node_id=self.node._id, user_id=self.user._id) node, user = view.get_object() nt.assert_is_instance(node, Node) nt.assert_is_instance(user, User) @mock.patch('admin.nodes.views.Node.remove_contributor') def test_remove_contributor(self, mock_remove_contributor): user_id = self.user_2._id node_id = self.node._id view = setup_log_view(self.view, self.request, node_id=node_id, user_id=user_id) view.delete(self.request) mock_remove_contributor.assert_called_with(self.user_2, None, log=False) def test_integration_remove_contributor(self): nt.assert_in(self.user_2, self.node.contributors) view = setup_log_view(self.view, self.request, node_id=self.node._id, user_id=self.user_2._id) count = OSFLogEntry.objects.count() view.delete(self.request) nt.assert_not_in(self.user_2, self.node.contributors) nt.assert_equal(OSFLogEntry.objects.count(), count + 1) def test_do_not_remove_last_admin(self): nt.assert_equal( len(list(self.node.get_admin_contributors(self.node.contributors))), 1 ) view = setup_log_view(self.view, self.request, node_id=self.node._id, user_id=self.user._id) count = OSFLogEntry.objects.count() view.delete(self.request) self.node.reload() # Reloads instance to show that nothing was removed nt.assert_equal(len(list(self.node.contributors)), 2) nt.assert_equal( len(list(self.node.get_admin_contributors(self.node.contributors))), 1 ) nt.assert_equal(OSFLogEntry.objects.count(), count) def test_no_log(self): view = setup_log_view(self.view, self.request, node_id=self.node._id, user_id=self.user_2._id) view.delete(self.request) nt.assert_not_equal(self.node.logs[-1].action, NodeLog.CONTRIB_REMOVED)
class TestGoogleDriveUtils(OsfTestCase): def setUp(self): super(TestGoogleDriveUtils, self).setUp() self.user = AuthUserFactory() self.user.add_addon('googledrive') self.project = ProjectFactory(creator=self.user) self.project.add_addon('googledrive', Auth(self.user)) self.node_settings = self.project.get_addon('googledrive') self.user_settings = self.user.get_addon('googledrive') oauth_settings = GoogleDriveOAuthSettingsFactory() self.user_settings.oauth_settings = oauth_settings self.node_settings.user_settings = self.user_settings self.node_settings.folder_id = '09120912' self.node_settings.folder_path = 'foo/bar' self.user_settings.save() self.node_settings.save() # Log user in self.app.authenticate(*self.user.auth) def test_serialize_settings_helper_returns_correct_urls(self): result = serialize_settings(self.node_settings, self.user) urls = result['urls'] assert_equal(urls['files'], self.project.web_url_for('collect_file_trees')) assert_equal(urls['config'], self.project.api_url_for('googledrive_config_put')) assert_equal(urls['deauthorize'], self.project.api_url_for('googledrive_deauthorize')) assert_equal(urls['importAuth'], self.project.api_url_for('googledrive_import_user_auth')) # Includes endpoint for fetching folders only # NOTE: Querystring params are in camelCase assert_equal(urls['get_folders'], self.project.api_url_for('googledrive_folders')) def test_serialize_settings_helper_returns_correct_auth_info(self): self.user_settings.access_token = 'abc123' result = serialize_settings(self.node_settings, self.user) assert_equal(result['nodeHasAuth'], self.node_settings.has_auth) assert_true(result['userHasAuth']) assert_true(result['userIsOwner']) def test_serialize_settings_for_user_no_auth(self): no_addon_user = AuthUserFactory() result = serialize_settings(self.node_settings, no_addon_user) assert_false(result['userIsOwner']) assert_false(result['userHasAuth']) def test_googledrive_import_user_auth_returns_serialized_settings(self): self.node_settings.user_settings = None self.node_settings.save() url = api_url_for('googledrive_import_user_auth', pid=self.project._primary_key) res = self.app.put(url, auth=self.user.auth) self.project.reload() self.node_settings.reload() expected_result = serialize_settings(self.node_settings, self.user) result = res.json['result'] assert_equal(result, expected_result)
class TestMigrateDeletedWikis(OsfTestCase): # Whenever wiki is deleted, increment this variable to account for # fact that NodeLog.WIKI_DELETED is added to each time times_wiki_deleted = 0 def setUp(self): super(TestMigrateDeletedWikis, self).setUp() self.user = UserFactory() self.auth = Auth(user=self.user) self.project = ProjectFactory(creator=self.user) # Update home wiki (which can't be deleted) an a second wiki self.project.update_node_wiki('home', 'Hello world', self.auth) self.project.update_node_wiki('second', 'Hola mundo', self.auth) self.project.update_node_wiki('second', 'Hola mundo 2', self.auth) self.versions = self.project.wiki_pages_versions self.current = self.project.wiki_pages_current def test_get_targets(self): # delete second wiki to add something to targets self.project.delete_node_wiki('second', self.auth) TestMigrateDeletedWikis.times_wiki_deleted += 1 # Initial targets should include: user2, user3, user4, user5, user6 (5 in total) logs = get_targets() # assert len is equal to number of time a wiki is deleted in entire test script assert_equal(len(logs), TestMigrateDeletedWikis.times_wiki_deleted) def test_delete_wiki_node(self): self.project.delete_node_wiki('second', self.auth) TestMigrateDeletedWikis.times_wiki_deleted += 1 self.versions = self.project.wiki_pages_versions assert_true('second' not in self.versions) def test_migrate(self): logs = get_targets() migrate(logs, dry_run=False) self.project.reload() # Ensure that wiki pages that were targeted are not in versions for log in logs: node = log.node assert_true(node.title not in self.project.wiki_pages_versions) def test_migration_does_not_affect_home(self): logs = get_targets() migrate(logs, dry_run=False) self.project.reload() # Assert that 'home' has same versions as before self.versions = self.project.wiki_pages_versions assert_equal(len(self.versions['home']), 1) def test_deleted_wiki_versions_not_restored(self): self.project.delete_node_wiki('second', self.auth) TestMigrateDeletedWikis.times_wiki_deleted += 1 # create another wiki with name 'second' self.project.update_node_wiki('second', 'Hola mundo 3', self.auth) # Make sure old versions not restored assert_equal(len(self.versions['second']), 1)
def test_get_recently_added_contributors_with_limit(self): project = ProjectFactory(creator=self.user) for _ in range(5): project.add_contributor(AuthUserFactory(), auth=self.auth) project.save() url = self.project.api_url_for('get_recently_added_contributors', max=4) res = self.app.get(url, auth=self.user.auth) project.reload() assert_equal(len(res.json['contributors']), 4)
def test_wiki_pages_that_do_not_exist_do_not_get_cloned(self): project = ProjectFactory(creator=self.user, is_public=True) wiki = NodeWikiFactory(node=project) NodeWikiPage.remove_one(wiki._id) # deleted wiki record in node.wiki_pages_versions assert_in(wiki._id, project.wiki_pages_versions[wiki.page_name]) main() project.reload() # wiki_id gets removed from node.wiki_pages_versions assert_not_in(wiki._id, project.wiki_pages_versions[wiki.page_name])
def test_a_public_project_from_home_page(self): project = ProjectFactory(title='Foobar Project', is_public=True) # Searches a part of the name res = self.app.get('/').maybe_follow() project.reload() form = res.forms['searchBar'] form['q'] = 'Foobar' res = form.submit().maybe_follow() # A link to the project is shown as a result assert_in('Foobar Project', res)
def test_a_public_project_from_home_page(self): project = ProjectFactory(title="Foobar Project", is_public=True) # Searches a part of the name res = self.app.get("/").maybe_follow() project.reload() form = res.forms["searchBar"] form["q"] = "Foobar" res = form.submit().maybe_follow() # A link to the project is shown as a result assert_in("Foobar Project", res)
def test_get_recently_added_contributors(self): project = ProjectFactory(creator=self.user) project.add_contributor(AuthUserFactory(), auth=self.auth) project.add_contributor(AuthUserFactory(), auth=self.auth) # has one unregistered contributor project.add_unregistered_contributor(fullname=fake.name(), email=fake.email(), auth=self.auth) project.save() url = self.project.api_url_for("get_recently_added_contributors") res = self.app.get(url, auth=self.user.auth) project.reload() recent = [c for c in self.user.recently_added if c.is_active] assert_equal(len(res.json["contributors"]), len(recent))
class StorageTestCase(OsfTestCase): def setUp(self): super(StorageTestCase, self).setUp() self.project = ProjectFactory() self.user = self.project.creator self.node_settings = self.project.get_addon('osfstorage') self.auth_obj = Auth(user=self.project.creator) # Refresh records from database; necessary for comparing dates self.project.reload() self.user.reload()
class TestNodeContributorPartialUpdate(ApiTestCase): def setUp(self): super(TestNodeContributorPartialUpdate, self).setUp() self.user = AuthUserFactory() self.user_two = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.project.add_contributor(self.user_two, permissions=[permissions.READ, permissions.WRITE], visible=True, save=True) self.url_creator = '/{}nodes/{}/contributors/{}/'.format(API_BASE, self.project._id, self.user._id) self.url_contributor = '/{}nodes/{}/contributors/{}/'.format(API_BASE, self.project._id, self.user_two._id) def test_patch_bibliographic_only(self): creator_id = '{}-{}'.format(self.project._id, self.user._id) data = { 'data': { 'id': creator_id, 'type': 'contributors', 'attributes': { 'bibliographic': False, } } } res = self.app.patch_json_api(self.url_creator, data, auth=self.user.auth) assert_equal(res.status_code, 200) self.project.reload() assert_equal(self.project.get_permissions(self.user), [permissions.READ, permissions.WRITE, permissions.ADMIN]) assert_false(self.project.get_visible(self.user)) def test_patch_permission_only(self): user_three = AuthUserFactory() self.project.add_contributor(user_three, permissions=[permissions.READ, permissions.WRITE], visible=False, save=True) url_contributor = '/{}nodes/{}/contributors/{}/'.format(API_BASE, self.project._id, user_three._id) contributor_id = '{}-{}'.format(self.project._id, user_three._id) data = { 'data': { 'id': contributor_id, 'type': 'contributors', 'attributes': { 'permission': permissions.READ, } } } res = self.app.patch_json_api(url_contributor, data, auth=self.user.auth) assert_equal(res.status_code, 200) self.project.reload() assert_equal(self.project.get_permissions(user_three), [permissions.READ]) assert_false(self.project.get_visible(user_three))
class TestWikiDelete(OsfTestCase): def setUp(self): super(TestWikiDelete, self).setUp() self.project = ProjectFactory(is_public=True) api_key = ApiKeyFactory() self.project.creator.api_keys.append(api_key) self.project.creator.save() self.consolidate_auth = Auth(user=self.project.creator, api_key=api_key) self.auth = ('test', api_key._primary_key) self.project.update_node_wiki('Elephants', 'Hello Elephants', self.consolidate_auth) self.project.update_node_wiki('Lions', 'Hello Lions', self.consolidate_auth) self.elephant_wiki = self.project.get_wiki_page('Elephants') self.lion_wiki = self.project.get_wiki_page('Lions') @mock.patch('website.addons.wiki.utils.broadcast_to_sharejs') def test_project_wiki_delete(self, mock_shrejs): assert_in('elephants', self.project.wiki_pages_current) url = self.project.api_url_for( 'project_wiki_delete', wname='elephants' ) self.app.delete( url, auth=self.auth ) self.project.reload() assert_not_in('elephants', self.project.wiki_pages_current) @mock.patch('website.addons.wiki.utils.broadcast_to_sharejs') def test_project_wiki_delete_w_valid_special_characters(self, mock_sharejs): # TODO: Need to understand why calling update_node_wiki with failure causes transaction rollback issue later # with assert_raises(NameInvalidError): # self.project.update_node_wiki(SPECIAL_CHARACTERS_ALL, 'Hello Special Characters', self.consolidate_auth) self.project.update_node_wiki(SPECIAL_CHARACTERS_ALLOWED, 'Hello Special Characters', self.consolidate_auth) self.special_characters_wiki = self.project.get_wiki_page(SPECIAL_CHARACTERS_ALLOWED) assert_in(to_mongo_key(SPECIAL_CHARACTERS_ALLOWED), self.project.wiki_pages_current) url = self.project.api_url_for( 'project_wiki_delete', wname=SPECIAL_CHARACTERS_ALLOWED ) self.app.delete( url, auth=self.auth ) self.project.reload() assert_not_in(to_mongo_key(SPECIAL_CHARACTERS_ALLOWED), self.project.wiki_pages_current)
def test_get_recently_added_contributors(self): project = ProjectFactory(creator=self.user) project.add_contributor(AuthUserFactory(), auth=self.auth) project.add_contributor(AuthUserFactory(), auth=self.auth) # has one unregistered contributor project.add_unregistered_contributor( fullname=fake.name(), email=fake.email(), auth=self.auth, ) project.save() url = self.project.api_url_for('get_recently_added_contributors') res = self.app.get(url, auth=self.user.auth) project.reload() recent = [c for c in self.user.recently_added if c.is_active()] assert_equal(len(res.json['contributors']), len(recent))
class TestPopulateNewAndNoteworthy(OsfTestCase): def setUp(self): super(TestPopulateNewAndNoteworthy, self).setUp() self.nn1 = ProjectFactory(is_public=True) self.nn2 = ProjectFactory(is_public=True) self.nn3 = ProjectFactory(is_public=True) self.nn4 = ProjectFactory(is_public=True) self.nn5 = ProjectFactory(is_public=True) def tearDown(self): super(TestPopulateNewAndNoteworthy, self).tearDown() Node.remove() def test_get_new_and_noteworthy_nodes(self): new_noteworthy = script.get_new_and_noteworthy_nodes() assert_equal(set(new_noteworthy), { self.nn1._id, self.nn2._id, self.nn3._id, self.nn4._id, self.nn5._id }) def test_populate_new_and_noteworthy(self): self.new_and_noteworthy_links_node = ProjectFactory() self.new_and_noteworthy_links_node._id = NEW_AND_NOTEWORTHY_LINKS_NODE self.new_and_noteworthy_links_node.save() assert_equal(len(self.new_and_noteworthy_links_node.nodes), 0) script.main(dry_run=False) self.new_and_noteworthy_links_node.reload() assert_equal(len(self.new_and_noteworthy_links_node.nodes), 5) script.main(dry_run=False) self.new_and_noteworthy_links_node.reload() new_and_noteworthy_node_links = { pointer.node._id for pointer in self.new_and_noteworthy_links_node.nodes } assert_equal(set(new_and_noteworthy_node_links), { self.nn1._id, self.nn2._id, self.nn3._id, self.nn4._id, self.nn5._id })
def test_set_user_auth(self): project = ProjectFactory() project.add_addon('dataverse', auth=Auth(self.user)) node_settings = project.get_addon('dataverse') num_old_logs = len(project.logs) assert_false(node_settings.user_settings) node_settings.set_user_auth(self.user_settings) node_settings.save() assert_equal(node_settings.user_settings, self.user_settings) # Test log project.reload() assert_equal(len(project.logs), num_old_logs + 1) last_log = project.logs[-1] assert_equal(last_log.action, 'dataverse_node_authorized') assert_equal(last_log.params['node'], project._primary_key) assert_is_none(last_log.params['project'])
def test_import_auth(self): ea = self.ExternalAccountFactory() self.user.external_accounts.append(ea) self.user.save() node = ProjectFactory(creator=self.user) node_settings = node.get_or_add_addon(self.ADDON_SHORT_NAME, auth=Auth(self.user)) node.save() url = node.api_url_for("{0}_import_auth".format(self.ADDON_SHORT_NAME)) res = self.app.put_json(url, {"external_account_id": ea._id}, auth=self.user.auth) assert_equal(res.status_code, http.OK) assert_in("result", res.json) node_settings.reload() assert_equal(node_settings.external_account._id, ea._id) node.reload() last_log = node.logs[-1] assert_equal(last_log.action, "{0}_node_authorized".format(self.ADDON_SHORT_NAME))
def test_import_auth(self): ea = self.ExternalAccountFactory() self.user.external_accounts.append(ea) self.user.save() node = ProjectFactory(creator=self.user) node_settings = node.get_or_add_addon(self.ADDON_SHORT_NAME, auth=Auth(self.user)) node.save() url = node.api_url_for('{0}_import_auth'.format(self.ADDON_SHORT_NAME)) res = self.app.put_json(url, { 'external_account_id': ea._id }, auth=self.user.auth) assert_equal(res.status_code, http.OK) assert_in('result', res.json) node_settings.reload() assert_equal(node_settings.external_account._id, ea._id) node.reload() last_log = node.logs.latest() assert_equal(last_log.action, '{0}_node_authorized'.format(self.ADDON_SHORT_NAME))
class TestPopulateNewAndNoteworthy(OsfTestCase): def setUp(self): super(TestPopulateNewAndNoteworthy, self).setUp() self.nn1 = ProjectFactory(is_public=True) self.nn2 = ProjectFactory(is_public=True) self.nn3 = ProjectFactory(is_public=True) self.nn4 = ProjectFactory(is_public=True) self.nn5 = ProjectFactory(is_public=True) def tearDown(self): super(TestPopulateNewAndNoteworthy, self).tearDown() Node.remove() def test_get_new_and_noteworthy_nodes(self): new_noteworthy = script.get_new_and_noteworthy_nodes() assert_equal(set(new_noteworthy), {self.nn1._id, self.nn2._id, self.nn3._id, self.nn4._id, self.nn5._id}) def test_populate_new_and_noteworthy(self): self.new_and_noteworthy_links_node = ProjectFactory() self.new_and_noteworthy_links_node._id = NEW_AND_NOTEWORTHY_LINKS_NODE self.new_and_noteworthy_links_node.save() assert_equal(len(self.new_and_noteworthy_links_node.nodes), 0) script.main(dry_run=False) self.new_and_noteworthy_links_node.reload() assert_equal(len(self.new_and_noteworthy_links_node.nodes), 5) script.main(dry_run=False) self.new_and_noteworthy_links_node.reload() new_and_noteworthy_node_links = {pointer.node._id for pointer in self.new_and_noteworthy_links_node.nodes} assert_equal(set(new_and_noteworthy_node_links), {self.nn1._id, self.nn2._id, self.nn3._id, self.nn4._id, self.nn5._id})
def test_POST_register_make_public_immediately_creates_private_pending_registration_for_public_project(self, mock_enqueue): public_project = ProjectFactory(is_public=True, creator=self.user) component = NodeFactory( creator=self.user, parent=public_project, title='Component', is_public=True ) subproject = ProjectFactory( creator=self.user, parent=public_project, title='Subproject', is_public=True ) subproject_component = NodeFactory( creator=self.user, parent=subproject, title='Subcomponent', is_public=True ) res = self.app.post( public_project.api_url_for('node_register_template_page_post', template=u'Open-Ended_Registration'), self.valid_make_public_payload, content_type='application/json', auth=self.user.auth ) public_project.reload() assert_equal(res.status_code, 201) assert_equal(res.json['urls']['registrations'], public_project.web_url_for('node_registrations')) # Last node directly registered from self.project registration = Node.load(public_project.node__registrations[-1]) assert_true(registration.is_registration) assert_false(registration.is_public) for node in registration.get_descendants_recursive(): assert_true(node.is_registration) assert_false(node.is_public)
def test_users_projects_in_common_exclude_deleted_projects(self): project_list = [] for x in range(1, 10): project = ProjectFactory(creator=self.user_one) project.add_contributor(contributor=self.user_two, permissions=CREATOR_PERMISSIONS, auth=Auth(user=self.user_one)) project.save() project_list.append(project) for x in range(1, 5): project = project_list[x] project.reload() project.remove_node(auth=Auth(user=self.user_one)) project.save() url = "/{}users/{}/nodes/?embed=contributors&show_projects_in_common=true".format( API_BASE, self.user_two._id) res = self.app.get(url, auth=self.user_two.auth) user_json = res.json['data'][0]['embeds']['contributors']['data'] for user in user_json: meta = user['embeds']['users']['data']['relationships']['nodes'][ 'links']['related']['meta'] assert_in('projects_in_common', meta) assert_equal(meta['projects_in_common'], 5)
def test_users_projects_in_common_exclude_deleted_projects(self): project_list=[] for x in range(1,10): project = ProjectFactory(creator=self.user_one) project.add_contributor( contributor=self.user_two, permissions=CREATOR_PERMISSIONS, auth=Auth(user=self.user_one) ) project.save() project_list.append(project) for x in range(1,5): project = project_list[x] project.reload() project.remove_node(auth=Auth(user=self.user_one)) project.save() url = "/{}users/{}/nodes/?embed=contributors&show_projects_in_common=true".format(API_BASE, self.user_two._id) res = self.app.get(url, auth=self.user_two.auth) user_json = res.json['data'][0]['embeds']['contributors']['data'] for user in user_json: meta = user['embeds']['users']['data']['relationships']['nodes']['links']['related']['meta'] assert_in('projects_in_common', meta) assert_equal(meta['projects_in_common'], 5)
class TestBoxNodeSettingsModel(OsfTestCase): def setUp(self): super(TestBoxNodeSettingsModel, self).setUp() self.user = UserFactory() self.user.add_addon('box') self.user.save() self.oauth = BoxOAuthSettings(user_id='not sleep', access_token='seems legit') self.oauth.save() self.user_settings = self.user.get_addon('box') self.user_settings.oauth_settings = self.oauth self.user_settings.save() self.project = ProjectFactory() self.node_settings = BoxNodeSettingsFactory( user_settings=self.user_settings, folder_id='1234567890', owner=self.project) def test_complete_true(self): assert_true(self.node_settings.has_auth) assert_true(self.node_settings.complete) def test_complete_false(self): self.node_settings.folder_id = None assert_true(self.node_settings.has_auth) assert_false(self.node_settings.complete) def test_complete_auth_false(self): self.node_settings.user_settings = None assert_false(self.node_settings.has_auth) assert_false(self.node_settings.complete) def test_fields(self): node_settings = BoxNodeSettings(user_settings=self.user_settings) node_settings.save() assert_true(node_settings.user_settings) assert_equal(node_settings.user_settings.owner, self.user) assert_true(hasattr(node_settings, 'folder_id')) assert_true(hasattr(node_settings, 'user_settings')) def test_folder_defaults_to_none(self): node_settings = BoxNodeSettings(user_settings=self.user_settings) node_settings.save() assert_is_none(node_settings.folder_id) def test_has_auth(self): self.user_settings.access_token = None settings = BoxNodeSettings(user_settings=self.user_settings) settings.save() assert_false(settings.has_auth) settings.user_settings.access_token = '123abc' settings.user_settings.save() assert_true(settings.has_auth) def test_to_json(self): settings = self.node_settings user = UserFactory() result = settings.to_json(user) assert_equal(result['addon_short_name'], 'box') def test_delete(self): assert_true(self.node_settings.user_settings) assert_true(self.node_settings.folder_id) old_logs = self.project.logs self.node_settings.delete() self.node_settings.save() assert_is(self.node_settings.user_settings, None) assert_is(self.node_settings.folder_id, None) assert_true(self.node_settings.deleted) assert_equal(self.project.logs, old_logs) def test_deauthorize(self): assert_true(self.node_settings.user_settings) assert_true(self.node_settings.folder_id) self.node_settings.deauthorize(auth=Auth(self.user)) self.node_settings.save() assert_is(self.node_settings.user_settings, None) assert_is(self.node_settings.folder_id, None) last_log = self.project.logs[-1] assert_equal(last_log.action, 'box_node_deauthorized') params = last_log.params assert_in('node', params) assert_in('project', params) assert_in('folder_id', params) def test_set_folder(self): folder_id = '1234567890' self.node_settings.set_folder(folder_id, auth=Auth(self.user)) self.node_settings.save() # Folder was set assert_equal(self.node_settings.folder_id, folder_id) # Log was saved last_log = self.project.logs[-1] assert_equal(last_log.action, 'box_folder_selected') def test_set_user_auth(self): node_settings = BoxNodeSettingsFactory() user_settings = BoxUserSettingsFactory() node_settings.set_user_auth(user_settings) node_settings.save() assert_true(node_settings.has_auth) assert_equal(node_settings.user_settings, user_settings) # A log was saved last_log = node_settings.owner.logs[-1] assert_equal(last_log.action, 'box_node_authorized') log_params = last_log.params assert_equal(log_params['folder_id'], node_settings.folder_id) assert_equal(log_params['node'], node_settings.owner._primary_key) assert_equal(last_log.user, user_settings.owner) def test_serialize_credentials(self): self.user_settings.access_token = 'secret' self.user_settings.save() credentials = self.node_settings.serialize_waterbutler_credentials() expected = {'token': self.node_settings.user_settings.access_token} assert_equal(credentials, expected) def test_serialize_credentials_not_authorized(self): self.node_settings.user_settings = None self.node_settings.save() with assert_raises(exceptions.AddonError): self.node_settings.serialize_waterbutler_credentials() def test_serialize_settings(self): settings = self.node_settings.serialize_waterbutler_settings() expected = {'folder': self.node_settings.folder_id} assert_equal(settings, expected) def test_serialize_settings_not_configured(self): self.node_settings.folder_id = None self.node_settings.save() with assert_raises(exceptions.AddonError): self.node_settings.serialize_waterbutler_settings() def test_create_log(self): action = 'file_added' path = 'pizza.nii' nlog = len(self.project.logs) self.node_settings.create_waterbutler_log( auth=Auth(user=self.user), action=action, metadata={'path': path}, ) self.project.reload() assert_equal(len(self.project.logs), nlog + 1) assert_equal( self.project.logs[-1].action, 'box_{0}'.format(action), ) assert_equal( self.project.logs[-1].params['path'], os.path.join(self.node_settings.folder_id, path), )
class TestDropboxNodeSettingsModel(OsfTestCase): def setUp(self): super(TestDropboxNodeSettingsModel, self).setUp() self.user = UserFactory() self.user.add_addon('dropbox') self.user.save() self.user_settings = self.user.get_addon('dropbox') self.project = ProjectFactory() self.node_settings = DropboxNodeSettingsFactory( user_settings=self.user_settings, owner=self.project) def test_complete_true(self): self.node_settings.user_settings.access_token = 'seems legit' assert_true(self.node_settings.has_auth) assert_true(self.node_settings.complete) def test_complete_false(self): self.node_settings.user_settings.access_token = 'seems legit' self.node_settings.folder = None assert_true(self.node_settings.has_auth) assert_false(self.node_settings.complete) def test_complete_auth_false(self): self.node_settings.user_settings = None assert_false(self.node_settings.has_auth) assert_false(self.node_settings.complete) def test_fields(self): node_settings = DropboxNodeSettings(user_settings=self.user_settings) node_settings.save() assert_true(node_settings.user_settings) assert_equal(node_settings.user_settings.owner, self.user) assert_true(hasattr(node_settings, 'folder')) assert_true(hasattr(node_settings, 'registration_data')) def test_folder_defaults_to_none(self): node_settings = DropboxNodeSettings(user_settings=self.user_settings) node_settings.save() assert_is_none(node_settings.folder) def test_has_auth(self): settings = DropboxNodeSettings(user_settings=self.user_settings) settings.save() assert_false(settings.has_auth) settings.user_settings.access_token = '123abc' settings.user_settings.save() assert_true(settings.has_auth) def test_to_json(self): settings = self.node_settings user = UserFactory() result = settings.to_json(user) assert_equal(result['addon_short_name'], 'dropbox') def test_delete(self): assert_true(self.node_settings.user_settings) assert_true(self.node_settings.folder) old_logs = self.project.logs self.node_settings.delete() self.node_settings.save() assert_is(self.node_settings.user_settings, None) assert_is(self.node_settings.folder, None) assert_true(self.node_settings.deleted) assert_equal(self.project.logs, old_logs) def test_deauthorize(self): assert_true(self.node_settings.user_settings) assert_true(self.node_settings.folder) self.node_settings.deauthorize(auth=Auth(self.user)) self.node_settings.save() assert_is(self.node_settings.user_settings, None) assert_is(self.node_settings.folder, None) last_log = self.project.logs[-1] assert_equal(last_log.action, 'dropbox_node_deauthorized') params = last_log.params assert_in('node', params) assert_in('project', params) assert_in('folder', params) def test_set_folder(self): folder_name = 'queen/freddie' self.node_settings.set_folder(folder_name, auth=Auth(self.user)) self.node_settings.save() # Folder was set assert_equal(self.node_settings.folder, folder_name) # Log was saved last_log = self.project.logs[-1] assert_equal(last_log.action, 'dropbox_folder_selected') def test_set_user_auth(self): node_settings = DropboxNodeSettingsFactory() user_settings = DropboxUserSettingsFactory() node_settings.set_user_auth(user_settings) node_settings.save() assert_true(node_settings.has_auth) assert_equal(node_settings.user_settings, user_settings) # A log was saved last_log = node_settings.owner.logs[-1] assert_equal(last_log.action, 'dropbox_node_authorized') log_params = last_log.params assert_equal(log_params['folder'], node_settings.folder) assert_equal(log_params['node'], node_settings.owner._primary_key) assert_equal(last_log.user, user_settings.owner) def test_serialize_credentials(self): self.user_settings.access_token = 'secret' self.user_settings.save() credentials = self.node_settings.serialize_waterbutler_credentials() expected = {'token': self.node_settings.user_settings.access_token} assert_equal(credentials, expected) def test_serialize_credentials_not_authorized(self): self.node_settings.user_settings = None self.node_settings.save() with assert_raises(exceptions.AddonError): self.node_settings.serialize_waterbutler_credentials() def test_serialize_settings(self): settings = self.node_settings.serialize_waterbutler_settings() expected = {'folder': self.node_settings.folder} assert_equal(settings, expected) def test_serialize_settings_not_configured(self): self.node_settings.folder = None self.node_settings.save() with assert_raises(exceptions.AddonError): self.node_settings.serialize_waterbutler_settings() def test_create_log(self): action = 'file_added' path = 'pizza.nii' self.node_settings.folder = '/SomeOddPath' self.node_settings.save() nlog = len(self.project.logs) self.node_settings.create_waterbutler_log( auth=Auth(user=self.user), action=action, metadata={'path': path}, ) self.project.reload() assert_equal(len(self.project.logs), nlog + 1) assert_equal( self.project.logs[-1].action, 'dropbox_{0}'.format(action), ) assert_equal( self.project.logs[-1].params['path'], path, ) @mock.patch('website.archiver.tasks.archive') def test_does_not_get_copied_to_registrations(self, mock_archive): registration = self.project.register_node( schema=None, auth=Auth(user=self.project.creator), template='Template1', data='hodor') assert_false(registration.has_addon('dropbox'))
class TestViewsConfig(OsfTestCase): def setUp(self): super(TestViewsConfig, self).setUp() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.auth = ('test', self.user.api_keys[0]._primary_key) self.project = ProjectFactory(creator=self.user) self.non_authenticator = AuthUserFactory() self.project.add_contributor( contributor=self.non_authenticator, auth=Auth(self.project.creator), ) self.project.add_addon('figshare', auth=self.consolidated_auth) self.project.creator.add_addon('figshare') self.node_settings = self.project.get_addon('figshare') self.user_settings = self.project.creator.get_addon('figshare') self.user_settings.oauth_access_token = 'legittoken' self.user_settings.oauth_access_token_secret = 'legittoken' self.user_settings.save() self.node_settings.user_settings = self.user_settings self.node_settings.figshare_id = '123456' self.node_settings.figshare_type = 'project' self.node_settings.figshare_title = 'FIGSHARE_TITLE' self.node_settings.save() self.figshare = create_mock_figshare('test') def configure_responses(self): httpretty.register_uri( httpretty.GET, join_path(self.node_settings.api_url, 'articles'), body=dumps(self.figshare.articles.return_value) ) httpretty.register_uri( httpretty.GET, join_path(self.node_settings.api_url, 'articles', '902210'), body=dumps(self.figshare.article.return_value) ) @httpretty.activate def test_import_auth(self): self.configure_responses() """Testing figshare_import_user_auth to ensure that auth gets imported correctly""" settings = self.node_settings settings.user_settings = None settings.save() url = '/api/v1/project/{0}/figshare/config/import-auth/'.format(self.project._id) self.app.put(url, auth=self.user.auth) self.node_settings.reload() assert_is_not_none(settings.user_settings) def test_cancelled_oauth_request_from_user_settings_page_redirects_correctly(self): res = self.app.get(api_url_for('figshare_oauth_callback', uid=self.user._id), auth=self.user.auth) assert_equal(res.status_code, 302) assert_urls_equal(res.headers['location'], web_url_for('user_addons')) def test_cancelled_oauth_request_from_node_settings_page_redirects_correctly(self): res = self.app.get(api_url_for('figshare_oauth_callback', uid=self.user._id, nid=self.project._id), auth=self.user.auth) assert_equal(res.status_code, 302) assert_urls_equal(res.headers['location'], self.project.web_url_for('node_setting')) def test_deauthorize(self): """Testing figshare_deauthorize to ensure user auth gets removed from the node and that the AddonNodeSettings are cleared """ settings = self.node_settings url = '/api/v1/project/{0}/figshare/config/'.format(self.project._id) self.app.delete(url, auth=self.user.auth) self.node_settings.reload() assert_true(settings.user_settings is None) is_none = ( settings.figshare_id is None and settings.figshare_title is None and settings.figshare_type is None ) assert_true(is_none) def test_config_no_change(self): nlogs = len(self.project.logs) url = self.project.api_url_for('figshare_config_put') rv = self.app.put_json( url, { 'selected': { 'id': '123456', 'name': 'FIGSHARE_TITLE', 'type': 'project', }, }, auth=self.user.auth, ) self.project.reload() assert_equal(rv.status_int, http.OK) assert_equal(len(self.project.logs), nlogs) def test_config_change(self): nlogs = len(self.project.logs) url = self.project.api_url_for('figshare_config_put') rv = self.app.put_json( url, { 'selected': { 'id': 'project_9001', 'name': 'IchangedbecauseIcan', 'type': 'project' }, }, auth=self.user.auth, ) self.project.reload() self.node_settings.reload() assert_equal(rv.status_int, http.OK) assert_equal(self.node_settings.figshare_id, 'project_9001') assert_equal(self.node_settings.figshare_title, 'IchangedbecauseIcan') assert_equal(len(self.project.logs), nlogs + 1) assert_equal( self.project.logs[nlogs].action, 'figshare_content_linked' ) def test_config_change_invalid(self): nlogs = len(self.project.logs) url = self.project.api_url_for('figshare_config_put') rv = self.app.put_json( url, { 'selected': { 'type': 'project' }, }, auth=self.user.auth, expect_errors=True, ) self.project.reload() self.node_settings.reload() assert_equal(rv.status_int, http.BAD_REQUEST) assert_equal(len(self.project.logs), nlogs) def test_config_change_not_owner(self): user2 = AuthUserFactory() self.project.add_contributor(user2, save=True) nlogs = len(self.project.logs) url = self.project.api_url_for('figshare_config_put') res = self.app.put_json( url, {}, auth=user2.auth, expect_errors=True, ) self.project.reload() assert_equal(res.status_int, http.FORBIDDEN) assert_equal(nlogs, len(self.project.logs)) @httpretty.activate def test_serialize_settings_helper_returns_correct_auth_info(self): self.configure_responses() result = serialize_settings(self.node_settings, self.user, client=figshare_mock) assert_equal(result['nodeHasAuth'], self.node_settings.has_auth) assert_true(result['userHasAuth']) assert_true(result['userIsOwner']) @httpretty.activate def test_serialize_settings_for_user_no_auth(self): self.configure_responses() no_addon_user = AuthUserFactory() result = serialize_settings(self.node_settings, no_addon_user, client=figshare_mock) assert_false(result['userIsOwner']) assert_false(result['userHasAuth'])
class TestWikiRename(OsfTestCase): def setUp(self): super(TestWikiRename, self).setUp() self.project = ProjectFactory(is_public=True) api_key = ApiKeyFactory() self.project.creator.api_keys.append(api_key) self.project.creator.save() self.consolidate_auth = Auth(user=self.project.creator, api_key=api_key) self.auth = ('test', api_key._primary_key) self.project.update_node_wiki('home', 'Hello world', self.consolidate_auth) self.page_name = 'page2' self.project.update_node_wiki(self.page_name, 'content', self.consolidate_auth) self.project.save() self.page = self.project.get_wiki_page(self.page_name) self.wiki = self.project.get_wiki_page('home') self.url = self.project.api_url_for( 'project_wiki_rename', wname=self.page_name, ) def test_rename_wiki_page_valid(self, new_name=u'away'): self.app.put_json(self.url, {'value': new_name}, auth=self.auth) self.project.reload() old_wiki = self.project.get_wiki_page(self.page_name) assert_false(old_wiki) new_wiki = self.project.get_wiki_page(new_name) assert_true(new_wiki) assert_equal(new_wiki._primary_key, self.page._primary_key) assert_equal(new_wiki.content, self.page.content) assert_equal(new_wiki.version, self.page.version) def test_rename_wiki_page_invalid(self, new_name=u'invalid/name'): res = self.app.put_json( self.url, {'value': new_name}, auth=self.auth, expect_errors=True, ) assert_equal(http.BAD_REQUEST, res.status_code) assert_equal(res.json['message_short'], 'Invalid name') assert_equal(res.json['message_long'], 'Page name cannot contain forward slashes.') self.project.reload() old_wiki = self.project.get_wiki_page(self.page_name) assert_true(old_wiki) def test_rename_wiki_page_duplicate(self): self.project.update_node_wiki('away', 'Hello world', self.consolidate_auth) new_name = 'away' res = self.app.put_json( self.url, {'value': new_name}, auth=self.auth, expect_errors=True, ) assert_equal(res.status_code, 409) def test_rename_wiki_name_not_found(self): url = self.project.api_url_for('project_wiki_rename', wname='not_found_page_name') res = self.app.put_json(url, {'value': 'new name'}, auth=self.auth, expect_errors=True) assert_equal(res.status_code, 404) def test_cannot_rename_wiki_page_to_home(self): user = AuthUserFactory() # A fresh project where the 'home' wiki page has no content project = ProjectFactory(creator=user) project.update_node_wiki('Hello', 'hello world', Auth(user=user)) url = project.api_url_for('project_wiki_rename', wname=to_mongo_key('Hello')) res = self.app.put_json(url, {'value': 'home'}, auth=user.auth, expect_errors=True) assert_equal(res.status_code, 409) def test_rename_wiki_name_with_value_missing(self): # value is missing res = self.app.put_json(self.url, {}, auth=self.auth, expect_errors=True) assert_equal(res.status_code, 400) def test_rename_wiki_page_duplicate_different_casing(self): # attempt to rename 'page2' from setup to different case of 'away'. old_name = 'away' new_name = 'AwAy' self.project.update_node_wiki(old_name, 'Hello world', self.consolidate_auth) res = self.app.put_json(self.url, {'value': new_name}, auth=self.auth, expect_errors=True) assert_equal(res.status_code, 409) def test_rename_wiki_page_same_name_different_casing(self): old_name = 'away' new_name = 'AWAY' self.project.update_node_wiki(old_name, 'Hello world', self.consolidate_auth) url = self.project.api_url_for('project_wiki_rename', wname=old_name) res = self.app.put_json(url, {'value': new_name}, auth=self.auth, expect_errors=False) assert_equal(res.status_code, 200) def test_cannot_rename_home_page(self): url = self.project.api_url_for('project_wiki_rename', wname='home') res = self.app.put_json(url, {'value': 'homelol'}, auth=self.auth, expect_errors=True) assert_equal(res.status_code, 400) def test_can_rename_to_a_deleted_page(self): self.project.delete_node_wiki(self.page_name, self.consolidate_auth) self.project.save() # Creates a new page self.project.update_node_wiki('page3', 'moarcontent', self.consolidate_auth) self.project.save() # Renames the wiki to the deleted page url = self.project.api_url_for('project_wiki_rename', wname='page3') res = self.app.put_json(url, {'value': self.page_name}, auth=self.auth) assert_equal(res.status_code, 200) def test_rename_wiki_page_with_valid_html(self): # script is not an issue since data is sanitized via bleach or mako before display. self.test_rename_wiki_page_valid(new_name=u'<html>hello<html>') def test_rename_wiki_page_with_invalid_html(self): # script is not an issue since data is sanitized via bleach or mako before display. # with that said routes still do not accept forward slashes self.test_rename_wiki_page_invalid(new_name=u'<html>hello</html>') def test_rename_wiki_page_with_non_ascii_title(self): self.test_rename_wiki_page_valid(new_name=u'øˆ∆´ƒøßå√ß') def test_rename_wiki_page_with_valid_special_character_title(self): self.test_rename_wiki_page_valid(new_name=SPECIAL_CHARACTERS_ALLOWED) def test_rename_wiki_page_with_invalid_special_character_title(self): self.test_rename_wiki_page_invalid(new_name=SPECIAL_CHARACTERS_ALL)
class RegistrationEmbargoViewsTestCase(OsfTestCase): def setUp(self): super(RegistrationEmbargoViewsTestCase, self).setUp() ensure_schemas() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.registration = RegistrationFactory(project=self.project, creator=self.user) current_month = datetime.datetime.now().strftime("%B") current_year = datetime.datetime.now().strftime("%Y") self.valid_make_public_payload = json.dumps({ u'embargoEndDate': u'Fri, 01, {month} {year} 00:00:00 GMT'.format(month=current_month, year=current_year), u'registrationChoice': 'immediate', u'summary': unicode(fake.sentence()) }) valid_date = datetime.datetime.now() + datetime.timedelta(days=180) self.valid_embargo_payload = json.dumps({ u'embargoEndDate': unicode(valid_date.strftime('%a, %d, %B %Y %H:%M:%S')) + u' GMT', u'registrationChoice': 'embargo', u'summary': unicode(fake.sentence()) }) self.invalid_embargo_date_payload = json.dumps({ u'embargoEndDate': u"Thu, 01 {month} {year} 05:00:00 GMT".format( month=current_month, year=str(int(current_year) - 1)), u'registrationChoice': 'embargo', u'summary': unicode(fake.sentence()) }) @mock.patch('framework.tasks.handlers.enqueue_task') def test_POST_register_make_public_immediately_creates_registration_approval( self, mock_enqueue): res = self.app.post(self.project.api_url_for( 'node_register_template_page_post', template=u'Open-Ended_Registration'), self.valid_make_public_payload, content_type='application/json', auth=self.user.auth) assert_equal(res.status_code, 201) registration = Node.find().sort('-registered_date')[0] assert_true(registration.is_registration) assert_not_equal(registration.registration_approval, None) # Regression test for https://openscience.atlassian.net/browse/OSF-5039 @mock.patch('framework.tasks.handlers.enqueue_task') def test_POST_register_make_public_immediately_creates_private_pending_registration_for_public_project( self, mock_enqueue): public_project = ProjectFactory(is_public=True, creator=self.user) component = NodeFactory(creator=self.user, parent=public_project, title='Component', is_public=True) subproject = ProjectFactory(creator=self.user, parent=public_project, title='Subproject', is_public=True) subproject_component = NodeFactory(creator=self.user, parent=subproject, title='Subcomponent', is_public=True) res = self.app.post(public_project.api_url_for( 'node_register_template_page_post', template=u'Open-Ended_Registration'), self.valid_make_public_payload, content_type='application/json', auth=self.user.auth) public_project.reload() assert_equal(res.status_code, 201) # Last node directly registered from self.project registration = Node.load(public_project.node__registrations[-1]) assert_true(registration.is_registration) assert_false(registration.is_public) for node in registration.get_descendants_recursive(): assert_true(node.is_registration) assert_false(node.is_public) @mock.patch('framework.tasks.handlers.enqueue_task') def test_POST_register_make_public_does_not_make_children_public( self, mock_enqueue): component = NodeFactory(creator=self.user, parent=self.project, title='Component') subproject = ProjectFactory(creator=self.user, parent=self.project, title='Subproject') subproject_component = NodeFactory(creator=self.user, parent=subproject, title='Subcomponent') res = self.app.post(self.project.api_url_for( 'node_register_template_page_post', template=u'Open-Ended_Registration'), self.valid_make_public_payload, content_type='application/json', auth=self.user.auth) self.project.reload() # Last node directly registered from self.project registration = Node.load(self.project.node__registrations[-1]) assert_false(registration.is_public) for node in registration.get_descendants_recursive(): assert_true(node.is_registration) assert_false(node.is_public) @mock.patch('framework.tasks.handlers.enqueue_task') def test_POST_register_embargo_is_not_public(self, mock_enqueue): res = self.app.post(self.project.api_url_for( 'node_register_template_page_post', template=u'Open-Ended_Registration'), self.valid_embargo_payload, content_type='application/json', auth=self.user.auth) assert_equal(res.status_code, 201) registration = Node.find().sort('-registered_date')[0] assert_true(registration.is_registration) assert_false(registration.is_public) assert_true(registration.is_pending_embargo_for_existing_registration) assert_is_not_none(registration.embargo) # Regression test for https://openscience.atlassian.net/browse/OSF-5071 @mock.patch('framework.tasks.handlers.enqueue_task') def test_POST_register_embargo_does_not_make_project_or_children_public( self, mock_enqueue): public_project = ProjectFactory(creator=self.user, is_public=True) component = NodeFactory(creator=self.user, parent=public_project, title='Component', is_public=True) subproject = ProjectFactory(creator=self.user, parent=public_project, title='Subproject', is_public=True) subproject_component = NodeFactory(creator=self.user, parent=subproject, title='Subcomponent', is_public=True) res = self.app.post(public_project.api_url_for( 'node_register_template_page_post', template=u'Open-Ended_Registration'), self.valid_embargo_payload, content_type='application/json', auth=self.user.auth) public_project.reload() assert_equal(res.status_code, 201) # Last node directly registered from self.project registration = Node.load(public_project.node__registrations[-1]) assert_true(registration.is_registration) assert_false(registration.is_public) assert_true(registration.is_pending_embargo_for_existing_registration) assert_is_not_none(registration.embargo) for node in registration.get_descendants_recursive(): assert_true(node.is_registration) assert_false(node.is_public) @mock.patch('framework.tasks.handlers.enqueue_task') def test_POST_invalid_embargo_end_date_returns_HTTPBad_Request( self, mock_enqueue): res = self.app.post(self.project.api_url_for( 'node_register_template_page_post', template=u'Open-Ended_Registration'), self.invalid_embargo_date_payload, content_type='application/json', auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) @mock.patch('framework.tasks.handlers.enqueue_task') def test_valid_POST_embargo_adds_to_parent_projects_log( self, mock_enquque): initial_project_logs = len(self.project.logs) res = self.app.post(self.project.api_url_for( 'node_register_template_page_post', template=u'Open-Ended_Registration'), self.valid_embargo_payload, content_type='application/json', auth=self.user.auth) self.project.reload() # Logs: Created, registered, embargo initiated assert_equal(len(self.project.logs), initial_project_logs + 1) def test_non_contributor_GET_approval_returns_HTTPError(self): non_contributor = AuthUserFactory() self.registration.embargo_registration( self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10)) self.registration.save() assert_true(self.registration.is_pending_embargo) approval_token = self.registration.embargo.approval_state[ self.user._id]['approval_token'] 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(http.FORBIDDEN, res.status_code) assert_true(self.registration.is_pending_embargo) assert_false(self.registration.embargo_end_date) def test_non_contributor_GET_disapproval_returns_HTTPError(self): non_contributor = AuthUserFactory() self.registration.embargo_registration( self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10)) self.registration.save() assert_true(self.registration.is_pending_embargo) rejection_token = self.registration.embargo.approval_state[ self.user._id]['rejection_token'] approval_url = self.registration.web_url_for('view_project', token=rejection_token) res = self.app.get(approval_url, auth=non_contributor.auth, expect_errors=True) assert_equal(http.FORBIDDEN, res.status_code) assert_true(self.registration.is_pending_embargo) assert_false(self.registration.embargo_end_date)
class TestGoogleDriveConfigViews(OsfTestCase): def setUp(self): super(TestGoogleDriveConfigViews, self).setUp() self.user = AuthUserFactory() self.user.add_addon('googledrive') self.user_settings = self.user.get_addon('googledrive') self.project = ProjectFactory(creator=self.user) self.project.add_addon('googledrive', Auth(self.user)) self.node_settings = self.project.get_addon('googledrive') self.node_settings.user_settings = self.user_settings oauth_settings = GoogleDriveOAuthSettingsFactory() oauth_settings.save() self.user_settings.oauth_settings = oauth_settings self.node_settings.save() # Log user in self.app.authenticate(*self.user.auth) def test_drive_user_config_get_returns_correct_urls(self): self.user.add_addon('googledrive') url = api_url_for('googledrive_user_config_get', Auth(self.user)) res = self.app.get(url) assert_equal(res.status_code, 200) result = res.json['result']['urls'] assert_true(result['create'], api_url_for('googledrive_oauth_start_user')) assert_true(result['delete'], api_url_for('googledrive_oauth_delete_user')) def test_drive_user_config_get_has_auth(self): self.user.add_addon('googledrive') user_settings = self.user.get_addon('googledrive') user_settings.access_token = 'abc123' user_settings.save() url = api_url_for('googledrive_user_config_get', Auth(self.user)) res = self.app.get(url) assert_equal(res.status_code, 200) result = res.json['result'] assert_true(result['userHasAuth']) def test_drive_user_config_get_not_has_auth(self): self.user_settings.access_token = None self.user_settings.save() url = api_url_for('googledrive_user_config_get', Auth(self.user)) res = self.app.get(url) assert_equal(res.status_code, 200) result = res.json['result'] assert_false(result['userHasAuth']) # TODO def test_googledrive_config_put(self): url = self.project.api_url_for('googledrive_config_put') selected = { 'path': 'Google Drive/ My Folder', 'name': 'Google Drive/ My Folder', 'id': '12345' } # Can set folder through API call res = self.app.put_json(url, {'selected': selected}, auth=self.user.auth) assert_equal(res.status_code, 200) self.node_settings.reload() self.project.reload() # Folder was set assert_equal(self.node_settings.folder_name, ' My Folder') # A log event was created last_log = self.project.logs[-1] assert_equal(last_log.action, 'googledrive_folder_selected') params = last_log.params assert_equal(params['folder'], self.node_settings.folder_name)
class TestPopulateNewAndNoteworthy(OsfTestCase): def setUp(self): super(TestPopulateNewAndNoteworthy, self).setUp() self.pop1 = ProjectFactory(is_public=True) self.pop2 = ProjectFactory(is_public=True) self.popreg1 = RegistrationFactory(is_public=True) self.popreg2 = RegistrationFactory(is_public=True) def tearDown(self): super(TestPopulateNewAndNoteworthy, self).tearDown() Node.remove() @mock.patch('website.project.utils.get_keen_activity') def test_populate_popular_nodes_and_registrations(self, mock_client): # only for setup, not used self.new_noteworthy_node = ProjectFactory() self.new_noteworthy_node._id = NEW_AND_NOTEWORTHY_LINKS_NODE self.new_noteworthy_node.save() self.popular_links_node = ProjectFactory() self.popular_links_node._id = POPULAR_LINKS_NODE self.popular_links_node.save() self.popular_links_registrations = ProjectFactory() self.popular_links_registrations._id = POPULAR_LINKS_REGISTRATIONS self.popular_links_registrations.save() popular_nodes = [self.pop1, self.pop2] popular_registrations = [self.popreg1, self.popreg2] node_pageviews = [ { 'result': 5, 'node.id': self.pop1._id }, { 'result': 5, 'node.id': self.pop2._id }, { 'result': 5, 'node.id': self.popreg1._id }, { 'result': 5, 'node.id': self.popreg2._id } ] node_visits = [ { 'result': 2, 'node.id': self.pop1._id }, { 'result': 2, 'node.id': self.pop2._id }, { 'result': 2, 'node.id': self.popreg1._id }, { 'result': 2, 'node.id': self.popreg2._id } ] mock_client.return_value = {'node_pageviews': node_pageviews, 'node_visits': node_visits} assert_equal(len(self.popular_links_node.nodes), 0) assert_equal(len(self.popular_links_registrations.nodes), 0) script.main(dry_run=False) self.popular_links_node.reload() self.popular_links_registrations.reload() assert_equal(len(self.popular_links_node.nodes), 2) assert_equal(len(self.popular_links_registrations.nodes), 2) assert_items_equal( popular_nodes, [pointer.node for pointer in self.popular_links_node.nodes] ) assert_items_equal( popular_registrations, [pointer.node for pointer in self.popular_links_registrations.nodes] )
class TestClaiming(OsfTestCase): def setUp(self): super(TestClaiming, self).setUp() self.referrer = AuthUserFactory() self.project = ProjectFactory(creator=self.referrer, is_public=True) def test_correct_name_shows_in_contributor_list(self): name1, email = fake.name(), fake.email() UnregUserFactory(fullname=name1, email=email) name2, email = fake.name(), fake.email() # Added with different name self.project.add_unregistered_contributor(fullname=name2, email=email, auth=Auth(self.referrer)) self.project.save() res = self.app.get(self.project.url, auth=self.referrer.auth) # Correct name is shown assert_in_html(name2, res) assert_not_in(name1, res) def test_user_can_set_password_on_claim_page(self): name, email = fake.name(), fake.email() new_user = self.project.add_unregistered_contributor( email=email, fullname=name, auth=Auth(self.referrer) ) self.project.save() claim_url = new_user.get_claim_url(self.project._primary_key) res = self.app.get(claim_url) self.project.reload() assert_in('Set Password', res) form = res.forms['setPasswordForm'] #form['username'] = new_user.username #Removed as long as E-mail can't be updated. form['password'] = '******' form['password2'] = 'killerqueen' res = form.submit().follow() new_user.reload() assert_true(new_user.check_password('killerqueen')) def test_sees_is_redirected_if_user_already_logged_in(self): name, email = fake.name(), fake.email() new_user = self.project.add_unregistered_contributor( email=email, fullname=name, auth=Auth(self.referrer) ) self.project.save() existing = AuthUserFactory() claim_url = new_user.get_claim_url(self.project._primary_key) # a user is already logged in res = self.app.get(claim_url, auth=existing.auth, expect_errors=True) assert_equal(res.status_code, 302) def test_unregistered_users_names_are_project_specific(self): name1, name2, email = fake.name(), fake.name(), fake.email() project2 = ProjectFactory(creator=self.referrer) # different projects use different names for the same unreg contributor self.project.add_unregistered_contributor( email=email, fullname=name1, auth=Auth(self.referrer) ) self.project.save() project2.add_unregistered_contributor( email=email, fullname=name2, auth=Auth(self.referrer) ) project2.save() self.app.authenticate(*self.referrer.auth) # Each project displays a different name in the contributor list res = self.app.get(self.project.url) assert_in_html(name1, res) res2 = self.app.get(project2.url) assert_in_html(name2, res2) @unittest.skip("as long as E-mails cannot be changed") def test_cannot_set_email_to_a_user_that_already_exists(self): reg_user = UserFactory() name, email = fake.name(), fake.email() new_user = self.project.add_unregistered_contributor( email=email, fullname=name, auth=Auth(self.referrer) ) self.project.save() # Goes to claim url and successfully claims account claim_url = new_user.get_claim_url(self.project._primary_key) res = self.app.get(claim_url) self.project.reload() assert_in('Set Password', res) form = res.forms['setPasswordForm'] # Fills out an email that is the username of another user form['username'] = reg_user.username form['password'] = '******' form['password2'] = 'killerqueen' res = form.submit().maybe_follow(expect_errors=True) assert_in( language.ALREADY_REGISTERED.format(email=reg_user.username), res ) def test_correct_display_name_is_shown_at_claim_page(self): original_name = fake.name() unreg = UnregUserFactory(fullname=original_name) different_name = fake.name() new_user = self.project.add_unregistered_contributor( email=unreg.username, fullname=different_name, auth=Auth(self.referrer), ) self.project.save() claim_url = new_user.get_claim_url(self.project._primary_key) res = self.app.get(claim_url) # Correct name (different_name) should be on page assert_in_html(different_name, res)
class TestSetPreprintFile(OsfTestCase): def setUp(self): super(TestSetPreprintFile, self).setUp() self.user = AuthUserFactory() self.auth = Auth(user=self.user) self.read_write_user = AuthUserFactory() self.read_write_user_auth = Auth(user=self.read_write_user) self.project = ProjectFactory(creator=self.user) self.file = OsfStorageFile.create( is_file=True, node=self.project, path='/panda.txt', name='panda.txt', materialized_path='/panda.txt') self.file.save() self.file_two = OsfStorageFile.create( is_file=True, node=self.project, path='/pandapanda.txt', name='pandapanda.txt', materialized_path='/pandapanda.txt') self.file_two.save() self.project.add_contributor(self.read_write_user, permissions=[permissions.WRITE]) self.project.save() self.preprint = PreprintFactory(project=self.project, finish=False) @assert_logs(NodeLog.MADE_PUBLIC, 'project') @assert_logs(NodeLog.PREPRINT_INITIATED, 'project', -2) def test_is_preprint_property_new_file_to_published(self): assert_false(self.project.is_preprint) self.preprint.set_primary_file(self.file, auth=self.auth, save=True) self.project.reload() assert_false(self.project.is_preprint) with assert_raises(ValueError): self.preprint.set_published(True, auth=self.auth, save=True) self.preprint.provider = PreprintProviderFactory() self.preprint.set_subjects([[SubjectFactory()._id]], auth=self.auth, save=True) self.project.reload() assert_false(self.project.is_preprint) self.preprint.set_published(True, auth=self.auth, save=True) self.project.reload() assert_true(self.project.is_preprint) def test_project_made_public(self): assert_false(self.project.is_public) self.preprint.set_primary_file(self.file, auth=self.auth, save=True) assert_false(self.project.is_public) with assert_raises(ValueError): self.preprint.set_published(True, auth=self.auth, save=True) self.preprint.provider = PreprintProviderFactory() self.preprint.set_subjects([[SubjectFactory()._id]], auth=self.auth, save=True) self.project.reload() assert_false(self.project.is_public) self.preprint.set_published(True, auth=self.auth, save=True) self.project.reload() assert_true(self.project.is_public) def test_add_primary_file(self): self.preprint.set_primary_file(self.file, auth=self.auth, save=True) assert_equal(self.project.preprint_file, self.file) assert_equal(type(self.project.preprint_file), type(self.file.stored_object)) @assert_logs(NodeLog.PREPRINT_FILE_UPDATED, 'project') def test_change_primary_file(self): self.preprint.set_primary_file(self.file, auth=self.auth, save=True) assert_equal(self.project.preprint_file, self.file) self.preprint.set_primary_file(self.file_two, auth=self.auth, save=True) assert_equal(self.project.preprint_file._id, self.file_two._id) def test_add_invalid_file(self): with assert_raises(AttributeError): self.preprint.set_primary_file('inatlanta', auth=self.auth, save=True) def test_preprint_created_date(self): self.preprint.set_primary_file(self.file, auth=self.auth, save=True) assert_equal(self.project.preprint_file._id, self.file._id) assert(self.preprint.date_created) assert_not_equal(self.project.date_created, self.preprint.date_created) def test_non_admin_update_file(self): self.preprint.set_primary_file(self.file, auth=self.auth, save=True) assert_equal(self.project.preprint_file._id, self.file._id) with assert_raises(PermissionsError): self.preprint.set_primary_file(self.file_two, auth=self.read_write_user_auth, save=True) assert_equal(self.project.preprint_file._id, self.file._id)
class TestNodeChildrenBulkCreate(ApiTestCase): def setUp(self): super(TestNodeChildrenBulkCreate, self).setUp() self.user = AuthUserFactory() self.user_two = AuthUserFactory() self.project = ProjectFactory(creator=self.user, is_public=True) self.url = '/{}nodes/{}/children/'.format(API_BASE, self.project._id) self.child = { 'type': 'nodes', 'attributes': { 'title': 'child', 'description': 'this is a child project', 'category': 'project' } } self.child_two = { 'type': 'nodes', 'attributes': { 'title': 'second child', 'description': 'this is my hypothesis', 'category': 'hypothesis' } } def test_bulk_children_create_blank_request(self): res = self.app.post_json_api(self.url, auth=self.user.auth, expect_errors=True, bulk=True) assert_equal(res.status_code, 400) def test_bulk_creates_children_limits(self): res = self.app.post_json_api(self.url, {'data': [self.child] * 101}, auth=self.user.auth, expect_errors=True, bulk=True) assert_equal(res.status_code, 400) assert_equal(res.json['errors'][0]['detail'], 'Bulk operation limit is 100, got 101.') assert_equal(res.json['errors'][0]['source']['pointer'], '/data') def test_bulk_creates_children_logged_out_user(self): res = self.app.post_json_api(self.url, {'data': [self.child, self.child_two]}, expect_errors=True, bulk=True) assert_equal(res.status_code, 401) self.project.reload() assert_equal(len(self.project.nodes), 0) def test_bulk_creates_children_logged_in_owner(self): res = self.app.post_json_api(self.url, {'data': [self.child, self.child_two]}, auth=self.user.auth, bulk=True) assert_equal(res.status_code, 201) assert_equal(res.json['data'][0]['attributes']['title'], self.child['attributes']['title']) assert_equal(res.json['data'][0]['attributes']['description'], self.child['attributes']['description']) assert_equal(res.json['data'][0]['attributes']['category'], self.child['attributes']['category']) assert_equal(res.json['data'][1]['attributes']['title'], self.child_two['attributes']['title']) assert_equal(res.json['data'][1]['attributes']['description'], self.child_two['attributes']['description']) assert_equal(res.json['data'][1]['attributes']['category'], self.child_two['attributes']['category']) self.project.reload() assert_equal(res.json['data'][0]['id'], self.project.nodes[0]._id) assert_equal(res.json['data'][1]['id'], self.project.nodes[1]._id) assert_equal(self.project.nodes[0].logs[0].action, NodeLog.PROJECT_CREATED) assert_equal(self.project.nodes[1].logs[0].action, NodeLog.PROJECT_CREATED) def test_bulk_creates_children_child_logged_in_write_contributor(self): self.project.add_contributor( self.user_two, permissions=[permissions.READ, permissions.WRITE], auth=Auth(self.user), save=True) res = self.app.post_json_api(self.url, {'data': [self.child, self.child_two]}, auth=self.user_two.auth, bulk=True) assert_equal(res.status_code, 201) assert_equal(res.json['data'][0]['attributes']['title'], self.child['attributes']['title']) assert_equal(res.json['data'][0]['attributes']['description'], self.child['attributes']['description']) assert_equal(res.json['data'][0]['attributes']['category'], self.child['attributes']['category']) assert_equal(res.json['data'][1]['attributes']['title'], self.child_two['attributes']['title']) assert_equal(res.json['data'][1]['attributes']['description'], self.child_two['attributes']['description']) assert_equal(res.json['data'][1]['attributes']['category'], self.child_two['attributes']['category']) self.project.reload() child_id = res.json['data'][0]['id'] child_two_id = res.json['data'][1]['id'] assert_equal(child_id, self.project.nodes[0]._id) assert_equal(child_two_id, self.project.nodes[1]._id) assert_equal( Node.load(child_id).logs[0].action, NodeLog.PROJECT_CREATED) assert_equal(self.project.nodes[1].logs[0].action, NodeLog.PROJECT_CREATED) def test_bulk_creates_children_logged_in_read_contributor(self): self.project.add_contributor(self.user_two, permissions=[permissions.READ], auth=Auth(self.user), save=True) res = self.app.post_json_api(self.url, {'data': [self.child, self.child_two]}, auth=self.user_two.auth, expect_errors=True, bulk=True) assert_equal(res.status_code, 403) self.project.reload() assert_equal(len(self.project.nodes), 0) def test_bulk_creates_children_logged_in_non_contributor(self): res = self.app.post_json_api(self.url, {'data': [self.child, self.child_two]}, auth=self.user_two.auth, expect_errors=True, bulk=True) assert_equal(res.status_code, 403) self.project.reload() assert_equal(len(self.project.nodes), 0) def test_bulk_creates_children_and_sanitizes_html_logged_in_owner(self): title = '<em>Cool</em> <strong>Project</strong>' description = 'An <script>alert("even cooler")</script> child' res = self.app.post_json_api(self.url, { 'data': [{ 'type': 'nodes', 'attributes': { 'title': title, 'description': description, 'category': 'project', 'public': True } }] }, auth=self.user.auth, bulk=True) child_id = res.json['data'][0]['id'] assert_equal(res.status_code, 201) url = '/{}nodes/{}/'.format(API_BASE, child_id) res = self.app.get(url, auth=self.user.auth) assert_equal(res.json['data']['attributes']['title'], strip_html(title)) assert_equal(res.json['data']['attributes']['description'], strip_html(description)) assert_equal(res.json['data']['attributes']['category'], 'project') self.project.reload() child_id = res.json['data']['id'] assert_equal(child_id, self.project.nodes[0]._id) assert_equal( Node.load(child_id).logs[0].action, NodeLog.PROJECT_CREATED) def test_cannot_bulk_create_children_on_a_registration(self): registration = RegistrationFactory(project=self.project, creator=self.user) url = '/{}nodes/{}/children/'.format(API_BASE, registration._id) res = self.app.post_json_api(url, { 'data': [ self.child_two, { 'type': 'nodes', 'attributes': { 'title': fake.catch_phrase(), 'description': fake.bs(), 'category': 'project', 'public': True, } } ] }, auth=self.user.auth, expect_errors=True, bulk=True) assert_equal(res.status_code, 404) self.project.reload() assert_equal(len(self.project.nodes), 0) def test_bulk_creates_children_no_type(self): child = { 'data': [ self.child_two, { 'attributes': { 'title': 'child', 'description': 'this is a child project', 'category': 'project', } } ] } res = self.app.post_json_api(self.url, child, auth=self.user.auth, expect_errors=True, bulk=True) assert_equal(res.status_code, 400) assert_equal(res.json['errors'][0]['detail'], 'This field may not be null.') assert_equal(res.json['errors'][0]['source']['pointer'], '/data/1/type') self.project.reload() assert_equal(len(self.project.nodes), 0) def test_bulk_creates_children_incorrect_type(self): child = { 'data': [ self.child_two, { 'type': 'Wrong type.', 'attributes': { 'title': 'child', 'description': 'this is a child project', 'category': 'project', } } ] } res = self.app.post_json_api(self.url, child, auth=self.user.auth, expect_errors=True, bulk=True) assert_equal(res.status_code, 409) assert_equal(res.json['errors'][0]['detail'], 'Resource identifier does not match server endpoint.') self.project.reload() assert_equal(len(self.project.nodes), 0) def test_bulk_creates_children_properties_not_nested(self): child = { 'data': [ self.child_two, { 'title': 'child', 'description': 'this is a child project', 'category': 'project', } ] } res = self.app.post_json_api(self.url, child, auth=self.user.auth, expect_errors=True, bulk=True) assert_equal(res.status_code, 400) assert_equal(res.json['errors'][0]['detail'], 'Request must include /data/attributes.') assert_equal(res.json['errors'][0]['source']['pointer'], '/data/attributes') self.project.reload() assert_equal(len(self.project.nodes), 0)
class TestDeleteNodeLink(ApiTestCase): def setUp(self): super(TestDeleteNodeLink, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user, is_public=False) self.pointer_project = ProjectFactory(creator=self.user, is_public=True) self.pointer = self.project.add_pointer(self.pointer_project, auth=Auth(self.user), save=True) self.private_url = '/{}nodes/{}/node_links/{}/'.format(API_BASE, self.project._id, self.pointer._id) self.user_two = AuthUserFactory() self.public_project = ProjectFactory(is_public=True, creator=self.user) self.public_pointer_project = ProjectFactory(is_public=True, creator=self.user) self.public_pointer = self.public_project.add_pointer(self.public_pointer_project, auth=Auth(self.user), save=True) self.public_url = '/{}nodes/{}/node_links/{}/'.format(API_BASE, self.public_project._id, self.public_pointer._id) def test_delete_node_link_no_permissions_for_target_node(self): pointer_project = ProjectFactory(creator=self.user_two, is_public=False) pointer = self.public_project.add_pointer(pointer_project, auth=Auth(self.user), save=True) assert_in(pointer, self.public_project.nodes) url = '/{}nodes/{}/node_links/{}/'.format(API_BASE, self.public_project._id, pointer._id) res = self.app.delete_json_api(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 204) self.public_project.reload() assert_not_in(pointer, self.public_project.nodes) def test_cannot_delete_if_registration(self): registration = RegistrationFactory(project=self.public_project) url = '/{}registrations/{}/node_links/'.format( API_BASE, registration._id, ) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) pointer_id = res.json['data'][0]['id'] url = '/{}nodes/{}/node_links/{}/'.format( API_BASE, registration._id, pointer_id, ) res = self.app.delete(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_deletes_public_node_pointer_logged_out(self): res = self.app.delete(self.public_url, expect_errors=True) assert_equal(res.status_code, 401) assert_in('detail', res.json['errors'][0].keys()) def test_deletes_public_node_pointer_fails_if_bad_auth(self): node_count_before = len(self.public_project.nodes_pointer) res = self.app.delete(self.public_url, auth=self.user_two.auth, expect_errors=True) # This is could arguably be a 405, but we don't need to go crazy with status codes assert_equal(res.status_code, 403) assert_in('detail', res.json['errors'][0]) self.public_project.reload() assert_equal(node_count_before, len(self.public_project.nodes_pointer)) @assert_logs(NodeLog.POINTER_REMOVED, 'public_project') def test_deletes_public_node_pointer_succeeds_as_owner(self): node_count_before = len(self.public_project.nodes_pointer) res = self.app.delete(self.public_url, auth=self.user.auth) self.public_project.reload() assert_equal(res.status_code, 204) assert_equal(node_count_before - 1, len(self.public_project.nodes_pointer)) def test_deletes_private_node_pointer_logged_out(self): res = self.app.delete(self.private_url, expect_errors=True) assert_equal(res.status_code, 401) assert_in('detail', res.json['errors'][0]) @assert_logs(NodeLog.POINTER_REMOVED, 'project') def test_deletes_private_node_pointer_logged_in_contributor(self): res = self.app.delete(self.private_url, auth=self.user.auth) self.project.reload() # Update the model to reflect changes made by post request assert_equal(res.status_code, 204) assert_equal(len(self.project.nodes_pointer), 0) def test_deletes_private_node_pointer_logged_in_non_contributor(self): res = self.app.delete(self.private_url, auth=self.user_two.auth, expect_errors=True) assert_equal(res.status_code, 403) assert_in('detail', res.json['errors'][0]) @assert_logs(NodeLog.POINTER_REMOVED, 'public_project') def test_return_deleted_public_node_pointer(self): res = self.app.delete(self.public_url, auth=self.user.auth) self.public_project.reload() # Update the model to reflect changes made by post request assert_equal(res.status_code, 204) #check that deleted pointer can not be returned res = self.app.get(self.public_url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 404) @assert_logs(NodeLog.POINTER_REMOVED, 'project') def test_return_deleted_private_node_pointer(self): res = self.app.delete(self.private_url, auth=self.user.auth) self.project.reload() # Update the model to reflect changes made by post request assert_equal(res.status_code, 204) #check that deleted pointer can not be returned res = self.app.get(self.private_url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 404) # Regression test for https://openscience.atlassian.net/browse/OSF-4322 def test_delete_link_that_is_not_linked_to_correct_node(self): project = ProjectFactory(creator=self.user) # The node link belongs to a different project res = self.app.delete( '/{}nodes/{}/node_links/{}/'.format(API_BASE, project._id, self.public_pointer._id), auth=self.user.auth, expect_errors=True ) assert_equal(res.status_code, 404) errors = res.json['errors'] assert_equal(len(errors), 1) assert_equal(errors[0]['detail'], 'Node link does not belong to the requested node.')
class TestFilesViews(OsfTestCase): def setUp(self): super(TestFilesViews, self).setUp() self.user = AuthUserFactory() self.auth = ('test', self.user.api_keys[0]._primary_key) self.consolidated_auth = Auth(user=self.user) self.project = ProjectFactory(creator=self.user) self.project.add_addon('osffiles', auth=self.consolidated_auth) self.node_settings = self.project.get_addon('osffiles') self.fid = 'firstfile' self._upload_file(self.fid, 'firstcontent') def _upload_file(self, name, content, **kwargs): url = self.project.api_url + 'osffiles/' res = self.app.post( url, upload_files=[ ('file', name, content), ], auth=self.auth, **kwargs ) self.project.reload() return res def test_download_file(self): url = self.project.uploads[0].download_url(self.project) res = self.app.get(url, auth=self.user.auth).maybe_follow() assert_equal(res.body, 'firstcontent') def test_download_file_by_version_with_bad_version_value(self): url = self.project.web_url_for('download_file_by_version', fid=self.fid, vid='bad' ) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) assert_in('Invalid version', res.body) def test_download_file_by_version_with_nonexistent_file(self): url = self.project.web_url_for( 'download_file_by_version', fid='notfound', vid=0 ) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 404) def test_download_file_by_version_with_bad_version_number(self): url = self.project.web_url_for( 'download_file_by_version', fid=self.fid, vid=9999 ) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 404) def test_download_file_by_version_with_negative_version_number(self): url = self.project.web_url_for( 'download_file_by_version', fid=self.fid, vid=-1 ) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) def test_upload_file(self): node_addon = self.project.get_addon('osffiles') res = self._upload_file( 'newfile', 'a' * (node_addon.config.max_file_size) ) self.project.reload() assert_equal( self.project.logs[-1].action, 'file_added' ) assert_equal(res.status_code, 201) assert_true(isinstance(res.json, dict), 'return value is a dict') assert_equal(res.json['name'], 'newfile') assert_in('newfile', self.project.files_current) def test_upload_file_unicode_name(self): node_addon = self.project.get_addon('osffiles') res = self._upload_file( '_néwfile', 'a' * (node_addon.config.max_file_size) ) self.project.reload() assert_equal( self.project.logs[-1].action, 'file_added' ) assert_equal(res.status_code, 201) assert_true(isinstance(res.json, dict), 'return value is a dict') assert_equal(res.json['name'], '_newfile') assert_in('_newfile', self.project.files_current) def test_upload_file_too_large(self): node_addon = self.project.get_addon('osffiles') res = self._upload_file( 'newfile', 'a' * (node_addon.config.max_file_size + 1), expect_errors=True, ) self.project.reload() assert_equal(res.status_code, 400) assert_not_in('newfile', self.project.files_current) def test_file_info(self): # Upload a new version of firstfile self._upload_file(self.fid, 'secondcontent') url = self.project.api_url_for('file_info', fid=self.project.uploads[0].filename) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) file_obj = self.project.get_file_object(self.fid, version=1) data = res.json assert_equal(data['file_name'], self.fid) assert_equal(data['registered'], self.project.is_registration) assert_equal(len(data['versions']), 2) assert_equal(data['urls']['files'], self.project.web_url_for('collect_file_trees')) assert_equal(data['urls']['latest']['download'], file_obj.download_url(self.project)) assert_equal(data['urls']['api'], file_obj.api_url(self.project)) version = res.json['versions'][0] assert_equal(version['file_name'], self.fid) assert_equal(version['version_number'], 2) assert_equal(version['modified_date'], file_obj.date_uploaded.strftime('%Y/%m/%d %I:%M %p')) assert_in('downloads', version) assert_equal(version['committer_name'], file_obj.uploader.fullname) assert_equal(version['committer_url'], file_obj.uploader.url) def test_file_info_with_anonymous_link(self): link = PrivateLinkFactory(anonymous=True) link.nodes.append(self.project) link.save() self._upload_file('firstfile', 'secondcontent') url = self.project.api_url_for( 'file_info', fid=self.project.uploads[0].filename ) res = self.app.get(url, {'view_only': link.key}) assert_not_in(self.user.fullname, res.body) assert_not_in(self.user._id, res.body) def test_delete_file(self): url = self.project.api_url_for('delete_file', fid=self.fid) res = self.app.delete(url, auth=self.auth).maybe_follow() assert_equal(res.status_code, 200) self.project.reload() assert_not_in('firstfile', self.project.files_current) def test_delete_file_returns_404_when_file_is_already_deleted(self): self.project.remove_file(Auth(self.project.creator), self.fid) url = self.project.api_url_for('delete_file', fid=self.fid) res = self.app.delete_json(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 404) def test_file_urls(self): url = self.project.api_url + 'osffiles/hgrid/' res = self.app.get(url, auth=self.auth).maybe_follow() assert_equal(len(res.json), 1) for url in ['view', 'download', 'delete']: assert_in( self.project._id, res.json[0]['urls'][url] ) def test_file_urls_fork(self): fork = self.project.fork_node(auth=Auth(user=self.user)) url = fork.api_url + 'osffiles/hgrid/' res = self.app.get(url, auth=self.auth).maybe_follow() assert_equal(len(res.json), 1) for url in ['view', 'download', 'delete']: assert_in( fork._id, res.json[0]['urls'][url] ) def test_file_urls_registration(self): registration = self.project.register_node( None, Auth(user=self.user), '', '' ) url = registration.api_url + 'osffiles/hgrid/' res = self.app.get(url, auth=self.auth).maybe_follow() assert_equal(len(res.json), 1) for url in ['view', 'download', 'delete']: assert_in( registration._id, res.json[0]['urls'][url] ) def test_view_creates_guid(self): guid_fid = 'unique' guid_content = 'snowflake' self._upload_file(guid_fid, guid_content) node_file = NodeFile.load(self.project.files_current[guid_fid]) guid_count = OsfGuidFile.find().count() # View file for the first time url = node_file.url(self.project) res = self.app.get( url, auth=self.user.auth, ).follow( auth=self.user.auth, ) guid = OsfGuidFile.find_one( Q('node', 'eq', self.project) & Q('name', 'eq', guid_fid) ) # GUID count has been incremented by one assert_equal( OsfGuidFile.find().count(), guid_count + 1 ) # Client has been redirected to GUID assert_equal( res.request.path.strip('/'), guid._id, ) # View file for the second time self.app.get( url, auth=self.user.auth, ).follow( auth=self.user.auth, ) # GUID count has not been incremented assert_equal( OsfGuidFile.find().count(), guid_count + 1 ) def test_guid_url_returns_404(self): f = NodeFile() f.save() url = '/{}/'.format(f._id) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 404) def test_sees_delete_button_if_can_write(self): url = self.project.uploads[0].url(self.project) res = self.app.get( url, auth=self.user.auth, ).maybe_follow( auth=self.user.auth, ) assert_in('Download', res) assert_in('Delete', res) def test_does_not_see_delete_button_if_cannot_write(self): self.project.is_public = True self.project.save() user2 = AuthUserFactory() url = self.project.uploads[0].url(self.project) res = self.app.get( url, auth=user2.auth, ).maybe_follow( auth=user2.auth, ) assert_in('Download', res) assert_not_in('Delete', res)
class TestFilesViews(OsfTestCase): def setUp(self): super(TestFilesViews, self).setUp() self.user = AuthUserFactory() self.auth = ('test', self.user.api_keys[0]._primary_key) self.consolidated_auth = Auth(user=self.user) self.project = ProjectFactory(creator=self.user) self.project.add_addon('osffiles', auth=self.consolidated_auth) self.node_settings = self.project.get_addon('osffiles') self.fid = 'firstfile' self._upload_file(self.fid, 'firstcontent') def _upload_file(self, name, content, **kwargs): url = self.project.api_url + 'osffiles/' res = self.app.post(url, upload_files=[ ('file', name, content), ], auth=self.auth, **kwargs) self.project.reload() return res def test_download_file(self): url = self.project.uploads[0].download_url(self.project) res = self.app.get(url, auth=self.user.auth).maybe_follow() assert_equal(res.body, 'firstcontent') def test_download_file_by_version_with_bad_version_value(self): url = self.project.web_url_for('download_file_by_version', fid=self.fid, vid='bad') res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) assert_in('Invalid version', res.body) def test_download_file_by_version_with_nonexistent_file(self): url = self.project.web_url_for('download_file_by_version', fid='notfound', vid=0) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 404) def test_download_file_by_version_with_bad_version_number(self): url = self.project.web_url_for('download_file_by_version', fid=self.fid, vid=9999) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 404) def test_download_file_by_version_with_negative_version_number(self): url = self.project.web_url_for('download_file_by_version', fid=self.fid, vid=-1) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) def test_upload_file(self): node_addon = self.project.get_addon('osffiles') res = self._upload_file('newfile', 'a' * (node_addon.config.max_file_size)) self.project.reload() assert_equal(self.project.logs[-1].action, 'file_added') assert_equal(res.status_code, 201) assert_true(isinstance(res.json, dict), 'return value is a dict') assert_equal(res.json['name'], 'newfile') assert_in('newfile', self.project.files_current) def test_upload_file_unicode_name(self): node_addon = self.project.get_addon('osffiles') res = self._upload_file('_néwfile', 'a' * (node_addon.config.max_file_size)) self.project.reload() assert_equal(self.project.logs[-1].action, 'file_added') assert_equal(res.status_code, 201) assert_true(isinstance(res.json, dict), 'return value is a dict') assert_equal(res.json['name'], '_newfile') assert_in('_newfile', self.project.files_current) def test_upload_file_too_large(self): node_addon = self.project.get_addon('osffiles') res = self._upload_file( 'newfile', 'a' * (node_addon.config.max_file_size + 1), expect_errors=True, ) self.project.reload() assert_equal(res.status_code, 400) assert_not_in('newfile', self.project.files_current) def test_file_info(self): # Upload a new version of firstfile self._upload_file(self.fid, 'secondcontent') url = self.project.api_url_for('file_info', fid=self.project.uploads[0].filename) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) file_obj = self.project.get_file_object(self.fid, version=1) data = res.json assert_equal(data['file_name'], self.fid) assert_equal(data['registered'], self.project.is_registration) assert_equal(len(data['versions']), 2) assert_equal(data['urls']['files'], self.project.web_url_for('collect_file_trees')) assert_equal(data['urls']['latest']['download'], file_obj.download_url(self.project)) assert_equal(data['urls']['api'], file_obj.api_url(self.project)) version = res.json['versions'][0] assert_equal(version['file_name'], self.fid) assert_equal(version['version_number'], 2) assert_equal(version['modified_date'], file_obj.date_uploaded.strftime('%Y/%m/%d %I:%M %p')) assert_in('downloads', version) assert_equal(version['committer_name'], file_obj.uploader.fullname) assert_equal(version['committer_url'], file_obj.uploader.url) def test_file_info_with_anonymous_link(self): link = PrivateLinkFactory(anonymous=True) link.nodes.append(self.project) link.save() self._upload_file('firstfile', 'secondcontent') url = self.project.api_url_for('file_info', fid=self.project.uploads[0].filename) res = self.app.get(url, {'view_only': link.key}) assert_not_in(self.user.fullname, res.body) assert_not_in(self.user._id, res.body) def test_delete_file(self): url = self.project.api_url_for('delete_file', fid=self.fid) res = self.app.delete(url, auth=self.auth).maybe_follow() assert_equal(res.status_code, 200) self.project.reload() assert_not_in('firstfile', self.project.files_current) def test_delete_file_returns_404_when_file_is_already_deleted(self): self.project.remove_file(Auth(self.project.creator), self.fid) url = self.project.api_url_for('delete_file', fid=self.fid) res = self.app.delete_json(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 404) def test_file_urls(self): url = self.project.api_url + 'osffiles/hgrid/' res = self.app.get(url, auth=self.auth).maybe_follow() assert_equal(len(res.json), 1) for url in ['view', 'download', 'delete']: assert_in(self.project._id, res.json[0]['urls'][url]) def test_file_urls_fork(self): fork = self.project.fork_node(auth=Auth(user=self.user)) url = fork.api_url + 'osffiles/hgrid/' res = self.app.get(url, auth=self.auth).maybe_follow() assert_equal(len(res.json), 1) for url in ['view', 'download', 'delete']: assert_in(fork._id, res.json[0]['urls'][url]) def test_file_urls_registration(self): registration = self.project.register_node(None, Auth(user=self.user), '', '') url = registration.api_url + 'osffiles/hgrid/' res = self.app.get(url, auth=self.auth).maybe_follow() assert_equal(len(res.json), 1) for url in ['view', 'download', 'delete']: assert_in(registration._id, res.json[0]['urls'][url]) def test_view_creates_guid(self): guid_fid = 'unique' guid_content = 'snowflake' self._upload_file(guid_fid, guid_content) node_file = NodeFile.load(self.project.files_current[guid_fid]) guid_count = OsfGuidFile.find().count() # View file for the first time url = node_file.url(self.project) res = self.app.get( url, auth=self.user.auth, ).follow(auth=self.user.auth, ) guid = OsfGuidFile.find_one( Q('node', 'eq', self.project) & Q('name', 'eq', guid_fid)) # GUID count has been incremented by one assert_equal(OsfGuidFile.find().count(), guid_count + 1) # Client has been redirected to GUID assert_equal( res.request.path.strip('/'), guid._id, ) # View file for the second time self.app.get( url, auth=self.user.auth, ).follow(auth=self.user.auth, ) # GUID count has not been incremented assert_equal(OsfGuidFile.find().count(), guid_count + 1) def test_guid_url_returns_404(self): f = NodeFile() f.save() url = '/{}/'.format(f._id) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 404) def test_sees_delete_button_if_can_write(self): url = self.project.uploads[0].url(self.project) res = self.app.get( url, auth=self.user.auth, ).maybe_follow(auth=self.user.auth, ) assert_in('Download', res) assert_in('Delete', res) def test_does_not_see_delete_button_if_cannot_write(self): self.project.is_public = True self.project.save() user2 = AuthUserFactory() url = self.project.uploads[0].url(self.project) res = self.app.get( url, auth=user2.auth, ).maybe_follow(auth=user2.auth, ) assert_in('Download', res) assert_not_in('Delete', res)
class TestGoogleDriveAuthViews(OsfTestCase): def setUp(self): super(TestGoogleDriveAuthViews, self).setUp() self.user = AuthUserFactory() self.user.add_addon('googledrive') self.project = ProjectFactory(creator=self.user) self.project.add_addon('googledrive', Auth(self.user)) self.node_settings = self.project.get_addon('googledrive') self.user_settings = self.user.get_addon('googledrive') oauth_settings = GoogleDriveOAuthSettingsFactory() self.user_settings.oauth_settings = oauth_settings self.node_settings.user_settings = self.user_settings # Log user in self.app.authenticate(*self.user.auth) self.flow = mock.Mock() self.credentials = mock.Mock() # Class variables(self) are usually used to mark mock variables. Can be removed later. @mock.patch('website.addons.googledrive.views.auth.GoogleAuthClient.start') def test_googledrive_oauth_start(self, mock_auth_client_start): url = api_url_for('googledrive_oauth_start_user', Auth(self.user)) authorization_url = 'https://fake.domain/' state = 'secure state' mock_auth_client_start.return_value = (authorization_url, state) res = self.app.post(url) assert_true(res.json['url'], authorization_url) @mock.patch('website.addons.googledrive.views.auth.GoogleAuthClient.userinfo') @mock.patch('website.addons.googledrive.views.auth.GoogleAuthClient.finish') @mock.patch('website.addons.googledrive.views.auth.session') def test_googledrive_oauth_finish(self, mock_session, mock_auth_client_finish, mock_auth_client_userinfo): user_no_addon = AuthUserFactory() nid = self.project._primary_key state = '1234' mock_session.data = { 'googledrive_auth_nid': nid, 'googledrive_auth_state': state, } mock_auth_client_finish.return_value = { 'access_token': '1111', 'refresh_token': '2222', 'expires_at': time.time() + 3600, } mock_auth_client_userinfo.return_value = { 'sub': 'unique id', 'name': 'test-user', } url = api_url_for('googledrive_oauth_finish', user_no_addon.auth, nid=self.project._primary_key, code='1234', state=state) res = self.app.get(url) assert_is_redirect(res) @mock.patch('website.addons.googledrive.views.auth.flash') def test_googledrive_oauth_finish_cancelled(self, mock_flash): user_no_addon = AuthUserFactory() url = api_url_for( 'googledrive_oauth_finish', user_no_addon.auth, nid=self.project._primary_key, code='1234', state='3322', error='User declined!' ) res = self.app.get(url) assert_is_redirect(res) mock_flash.assert_called_once() @mock.patch('website.addons.googledrive.views.auth.GoogleAuthClient.userinfo') @mock.patch('website.addons.googledrive.views.auth.GoogleAuthClient.finish') @mock.patch('website.addons.googledrive.views.auth.session') def test_googledrive_oauth_finish_user_only(self, mock_session, mock_auth_client_finish, mock_auth_client_userinfo): user_no_addon = AuthUserFactory() state = '1234' mock_session.data = { 'googledrive_auth_state': state, } mock_auth_client_finish.return_value = { 'access_token': '1111', 'refresh_token': '2222', 'expires_at': time.time() + 3600, } mock_auth_client_userinfo.return_value = { 'sub': 'unique id', 'name': 'test-user', } url = api_url_for('googledrive_oauth_finish', user_no_addon.auth, code='1234', state=state) res = self.app.get(url) assert_is_redirect(res) @mock.patch('website.addons.googledrive.views.auth.GoogleAuthClient.revoke') def test_googledrive_oauth_delete_user(self, mock_auth_client_revoke): self.user_settings.access_token = 'abc123' self.user_settings.save() assert_true(self.user_settings.has_auth) self.user.save() url = api_url_for('googledrive_oauth_delete_user') self.app.delete(url) self.user_settings.reload() mock_auth_client_revoke.assert_called_once() assert_false(self.user_settings.has_auth) def test_googledrive_deauthorize(self): self.node_settings.folder_id = 'foobar' self.node_settings.folder_path = 'My folder' self.node_settings.save() url = self.project.api_url_for('googledrive_deauthorize') self.app.delete(url) self.project.reload() self.node_settings.reload() assert_false(self.node_settings.has_auth) assert_is(self.node_settings.folder_id, None) assert_is(self.node_settings.folder_path, None) assert_is(self.node_settings.user_settings, None)
class TestClaiming(OsfTestCase): def setUp(self): super(TestClaiming, self).setUp() self.referrer = AuthUserFactory() self.project = ProjectFactory(creator=self.referrer, is_public=True) def test_correct_name_shows_in_contributor_list(self): name1, email = fake.name(), fake.email() UnregUserFactory(fullname=name1, email=email) name2, email = fake.name(), fake.email() # Added with different name self.project.add_unregistered_contributor(fullname=name2, email=email, auth=Auth(self.referrer)) self.project.save() res = self.app.get(self.project.url, auth=self.referrer.auth) # Correct name is shown assert_in(name2, res) assert_not_in(name1, res) def test_user_can_set_password_on_claim_page(self): name, email = fake.name(), fake.email() new_user = self.project.add_unregistered_contributor( email=email, fullname=name, auth=Auth(self.referrer)) self.project.save() claim_url = new_user.get_claim_url(self.project._primary_key) res = self.app.get(claim_url) self.project.reload() assert_in('Set Password', res) form = res.forms['setPasswordForm'] #form['username'] = new_user.username #Removed as long as E-mail can't be updated. form['password'] = '******' form['password2'] = 'killerqueen' res = form.submit().follow() new_user.reload() assert_true(new_user.check_password('killerqueen')) def test_sees_is_redirected_if_user_already_logged_in(self): name, email = fake.name(), fake.email() new_user = self.project.add_unregistered_contributor( email=email, fullname=name, auth=Auth(self.referrer)) self.project.save() existing = AuthUserFactory() claim_url = new_user.get_claim_url(self.project._primary_key) # a user is already logged in res = self.app.get(claim_url, auth=existing.auth, expect_errors=True) assert_equal(res.status_code, 302) def test_unregistered_users_names_are_project_specific(self): name1, name2, email = fake.name(), fake.name(), fake.email() project2 = ProjectFactory(creator=self.referrer) # different projects use different names for the same unreg contributor self.project.add_unregistered_contributor(email=email, fullname=name1, auth=Auth(self.referrer)) self.project.save() project2.add_unregistered_contributor(email=email, fullname=name2, auth=Auth(self.referrer)) project2.save() self.app.authenticate(*self.referrer.auth) # Each project displays a different name in the contributor list res = self.app.get(self.project.url) assert_in(name1, res) res2 = self.app.get(project2.url) assert_in(name2, res2) @unittest.skip("as long as E-mails cannot be changed") def test_cannot_set_email_to_a_user_that_already_exists(self): reg_user = UserFactory() name, email = fake.name(), fake.email() new_user = self.project.add_unregistered_contributor( email=email, fullname=name, auth=Auth(self.referrer)) self.project.save() # Goes to claim url and successfully claims account claim_url = new_user.get_claim_url(self.project._primary_key) res = self.app.get(claim_url) self.project.reload() assert_in('Set Password', res) form = res.forms['setPasswordForm'] # Fills out an email that is the username of another user form['username'] = reg_user.username form['password'] = '******' form['password2'] = 'killerqueen' res = form.submit().maybe_follow(expect_errors=True) assert_in(language.ALREADY_REGISTERED.format(email=reg_user.username), res) def test_correct_display_name_is_shown_at_claim_page(self): original_name = fake.name() unreg = UnregUserFactory(fullname=original_name) different_name = fake.name() new_user = self.project.add_unregistered_contributor( email=unreg.username, fullname=different_name, auth=Auth(self.referrer), ) self.project.save() claim_url = new_user.get_claim_url(self.project._primary_key) res = self.app.get(claim_url) # Correct name (different_name) should be on page assert_in(different_name, res)
class TestWikiViews(OsfTestCase): def setUp(self): super(TestWikiViews, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(is_public=True, creator=self.user) self.consolidate_auth = Auth(user=self.project.creator) def test_wiki_url_get_returns_200(self): url = self.project.web_url_for('project_wiki_page', wname='home') res = self.app.get(url) assert_equal(res.status_code, 200) def test_wiki_url_for_pointer_returns_200(self): # TODO: explain how this tests a pointer project = ProjectFactory(is_public=True) self.project.add_pointer(project, Auth(self.project.creator), save=True) url = self.project.web_url_for('project_wiki_page', wname='home') res = self.app.get(url) assert_equal(res.status_code, 200) def test_wiki_content_returns_200(self): node = ProjectFactory(is_public=True) url = node.api_url_for('wiki_page_content', wname='somerandomid') res = self.app.get(url) assert_equal(res.status_code, 200) def test_wiki_url_for_component_returns_200(self): component = NodeFactory(project=self.project, is_public=True) url = component.web_url_for('project_wiki_page', wname='home') res = self.app.get(url) assert_equal(res.status_code, 200) def test_serialize_wiki_toc(self): project = ProjectFactory() auth = Auth(project.creator) NodeFactory(project=project, creator=project.creator) no_wiki = NodeFactory(project=project, creator=project.creator) project.save() serialized = _serialize_wiki_toc(project, auth=auth) assert_equal(len(serialized), 2) no_wiki.delete_addon('wiki', auth=auth) serialized = _serialize_wiki_toc(project, auth=auth) assert_equal(len(serialized), 1) def test_get_wiki_url_pointer_component(self): """Regression test for issues https://github.com/CenterForOpenScience/osf/issues/363 and https://github.com/CenterForOpenScience/openscienceframework.org/issues/574 """ user = UserFactory() pointed_node = NodeFactory(creator=user) project = ProjectFactory(creator=user) auth = Auth(user=user) project.add_pointer(pointed_node, auth=auth, save=True) serialized = _serialize_wiki_toc(project, auth) assert_equal( serialized[0]['url'], pointed_node.web_url_for('project_wiki_page', wname='home', _guid=True)) def test_project_wiki_edit_post(self): self.project.update_node_wiki('home', content='old content', auth=Auth(self.project.creator)) url = self.project.web_url_for('project_wiki_edit_post', wname='home') res = self.app.post(url, { 'content': 'new content' }, auth=self.user.auth).follow() assert_equal(res.status_code, 200) self.project.reload() # page was updated with new content new_wiki = self.project.get_wiki_page('home') assert_equal(new_wiki.content, 'new content') def test_project_wiki_edit_post_with_new_wname_and_no_content(self): page_name = fake.catch_phrase() old_wiki_page_count = NodeWikiPage.find().count() url = self.project.web_url_for('project_wiki_edit_post', wname=page_name) # User submits to edit form with no content res = self.app.post(url, {'content': ''}, auth=self.user.auth).follow() assert_equal(res.status_code, 200) new_wiki_page_count = NodeWikiPage.find().count() # A new wiki page was created in the db assert_equal(new_wiki_page_count, old_wiki_page_count + 1) # Node now has the new wiki page associated with it self.project.reload() new_page = self.project.get_wiki_page(page_name) assert_is_not_none(new_page) def test_project_wiki_edit_post_with_new_wname_and_content(self): page_name, page_content = fake.catch_phrase(), fake.bs() old_wiki_page_count = NodeWikiPage.find().count() url = self.project.web_url_for('project_wiki_edit_post', wname=page_name) # User submits to edit form with no content res = self.app.post(url, { 'content': page_content }, auth=self.user.auth).follow() assert_equal(res.status_code, 200) new_wiki_page_count = NodeWikiPage.find().count() # A new wiki page was created in the db assert_equal(new_wiki_page_count, old_wiki_page_count + 1) # Node now has the new wiki page associated with it self.project.reload() new_page = self.project.get_wiki_page(page_name) assert_is_not_none(new_page) # content was set assert_equal(new_page.content, page_content) def test_project_wiki_edit_post_with_non_ascii_title(self): # regression test for https://github.com/CenterForOpenScience/openscienceframework.org/issues/1040 # wname doesn't exist in the db, so it will be created new_wname = u'øˆ∆´ƒøßå√ß' url = self.project.web_url_for('project_wiki_edit_post', wname=new_wname) res = self.app.post(url, { 'content': 'new content' }, auth=self.user.auth).follow() assert_equal(res.status_code, 200) self.project.reload() wiki = self.project.get_wiki_page(new_wname) assert_equal(wiki.page_name, new_wname) # updating content should return correct url as well. res = self.app.post(url, { 'content': 'updated content' }, auth=self.user.auth).follow() assert_equal(res.status_code, 200) def test_project_wiki_edit_post_with_special_characters(self): new_wname = 'title: ' + SPECIAL_CHARACTERS_ALLOWED new_wiki_content = 'content: ' + SPECIAL_CHARACTERS_ALL url = self.project.web_url_for('project_wiki_edit_post', wname=new_wname) res = self.app.post(url, { 'content': new_wiki_content }, auth=self.user.auth).follow() assert_equal(res.status_code, 200) self.project.reload() wiki = self.project.get_wiki_page(new_wname) assert_equal(wiki.page_name, new_wname) assert_equal(wiki.content, new_wiki_content) assert_equal(res.status_code, 200) def test_wiki_edit_get_home(self): url = self.project.web_url_for('project_wiki_edit', wname='home') res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) def test_project_wiki_compare_returns_200(self): self.project.update_node_wiki('home', 'updated content', Auth(self.user)) self.project.save() url = self.project.web_url_for('project_wiki_compare', wname='home', wver=1) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) def test_project_wiki_compare_with_invalid_wname(self): url = self.project.web_url_for('project_wiki_compare', wname='this-doesnt-exist', wver=1) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 404) def test_wiki_page_creation_strips_whitespace(self): # Regression test for: # https://github.com/CenterForOpenScience/openscienceframework.org/issues/1080 # wname has a trailing space url = self.project.web_url_for('project_wiki_edit', wname='cupcake ') res = self.app.post(url, { 'content': 'blah' }, auth=self.user.auth).follow() assert_equal(res.status_code, 200) self.project.reload() wiki = self.project.get_wiki_page('cupcake') assert_is_not_none(wiki) def test_wiki_validate_name(self): url = self.project.api_url_for('project_wiki_validate_name', wname='Capslock') res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) def test_wiki_validate_name_cannot_create_home(self): url = self.project.api_url_for('project_wiki_validate_name', wname='home') res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 409) def test_project_wiki_validate_name_mixed_casing(self): url = self.project.api_url_for('project_wiki_validate_name', wname='CaPsLoCk') res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_not_in('capslock', self.project.wiki_pages_current) self.project.update_node_wiki('CaPsLoCk', 'hello', self.consolidate_auth) assert_in('capslock', self.project.wiki_pages_current) def test_project_wiki_validate_name_diplay_correct_capitalization(self): url = self.project.api_url_for('project_wiki_validate_name', wname='CaPsLoCk') res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_in('CaPsLoCk', res) def test_project_wiki_validate_name_conflict_different_casing(self): url = self.project.api_url_for('project_wiki_validate_name', wname='CAPSLOCK') res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) self.project.update_node_wiki('CaPsLoCk', 'hello', self.consolidate_auth) assert_in('capslock', self.project.wiki_pages_current) url = self.project.api_url_for('project_wiki_validate_name', wname='capslock') res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 409) def test_project_dashboard_shows_no_wiki_content_text(self): # Regression test for: # https://github.com/CenterForOpenScience/openscienceframework.org/issues/1104 project = ProjectFactory(creator=self.user) url = project.web_url_for('view_project') res = self.app.get(url, auth=self.user.auth) assert_in('No wiki content', res) def test_project_dashboard_wiki_wname_get_shows_non_ascii_characters(self): # Regression test for: # https://github.com/CenterForOpenScience/openscienceframework.org/issues/1104 text = u'你好' self.project.update_node_wiki('home', text, Auth(self.user)) # can view wiki preview from project dashboard url = self.project.web_url_for('view_project') res = self.app.get(url, auth=self.user.auth) assert_in(text, res) def test_project_wiki_home_api_route(self): url = self.project.api_url_for('project_wiki_home') res = self.app.get(url, auth=self.user.auth) assert_equals(res.status_code, 302) # TODO: should this route exist? it redirects you to the web_url_for, not api_url_for. # page_url = self.project.api_url_for('project_wiki_page', wname='home') # assert_in(page_url, res.location) def test_project_wiki_home_web_route(self): page_url = self.project.web_url_for('project_wiki_page', wname='home', _guid=True) url = self.project.web_url_for('project_wiki_home') res = self.app.get(url, auth=self.user.auth) assert_equals(res.status_code, 302) assert_in(page_url, res.location) def test_wiki_id_url_get_returns_302_and_resolves(self): name = 'page by id' self.project.update_node_wiki(name, 'some content', Auth(self.project.creator)) page = self.project.get_wiki_page(name) page_url = self.project.web_url_for('project_wiki_page', wname=page.page_name, _guid=True) url = self.project.web_url_for('project_wiki_id_page', wid=page._primary_key, _guid=True) res = self.app.get(url) assert_equal(res.status_code, 302) assert_in(page_url, res.location) res = res.follow() assert_equal(res.status_code, 200) assert_in(page_url, res.request.url) def test_wiki_id_url_get_returns_404(self): url = self.project.web_url_for('project_wiki_id_page', wid='12345', _guid=True) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 404) def test_home_is_capitalized_in_web_view(self): url = self.project.web_url_for('project_wiki_home', wid='home', _guid=True) res = self.app.get(url, auth=self.user.auth).follow(auth=self.user.auth) page_name_elem = res.html.find('span', {'id': 'pageName'}) assert_in('Home', page_name_elem.text)
class TestNodeTags(ApiTestCase): def setUp(self): super(TestNodeTags, self).setUp() self.user = AuthUserFactory() self.admin = AuthUserFactory() self.user_two = AuthUserFactory() self.read_only_contributor = AuthUserFactory() self.public_project = ProjectFactory(title="Project One", is_public=True, creator=self.user) self.public_project.add_contributor(self.user, permissions=permissions.DEFAULT_CONTRIBUTOR_PERMISSIONS, save=True) self.private_project = ProjectFactory(title="Project Two", is_public=False, creator=self.user) self.private_project.add_contributor(self.user, permissions=permissions.DEFAULT_CONTRIBUTOR_PERMISSIONS, save=True) self.private_project.add_contributor(self.admin, permissions=permissions.CREATOR_PERMISSIONS, save=True) self.public_url = '/{}nodes/{}/'.format(API_BASE, self.public_project._id) self.private_url = '/{}nodes/{}/'.format(API_BASE, self.private_project._id) self.one_new_tag_json = { 'data': { 'id': self.public_project._id, 'type': 'nodes', 'attributes': { 'tags': ['new-tag'] } } } self.private_payload = { 'data': { 'id': self.private_project._id, 'type': 'nodes', 'attributes': { 'tags': ['new-tag'] } } } def test_public_project_starts_with_no_tags(self): res = self.app.get(self.public_url) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']['attributes']['tags']), 0) @assert_logs(NodeLog.TAG_ADDED, 'public_project') def test_contributor_can_add_tag_to_public_project(self): res = self.app.patch_json_api(self.public_url, self.one_new_tag_json, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 200) # Ensure data is correct from the PATCH response assert_equal(len(res.json['data']['attributes']['tags']), 1) assert_equal(res.json['data']['attributes']['tags'][0], 'new-tag') # Ensure data is correct in the database self.public_project.reload() assert_equal(len(self.public_project.tags), 1) assert_equal(self.public_project.tags[0]._id, 'new-tag') # Ensure data is correct when GETting the resource again reload_res = self.app.get(self.public_url) assert_equal(len(reload_res.json['data']['attributes']['tags']), 1) assert_equal(reload_res.json['data']['attributes']['tags'][0], 'new-tag') @assert_logs(NodeLog.TAG_ADDED, 'private_project') def test_contributor_can_add_tag_to_private_project(self): res = self.app.patch_json_api(self.private_url, self.private_payload, auth=self.user.auth) assert_equal(res.status_code, 200) # Ensure data is correct from the PATCH response assert_equal(len(res.json['data']['attributes']['tags']), 1) assert_equal(res.json['data']['attributes']['tags'][0], 'new-tag') # Ensure data is correct in the database self.private_project.reload() assert_equal(len(self.private_project.tags), 1) assert_equal(self.private_project.tags[0]._id, 'new-tag') # Ensure data is correct when GETting the resource again reload_res = self.app.get(self.private_url, auth=self.user.auth) assert_equal(len(reload_res.json['data']['attributes']['tags']), 1) assert_equal(reload_res.json['data']['attributes']['tags'][0], 'new-tag') def test_partial_update_project_does_not_clear_tags(self): res = self.app.patch_json_api(self.private_url, self.private_payload, auth=self.admin.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']['attributes']['tags']), 1) new_payload = { 'data': { 'id': self.private_project._id, 'type': 'nodes', 'attributes': { 'public': True } } } res = self.app.patch_json_api(self.private_url, new_payload, auth=self.admin.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']['attributes']['tags']), 1) new_payload['data']['attributes']['public'] = False res = self.app.patch_json_api(self.private_url, new_payload, auth=self.admin.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']['attributes']['tags']), 1) def test_non_authenticated_user_cannot_add_tag_to_public_project(self): res = self.app.patch_json_api(self.public_url, self.one_new_tag_json, expect_errors=True, auth=None) assert_equal(res.status_code, 401) def test_non_authenticated_user_cannot_add_tag_to_private_project(self): res = self.app.patch_json_api(self.private_url, self.private_payload, expect_errors=True, auth=None) assert_equal(res.status_code, 401) def test_non_contributor_cannot_add_tag_to_public_project(self): res = self.app.patch_json_api(self.public_url, self.one_new_tag_json, expect_errors=True, auth=self.user_two.auth) assert_equal(res.status_code, 403) def test_non_contributor_cannot_add_tag_to_private_project(self): res = self.app.patch_json_api(self.private_url, self.private_payload, expect_errors=True, auth=self.user_two.auth) assert_equal(res.status_code, 403) def test_read_only_contributor_cannot_add_tag_to_public_project(self): res = self.app.patch_json_api(self.public_url, self.one_new_tag_json, expect_errors=True, auth=self.read_only_contributor.auth) assert_equal(res.status_code, 403) def test_read_only_contributor_cannot_add_tag_to_private_project(self): res = self.app.patch_json_api(self.private_url, self.private_payload, expect_errors=True, auth=self.read_only_contributor.auth) assert_equal(res.status_code, 403)\ @assert_logs(NodeLog.TAG_ADDED, 'private_project', -4) @assert_logs(NodeLog.TAG_ADDED, 'private_project', -3) @assert_logs(NodeLog.TAG_REMOVED, 'private_project', -2) @assert_logs(NodeLog.TAG_REMOVED, 'private_project') def test_tags_add_and_remove_properly(self): res = self.app.patch_json_api(self.private_url, self.private_payload, auth=self.user.auth) assert_equal(res.status_code, 200) # Ensure adding tag data is correct from the PATCH response assert_equal(len(res.json['data']['attributes']['tags']), 1) assert_equal(res.json['data']['attributes']['tags'][0], 'new-tag') # Ensure removing and adding tag data is correct from the PATCH response res = self.app.patch_json_api(self.private_url, {'data': {'id': self.private_project._id, 'type':'nodes', 'attributes': {'tags':['newer-tag']}}}, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']['attributes']['tags']), 1) assert_equal(res.json['data']['attributes']['tags'][0], 'newer-tag') # Ensure removing tag data is correct from the PATCH response res = self.app.patch_json_api(self.private_url, {'data': {'id': self.private_project._id, 'type':'nodes', 'attributes': {'tags': []}}}, auth=self.user.auth) assert_equal(res.status_code, 200) assert_equal(len(res.json['data']['attributes']['tags']), 0) def test_tags_post_object_instead_of_list(self): url = '/{}nodes/'.format(API_BASE) payload = {'data': { 'type': 'nodes', 'attributes': { 'title': 'new title', 'category': 'project', 'tags': {'foo': 'bar'} } }} res = self.app.post_json_api(url, payload, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) assert_equal(res.json['errors'][0]['detail'], 'Expected a list of items but got type "dict".') def test_tags_patch_object_instead_of_list(self): self.one_new_tag_json['data']['attributes']['tags'] = {'foo': 'bar'} res = self.app.patch_json_api(self.public_url, self.one_new_tag_json, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) assert_equal(res.json['errors'][0]['detail'], 'Expected a list of items but got type "dict".')