class TestExplorePublicActivity(OsfTestCase): def setUp(self): super(TestExplorePublicActivity, self).setUp() self.project = ProjectFactory(is_public=True) self.registration = RegistrationFactory(project=self.project) self.private_project = ProjectFactory(title="Test private project") self.popular_project = ProjectFactory(is_public=True) self.popular_registration = RegistrationFactory(project=self.project) # Add project to new and noteworthy projects self.new_and_noteworthy_links_node = ProjectFactory() self.new_and_noteworthy_links_node._id = settings.NEW_AND_NOTEWORTHY_LINKS_NODE self.new_and_noteworthy_links_node.add_pointer(self.project, auth=Auth(self.new_and_noteworthy_links_node.creator), save=True) # Set up popular projects and registrations self.popular_links_node = ProjectFactory() self.popular_links_node._id = settings.POPULAR_LINKS_NODE self.popular_links_node.add_pointer(self.popular_project, auth=Auth(self.popular_links_node.creator), save=True) self.popular_links_registrations = ProjectFactory() self.popular_links_registrations._id = settings.POPULAR_LINKS_REGISTRATIONS self.popular_links_registrations.add_pointer(self.popular_registration, auth=Auth(self.popular_links_registrations.creator), save=True) def tearDown(self): super(TestExplorePublicActivity, self).tearDown() Node.remove() def test_explore_page_loads_when_settings_not_configured(self): old_settings_values = settings.POPULAR_LINKS_NODE, settings.NEW_AND_NOTEWORTHY_LINKS_NODE, settings.POPULAR_LINKS_REGISTRATIONS settings.POPULAR_LINKS_NODE = 'notanode' settings.NEW_AND_NOTEWORTHY_LINKS_NODE = 'alsototallywrong' settings.POPULAR_LINKS_REGISTRATIONS = 'nopenope' url = self.project.web_url_for('activity') res = self.app.get(url) assert_equal(res.status_code, 200) settings.POPULAR_LINKS_NODE, settings.NEW_AND_NOTEWORTHY_LINKS_NODE, settings.POPULAR_LINKS_REGISTRATIONS = old_settings_values def test_new_and_noteworthy_and_popular_nodes_show_in_explore_activity(self): url = self.project.web_url_for('activity') res = self.app.get(url) # New and Noteworthy assert_in(str(self.project.title), res) assert_in(str(self.project.date_created.date()), res) assert_in(str(self.registration.title), res) assert_in(str(self.registration.registered_date.date()), res) assert_not_in(str(self.private_project.title), res) # Popular Projects and Registrations assert_in(str(self.popular_project.title), res) assert_in(str(self.popular_project.date_created.date()), res) assert_in(str(self.popular_registration.title), res) assert_in(str(self.popular_registration.registered_date.date()), res)
class TestWikiCompare(OsfTestCase): def setUp(self): super(TestWikiCompare, 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.wiki = self.project.get_wiki_page('home') def test_compare_wiki_page_valid(self): self.project.update_node_wiki('home', 'Hello World', self.consolidate_auth) url_v1_to_v2 = self.project.web_url_for('project_wiki_compare', wname='home', wver=1) res = self.app.get(url_v1_to_v2) comparison_v1_to_v2 = \ '<span style="background:#D16587; font-size:1.5em;">h</span>' \ '<span style="background:#4AA02C; font-size:1.5em; ">H</span>ello ' \ '<span style="background:#D16587; font-size:1.5em;">w</span>' \ '<span style="background:#4AA02C; font-size:1.5em; ">W</span>orld' assert_equal(res.status_int, http.OK) assert_true(comparison_v1_to_v2 in res.body) url_v2_to_v2 = self.project.web_url_for('project_wiki_compare', wname='home', wver=2) res = self.app.get(url_v2_to_v2) comparison_v2_to_v2 = 'Hello World' assert_equal(res.status_int, http.OK) assert_true(comparison_v2_to_v2 in res.body) def test_compare_wiki_page_sanitized(self): content_js_script = '<script>alert(''a problem'');</script>' self.project.update_node_wiki('home', content_js_script, self.consolidate_auth) url_v1_to_v2 = self.project.web_url_for('project_wiki_compare', wname='home', wver=1) res = self.app.get(url_v1_to_v2) comparison_v1_to_v2 = \ '<span style="background:#D16587; font-size:1.5em;">h</span>' \ '<span style="background:#4AA02C; font-size:1.5em; "><script>al</span>e' \ '<span style="background:#4AA02C; font-size:1.5em; ">rt(''a prob</span>l' \ '<span style="background:#D16587; font-size:1.5em;">lo wo</span>' \ '<span style="background:#4AA02C; font-size:1.5em; ">em'');</span>r' \ '<span style="background:#D16587; font-size:1.5em;">ld</span>' \ '<span style="background:#4AA02C; font-size:1.5em; ">ipt></span>' assert_equal(res.status_int, http.OK) assert_true(content_js_script not in res.body) assert_true(comparison_v1_to_v2 in res.body) url_v2_to_v2 = self.project.web_url_for('project_wiki_compare', wname='home', wver=2) res = self.app.get(url_v2_to_v2) comparison_v2_to_v2 = '<script>alert(''a problem'');</script>' assert_equal(res.status_int, http.OK) assert_true(content_js_script not in res.body) assert_true(comparison_v2_to_v2 in res.body)
def test_build_dropbox_urls_file(self): node = ProjectFactory() fake_metadata = mock_responses['metadata_single'] result = utils.build_dropbox_urls(fake_metadata, node) path = utils.clean_path(fake_metadata['path']) assert_equal(result['download'], node.web_url_for('dropbox_download', path=path)) assert_equal(result['view'], node.web_url_for('dropbox_view_file', path=path)) assert_equal(result['delete'], node.api_url_for('dropbox_delete_file', path=path))
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_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_build_dropbox_urls_file(self): node = ProjectFactory() fake_metadata = mock_responses['metadata_single'] result = utils.build_dropbox_urls(fake_metadata, node) path = utils.clean_path(fake_metadata['path']) assert_equal( result['download'], node.web_url_for('dropbox_download', path=path) ) assert_equal( result['view'], node.web_url_for('dropbox_view_file', path=path) ) assert_equal( result['delete'], node.api_url_for('dropbox_delete_file', path=path) )
class RegistrationsTestBase(OsfTestCase): def setUp(self): super(RegistrationsTestBase, self).setUp() self.user = AuthUserFactory() self.auth = Auth(self.user) self.node = ProjectFactory(creator=self.user) self.non_admin = AuthUserFactory() self.node.add_contributor( self.non_admin, permissions.DEFAULT_CONTRIBUTOR_PERMISSIONS, auth=self.auth, save=True ) self.non_contrib = AuthUserFactory() MetaSchema.remove() ensure_schemas() self.meta_schema = MetaSchema.find_one( Q('name', 'eq', 'Open-Ended Registration') & Q('schema_version', 'eq', 2) ) self.draft = DraftRegistrationFactory( initiator=self.user, branched_from=self.node, registration_schema=self.meta_schema, registration_metadata={ 'summary': {'value': 'Some airy'} } ) current_month = dt.datetime.now().strftime("%B") current_year = dt.datetime.now().strftime("%Y") valid_date = dt.datetime.now() + dt.timedelta(days=180) self.embargo_payload = { u'embargoEndDate': unicode(valid_date.strftime('%a, %d, %B %Y %H:%M:%S')) + u' GMT', u'registrationChoice': 'embargo' } self.invalid_embargo_date_payload = { u'embargoEndDate': u"Thu, 01 {month} {year} 05:00:00 GMT".format( month=current_month, year=str(int(current_year) - 1) ), u'registrationChoice': 'embargo' } self.immediate_payload = { 'registrationChoice': 'immediate' } self.invalid_payload = { 'registrationChoice': 'foobar' } def draft_url(self, view_name): return self.node.web_url_for(view_name, draft_id=self.draft._id) def draft_api_url(self, view_name): return self.node.api_url_for(view_name, draft_id=self.draft._id)
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 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 TestViewHelpers(OsfTestCase): def setUp(self): super(TestViewHelpers, self).setUp() self.project = ProjectFactory() self.wname = 'New page' self.project.update_node_wiki(self.wname, 'some content', Auth(self.project.creator)) def test_get_wiki_web_urls(self): urls = _get_wiki_web_urls(self.project, self.wname) assert_equal(urls['compare'], self.project.web_url_for('project_wiki_compare', wname=self.wname, wver=1, _guid=True)) assert_equal(urls['edit'], self.project.web_url_for('project_wiki_edit', wname=self.wname, _guid=True)) assert_equal(urls['home'], self.project.web_url_for('project_wiki_home', _guid=True)) assert_equal(urls['page'], self.project.web_url_for('project_wiki_page', wname=self.wname, _guid=True)) def test_get_wiki_api_urls(self): urls = _get_wiki_api_urls(self.project, self.wname) assert_equal(urls['delete'], self.project.api_url_for('project_wiki_delete', wname=self.wname)) assert_equal(urls['rename'], self.project.api_url_for('project_wiki_rename', wname=self.wname))
def test_links(self): user = AuthUserFactory() project = ProjectFactory(creator=user) wiki = NodeWikiFactory( content='[[wiki2]]', user=user, node=project, ) assert_in( project.web_url_for('project_wiki_page', wname='wiki2'), wiki.html(project), )
class TestViewHelpers(OsfTestCase): def setUp(self): super(TestViewHelpers, self).setUp() self.project = ProjectFactory() self.wname = 'New page' self.project.update_node_wiki(self.wname, 'some content', Auth(self.project.creator)) def test_get_wiki_web_urls(self): urls = _get_wiki_web_urls(self.project, self.wname) assert_equal(urls['base'], self.project.web_url_for('project_wiki_home', _guid=True)) assert_equal(urls['edit'], self.project.web_url_for('project_wiki_view', wname=self.wname, _guid=True)) assert_equal(urls['home'], self.project.web_url_for('project_wiki_home', _guid=True)) assert_equal(urls['page'], self.project.web_url_for('project_wiki_view', wname=self.wname, _guid=True)) def test_get_wiki_api_urls(self): urls = _get_wiki_api_urls(self.project, self.wname) assert_equal(urls['base'], self.project.api_url_for('project_wiki_home')) assert_equal(urls['delete'], self.project.api_url_for('project_wiki_delete', wname=self.wname)) assert_equal(urls['rename'], self.project.api_url_for('project_wiki_rename', wname=self.wname)) assert_equal(urls['content'], self.project.api_url_for('wiki_page_content', wname=self.wname))
def test_links(self): user = AuthUserFactory() project = ProjectFactory(creator=user) wiki = NodeWikiFactory( content='[[wiki2]]', user=user, node=project, ) assert_in( project.web_url_for('project_wiki_page', wname='wiki2'), wiki.html(project), )
class TestPrivateLinkView(OsfTestCase): def setUp(self): super(TestPrivateLinkView, self).setUp() self.user = AuthUserFactory() # Is NOT a contributor self.project = ProjectFactory(is_public=False) self.link = PrivateLinkFactory(anonymous=True) self.link.nodes.append(self.project) self.link.save() self.project_url = self.project.web_url_for('view_project') def test_anonymous_link_hide_contributor(self): res = self.app.get(self.project_url, {'view_only': self.link.key}) assert_in("Anonymous Contributors", res.body) assert_not_in(self.user.fullname, res) def test_anonymous_link_hides_citations(self): res = self.app.get(self.project_url, {'view_only': self.link.key}) assert_not_in('Citation:', res) def test_no_warning_for_read_only_user_with_valid_link(self): link2 = PrivateLinkFactory(anonymous=False) link2.nodes.append(self.project) link2.save() self.project.add_contributor( self.user, permissions=['read'], save=True, ) res = self.app.get(self.project_url, {'view_only': link2.key}, auth=self.user.auth) assert_not_in( "is being viewed through a private, view-only link. " "Anyone with the link can view this project. Keep " "the link safe.", res.body ) def test_no_warning_for_read_only_user_with_invalid_link(self): self.project.add_contributor( self.user, permissions=['read'], save=True, ) res = self.app.get(self.project_url, {'view_only': "not_valid"}, auth=self.user.auth) assert_not_in( "is being viewed through a private, view-only link. " "Anyone with the link can view this project. Keep " "the link safe.", res.body )
class TestPrivateLinkView(OsfTestCase): def setUp(self): super(TestPrivateLinkView, self).setUp() self.user = AuthUserFactory() # Is NOT a contributor self.project = ProjectFactory(is_public=False) self.link = PrivateLinkFactory(anonymous=True) self.link.nodes.append(self.project) self.link.save() self.project_url = self.project.web_url_for('view_project') def test_anonymous_link_hide_contributor(self): res = self.app.get(self.project_url, {'view_only': self.link.key}) assert_in("Anonymous Contributors", res.body) assert_not_in(self.user.fullname, res) def test_anonymous_link_hides_citations(self): res = self.app.get(self.project_url, {'view_only': self.link.key}) assert_not_in('Citation:', res) def test_no_warning_for_read_only_user_with_valid_link(self): link2 = PrivateLinkFactory(anonymous=False) link2.nodes.append(self.project) link2.save() self.project.add_contributor( self.user, permissions=['read'], save=True, ) res = self.app.get(self.project_url, {'view_only': link2.key}, auth=self.user.auth) assert_not_in( "is being viewed through a private, view-only link. " "Anyone with the link can view this project. Keep " "the link safe.", res.body ) def test_no_warning_for_read_only_user_with_invalid_link(self): self.project.add_contributor( self.user, permissions=['read'], save=True, ) res = self.app.get(self.project_url, {'view_only': "not_valid"}, auth=self.user.auth) assert_not_in( "is being viewed through a private, view-only link. " "Anyone with the link can view this project. Keep " "the link safe.", res.body )
class TestComponents(OsfTestCase): def setUp(self): super(TestComponents, self).setUp() self.user = AuthUserFactory() self.consolidate_auth = Auth(user=self.user) self.project = ProjectFactory(creator=self.user) self.project.add_contributor(contributor=self.user, auth=self.consolidate_auth) # A non-project componenet self.component = NodeFactory(category="hypothesis", creator=self.user, parent=self.project) self.component.save() self.component.set_privacy("public", self.consolidate_auth) self.component.set_privacy("private", self.consolidate_auth) self.project.save() self.project_url = self.project.web_url_for("view_project") def test_can_create_component_from_a_project(self): res = self.app.get(self.project.url, auth=self.user.auth).maybe_follow() assert_in("Add Component", res) def test_can_create_component_from_a_component(self): res = self.app.get(self.component.url, auth=self.user.auth).maybe_follow() assert_in("Add Component", res) def test_sees_parent(self): res = self.app.get(self.component.url, auth=self.user.auth).maybe_follow() parent_title = res.html.find_all("h2", class_="node-parent-title") assert_equal(len(parent_title), 1) assert_in(self.project.title, parent_title[0].text) # Bs4 will handle unescaping HTML here def test_delete_project(self): res = self.app.get(self.component.url + "settings/", auth=self.user.auth).maybe_follow() assert_in("Delete {0}".format(self.component.project_or_component), res) def test_cant_delete_project_if_not_admin(self): non_admin = AuthUserFactory() self.component.add_contributor(non_admin, permissions=["read", "write"], auth=self.consolidate_auth, save=True) res = self.app.get(self.component.url + "settings/", auth=non_admin.auth).maybe_follow() assert_not_in("Delete {0}".format(self.component.project_or_component), res) def test_can_configure_comments_if_admin(self): res = self.app.get(self.component.url + "settings/", auth=self.user.auth).maybe_follow() assert_in("Configure Commenting", res) def test_cant_configure_comments_if_not_admin(self): non_admin = AuthUserFactory() self.component.add_contributor(non_admin, permissions=["read", "write"], auth=self.consolidate_auth, save=True) res = self.app.get(self.component.url + "settings/", auth=non_admin.auth).maybe_follow() assert_not_in("Configure commenting", res) def test_components_should_have_component_list(self): res = self.app.get(self.component.url, auth=self.user.auth) assert_in("Components", res)
class TestExplorePublicActivity(OsfTestCase): def setUp(self): super(TestExplorePublicActivity, self).setUp() self.project = ProjectFactory(is_public=True) self.registration = RegistrationFactory(project=self.project) self.private_project = ProjectFactory(title="Test private project") def test_newest_public_project_and_registrations_show_in_explore_activity(self): url = self.project.web_url_for("activity") res = self.app.get(url) assert_in(str(self.project.title), res) assert_in(str(self.project.date_created.date()), res) assert_in(str(self.registration.title), res) assert_in(str(self.registration.registered_date.date()), res) assert_not_in(str(self.private_project.title), res)
class TestExplorePublicActivity(OsfTestCase): def setUp(self): super(TestExplorePublicActivity, self).setUp() self.project = ProjectFactory(is_public=True) self.registration = RegistrationFactory(project=self.project) self.private_project = ProjectFactory(title="Test private project") # Add project to new and noteworthy projects self.new_and_noteworthy_links_node = ProjectFactory() self.new_and_noteworthy_links_node._id = settings.NEW_AND_NOTEWORTHY_LINKS_NODE self.new_and_noteworthy_links_node.add_pointer( self.project, auth=Auth(self.new_and_noteworthy_links_node.creator), save=True) @mock.patch('website.discovery.views.KeenClient') def test_new_and_noteworthy_and_registrations_show_in_explore_activity( self, mock_client): mock_client.count.return_value = { 'result': [{ 'result': 5, 'node.id': self.project._id }, { 'result': 5, 'node.id': self.registration._id }] } mock_client.count_unique.return_value = { 'result': [{ 'result': 2, 'node.id': self.project._id }, { 'result': 2, 'node.id': self.registration._id }] } url = self.project.web_url_for('activity') res = self.app.get(url) assert_in(str(self.project.title), res) assert_in(str(self.project.date_created.date()), res) assert_in(str(self.registration.title), res) assert_in(str(self.registration.registered_date.date()), res) assert_not_in(str(self.private_project.title), res)
class TestExplorePublicActivity(OsfTestCase): def setUp(self): super(TestExplorePublicActivity, self).setUp() self.project = ProjectFactory(is_public=True) self.registration = RegistrationFactory(project=self.project) self.private_project = ProjectFactory(title="Test private project") def test_newest_public_project_and_registrations_show_in_explore_activity( self): url = self.project.web_url_for('activity') res = self.app.get(url) assert_in(str(self.project.title), res) assert_in(str(self.project.date_created.date()), res) assert_in(str(self.registration.title), res) assert_in(str(self.registration.registered_date.date()), res) assert_not_in(str(self.private_project.title), res)
class TestExplorePublicActivity(OsfTestCase): def setUp(self): super(TestExplorePublicActivity, self).setUp() self.project = ProjectFactory(is_public=True) self.registration = RegistrationFactory(project=self.project) self.private_project = ProjectFactory(title="Test private project") @mock.patch('website.discovery.views.KeenClient') def test_newest_public_project_and_registrations_show_in_explore_activity(self, mock_client): mock_client.count.return_value = { 'result': [ { 'result': 5, 'node.id': self.project._id }, { 'result': 5, 'node.id': self.registration._id } ] } mock_client.count_unique.return_value = { 'result': [ { 'result': 2, 'node.id': self.project._id }, { 'result': 2, 'node.id': self.registration._id } ] } url = self.project.web_url_for('activity') res = self.app.get(url) assert_in(str(self.project.title), res) assert_in(str(self.project.date_created.date()), res) assert_in(str(self.registration.title), res) assert_in(str(self.registration.registered_date.date()), res) assert_not_in(str(self.private_project.title), res)
class TestPrivateLinkView(OsfTestCase): def setUp(self): super(TestPrivateLinkView, self).setUp() self.user = AuthUserFactory() # Is NOT a contributor self.project = ProjectFactory(is_public=False) self.link = PrivateLinkFactory(anonymous=True) self.link.nodes.append(self.project) self.link.save() self.project_url = self.project.web_url_for('view_project') def test_anonymous_link_hide_contributor(self): res = self.app.get(self.project_url, {'view_only': self.link.key}) assert_in("Anonymous Contributors", res.body) assert_not_in(self.user.fullname, res) def test_anonymous_link_hides_citations(self): res = self.app.get(self.project_url, {'view_only': self.link.key}) assert_not_in('Citation:', res)
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) 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) 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_GET_disapprove_with_valid(self): project = ProjectFactory(creator=self.user) registration = RegistrationFactory(project=project) registration.embargo_registration( self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10) ) registration.save() assert_true(registration.is_pending_embargo) rejection_token = registration.embargo.approval_state[self.user._id]['rejection_token'] res = self.app.get( registration.registered_from.web_url_for('view_project', token=rejection_token), auth=self.user.auth, ) registration.embargo.reload() assert_equal(registration.embargo.state, Embargo.REJECTED) assert_false(registration.is_pending_embargo) assert_equal(res.status_code, 200) assert_equal(project.web_url_for('view_project'), res.request.path)
def test_GET_disapprove_with_valid(self): project = ProjectFactory(creator=self.user) registration = RegistrationFactory(project=project) registration.embargo_registration( self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10) ) registration.save() assert_true(registration.is_pending_embargo) rejection_token = registration.embargo.approval_state[self.user._id]['rejection_token'] res = self.app.get( registration.registered_from.web_url_for('view_project', token=rejection_token), auth=self.user.auth, ) registration.embargo.reload() assert_equal(registration.embargo.state, Embargo.REJECTED) assert_false(registration.is_pending_embargo) assert_equal(res.status_code, 200) assert_equal(project.web_url_for('view_project'), res.request.path)
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_view', wname='home') res = self.app.get(url) assert_equal(res.status_code, 200) def test_wiki_url_404_with_no_write_permission(self): url = self.project.web_url_for('project_wiki_view', wname='somerandomid') res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 404) @mock.patch('website.addons.wiki.utils.broadcast_to_sharejs') def test_wiki_deleted_404_with_no_write_permission(self, mock_sharejs): self.project.update_node_wiki('funpage', 'Version 1', Auth(self.user)) self.project.save() url = self.project.web_url_for('project_wiki_view', wname='funpage') res = self.app.get(url) assert_equal(res.status_code, 200) delete_url = self.project.api_url_for('project_wiki_delete', wname='funpage') self.app.delete(delete_url, auth=self.user.auth) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 404) def test_wiki_url_with_path_get_returns_200(self): self.project.update_node_wiki('funpage', 'Version 1', Auth(self.user)) self.project.update_node_wiki('funpage', 'Version 2', Auth(self.user)) self.project.save() url = self.project.web_url_for( 'project_wiki_view', wname='funpage', ) + '?view&compare=1&edit' res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) def test_wiki_url_with_edit_get_returns_404_with_no_write_permission(self): self.project.update_node_wiki('funpage', 'Version 1', Auth(self.user)) self.project.update_node_wiki('funpage', 'Version 2', Auth(self.user)) self.project.save() url = self.project.web_url_for( 'project_wiki_view', wname='funpage', compare=1, ) res = self.app.get(url) assert_equal(res.status_code, 200) url = self.project.web_url_for( 'project_wiki_view', wname='funpage', ) + '?edit' res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 403) 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_view', wname='home') res = self.app.get(url) assert_equal(res.status_code, 200) def test_wiki_draft_returns_200(self): url = self.project.api_url_for('wiki_page_draft', wname='somerandomid') res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) def test_wiki_content_returns_200(self): url = self.project.api_url_for('wiki_page_content', wname='somerandomid') res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) @mock.patch('website.addons.wiki.model.NodeWikiPage.rendered_before_update', new_callable=mock.PropertyMock) def test_wiki_content_use_python_render(self, mock_rendered_before_update): content = 'Some content' self.project.update_node_wiki('somerandomid', content, Auth(self.user)) self.project.save() mock_rendered_before_update.return_value = True url = self.project.api_url_for('wiki_page_content', wname='somerandomid') res = self.app.get(url, auth=self.user.auth) assert_equal(content, res.json['wiki_content']) assert_in(content, res.json['wiki_rendered']) mock_rendered_before_update.return_value = False res = self.app.get(url, auth=self.user.auth) assert_equal(content, res.json['wiki_content']) assert_equal('', res.json['wiki_rendered']) def test_wiki_url_for_component_returns_200(self): component = NodeFactory(project=self.project, is_public=True) url = component.web_url_for('project_wiki_view', 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_view', 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): # note: forward slashes not allowed in page_name page_name = fake.catch_phrase().replace('/', ' ') 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): # note: forward slashes not allowed in page_name page_name = fake.catch_phrase().replace('/' , ' ') page_content = 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_view', wname='home') res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) def test_project_wiki_view_scope(self): self.project.update_node_wiki('home', 'Version 1', Auth(self.user)) self.project.update_node_wiki('home', 'Version 2', Auth(self.user)) self.project.save() url = self.project.web_url_for('project_wiki_view', wname='home', view=2) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) url = self.project.web_url_for('project_wiki_view', wname='home', view=3) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) url = self.project.web_url_for('project_wiki_view', wname='home', view=0) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) 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_view', wname='home') + '?compare' res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) def test_project_wiki_compare_scope(self): self.project.update_node_wiki('home', 'Version 1', Auth(self.user)) self.project.update_node_wiki('home', 'Version 2', Auth(self.user)) self.project.save() url = self.project.web_url_for('project_wiki_view', wname='home', compare=2) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) url = self.project.web_url_for('project_wiki_view', wname='home', compare=3) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) url = self.project.web_url_for('project_wiki_view', wname='home', compare=0) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) 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_view', 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_view', 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_view', 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_view', 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) def test_wiki_widget_no_content(self): url = self.project.api_url_for('wiki_widget', wid='home') res = self.app.get(url, auth=self.user.auth) assert_is_none(res.json['wiki_content']) def test_wiki_widget_short_content_no_cutoff(self): short_content = 'a' * 150 self.project.update_node_wiki('home', short_content, Auth(self.user)) url = self.project.api_url_for('wiki_widget', wid='home') res = self.app.get(url, auth=self.user.auth) assert_in(short_content, res.json['wiki_content']) assert_not_in('...', res.json['wiki_content']) assert_false(res.json['more']) def test_wiki_widget_long_content_cutoff(self): long_content = 'a' * 600 self.project.update_node_wiki('home', long_content, Auth(self.user)) url = self.project.api_url_for('wiki_widget', wid='home') res = self.app.get(url, auth=self.user.auth) assert_less(len(res.json['wiki_content']), 520) # wiggle room for closing tags assert_in('...', res.json['wiki_content']) assert_true(res.json['more']) @mock.patch('website.addons.wiki.model.NodeWikiPage.rendered_before_update', new_callable=mock.PropertyMock) def test_wiki_widget_use_python_render(self, mock_rendered_before_update): # New pages use js renderer mock_rendered_before_update.return_value = False self.project.update_node_wiki('home', 'updated content', Auth(self.user)) url = self.project.api_url_for('wiki_widget', wid='home') res = self.app.get(url, auth=self.user.auth) assert_false(res.json['use_python_render']) # Old pages use python renderer mock_rendered_before_update.return_value = True res = self.app.get(url, auth=self.user.auth) assert_true(res.json['use_python_render']) def test_read_only_users_cannot_view_edit_pane(self): url = self.project.web_url_for('project_wiki_view', wname='home') # No write permissions res = self.app.get(url) assert_equal(res.status_code, 200) assert_not_in('data-osf-panel="Edit"', res.text) # Write permissions res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_in('data-osf-panel="Edit"', res.text)
class TestAuthBasicAuthentication(OsfTestCase): TOTP_SECRET = 'b8f85986068f8079aa9d' def setUp(self): super(TestAuthBasicAuthentication, self).setUp() self.user1 = AuthUserFactory() self.user2 = AuthUserFactory() # Test projects for which a given user DOES and DOES NOT have appropriate permissions self.reachable_project = ProjectFactory(title="Private Project User 1", is_public=False, creator=self.user1) self.unreachable_project = ProjectFactory(title="Private Project User 2", is_public=False, creator=self.user2) self.reachable_url = self.reachable_project.web_url_for('view_project') self.unreachable_url = self.unreachable_project.web_url_for('view_project') def test_missing_credential_fails(self): res = self.app.get(self.unreachable_url, auth=None, expect_errors=True) assert_equal(res.status_code, 302) assert_true('Location' in res.headers) assert_true('/login' in res.headers['Location']) def test_invalid_credential_fails(self): res = self.app.get(self.unreachable_url, auth=(self.user1.username, 'invalid password'), expect_errors=True) assert_equal(res.status_code, 401) assert_true('<h2 id=\'error\' data-http-status-code="401">Unauthorized</h2>' in res.body) def test_valid_credential_authenticates_and_has_permissions(self): res = self.app.get(self.reachable_url, auth=self.user1.auth) assert_equal(res.status_code, 200) def test_valid_credential_authenticates_but_user_lacks_object_permissions(self): res = self.app.get(self.unreachable_url, auth=self.user1.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_valid_credential_but_twofactor_required(self): user1_addon = self.user1.get_or_add_addon('twofactor') user1_addon.totp_drift = 1 user1_addon.totp_secret = self.TOTP_SECRET user1_addon.is_confirmed = True user1_addon.save() res = self.app.get(self.reachable_url, auth=self.user1.auth, expect_errors=True) assert_equal(res.status_code, 401) assert_true('<h2 id=\'error\' data-http-status-code="401">Unauthorized</h2>' in res.body) def test_valid_credential_twofactor_invalid_otp(self): user1_addon = self.user1.get_or_add_addon('twofactor') user1_addon.totp_drift = 1 user1_addon.totp_secret = self.TOTP_SECRET user1_addon.is_confirmed = True user1_addon.save() res = self.app.get(self.reachable_url, auth=self.user1.auth, headers={'X-OSF-OTP': 'invalid otp'}, expect_errors=True) assert_equal(res.status_code, 401) assert_true('<h2 id=\'error\' data-http-status-code="401">Unauthorized</h2>' in res.body) def test_valid_credential_twofactor_valid_otp(self): user1_addon = self.user1.get_or_add_addon('twofactor') user1_addon.totp_drift = 1 user1_addon.totp_secret = self.TOTP_SECRET user1_addon.is_confirmed = True user1_addon.save() res = self.app.get(self.reachable_url, auth=self.user1.auth, headers={'X-OSF-OTP': _valid_code(self.TOTP_SECRET)}) assert_equal(res.status_code, 200)
class TestAddonFileViews(OsfTestCase): @classmethod def setUpClass(cls): super(TestAddonFileViews, cls).setUpClass() PROVIDER_MAP['github'] = [TestFolder, TestFile, TestFileNode] TestFileNode.provider = 'github' def setUp(self): super(TestAddonFileViews, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.user.add_addon('github') self.project.add_addon('github', auth=Auth(self.user)) self.user_addon = self.user.get_addon('github') self.node_addon = self.project.get_addon('github') self.oauth = GitHubAccountFactory() self.oauth.save() self.user.external_accounts.append(self.oauth) self.user.save() self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth self.node_addon.repo = 'Truth' self.node_addon.user = '******' self.node_addon.save() @classmethod def tearDownClass(cls): super(TestAddonFileViews, cls).tearDownClass() PROVIDER_MAP['github'] = [ models.GithubFolder, models.GithubFile, models.GithubFileNode ] del PROVIDER_MAP['test_addons'] TrashedFileNode.remove() def get_test_file(self): version = models.FileVersion(identifier='1') version.save() versions = [version] ret = TestFile(name='Test', node=self.project, path='/test/Test', materialized_path='/test/Test', versions=versions) ret.save() return ret def get_second_test_file(self): version = models.FileVersion(identifier='1') version.save() ret = TestFile(name='Test2', node=self.project, path='/test/Test2', materialized_path='/test/Test2', versions=[version]) ret.save() return ret def get_mako_return(self): ret = serialize_node(self.project, Auth(self.user), primary=True) ret.update({ 'error': '', 'provider': '', 'file_path': '', 'sharejs_uuid': '', 'private': '', 'urls': { 'files': '', 'render': '', 'sharejs': '', 'mfr': '', 'gravatar': '', 'external': '', 'archived_from': '', }, 'size': '', 'extra': '', 'file_name': '', 'materialized_path': '', 'file_id': '', }) ret.update(rubeus.collect_addon_assets(self.project)) return ret def test_redirects_to_guid(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.get(self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github'), auth=self.user.auth) assert_equals(resp.status_code, 302) assert_equals(resp.location, 'http://*****:*****@mock.patch('website.addons.base.views.addon_view_file') def test_action_view_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() file_node = self.get_test_file() guid = file_node.get_guid(create=True) mock_view_file.return_value = self.get_mako_return() self.app.get('/{}/?action=view'.format(guid._id), auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[0].user._id, self.user._id) assert_equals(args[1], self.project) assert_equals(args[2], file_node) assert_true(isinstance(args[3], file_node.touch(None).__class__)) @mock.patch('website.addons.base.views.addon_view_file') def test_no_action_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() file_node = self.get_test_file() guid = file_node.get_guid(create=True) mock_view_file.return_value = self.get_mako_return() self.app.get('/{}/'.format(guid._id), auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[0].user._id, self.user._id) assert_equals(args[1], self.project) assert_equals(args[2], file_node) assert_true(isinstance(args[3], file_node.touch(None).__class__)) def test_download_create_guid(self): file_node = self.get_test_file() assert_is(file_node.get_guid(), None) self.app.get(self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github', ), auth=self.user.auth) assert_true(file_node.get_guid()) def test_view_file_does_not_delete_file_when_requesting_invalid_version( self): with mock.patch( 'website.addons.github.model.GitHubNodeSettings.is_private', new_callable=mock.PropertyMock) as mock_is_private: mock_is_private.return_value = False file_node = self.get_test_file() assert_is(file_node.get_guid(), None) url = self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github', ) # First view generated GUID self.app.get(url, auth=self.user.auth) self.app.get(url + '?version=invalid', auth=self.user.auth, expect_errors=True) assert_is_not_none(StoredFileNode.load(file_node._id)) assert_is_none(TrashedFileNode.load(file_node._id)) def test_unauthorized_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get(self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download'), auth=self.user.auth, expect_errors=True) assert_equals(resp.status_code, 401) def test_nonstorage_addons_raise(self): resp = self.app.get(self.project.web_url_for( 'addon_view_or_download_file', path='sillywiki', provider='wiki', action='download'), auth=self.user.auth, expect_errors=True) assert_equals(resp.status_code, 400) def test_head_returns_url(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.head('/{}/'.format(guid._id), auth=self.user.auth) location = furl.furl(resp.location) assert_urls_equal( location.url, file_node.generate_waterbutler_url(direct=None, version=None)) def test_head_returns_url_with_version(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.head('/{}/?revision=1&foo=bar'.format(guid._id), auth=self.user.auth) location = furl.furl(resp.location) # Note: version is added but us but all other url params are added as well assert_urls_equal( location.url, file_node.generate_waterbutler_url(direct=None, revision=1, version=None, foo='bar')) def test_nonexistent_addons_raise(self): path = 'cloudfiles' self.project.delete_addon('github', Auth(self.user)) self.project.save() resp = self.app.get(self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download'), auth=self.user.auth, expect_errors=True) assert_equals(resp.status_code, 400) def test_unauth_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get(self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download'), auth=self.user.auth, expect_errors=True) assert_equals(resp.status_code, 401) def test_delete_action_creates_trashed_file_node(self): file_node = self.get_test_file() payload = { 'provider': file_node.provider, 'metadata': { 'path': '/test/Test', 'materialized': '/test/Test' } } views.addon_delete_file_node(self=None, node=self.project, user=self.user, event_type='file_removed', payload=payload) assert_false(StoredFileNode.load(file_node._id)) assert_true(TrashedFileNode.load(file_node._id)) def test_delete_action_for_folder_deletes_subfolders_and_creates_trashed_file_nodes( self): file_node = self.get_test_file() subfolder = TestFolder(name='folder', node=self.project, path='/test/folder/', materialized_path='/test/folder/', versions=[]) subfolder.save() payload = { 'provider': file_node.provider, 'metadata': { 'path': '/test/', 'materialized': '/test/' } } views.addon_delete_file_node(self=None, node=self.project, user=self.user, event_type='file_removed', payload=payload) assert_false(StoredFileNode.load(file_node._id)) assert_true(TrashedFileNode.load(file_node._id)) assert_false(StoredFileNode.load(subfolder._id)) @mock.patch('website.archiver.tasks.archive') def test_archived_from_url(self, mock_archive): file_node = self.get_test_file() second_file_node = self.get_second_test_file() file_node.copied_from = second_file_node registered_node = self.project.register_node( schema=get_default_metaschema(), auth=Auth(self.user), data=None, ) archived_from_url = views.get_archived_from_url( registered_node, file_node) view_url = self.project.web_url_for('addon_view_or_download_file', provider=file_node.provider, path=file_node.copied_from._id) assert_true(archived_from_url) assert_urls_equal(archived_from_url, view_url) @mock.patch('website.archiver.tasks.archive') def test_archived_from_url_without_copied_from(self, mock_archive): file_node = self.get_test_file() registered_node = self.project.register_node( schema=get_default_metaschema(), auth=Auth(self.user), data=None, ) archived_from_url = views.get_archived_from_url( registered_node, file_node) assert_false(archived_from_url) @mock.patch('website.archiver.tasks.archive') def test_copied_from_id_trashed(self, mock_archive): file_node = self.get_test_file() second_file_node = self.get_second_test_file() file_node.copied_from = second_file_node self.project.register_node( schema=get_default_metaschema(), auth=Auth(self.user), data=None, ) trashed_node = second_file_node.delete() assert_false(trashed_node.copied_from)
class TestAddonFileViews(OsfTestCase): @classmethod def setUpClass(cls): super(TestAddonFileViews, cls).setUpClass() PROVIDER_MAP['github'] = [TestFolder, TestFile, TestFileNode] TestFileNode.provider = 'github' def setUp(self): super(TestAddonFileViews, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.user.add_addon('github') self.project.add_addon('github', auth=Auth(self.user)) self.user_addon = self.user.get_addon('github') self.node_addon = self.project.get_addon('github') self.oauth = GitHubAccountFactory() self.oauth.save() self.user.external_accounts.append(self.oauth) self.user.save() self.node_addon.user_settings = self.user_addon self.node_addon.external_account = self.oauth self.node_addon.repo = 'Truth' self.node_addon.user = '******' self.node_addon.save() @classmethod def tearDownClass(cls): super(TestAddonFileViews, cls).tearDownClass() PROVIDER_MAP['github'] = [models.GithubFolder, models.GithubFile, models.GithubFileNode] del PROVIDER_MAP['test_addons'] TrashedFileNode.remove() def get_test_file(self): version = models.FileVersion(identifier='1') version.save() versions = [version] ret = TestFile( name='Test', node=self.project, path='/test/Test', materialized_path='/test/Test', versions=versions ) ret.save() return ret def get_second_test_file(self): version = models.FileVersion(identifier='1') version.save() ret = TestFile( name='Test2', node=self.project, path='/test/Test2', materialized_path='/test/Test2', versions=[version] ) ret.save() return ret def get_mako_return(self): ret = serialize_node(self.project, Auth(self.user), primary=True) ret.update({ 'error': '', 'provider': '', 'file_path': '', 'sharejs_uuid': '', 'private': '', 'urls': { 'files': '', 'render': '', 'sharejs': '', 'mfr': '', 'gravatar': '', 'external': '', 'archived_from': '', }, 'size': '', 'extra': '', 'file_name': '', 'materialized_path': '', 'file_id': '', }) ret.update(rubeus.collect_addon_assets(self.project)) return ret def test_redirects_to_guid(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github' ), auth=self.user.auth ) assert_equals(resp.status_code, 302) assert_equals(resp.location, 'http://*****:*****@mock.patch('website.addons.base.views.addon_view_file') def test_action_view_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() file_node = self.get_test_file() guid = file_node.get_guid(create=True) mock_view_file.return_value = self.get_mako_return() self.app.get('/{}/?action=view'.format(guid._id), auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[0].user._id, self.user._id) assert_equals(args[1], self.project) assert_equals(args[2], file_node) assert_true(isinstance(args[3], file_node.touch(None).__class__)) @mock.patch('website.addons.base.views.addon_view_file') def test_no_action_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() file_node = self.get_test_file() guid = file_node.get_guid(create=True) mock_view_file.return_value = self.get_mako_return() self.app.get('/{}/'.format(guid._id), auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[0].user._id, self.user._id) assert_equals(args[1], self.project) assert_equals(args[2], file_node) assert_true(isinstance(args[3], file_node.touch(None).__class__)) def test_download_create_guid(self): file_node = self.get_test_file() assert_is(file_node.get_guid(), None) self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github', ), auth=self.user.auth ) assert_true(file_node.get_guid()) def test_view_file_does_not_delete_file_when_requesting_invalid_version(self): with mock.patch('website.addons.github.model.GitHubNodeSettings.is_private', new_callable=mock.PropertyMock) as mock_is_private: mock_is_private.return_value = False file_node = self.get_test_file() assert_is(file_node.get_guid(), None) url = self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github', ) # First view generated GUID self.app.get(url, auth=self.user.auth) self.app.get(url + '?version=invalid', auth=self.user.auth, expect_errors=True) assert_is_not_none(StoredFileNode.load(file_node._id)) assert_is_none(TrashedFileNode.load(file_node._id)) def test_unauthorized_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 401) def test_nonstorage_addons_raise(self): resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path='sillywiki', provider='wiki', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 400) def test_head_returns_url(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.head('/{}/'.format(guid._id), auth=self.user.auth) location = furl.furl(resp.location) assert_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, version=None)) def test_head_returns_url_with_version(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.head('/{}/?revision=1&foo=bar'.format(guid._id), auth=self.user.auth) location = furl.furl(resp.location) # Note: version is added but us but all other url params are added as well assert_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, revision=1, version=None, foo='bar')) def test_nonexistent_addons_raise(self): path = 'cloudfiles' self.project.delete_addon('github', Auth(self.user)) self.project.save() resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 400) def test_unauth_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 401) def test_delete_action_creates_trashed_file_node(self): file_node = self.get_test_file() payload = { 'provider': file_node.provider, 'metadata': { 'path': '/test/Test', 'materialized': '/test/Test' } } views.addon_delete_file_node(self=None, node=self.project, user=self.user, event_type='file_removed', payload=payload) assert_false(StoredFileNode.load(file_node._id)) assert_true(TrashedFileNode.load(file_node._id)) def test_delete_action_for_folder_deletes_subfolders_and_creates_trashed_file_nodes(self): file_node = self.get_test_file() subfolder = TestFolder( name='folder', node=self.project, path='/test/folder/', materialized_path='/test/folder/', versions=[] ) subfolder.save() payload = { 'provider': file_node.provider, 'metadata': { 'path': '/test/', 'materialized': '/test/' } } views.addon_delete_file_node(self=None, node=self.project, user=self.user, event_type='file_removed', payload=payload) assert_false(StoredFileNode.load(file_node._id)) assert_true(TrashedFileNode.load(file_node._id)) assert_false(StoredFileNode.load(subfolder._id)) @mock.patch('website.archiver.tasks.archive') def test_archived_from_url(self, mock_archive): file_node = self.get_test_file() second_file_node = self.get_second_test_file() file_node.copied_from = second_file_node registered_node = self.project.register_node( schema=get_default_metaschema(), auth=Auth(self.user), data=None, ) archived_from_url = views.get_archived_from_url(registered_node, file_node) view_url = self.project.web_url_for('addon_view_or_download_file', provider=file_node.provider, path=file_node.copied_from._id) assert_true(archived_from_url) assert_urls_equal(archived_from_url, view_url) @mock.patch('website.archiver.tasks.archive') def test_archived_from_url_without_copied_from(self, mock_archive): file_node = self.get_test_file() registered_node = self.project.register_node( schema=get_default_metaschema(), auth=Auth(self.user), data=None, ) archived_from_url = views.get_archived_from_url(registered_node, file_node) assert_false(archived_from_url) @mock.patch('website.archiver.tasks.archive') def test_copied_from_id_trashed(self, mock_archive): file_node = self.get_test_file() second_file_node = self.get_second_test_file() file_node.copied_from = second_file_node self.project.register_node( schema=get_default_metaschema(), auth=Auth(self.user), data=None, ) trashed_node = second_file_node.delete() assert_false(trashed_node.copied_from)
class TestComponents(OsfTestCase): def setUp(self): super(TestComponents, self).setUp() self.user = AuthUserFactory() self.consolidate_auth = Auth(user=self.user) self.project = ProjectFactory(creator=self.user) self.project.add_contributor(contributor=self.user, auth=self.consolidate_auth) # A non-project componenet self.component = NodeFactory( category='hypothesis', creator=self.user, parent=self.project, ) self.component.save() self.component.set_privacy('public', self.consolidate_auth) self.component.set_privacy('private', self.consolidate_auth) self.project.save() self.project_url = self.project.web_url_for('view_project') def test_can_create_component_from_a_project(self): res = self.app.get(self.project.url, auth=self.user.auth).maybe_follow() assert_in('Add Component', res) def test_can_create_component_from_a_component(self): res = self.app.get(self.component.url, auth=self.user.auth).maybe_follow() assert_in('Add Component', res) def test_sees_parent(self): res = self.app.get(self.component.url, auth=self.user.auth).maybe_follow() parent_title = res.html.find_all('h2', class_='node-parent-title') assert_equal(len(parent_title), 1) assert_in(self.project.title, parent_title[0].text) def test_delete_project(self): res = self.app.get(self.component.url + 'settings/', auth=self.user.auth).maybe_follow() assert_in('Delete {0}'.format(self.component.project_or_component), res) def test_cant_delete_project_if_not_admin(self): non_admin = AuthUserFactory() self.component.add_contributor( non_admin, permissions=['read', 'write'], auth=self.consolidate_auth, save=True, ) res = self.app.get(self.component.url + 'settings/', auth=non_admin.auth).maybe_follow() assert_not_in('Delete {0}'.format(self.component.project_or_component), res) def test_can_configure_comments_if_admin(self): res = self.app.get( self.component.url + 'settings/', auth=self.user.auth, ).maybe_follow() assert_in('Configure Commenting', res) def test_cant_configure_comments_if_not_admin(self): non_admin = AuthUserFactory() self.component.add_contributor( non_admin, permissions=['read', 'write'], auth=self.consolidate_auth, save=True, ) res = self.app.get(self.component.url + 'settings/', auth=non_admin.auth).maybe_follow() assert_not_in('Configure commenting', res) def test_components_should_have_component_list(self): res = self.app.get(self.component.url, auth=self.user.auth) assert_in('Components', res) def test_does_show_registration_button(self): # No registrations on the component url = self.component.web_url_for('node_registrations') res = self.app.get(url, auth=self.user.auth) # New registration button is hidden assert_in('New Registration', res)
class TestAuthBasicAuthentication(OsfTestCase): TOTP_SECRET = 'b8f85986068f8079aa9d' def setUp(self): super(TestAuthBasicAuthentication, self).setUp() self.user1 = AuthUserFactory() self.user2 = AuthUserFactory() # Test projects for which a given user DOES and DOES NOT have appropriate permissions self.reachable_project = ProjectFactory(title="Private Project User 1", is_public=False, creator=self.user1) self.unreachable_project = ProjectFactory( title="Private Project User 2", is_public=False, creator=self.user2) self.reachable_url = self.reachable_project.web_url_for('view_project') self.unreachable_url = self.unreachable_project.web_url_for( 'view_project') def test_missing_credential_fails(self): res = self.app.get(self.unreachable_url, auth=None, expect_errors=True) assert_equal(res.status_code, 302) assert_true('Location' in res.headers) assert_true('/login' in res.headers['Location']) def test_invalid_credential_fails(self): res = self.app.get(self.unreachable_url, auth=(self.user1.username, 'invalid password'), expect_errors=True) assert_equal(res.status_code, 401) assert_true( '<h2 id=\'error\' data-http-status-code="401">Unauthorized</h2>' in res.body) def test_valid_credential_authenticates_and_has_permissions(self): res = self.app.get(self.reachable_url, auth=self.user1.auth) assert_equal(res.status_code, 200) def test_valid_credential_authenticates_but_user_lacks_object_permissions( self): res = self.app.get(self.unreachable_url, auth=self.user1.auth, expect_errors=True) assert_equal(res.status_code, 403) def test_valid_credential_but_twofactor_required(self): user1_addon = self.user1.get_or_add_addon('twofactor') user1_addon.totp_drift = 1 user1_addon.totp_secret = self.TOTP_SECRET user1_addon.is_confirmed = True user1_addon.save() res = self.app.get(self.reachable_url, auth=self.user1.auth, expect_errors=True) assert_equal(res.status_code, 401) assert_true( '<h2 id=\'error\' data-http-status-code="401">Unauthorized</h2>' in res.body) def test_valid_credential_twofactor_invalid_otp(self): user1_addon = self.user1.get_or_add_addon('twofactor') user1_addon.totp_drift = 1 user1_addon.totp_secret = self.TOTP_SECRET user1_addon.is_confirmed = True user1_addon.save() res = self.app.get(self.reachable_url, auth=self.user1.auth, headers={'X-OSF-OTP': 'invalid otp'}, expect_errors=True) assert_equal(res.status_code, 401) assert_true( '<h2 id=\'error\' data-http-status-code="401">Unauthorized</h2>' in res.body) def test_valid_credential_twofactor_valid_otp(self): user1_addon = self.user1.get_or_add_addon('twofactor') user1_addon.totp_drift = 1 user1_addon.totp_secret = self.TOTP_SECRET user1_addon.is_confirmed = True user1_addon.save() res = self.app.get( self.reachable_url, auth=self.user1.auth, headers={'X-OSF-OTP': _valid_code(self.TOTP_SECRET)}) assert_equal(res.status_code, 200)
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 TestAddonFileViews(OsfTestCase): def setUp(self): super(TestAddonFileViews, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.user.add_addon('github') self.project.add_addon('github', auth=Auth(self.user)) self.user_addon = self.user.get_addon('github') self.node_addon = self.project.get_addon('github') self.oauth = AddonGitHubOauthSettings( github_user_id='denbarell', oauth_access_token='Truthy' ) self.oauth.save() self.user_addon.oauth_settings = self.oauth self.user_addon.save() self.node_addon.user_settings = self.user_addon self.node_addon.repo = 'Truth' self.node_addon.user = '******' self.node_addon.save() # self.node_addon.user_settings = 'Truthy' # setattr(self.node_addon, 'has_auth', True) def get_mako_return(self): ret = serialize_node(self.project, Auth(self.user), primary=True) ret.update({ 'error': '', 'provider': '', 'file_path': '', 'sharejs_uuid': '', 'urls': { 'files': '', 'render': '', 'sharejs': '', 'mfr': '', 'gravatar': '', }, 'size': '', 'extra': '', 'file_name': '', 'materialized_path': '', }) ret.update(rubeus.collect_addon_assets(self.project)) return ret def test_redirects_to_guid(self): path = 'bigdata' guid, _ = self.node_addon.find_or_create_file_guid('/' + path) resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github' ), auth=self.user.auth ) assert_equals(resp.status_code, 302) assert_equals(resp.headers['Location'], 'http://*****:*****@mock.patch('website.addons.base.request') def test_public_download_url_includes_view_only(self, mock_request): view_only = 'justworkplease' mock_request.args = { 'view_only': view_only } path = 'cloudfiles' guid, _ = self.node_addon.find_or_create_file_guid('/' + path) assert_in('view_only={}'.format(view_only), guid.public_download_url) @mock.patch('website.addons.base.views.addon_view_file') def test_action_view_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() path = 'cloudfiles' mock_view_file.return_value = self.get_mako_return() guid, _ = self.node_addon.find_or_create_file_guid('/' + path) self.app.get(guid.guid_url + '?action=view', auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[-1], {'action': 'view'}) assert_equals(args[1], self.project) assert_equals(args[0].user, self.user) assert_equals(args[2], self.node_addon) @mock.patch('website.addons.base.views.addon_view_file') def test_no_action_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() path = 'cloudfiles' mock_view_file.return_value = self.get_mako_return() guid, _ = self.node_addon.find_or_create_file_guid('/' + path) self.app.get(guid.guid_url, auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[-1], {}) assert_equals(args[1], self.project) assert_equals(args[0].user, self.user) assert_equals(args[2], self.node_addon) def test_download_create_guid(self): path = 'cloudfiles' self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth ) guid, created = self.node_addon.find_or_create_file_guid('/' + path) assert_true(guid) assert_false(created) assert_equals(guid.waterbutler_path, '/' + path) def test_unauthorized_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 401) def test_head_returns_url(self): path = 'the little engine that couldnt' guid, _ = self.node_addon.find_or_create_file_guid('/' + path) download_url = furl.furl(guid.download_url) download_url.args['accept_url'] = 'false' resp = self.app.head(guid.guid_url, auth=self.user.auth) assert_urls_equal(resp.headers['Location'], download_url.url) def test_nonexistent_addons_raise(self): path = 'cloudfiles' self.project.delete_addon('github', Auth(self.user)) self.project.save() resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 400) def test_unauth_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 401)
class TestAddonFileViews(OsfTestCase): @classmethod def setUpClass(cls): super(TestAddonFileViews, cls).setUpClass() PROVIDER_MAP['github'] = [TestFolder, TestFile, TestFileNode] TestFileNode.provider = 'github' def setUp(self): super(TestAddonFileViews, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.user.add_addon('github') self.project.add_addon('github', auth=Auth(self.user)) self.user_addon = self.user.get_addon('github') self.node_addon = self.project.get_addon('github') self.oauth = AddonGitHubOauthSettings( github_user_id='denbarell', oauth_access_token='Truthy' ) self.oauth.save() self.user_addon.oauth_settings = self.oauth self.user_addon.save() self.node_addon.user_settings = self.user_addon self.node_addon.repo = 'Truth' self.node_addon.user = '******' self.node_addon.save() @classmethod def tearDownClass(cls): super(TestAddonFileViews, cls).tearDownClass() PROVIDER_MAP['github'] = [models.GithubFolder, models.GithubFile, models.GithubFileNode] del PROVIDER_MAP['test_addons'] def get_test_file(self): version = models.FileVersion(identifier='1') version.save() ret = TestFile( name='Test', node=self.project, path='/test/Test', materialized_path='/test/Test', versions=[version] ) ret.save() return ret def get_mako_return(self): ret = serialize_node(self.project, Auth(self.user), primary=True) ret.update({ 'error': '', 'provider': '', 'file_path': '', 'sharejs_uuid': '', 'private': '', 'urls': { 'files': '', 'render': '', 'sharejs': '', 'mfr': '', 'gravatar': '', 'external': '', }, 'size': '', 'extra': '', 'file_name': '', 'materialized_path': '', }) ret.update(rubeus.collect_addon_assets(self.project)) return ret def test_redirects_to_guid(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github' ), auth=self.user.auth ) assert_equals(resp.status_code, 302) assert_equals(resp.location, 'http://*****:*****@mock.patch('website.addons.base.views.addon_view_file') def test_action_view_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() file_node = self.get_test_file() guid = file_node.get_guid(create=True) mock_view_file.return_value = self.get_mako_return() self.app.get('/{}/?action=view'.format(guid._id), auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[0].user._id, self.user._id) assert_equals(args[1], self.project) assert_equals(args[2], file_node) assert_true(isinstance(args[3], file_node.touch(None).__class__)) @mock.patch('website.addons.base.views.addon_view_file') def test_no_action_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() file_node = self.get_test_file() guid = file_node.get_guid(create=True) mock_view_file.return_value = self.get_mako_return() self.app.get('/{}/'.format(guid._id), auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[0].user._id, self.user._id) assert_equals(args[1], self.project) assert_equals(args[2], file_node) assert_true(isinstance(args[3], file_node.touch(None).__class__)) def test_download_create_guid(self): file_node = self.get_test_file() assert_is(file_node.get_guid(), None) self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github', ), auth=self.user.auth ) assert_true(file_node.get_guid()) def test_unauthorized_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 401) def test_nonstorage_addons_raise(self): resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path='sillywiki', provider='wiki', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 400) def test_head_returns_url(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.head('/{}/'.format(guid._id), auth=self.user.auth) location = furl.furl(resp.location) assert_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, version=None)) def test_head_returns_url_with_version(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.head('/{}/?revision=1&foo=bar'.format(guid._id), auth=self.user.auth) location = furl.furl(resp.location) # Note: version is added but us but all other url params are added as well assert_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None, revision=1, version=1, foo='bar')) def test_nonexistent_addons_raise(self): path = 'cloudfiles' self.project.delete_addon('github', Auth(self.user)) self.project.save() resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 400) def test_unauth_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 401)
class TestAddonFileViews(OsfTestCase): @classmethod def setUpClass(cls): super(TestAddonFileViews, cls).setUpClass() PROVIDER_MAP['github'] = [TestFolder, TestFile, TestFileNode] TestFileNode.provider = 'github' def setUp(self): super(TestAddonFileViews, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.user.add_addon('github') self.project.add_addon('github', auth=Auth(self.user)) self.user_addon = self.user.get_addon('github') self.node_addon = self.project.get_addon('github') self.oauth = AddonGitHubOauthSettings(github_user_id='denbarell', oauth_access_token='Truthy') self.oauth.save() self.user_addon.oauth_settings = self.oauth self.user_addon.save() self.node_addon.user_settings = self.user_addon self.node_addon.repo = 'Truth' self.node_addon.user = '******' self.node_addon.save() @classmethod def tearDownClass(cls): super(TestAddonFileViews, cls).tearDownClass() PROVIDER_MAP['github'] = [ models.GithubFolder, models.GithubFile, models.GithubFileNode ] del PROVIDER_MAP['test_addons'] def get_test_file(self): ret = TestFile(name='Test', node=self.project, path='/test/Test', materialized_path='/test/Test') ret.save() return ret def get_mako_return(self): ret = serialize_node(self.project, Auth(self.user), primary=True) ret.update({ 'error': '', 'provider': '', 'file_path': '', 'sharejs_uuid': '', 'private': '', 'urls': { 'files': '', 'render': '', 'sharejs': '', 'mfr': '', 'gravatar': '', 'external': '', }, 'size': '', 'extra': '', 'file_name': '', 'materialized_path': '', }) ret.update(rubeus.collect_addon_assets(self.project)) return ret def test_redirects_to_guid(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.get(self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github'), auth=self.user.auth) assert_equals(resp.status_code, 302) assert_equals(resp.location, 'http://*****:*****@mock.patch('website.addons.base.views.addon_view_file') def test_action_view_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() file_node = self.get_test_file() guid = file_node.get_guid(create=True) mock_view_file.return_value = self.get_mako_return() self.app.get('/{}/?action=view'.format(guid._id), auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[0].user, self.user) assert_equals(args[1], self.project) assert_equals(args[2], file_node) assert_true(isinstance(args[3], file_node.touch(None).__class__)) @mock.patch('website.addons.base.views.addon_view_file') def test_no_action_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() file_node = self.get_test_file() guid = file_node.get_guid(create=True) mock_view_file.return_value = self.get_mako_return() self.app.get('/{}/'.format(guid._id), auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[0].user, self.user) assert_equals(args[1], self.project) assert_equals(args[2], file_node) assert_true(isinstance(args[3], file_node.touch(None).__class__)) def test_download_create_guid(self): file_node = self.get_test_file() assert_is(file_node.get_guid(), None) self.app.get(self.project.web_url_for( 'addon_view_or_download_file', path=file_node.path.strip('/'), provider='github', ), auth=self.user.auth) assert_true(file_node.get_guid()) def test_unauthorized_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get(self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download'), auth=self.user.auth, expect_errors=True) assert_equals(resp.status_code, 401) def test_nonstorage_addons_raise(self): resp = self.app.get(self.project.web_url_for( 'addon_view_or_download_file', path='sillywiki', provider='wiki', action='download'), auth=self.user.auth, expect_errors=True) assert_equals(resp.status_code, 400) def test_head_returns_url(self): file_node = self.get_test_file() guid = file_node.get_guid(create=True) resp = self.app.head('/{}/'.format(guid._id), auth=self.user.auth) location = furl.furl(resp.location) assert_urls_equal(location.url, file_node.generate_waterbutler_url(direct=None)) def test_nonexistent_addons_raise(self): path = 'cloudfiles' self.project.delete_addon('github', Auth(self.user)) self.project.save() resp = self.app.get(self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download'), auth=self.user.auth, expect_errors=True) assert_equals(resp.status_code, 400) def test_unauth_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get(self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download'), auth=self.user.auth, expect_errors=True) assert_equals(resp.status_code, 401)
class TestViewsCrud(OsfTestCase): def setUp(self): super(TestViewsCrud, 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 = '436' self.node_settings.figshare_type = 'project' self.node_settings.save() self.figshare = create_mock_figshare('test') # def test_publish_no_category(self): # url = '/api/v1/project/{0}/figshare/publish/article/9002/'.format(self.project._id) # rv = self.app.post_json(url, {}, auth=self.user.auth, expect_errors=True) # self.node_settings.reload() # self.project.reload() # assert_equal(rv.status_int, 400) @mock.patch('website.addons.figshare.api.Figshare.from_settings') def test_view_missing(self, mock_fig): mock_fig.return_value = self.figshare url = '/project/{0}/figshare/article/564/file/854280423/'.format(self.project._id) rv = self.app.get(url, auth=self.user.auth, expect_errors=True).maybe_follow() assert_equal(rv.status_int, http.NOT_FOUND) @mock.patch('website.addons.figshare.api.Figshare.create_project') def test_create_project_fail(self, faux_ject): faux_ject.return_value = False url = '/api/v1/project/{0}/figshare/new/project/'.format(self.project._id) rv = self.app.post_json(url, {'project': 'testme'}, auth=self.user.auth, expect_errors=True) assert_equal(rv.status_int, http.BAD_REQUEST) @mock.patch('website.addons.figshare.api.Figshare.create_project') def test_create_project_no_name(self, faux_ject): faux_ject.return_value = False url = '/api/v1/project/{0}/figshare/new/project/'.format(self.project._id) rv = self.app.post_json(url, {}, auth=self.user.auth, expect_errors=True) assert_equal(rv.status_int, http.BAD_REQUEST) @mock.patch('website.addons.figshare.api.Figshare.create_article') def test_create_fileset_no_name(self, faux_ject): faux_ject.return_value = False url = '/api/v1/project/{0}/figshare/new/fileset/'.format(self.project._id) rv = self.app.post_json(url, {}, auth=self.user.auth, expect_errors=True) assert_equal(rv.status_int, http.BAD_REQUEST) @mock.patch('website.addons.figshare.api.Figshare.create_article') def test_create_fileset_no_name(self, faux_ject): faux_ject.return_value = False url = '/api/v1/project/{0}/figshare/new/fileset/'.format(self.project._id) rv = self.app.post_json(url, {'name': ''}, auth=self.user.auth, expect_errors=True) assert_equal(rv.status_int, http.BAD_REQUEST) @mock.patch('website.addons.figshare.api.Figshare.create_project') def test_create_project_empty_name(self, faux_ject): faux_ject.return_value = False url = '/api/v1/project/{0}/figshare/new/project/'.format(self.project._id) rv = self.app.post_json(url, {'project': ''}, auth=self.user.auth, expect_errors=True) assert_equal(rv.status_int, http.BAD_REQUEST) @mock.patch('website.addons.figshare.api.Figshare.from_settings') def test_view_file_returns_urls(self, mock_fig): mock_fig.return_value = self.figshare aid = '564' file_id = '1348803' delete_url = self.project.api_url + 'figshare/article/{aid}/file/{fid}/'.format(aid=aid, fid=file_id) files_page_url = self.project.web_url_for('collect_file_trees') url = self.project.web_url_for( 'figshare_view_file', aid=aid, fid=file_id ) self.app.auth = self.user.auth resp = self.app.get(url, auth=self.app.auth).maybe_follow(auth=self.app.auth) assert_equal(resp.status_int, http.OK) assert_in(self.project._id, resp.body) assert_in(self.project.title, resp.body) assert_in(self.project.title, resp.body) assert_in(delete_url, resp.body) assert_in(files_page_url, resp.body) # TODO Fix me, not logged in? @mock.patch('website.addons.figshare.api.Figshare.from_settings') def test_view_private(self, mock_fig): mock_fig.return_value = self.figshare url = '/project/{0}/figshare/article/564/file/1348803/'.format(self.project._id) self.app.auth = self.user.auth resp = self.app.get(url, auth=self.user.auth).maybe_follow() assert_equal(resp.status_int, http.OK) assert_true('file is unpublished we cannot render it.' in resp.body) @mock.patch('website.addons.figshare.api.Figshare.from_settings') def test_view_file_with_anonymous_link(self, mock_fig): link = PrivateLinkFactory(anonymous=True) link.nodes.append(self.project) link.save() mock_fig.return_value = self.figshare url = self.project.web_url_for( 'figshare_view_file', aid='564',fid='1348803' ) self.app.auth = self.user.auth resp = self.app.get(url, {'view_only': link.key}).maybe_follow() assert_equal(resp.status_int, http.OK) assert_true('file is unpublished we cannot render it.' in resp.body) assert_not_in('View on Figshare', resp.body) @mock.patch('website.addons.figshare.api.Figshare.from_settings') def test_view_bad_file(self, mock_fig): mock_fig.return_value = self.figshare url = '/project/{0}/figshare/article/564/file/958351351/'.format(self.project._id) self.app.auth = self.user.auth resp = self.app.get(url, expect_errors=True).maybe_follow() assert_equal(resp.status_int, http.NOT_FOUND) @mock.patch('website.addons.figshare.api.Figshare.from_settings') def test_view_bad_article(self, mock_fig): mock_fig.return_value = self.figshare url = '/project/{0}/figshare/article/543813514/file/9/'.format(self.project._id) self.app.auth = self.user.auth resp = self.app.get(url, expect_errors=True).maybe_follow() assert_equal(resp.status_int, http.NOT_FOUND)
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 TestWikiCompare(OsfTestCase): def setUp(self): super(TestWikiCompare, 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.wiki = self.project.get_wiki_page('home') def test_compare_wiki_page_valid(self): self.project.update_node_wiki('home', 'Hello World', self.consolidate_auth) url_v1_to_v2 = self.project.web_url_for('project_wiki_compare', wname='home', wver=1) res = self.app.get(url_v1_to_v2) comparison_v1_to_v2 = \ '<span style="background:#D16587; font-size:1.5em;">h</span>' \ '<span style="background:#4AA02C; font-size:1.5em; ">H</span>ello ' \ '<span style="background:#D16587; font-size:1.5em;">w</span>' \ '<span style="background:#4AA02C; font-size:1.5em; ">W</span>orld' assert_equal(res.status_int, http.OK) assert_true(comparison_v1_to_v2 in res.body) url_v2_to_v2 = self.project.web_url_for('project_wiki_compare', wname='home', wver=2) res = self.app.get(url_v2_to_v2) comparison_v2_to_v2 = 'Hello World' assert_equal(res.status_int, http.OK) assert_true(comparison_v2_to_v2 in res.body) def test_compare_wiki_page_sanitized(self): content_js_script = '<script>alert(' 'a problem' ');</script>' self.project.update_node_wiki('home', content_js_script, self.consolidate_auth) url_v1_to_v2 = self.project.web_url_for('project_wiki_compare', wname='home', wver=1) res = self.app.get(url_v1_to_v2) comparison_v1_to_v2 = \ '<span style="background:#D16587; font-size:1.5em;">h</span>' \ '<span style="background:#4AA02C; font-size:1.5em; "><script>al</span>e' \ '<span style="background:#4AA02C; font-size:1.5em; ">rt(''a prob</span>l' \ '<span style="background:#D16587; font-size:1.5em;">lo wo</span>' \ '<span style="background:#4AA02C; font-size:1.5em; ">em'');</span>r' \ '<span style="background:#D16587; font-size:1.5em;">ld</span>' \ '<span style="background:#4AA02C; font-size:1.5em; ">ipt></span>' assert_equal(res.status_int, http.OK) assert_true(content_js_script not in res.body) assert_true(comparison_v1_to_v2 in res.body) url_v2_to_v2 = self.project.web_url_for('project_wiki_compare', wname='home', wver=2) res = self.app.get(url_v2_to_v2) comparison_v2_to_v2 = '<script>alert(' 'a problem' ');</script>' assert_equal(res.status_int, http.OK) assert_true(content_js_script not in res.body) assert_true(comparison_v2_to_v2 in res.body)
class TestAddonFileViews(OsfTestCase): def setUp(self): super(TestAddonFileViews, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.user.add_addon('github') self.project.add_addon('github', auth=Auth(self.user)) self.user_addon = self.user.get_addon('github') self.node_addon = self.project.get_addon('github') self.oauth = AddonGitHubOauthSettings( github_user_id='denbarell', oauth_access_token='Truthy' ) self.oauth.save() self.user_addon.oauth_settings = self.oauth self.user_addon.save() self.node_addon.user_settings = self.user_addon self.node_addon.save() # self.node_addon.user_settings = 'Truthy' # setattr(self.node_addon, 'has_auth', True) def get_mako_return(self): ret = serialize_node(self.project, Auth(self.user), primary=True) ret.update({ 'extra': '', 'provider': '', 'rendered': '', 'file_path': '', 'files_url': '', 'file_name': '', 'render_url': '', }) ret.update(rubeus.collect_addon_assets(self.project)) return ret def test_redirects_to_guid(self): path = 'bigdata' guid, _ = self.node_addon.find_or_create_file_guid('/' + path) resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github' ), auth=self.user.auth ) assert_equals(resp.status_code, 302) assert_equals(resp.headers['Location'], 'http://*****:*****@mock.patch('website.addons.base.request') def test_public_download_url_includes_view_only(self, mock_request): view_only = 'justworkplease' mock_request.args = { 'view_only': view_only } path = 'cloudfiles' guid, _ = self.node_addon.find_or_create_file_guid('/' + path) assert_in('view_only={}'.format(view_only), guid.public_download_url) @mock.patch('website.addons.base.views.addon_view_file') def test_action_view_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() path = 'cloudfiles' mock_view_file.return_value = self.get_mako_return() guid, _ = self.node_addon.find_or_create_file_guid('/' + path) self.app.get(guid.guid_url + '?action=view', auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[-1], {'action': 'view'}) assert_equals(args[1], self.project) assert_equals(args[0].user, self.user) assert_equals(args[2], self.node_addon) @mock.patch('website.addons.base.views.addon_view_file') def test_no_action_calls_view_file(self, mock_view_file): self.user.reload() self.project.reload() path = 'cloudfiles' mock_view_file.return_value = self.get_mako_return() guid, _ = self.node_addon.find_or_create_file_guid('/' + path) self.app.get(guid.guid_url, auth=self.user.auth) args, kwargs = mock_view_file.call_args assert_equals(kwargs, {}) assert_equals(args[-1], {}) assert_equals(args[1], self.project) assert_equals(args[0].user, self.user) assert_equals(args[2], self.node_addon) def test_download_create_guid(self): path = 'cloudfiles' self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth ) guid, created = self.node_addon.find_or_create_file_guid('/' + path) assert_true(guid) assert_false(created) assert_equals(guid.waterbutler_path, '/' + path) def test_unauthorized_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get( self.project.web_url_for( 'addon_view_or_download_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 403) def test_head_returns_url(self): path = 'the little engine that couldnt' guid, _ = self.node_addon.find_or_create_file_guid('/' + path) download_url = furl.furl(guid.download_url) download_url.args['accept_url'] = 'false' resp = self.app.head(guid.guid_url, auth=self.user.auth) assert_urls_equal(resp.headers['Location'], download_url.url) def test_nonexistent_addons_raise(self): path = 'cloudfiles' self.project.delete_addon('github', Auth(self.user)) self.project.save() resp = self.app.get( self.project.api_url_for( 'addon_render_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 400) def test_unauth_addons_raise(self): path = 'cloudfiles' self.node_addon.user_settings = None self.node_addon.save() resp = self.app.get( self.project.api_url_for( 'addon_render_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 401) def test_unconfigured_addons_raise(self): path = 'cloudfiles' self.node_addon.repo = None self.node_addon.save() resp = self.app.get( self.project.api_url_for( 'addon_render_file', path=path, provider='github', action='download' ), auth=self.user.auth, expect_errors=True ) assert_equals(resp.status_code, 400)
class TestGoogleDriveConfigViews(OsfTestCase): def setUp(self): super(TestGoogleDriveConfigViews, self).setUp() self.account = GoogleDriveAccountFactory() self.user = AuthUserFactory(external_accounts=[self.account]) self.user_settings = self.user.get_or_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.node_settings.user_settings = self.user_settings self.node_settings.save() self.user_settings.save() # Log user in self.app.authenticate(*self.user.auth) def test_list_googledrive_accounts_returns_accounts_single(self): url = api_url_for('list_googledrive_user_accounts') res = self.app.get(url) assert_equal(res.status_code, 200) assert_equal(len(res.json['accounts']), 1) assert_equal(res.json['accounts'][0]['provider_id'], self.account.provider_id) assert_equal(res.json['accounts'][0]['provider_name'], self.account.provider_name) def test_list_googledrive_accounts_returns_accounts_multiple(self): external_account = GoogleDriveAccountFactory() self.user.external_accounts.append(external_account) # self.account is already present self.user.save() url = api_url_for('list_googledrive_user_accounts') res = self.app.get(url) assert_equal(res.status_code, 200) assert_equal(len(res.json['accounts']), 2) def test_googledrive_config_get_return_correct_urls(self): url = self.project.api_url_for('googledrive_config_get') res = self.app.get(url) result = res.json['result'] assert_equal(result['urls']['accounts'], self.project.api_url_for('list_googledrive_user_accounts')) assert_equal(result['urls']['auth'], api_url_for('oauth_connect', service_name='googledrive')) assert_equal(result['urls']['config'], self.project.api_url_for('googledrive_config_put')) assert_equal(result['urls']['deauthorize'], self.project.api_url_for('googledrive_remove_user_auth')) assert_equal(result['urls']['files'], self.project.web_url_for('collect_file_trees')) assert_equal(result['urls']['folders'], self.project.api_url_for('googledrive_folders')) assert_equal(result['urls']['importAuth'], self.project.api_url_for('googledrive_import_user_auth')) assert_equal(result['urls']['settings'], web_url_for('user_addons')) def test_googledrive_config_get_has_auth(self): self.node_settings.set_auth(external_account=self.account, user=self.user) self.node_settings.save() url = self.project.api_url_for('googledrive_config_get') res = self.app.get(url) assert_equal(res.status_code, 200) result = res.json['result'] assert_true(result['nodeHasAuth']) def test_googledrive_config_get_does_not_has_auth(self): url = self.project.api_url_for('googledrive_config_get') res = self.app.get(url) result = res.json['result'] assert_false(result['nodeHasAuth']) def test_googledrive_config_put(self): self.node_settings.set_auth(external_account=self.account, user=self.user) self.node_settings.save() 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_path, 'Google Drive/ 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'], ' My Folder') def test_googledrive_import_user_auth(self): url = self.project.api_url_for('googledrive_import_user_auth', auth=self.user.auth) self.app.put_json(url, {'external_account_id': self.account._id}) self.node_settings.reload() assert_equal(self.node_settings.external_account, self.account) def test_googledrive_remove_user_auth(self): self.node_settings.set_auth(external_account=self.account, user=self.user) self.node_settings.save() assert_equal(self.node_settings.external_account, self.account) url = self.project.api_url_for('googledrive_remove_user_auth', auth=self.user.auth) self.app.delete(url) self.node_settings.reload() assert_equal(self.node_settings.external_account, None)
class TestLegacyViews(OsfTestCase): def setUp(self): super(TestLegacyViews, self).setUp() self.path = 'mercury.png' self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.node_addon = self.project.get_addon('osfstorage') file_record, _ = OsfStorageFileRecord.get_or_create(path=self.path, node_settings=self.node_addon) self.node_addon.save() file_record.save() def test_view_file_redirect(self): url = '/{0}/osffiles/{1}/'.format(self.project._id, self.path) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( 'addon_view_or_download_file', action='view', path=self.path, provider='osfstorage', ) assert_urls_equal(res.location, expected_url) def test_download_file_redirect(self): url = '/{0}/osffiles/{1}/download/'.format(self.project._id, self.path) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( 'addon_view_or_download_file', path=self.path, action='download', provider='osfstorage', ) assert_urls_equal(res.location, expected_url) def test_download_file_version_redirect(self): url = '/{0}/osffiles/{1}/version/3/download/'.format( self.project._id, self.path, ) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( 'addon_view_or_download_file', version=3, path=self.path, action='download', provider='osfstorage', ) assert_urls_equal(res.location, expected_url) def test_api_download_file_redirect(self): url = '/api/v1/project/{0}/osffiles/{1}/'.format(self.project._id, self.path) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( 'addon_view_or_download_file', path=self.path, action='download', provider='osfstorage', ) assert_urls_equal(res.location, expected_url) def test_api_download_file_version_redirect(self): url = '/api/v1/project/{0}/osffiles/{1}/version/3/'.format( self.project._id, self.path, ) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( 'addon_view_or_download_file', version=3, path=self.path, action='download', provider='osfstorage', ) assert_urls_equal(res.location, expected_url) def test_no_provider_name(self): url = '/{0}/files/{1}'.format( self.project._id, self.path, ) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( 'addon_view_or_download_file', action='view', path=self.path, provider='osfstorage', ) assert_urls_equal(res.location, expected_url) def test_action_as_param(self): url = '/{}/osfstorage/files/{}/?action=download'.format( self.project._id, self.path, ) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( 'addon_view_or_download_file', path=self.path, action='download', provider='osfstorage', ) assert_urls_equal(res.location, expected_url) def test_other_addon_redirect(self): url = '/project/{0}/mycooladdon/files/{1}/'.format( self.project._id, self.path, ) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( 'addon_view_or_download_file', action='view', path=self.path, provider='mycooladdon', ) assert_urls_equal(res.location, expected_url) def test_other_addon_redirect_download(self): url = '/project/{0}/mycooladdon/files/{1}/download/'.format( self.project._id, self.path, ) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( 'addon_view_or_download_file', path=self.path, action='download', provider='mycooladdon', ) assert_urls_equal(res.location, expected_url)
class TestExplorePublicActivity(OsfTestCase): def setUp(self): super(TestExplorePublicActivity, self).setUp() self.project = ProjectFactory(is_public=True) self.registration = RegistrationFactory(project=self.project) self.private_project = ProjectFactory(title="Test private project") self.popular_project = ProjectFactory(is_public=True) self.popular_registration = RegistrationFactory(project=self.project) # Add project to new and noteworthy projects self.new_and_noteworthy_links_node = ProjectFactory() self.new_and_noteworthy_links_node._id = settings.NEW_AND_NOTEWORTHY_LINKS_NODE self.new_and_noteworthy_links_node.add_pointer( self.project, auth=Auth(self.new_and_noteworthy_links_node.creator), save=True) # Set up popular projects and registrations self.popular_links_node = ProjectFactory() self.popular_links_node._id = settings.POPULAR_LINKS_NODE self.popular_links_node.add_pointer( self.popular_project, auth=Auth(self.popular_links_node.creator), save=True) self.popular_links_registrations = ProjectFactory() self.popular_links_registrations._id = settings.POPULAR_LINKS_REGISTRATIONS self.popular_links_registrations.add_pointer( self.popular_registration, auth=Auth(self.popular_links_registrations.creator), save=True) def tearDown(self): super(TestExplorePublicActivity, self).tearDown() Node.remove() def test_explore_page_loads_when_settings_not_configured(self): old_settings_values = settings.POPULAR_LINKS_NODE, settings.NEW_AND_NOTEWORTHY_LINKS_NODE, settings.POPULAR_LINKS_REGISTRATIONS settings.POPULAR_LINKS_NODE = 'notanode' settings.NEW_AND_NOTEWORTHY_LINKS_NODE = 'alsototallywrong' settings.POPULAR_LINKS_REGISTRATIONS = 'nopenope' url = self.project.web_url_for('activity') res = self.app.get(url) assert_equal(res.status_code, 200) settings.POPULAR_LINKS_NODE, settings.NEW_AND_NOTEWORTHY_LINKS_NODE, settings.POPULAR_LINKS_REGISTRATIONS = old_settings_values def test_new_and_noteworthy_and_popular_nodes_show_in_explore_activity( self): url = self.project.web_url_for('activity') res = self.app.get(url) # New and Noteworthy assert_in(str(self.project.title), res) assert_in(str(self.project.date_created.date()), res) assert_in(str(self.registration.title), res) assert_in(str(self.registration.registered_date.date()), res) assert_not_in(str(self.private_project.title), res) # Popular Projects and Registrations assert_in(str(self.popular_project.title), res) assert_in(str(self.popular_project.date_created.date()), res) assert_in(str(self.popular_registration.title), res) assert_in(str(self.popular_registration.registered_date.date()), res)
class TestLegacyViews(OsfTestCase): def setUp(self): super(TestLegacyViews, self).setUp() self.path = 'mercury.png' self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.node_addon = self.project.get_addon('osfstorage') file_record = self.node_addon.root_node.append_file(self.path) self.expected_path = file_record._id self.node_addon.save() file_record.save() def test_view_file_redirect(self): url = '/{0}/osffiles/{1}/'.format(self.project._id, self.path) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( 'addon_view_or_download_file', action='view', path=self.expected_path, provider='osfstorage', ) assert_urls_equal(res.location, expected_url) def test_download_file_redirect(self): url = '/{0}/osffiles/{1}/download/'.format(self.project._id, self.path) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( 'addon_view_or_download_file', path=self.expected_path, action='download', provider='osfstorage', ) assert_urls_equal(res.location, expected_url) def test_download_file_version_redirect(self): url = '/{0}/osffiles/{1}/version/3/download/'.format( self.project._id, self.path, ) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( 'addon_view_or_download_file', version=3, path=self.expected_path, action='download', provider='osfstorage', ) assert_urls_equal(res.location, expected_url) def test_api_download_file_redirect(self): url = '/api/v1/project/{0}/osffiles/{1}/'.format(self.project._id, self.path) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( 'addon_view_or_download_file', path=self.expected_path, action='download', provider='osfstorage', ) assert_urls_equal(res.location, expected_url) def test_api_download_file_version_redirect(self): url = '/api/v1/project/{0}/osffiles/{1}/version/3/'.format( self.project._id, self.path, ) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( 'addon_view_or_download_file', version=3, path=self.expected_path, action='download', provider='osfstorage', ) assert_urls_equal(res.location, expected_url) def test_no_provider_name(self): url = '/{0}/files/{1}'.format( self.project._id, self.path, ) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( 'addon_view_or_download_file', action='view', path=self.expected_path, provider='osfstorage', ) assert_urls_equal(res.location, expected_url) def test_action_as_param(self): url = '/{}/osfstorage/files/{}/?action=download'.format( self.project._id, self.path, ) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( 'addon_view_or_download_file', path=self.expected_path, action='download', provider='osfstorage', ) assert_urls_equal(res.location, expected_url) def test_other_addon_redirect(self): url = '/project/{0}/mycooladdon/files/{1}/'.format( self.project._id, self.path, ) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( 'addon_view_or_download_file', action='view', path=self.path, provider='mycooladdon', ) assert_urls_equal(res.location, expected_url) def test_other_addon_redirect_download(self): url = '/project/{0}/mycooladdon/files/{1}/download/'.format( self.project._id, self.path, ) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( 'addon_view_or_download_file', path=self.path, action='download', provider='mycooladdon', ) assert_urls_equal(res.location, expected_url)
class TestCRUD(OsfTestCase): def setUp(self): super(TestCRUD, self).setUp() self.github = create_mock_github(user='******', private=False) self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.project = ProjectFactory(creator=self.user) self.project.add_addon('github', auth=self.consolidated_auth) self.project.creator.add_addon('github') self.node_settings = self.project.get_addon('github') self.node_settings.user_settings = self.project.creator.get_addon( 'github') # Set the node addon settings to correspond to the values of the mock repo self.node_settings.user = self.github.repo.return_value.owner.login self.node_settings.repo = self.github.repo.return_value.name self.node_settings.save() @mock.patch('website.addons.github.views.crud.build_github_urls') @mock.patch('website.addons.github.api.GitHub.create_file') @mock.patch('website.addons.github.api.GitHub.tree') def test_create_file(self, mock_tree, mock_create, mock_urls): sha = '12345' size = 128 file_name = 'my_file' file_content = 'my_data' branch = 'master' mock_tree.return_value.tree = [] mock_create.return_value = { 'commit': Commit(dict(sha=sha)), 'content': Contents(dict(size=size, url='http://fake.url/')), } mock_urls.return_value = {} url = self.project.api_url_for('github_upload_file', branch=branch) self.app.post( url, upload_files=[ ('file', file_name, file_content), ], auth=self.user.auth, ) mock_create.assert_called_once_with( self.node_settings.user, self.node_settings.repo, file_name, MESSAGES['add'], file_content, branch=branch, author={ 'name': self.user.fullname, 'email': '{0}@osf.io'.format(self.user._id), }, ) @mock.patch('website.addons.github.api.GitHub.contents') @mock.patch('website.addons.github.api.GitHub.from_settings') @mock.patch('website.project.views.file.get_cache_content') def test_view_file(self, mock_cache, mock_settings, mock_contents): github_mock = self.github mock_settings.return_value = github_mock sha = self.github.tree.return_value.tree[0].sha github_mock.history.return_value = [{ 'sha': sha, 'name': 'fred', 'email': '{0}@osf.io'.format(self.user._id), 'date': datetime.date(2011, 10, 15).ctime(), }] mock_cache.return_value = "this is some html" guid = GithubGuidFile() path = github_mock.tree.return_value.tree[0].path guid.path = path guid.node = self.project guid.save() mock_contents.return_value.sha = sha github_mock.contents.return_value = mock_contents github_mock.file.return_value = (' ', ' ', 255) url = self.project.web_url_for('github_view_file', sha=sha, path=path) res = self.app.get( url, auth=self.user.auth, ) assert_equal(res.status_code, 302) res2 = res.follow(auth=self.user.auth) assert_equal(res2.request.path, '/{0}/'.format(guid._id)) assert_equal(res2.status_code, 200) @mock.patch('website.addons.github.api.GitHub.from_settings') @mock.patch('website.addons.github.views.crud.build_github_urls') def test_update_file(self, mock_urls, mock_settings): github_mock = self.github sha = github_mock.tree.return_value.tree[0].sha size = github_mock.tree.return_value.tree[0].size file_name = github_mock.tree.return_value.tree[0].path file_content = 'my_data' branch = 'master' mock_settings.return_value = github_mock github_mock.update_file.return_value = { 'commit': Commit(dict(sha=sha)), 'content': Contents(dict(size=size, url='http://fake.url/')), } mock_urls.return_value = {} url = self.project.api_url_for('github_upload_file', branch=branch, sha=sha) self.app.post( url, upload_files=[ ('file', file_name, file_content), ], auth=self.user.auth, ) github_mock.update_file.assert_called_once_with( self.node_settings.user, self.node_settings.repo, file_name, MESSAGES['update'], file_content, sha=sha, branch=branch, author={ 'name': self.user.fullname, 'email': '{0}@osf.io'.format(self.user._id), }, ) @mock.patch('website.addons.github.api.GitHub.file') def test_download_file(self, mock_file): file_name = 'my_file' file_content = 'my_content' file_size = 1024 mock_file.return_value = (file_name, file_content, file_size) url = self.project.web_url_for( 'github_download_file', path='my_file', branch='master', ) res = self.app.get( url, auth=self.user.auth, ) assert_equal(res.body, file_content) @mock.patch('website.addons.github.api.GitHub.file') def test_download_file_too_big(self, mock_file): mock_file.side_effect = TooBigError url = self.project.web_url_for( 'github_download_file', path='my_file', branch='master', ) res = self.app.get( url, auth=self.user.auth, expect_errors=True, ) assert_equal(res.status_code, http.BAD_REQUEST) @mock.patch('website.addons.github.api.GitHub.from_settings') @mock.patch('website.addons.github.api.GitHub.delete_file') @mock.patch('website.addons.github.api.GitHub.file') def test_delete_file(self, mock_file, mock_delete, mock_settings): github_mock = self.github sha = github_mock.tree.return_value.tree[0].sha size = github_mock.tree.return_value.tree[0].size file_name = github_mock.tree.return_value.tree[0].path branch = 'master' mock_settings.return_value = github_mock github_mock.delete_file.return_value = { 'commit': Commit(dict(sha=sha)), } url = self.project.api_url_for('github_delete_file', sha=sha, path=file_name, branch=branch) self.app.delete( url, auth=self.user.auth, ) github_mock.delete_file.assert_called_once_with( self.node_settings.user, self.node_settings.repo, file_name, MESSAGES['delete'], sha=sha, branch=branch, author={ 'name': self.user.fullname, 'email': '{0}@osf.io'.format(self.user._id), }, )
class RegistrationEmbargoViewsTestCase(OsfTestCase): def setUp(self): super(RegistrationEmbargoViewsTestCase, self).setUp() ensure_schemas() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.draft = DraftRegistrationFactory(branched_from=self.project) self.registration = RegistrationFactory(project=self.project, creator=self.user) current_month = 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.celery_tasks.handlers.enqueue_task') def test_register_draft_without_embargo_creates_registration_approval(self, mock_enqueue): res = self.app.post( self.project.api_url_for('register_draft_registration', draft_id=self.draft._id), self.valid_make_public_payload, content_type='application/json', auth=self.user.auth ) assert_equal(res.status_code, 202) registration = 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.celery_tasks.handlers.enqueue_task') def test_POST_register_make_public_immediately_creates_private_pending_registration_for_public_project(self, mock_enqueue): self.project.is_public = True self.project.save() component = NodeFactory( creator=self.user, parent=self.project, title='Component', is_public=True ) subproject = ProjectFactory( creator=self.user, parent=self.project, title='Subproject', is_public=True ) subproject_component = NodeFactory( creator=self.user, parent=subproject, title='Subcomponent', is_public=True ) res = self.app.post( self.project.api_url_for('register_draft_registration', draft_id=self.draft._id), self.valid_make_public_payload, content_type='application/json', auth=self.user.auth ) self.project.reload() assert_equal(res.status_code, 202) assert_equal(res.json['urls']['registrations'], self.project.web_url_for('node_registrations')) # Last node directly registered from self.project registration = Node.find( Q('registered_from', 'eq', self.project) ).sort('-registered_date')[0] assert_true(registration.is_registration) assert_false(registration.is_public) for node in registration.get_descendants_recursive(): assert_true(node.is_registration) assert_false(node.is_public) @mock.patch('framework.celery_tasks.handlers.enqueue_task') def test_POST_register_make_public_does_not_make_children_public(self, mock_enqueue): 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('register_draft_registration', draft_id=self.draft._id), self.valid_make_public_payload, content_type='application/json', auth=self.user.auth ) self.project.reload() # Last node directly registered from self.project registration = self.project.registrations_all[-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.celery_tasks.handlers.enqueue_task') def test_POST_register_embargo_is_not_public(self, mock_enqueue): res = self.app.post( self.project.api_url_for('register_draft_registration', draft_id=self.draft._id), self.valid_embargo_payload, content_type='application/json', auth=self.user.auth ) assert_equal(res.status_code, 202) registration = 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.celery_tasks.handlers.enqueue_task') def test_POST_register_embargo_does_not_make_project_or_children_public(self, mock_enqueue): self.project.is_public = True self.project.save() component = NodeFactory( creator=self.user, parent=self.project, title='Component', is_public=True ) subproject = ProjectFactory( creator=self.user, parent=self.project, title='Subproject', is_public=True ) subproject_component = NodeFactory( creator=self.user, parent=subproject, title='Subcomponent', is_public=True ) res = self.app.post( self.project.api_url_for('register_draft_registration', draft_id=self.draft._id), self.valid_embargo_payload, content_type='application/json', auth=self.user.auth ) self.project.reload() assert_equal(res.status_code, 202) assert_equal(res.json['urls']['registrations'], self.project.web_url_for('node_registrations')) # Last node directly registered from self.project registration = Node.find( Q('registered_from', 'eq', self.project) ).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) for node in registration.get_descendants_recursive(): assert_true(node.is_registration) assert_false(node.is_public) @mock.patch('framework.celery_tasks.handlers.enqueue_task') def test_POST_invalid_embargo_end_date_returns_HTTPBad_Request(self, mock_enqueue): res = self.app.post( self.project.api_url_for('register_draft_registration', draft_id=self.draft._id), self.invalid_embargo_date_payload, content_type='application/json', auth=self.user.auth, expect_errors=True ) assert_equal(res.status_code, 400) @mock.patch('framework.celery_tasks.handlers.enqueue_task') def test_valid_POST_embargo_adds_to_parent_projects_log(self, mock_enquque): initial_project_logs = len(self.project.logs) self.app.post( self.project.api_url_for('register_draft_registration', draft_id=self.draft._id), self.valid_embargo_payload, content_type='application/json', auth=self.user.auth ) self.project.reload() # Logs: Created, registered, embargo initiated assert_equal(len(self.project.logs), initial_project_logs + 1) @mock.patch('website.project.sanctions.TokenApprovableSanction.ask') def test_embargoed_registration_set_privacy_requests_embargo_termination(self, mock_ask): # Initiate and approve embargo for i in range(3): c = AuthUserFactory() self.registration.add_contributor(c, [permissions.ADMIN], auth=Auth(self.user)) self.registration.save() self.registration.embargo_registration( self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10) ) for user_id, embargo_tokens in self.registration.embargo.approval_state.iteritems(): approval_token = embargo_tokens['approval_token'] self.registration.embargo.approve_embargo(User.load(user_id), approval_token) self.registration.save() res = self.app.post( self.registration.api_url_for('project_set_privacy', permissions='public'), auth=self.user.auth, ) assert_equal(res.status_code, 200) for reg in self.registration.node_and_primary_descendants(): reg.reload() assert_false(reg.is_public) assert_true(reg.embargo_termination_approval) assert_true(reg.embargo_termination_approval.is_pending_approval) def test_cannot_request_termination_on_component_of_embargo(self): node = ProjectFactory() child = ProjectFactory(parent=node, creator=node.creator) with utils.mock_archive(node, embargo=True, autocomplete=True, autoapprove=True) as reg: with assert_raises(NodeStateError): reg.nodes[0].request_embargo_termination(Auth(node.creator)) @mock.patch('website.mails.send_mail') def test_embargoed_registration_set_privacy_sends_mail(self, mock_send_mail): """ Integration test for https://github.com/CenterForOpenScience/osf.io/pull/5294#issuecomment-212613668 """ # Initiate and approve embargo for i in range(3): c = AuthUserFactory() self.registration.add_contributor(c, [permissions.ADMIN], auth=Auth(self.user)) self.registration.save() self.registration.embargo_registration( self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10) ) for user_id, embargo_tokens in self.registration.embargo.approval_state.iteritems(): approval_token = embargo_tokens['approval_token'] self.registration.embargo.approve_embargo(User.load(user_id), approval_token) self.registration.save() res = self.app.post( self.registration.api_url_for('project_set_privacy', permissions='public'), auth=self.user.auth, ) assert_equal(res.status_code, 200) for admin in self.registration.admin_contributors: assert_true(any([c[0][0] == admin.username for c in mock_send_mail.call_args_list])) @mock.patch('website.project.sanctions.TokenApprovableSanction.ask') def test_make_child_embargoed_registration_public_asks_all_admins_in_tree(self, mock_ask): # Initiate and approve embargo node = NodeFactory(creator=self.user) c1 = AuthUserFactory() child = NodeFactory(parent=node, creator=c1) c2 = AuthUserFactory() NodeFactory(parent=child, creator=c2) registration = RegistrationFactory(project=node) registration.embargo_registration( self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10) ) for user_id, embargo_tokens in registration.embargo.approval_state.iteritems(): approval_token = embargo_tokens['approval_token'] registration.embargo.approve_embargo(User.load(user_id), approval_token) self.registration.save() res = self.app.post( registration.api_url_for('project_set_privacy', permissions='public'), auth=self.user.auth ) assert_equal(res.status_code, 200) asked_admins = [(admin._id, n._id) for admin, n in mock_ask.call_args[0][0]] for admin, node in registration.get_admin_contributors_recursive(): assert_in((admin._id, node._id), asked_admins) def test_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_true(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_true(self.registration.embargo_end_date)
class TestGitHubFileView(OsfTestCase): def setUp(self): super(TestGitHubFileView, self).setUp() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.project = ProjectFactory(creator=self.user) self.project.add_addon('github', auth=self.consolidated_auth) self.project.creator.add_addon('github') self.github = create_mock_github(user='******', private=False) self.node_settings = self.project.get_addon('github') self.node_settings.user_settings = self.project.creator.get_addon('github') # Set the node addon settings to correspond to the values of the mock repo self.node_settings.user = self.github.repo.return_value.owner.login self.node_settings.repo = self.github.repo.return_value.name self.node_settings.save() @mock.patch('website.addons.github.api.GitHub.commits') @mock.patch('website.addons.github.api.GitHub.file') @mock.patch('website.addons.github.api.GitHub.repo') def test_can_see_files_tab(self, mock_repo, mock_file, mock_commits): mock_commits.return_value = [Commit.from_json({ "url": "https://api.github.com/repos/octocat/Hello-World/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e", "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e", "commit": { "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e", "author": { "name": "Monalisa Octocat", "email": "*****@*****.**", "date": "2011-04-14T16:00:49Z" } } })] mock_repo.return_value = Repository.from_json({ "default_branch": "dev", 'url': u'https://api.github.com/repos/{user}/mock-repo/git/trees/dev'.format(user=self.user), 'sha': 'dev', 'private': False, 'tree': [ {u'mode': u'100644', u'path': u'coveragerc', u'sha': u'92029ff5ce192425d346b598d7e7dd25f5f05185', u'size': 245, u'type': u'file', u'url': u'https://api.github.com/repos/{user}/mock-repo/git/blobs/92029ff5ce192425d346b598d7e7dd25f5f05185'.format(user=self.user)}] }) mock_file.return_value = { u'name': u'coveragerc', u'content': u'ClRleHRCbG9iOiBTaW1wbGlmaWVkIFRleHQgUHJvY2Vzc2luZwo9PT09PT09', u'size': 245 } res = self.app.get(self.project.url, auth=self.user.auth) assert_in('a href="/{0}/files/"'.format(self.project._id), res) @mock.patch('website.addons.github.api.GitHub.commits') @mock.patch('website.addons.github.api.GitHub.file') @mock.patch('website.addons.github.api.GitHub.repo') @mock.patch('website.addons.github.api.GitHub.contents') def test_file_view(self, mock_contents, mock_repo, mock_file, mock_commits): mock_contents.return_value = None mock_commits.return_value = [Commit.from_json({ "url": "https://api.github.com/repos/octocat/Hello-World/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e", "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e", "commit": { "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e", "author": { "name": "Monalisa Octocat", "email": "*****@*****.**", "date": "2011-04-14T16:00:49Z" } } })] mock_repo.return_value = Repository.from_json({ "default_branch": "dev", 'url': u'https://api.github.com/repos/{user}/mock-repo/git/trees/dev'.format(user=self.user), 'sha': 'dev', 'private': False, 'tree': [ {u'mode': u'100644', u'path': u'coveragerc', u'sha': u'92029ff5ce192425d346b598d7e7dd25f5f05185', u'size': 245, u'type': u'file', u'url': u'https://api.github.com/repos/{user}/mock-repo/git/blobs/92029ff5ce192425d346b598d7e7dd25f5f05185'.format(user=self.user)}] }) mock_file.return_value = { u'name': u'coveragerc', u'content': u'ClRleHRCbG9iOiBTaW1wbGlmaWVkIFRleHQgUHJvY2Vzc2luZwo9PT09PT09', u'size': 245 } url = "/project/{0}/github/file/{1}/".format( self.project._id, "coveragerc" ) self.app.auth = self.user.auth res = self.app.get(url).maybe_follow() assert_in("6dcb09b5b57875f334f61aebed695e2e4193db5e", res) assert_in("Thu Apr 14 16:00:49 2011", res) assert_in("file-version-history", res) assert_in("icon-download-alt", res) @mock.patch('website.addons.github.api.GitHub.commits') @mock.patch('website.addons.github.api.GitHub.file') @mock.patch('website.addons.github.api.GitHub.repo') @mock.patch('website.addons.github.api.GitHub.contents') def test_file_view_deleted(self, mock_contents, mock_repo, mock_file, mock_commits): mock_contents.return_value = None mock_commits.return_value = [Commit.from_json({ "url": "https://api.github.com/repos/octocat/Hello-World/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e", "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e", "commit": { "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e", "author": { "name": "Monalisa Octocat", "email": "*****@*****.**", "date": "2011-04-14T16:00:49Z" } } })] mock_repo.return_value = Repository.from_json({ "default_branch": "dev", 'url': u'https://api.github.com/repos/{user}/mock-repo/git/trees/dev'.format(user=self.user), 'sha': 'dev', 'private': False, 'tree': [ {u'mode': u'100644', u'path': u'coveragerc', u'sha': u'92029ff5ce192425d346b598d7e7dd25f5f05185', u'size': 245, u'type': u'file', u'url': u'https://api.github.com/repos/{user}/mock-repo/git/blobs/92029ff5ce192425d346b598d7e7dd25f5f05185'.format(user=self.user)}] }) mock_file.return_value = (None, None, None) url = "/project/{0}/github/file/{1}/".format( self.project._id, "coveragerc" ) self.app.auth = self.user.auth res = self.app.get(url).maybe_follow() assert_in("icon-download-alt", res) assert_in("Thu Apr 14 16:00:49 2011", res) assert_in("This file does not exist at this commit", res) assert_in("6dcb09b5b57875f334f61aebed695e2e4193db5e", res) @mock.patch('website.addons.github.api.GitHub.commits') @mock.patch('website.addons.github.api.GitHub.file') @mock.patch('website.addons.github.api.GitHub.repo') @mock.patch('website.addons.github.api.GitHub.contents') def test_file_view_with_anonymous_link(self, mock_contents, mock_repo, mock_file, mock_commits): mock_contents.return_value = None mock_commits.return_value = [Commit.from_json({ "url": "https://api.github.com/repos/octocat/Hello-World/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e", "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e", "commit": { "url": "https://api.github.com/repos/octocat/Hello-World/git/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e", "author": { "name": "Monalisa Octocat", "email": "*****@*****.**", "date": "2011-04-14T16:00:49Z" } } })] mock_repo.return_value = Repository.from_json({ "default_branch": "dev", 'url': u'https://api.github.com/repos/{user}/mock-repo/git/trees/dev'.format(user=self.user), 'sha': 'dev', 'private': False, 'tree': [ {u'mode': u'100644', u'path': u'coveragerc', u'sha': u'92029ff5ce192425d346b598d7e7dd25f5f05185', u'size': 245, u'type': u'file', u'url': u'https://api.github.com/repos/{user}/mock-repo/git/blobs/92029ff5ce192425d346b598d7e7dd25f5f05185'.format(user=self.user)}] }) mock_file.return_value = { u'name': u'coveragerc', u'content': u'ClRleHRCbG9iOiBTaW1wbGlmaWVkIFRleHQgUHJvY2Vzc2luZwo9PT09PT09', u'size': 245 } link = PrivateLinkFactory(anonymous=True) link.nodes.append(self.project) link.save() url = self.project.web_url_for('github_view_file', path="coveragerc") res = self.app.get(url, {'view_only': link.key}).maybe_follow() assert_in("6dcb09b5b57875f334f61aebed695e2e4193db5e", res) assert_in("Thu Apr 14 16:00:49 2011", res) assert_in("file-version-history", res) assert_in("icon-download-alt", res) assert_not_in("Monalisa Octocat", res) assert_not_in("*****@*****.**", res)
class TestComponents(OsfTestCase): def setUp(self): super(TestComponents, self).setUp() self.user = AuthUserFactory() self.consolidate_auth = Auth(user=self.user) self.project = ProjectFactory(creator=self.user) self.project.add_contributor(contributor=self.user, auth=self.consolidate_auth) # A non-project componenet self.component = NodeFactory( category='hypothesis', creator=self.user, parent=self.project, ) self.component.save() self.component.set_privacy('public', self.consolidate_auth) self.component.set_privacy('private', self.consolidate_auth) self.project.save() self.project_url = self.project.web_url_for('view_project') def test_sees_parent(self): res = self.app.get(self.component.url, auth=self.user.auth).maybe_follow() parent_title = res.html.find_all('h2', class_='node-parent-title') assert_equal(len(parent_title), 1) assert_in(self.project.title, parent_title[0].text) # Bs4 will handle unescaping HTML here def test_delete_project(self): res = self.app.get( self.component.url + 'settings/', auth=self.user.auth ).maybe_follow() assert_in( 'Delete {0}'.format(self.component.project_or_component), res ) def test_cant_delete_project_if_not_admin(self): non_admin = AuthUserFactory() self.component.add_contributor( non_admin, permissions=['read', 'write'], auth=self.consolidate_auth, save=True, ) res = self.app.get( self.component.url + 'settings/', auth=non_admin.auth ).maybe_follow() assert_not_in( 'Delete {0}'.format(self.component.project_or_component), res ) def test_can_configure_comments_if_admin(self): res = self.app.get( self.component.url + 'settings/', auth=self.user.auth, ).maybe_follow() assert_in('Commenting', res) def test_cant_configure_comments_if_not_admin(self): non_admin = AuthUserFactory() self.component.add_contributor( non_admin, permissions=['read', 'write'], auth=self.consolidate_auth, save=True, ) res = self.app.get( self.component.url + 'settings/', auth=non_admin.auth ).maybe_follow() assert_not_in('Commenting', res) def test_components_should_have_component_list(self): res = self.app.get(self.component.url, auth=self.user.auth) assert_in('Components', 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 TestWikiUuid(OsfTestCase): def setUp(self): super(TestWikiUuid, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(is_public=True, creator=self.user) self.wname = 'foo.bar' self.wkey = to_mongo_key(self.wname) def test_uuid_generated_once(self): assert_is_none(self.project.wiki_private_uuids.get(self.wkey)) url = self.project.web_url_for('project_wiki_view', wname=self.wname) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) self.project.reload() private_uuid = self.project.wiki_private_uuids.get(self.wkey) assert_true(private_uuid) assert_not_in(private_uuid, res.body) assert_in(get_sharejs_uuid(self.project, self.wname), res.body) # Revisit page; uuid has not changed res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) self.project.reload() assert_equal(private_uuid, self.project.wiki_private_uuids.get(self.wkey)) def test_uuid_not_visible_without_write_permission(self): self.project.update_node_wiki(self.wname, 'some content', Auth(self.user)) self.project.save() assert_is_none(self.project.wiki_private_uuids.get(self.wkey)) url = self.project.web_url_for('project_wiki_view', wname=self.wname) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) self.project.reload() private_uuid = self.project.wiki_private_uuids.get(self.wkey) assert_true(private_uuid) assert_not_in(private_uuid, res.body) assert_in(get_sharejs_uuid(self.project, self.wname), res.body) # Users without write permission should not be able to access res = self.app.get(url) assert_equal(res.status_code, 200) assert_not_in(get_sharejs_uuid(self.project, self.wname), res.body) def test_uuid_not_generated_without_write_permission(self): self.project.update_node_wiki(self.wname, 'some content', Auth(self.user)) self.project.save() assert_is_none(self.project.wiki_private_uuids.get(self.wkey)) url = self.project.web_url_for('project_wiki_view', wname=self.wname) res = self.app.get(url) assert_equal(res.status_code, 200) self.project.reload() private_uuid = self.project.wiki_private_uuids.get(self.wkey) assert_is_none(private_uuid) def test_uuids_differ_between_pages(self): wname1 = 'foo.bar' url1 = self.project.web_url_for('project_wiki_view', wname=wname1) res1 = self.app.get(url1, auth=self.user.auth) assert_equal(res1.status_code, 200) wname2 = 'bar.baz' url2 = self.project.web_url_for('project_wiki_view', wname=wname2) res2 = self.app.get(url2, auth=self.user.auth) assert_equal(res2.status_code, 200) self.project.reload() uuid1 = get_sharejs_uuid(self.project, wname1) uuid2 = get_sharejs_uuid(self.project, wname2) assert_not_equal(uuid1, uuid2) assert_in(uuid1, res1) assert_in(uuid2, res2) assert_not_in(uuid1, res2) assert_not_in(uuid2, res1) def test_uuids_differ_between_forks(self): url = self.project.web_url_for('project_wiki_view', wname=self.wname) project_res = self.app.get(url, auth=self.user.auth) assert_equal(project_res.status_code, 200) self.project.reload() fork = self.project.fork_node(Auth(self.user)) assert_true(fork.is_fork_of(self.project)) fork_url = fork.web_url_for('project_wiki_view', wname=self.wname) fork_res = self.app.get(fork_url, auth=self.user.auth) assert_equal(fork_res.status_code, 200) fork.reload() # uuids are stored the same internally assert_equal( self.project.wiki_private_uuids.get(self.wkey), fork.wiki_private_uuids.get(self.wkey) ) project_uuid = get_sharejs_uuid(self.project, self.wname) fork_uuid = get_sharejs_uuid(fork, self.wname) assert_not_equal(project_uuid, fork_uuid) assert_in(project_uuid, project_res) assert_in(fork_uuid, fork_res) assert_not_in(project_uuid, fork_res) assert_not_in(fork_uuid, project_res) @mock.patch('website.addons.wiki.utils.broadcast_to_sharejs') def test_migration_does_not_affect_forks(self, mock_sharejs): original_uuid = generate_private_uuid(self.project, self.wname) self.project.update_node_wiki(self.wname, 'Hello world', Auth(self.user)) fork = self.project.fork_node(Auth(self.user)) assert_equal(original_uuid, fork.wiki_private_uuids.get(self.wkey)) migrate_uuid(self.project, self.wname) assert_not_equal(original_uuid, self.project.wiki_private_uuids.get(self.wkey)) assert_equal(original_uuid, fork.wiki_private_uuids.get(self.wkey)) @mock.patch('website.addons.wiki.utils.broadcast_to_sharejs') def test_uuid_persists_after_delete(self, mock_sharejs): assert_is_none(self.project.wiki_private_uuids.get(self.wkey)) # Create wiki page self.project.update_node_wiki(self.wname, 'Hello world', Auth(self.user)) # Visit wiki edit page edit_url = self.project.web_url_for('project_wiki_view', wname=self.wname) res = self.app.get(edit_url, auth=self.user.auth) assert_equal(res.status_code, 200) self.project.reload() original_private_uuid = self.project.wiki_private_uuids.get(self.wkey) original_sharejs_uuid = get_sharejs_uuid(self.project, self.wname) # Delete wiki delete_url = self.project.api_url_for('project_wiki_delete', wname=self.wname) res = self.app.delete(delete_url, auth=self.user.auth) assert_equal(res.status_code, 200) self.project.reload() assert_equal(original_private_uuid, self.project.wiki_private_uuids.get(self.wkey)) # Revisit wiki edit page res = self.app.get(edit_url, auth=self.user.auth) assert_equal(res.status_code, 200) self.project.reload() assert_equal(original_private_uuid, self.project.wiki_private_uuids.get(self.wkey)) assert_in(original_sharejs_uuid, res.body) @mock.patch('website.addons.wiki.utils.broadcast_to_sharejs') def test_uuid_persists_after_rename(self, mock_sharejs): new_wname = 'bar.baz' new_wkey = to_mongo_key(new_wname) assert_is_none(self.project.wiki_private_uuids.get(self.wkey)) assert_is_none(self.project.wiki_private_uuids.get(new_wkey)) # Create wiki page self.project.update_node_wiki(self.wname, 'Hello world', Auth(self.user)) wiki_page = self.project.get_wiki_page(self.wname) # Visit wiki edit page original_edit_url = self.project.web_url_for('project_wiki_view', wname=self.wname) res = self.app.get(original_edit_url, auth=self.user.auth) assert_equal(res.status_code, 200) self.project.reload() original_private_uuid = self.project.wiki_private_uuids.get(self.wkey) original_sharejs_uuid = get_sharejs_uuid(self.project, self.wname) # Rename wiki rename_url = self.project.api_url_for('project_wiki_rename', wname=self.wname) res = self.app.put_json( rename_url, {'value': new_wname, 'pk': wiki_page._id}, auth=self.user.auth, ) assert_equal(res.status_code, 200) self.project.reload() assert_is_none(self.project.wiki_private_uuids.get(self.wkey)) assert_equal(original_private_uuid, self.project.wiki_private_uuids.get(new_wkey)) # Revisit original wiki edit page res = self.app.get(original_edit_url, auth=self.user.auth) assert_equal(res.status_code, 200) self.project.reload() assert_not_equal(original_private_uuid, self.project.wiki_private_uuids.get(self.wkey)) assert_not_in(original_sharejs_uuid, res.body)
class TestGithubViews(OsfTestCase): def setUp(self): super(TestGithubViews, self).setUp() self.user = AuthUserFactory() self.consolidated_auth = Auth(user=self.user) self.project = ProjectFactory(creator=self.user) self.non_authenticator = UserFactory() self.project.add_contributor( contributor=self.non_authenticator, auth=self.consolidated_auth, ) self.project.save() self.project.add_addon('github', auth=self.consolidated_auth) self.project.creator.add_addon('github') self.github = create_mock_github(user='******', private=False) self.node_settings = self.project.get_addon('github') self.node_settings.user_settings = self.project.creator.get_addon( 'github') # Set the node addon settings to correspond to the values of the mock repo self.node_settings.user = self.github.repo.return_value.owner.login self.node_settings.repo = self.github.repo.return_value.name self.node_settings.save() def _get_sha_for_branch(self, branch=None, mock_branches=None): github_mock = self.github if mock_branches is None: mock_branches = github_mock.branches if branch is None: # Get default branch name branch = self.github.repo.return_value.default_branch for each in mock_branches.return_value: if each.name == branch: branch_sha = each.commit.sha return branch_sha # Tests for _get_refs @mock.patch('website.addons.github.api.GitHub.branches') @mock.patch('website.addons.github.api.GitHub.repo') def test_get_refs_defaults(self, mock_repo, mock_branches): github_mock = self.github mock_repo.return_value = github_mock.repo.return_value mock_branches.return_value = github_mock.branches.return_value branch, sha, branches = utils.get_refs(self.node_settings) assert_equal(branch, github_mock.repo.return_value.default_branch) assert_equal(sha, self._get_sha_for_branch( branch=None)) # Get refs for default branch assert_equal(branches, github_mock.branches.return_value) @mock.patch('website.addons.github.api.GitHub.branches') @mock.patch('website.addons.github.api.GitHub.repo') def test_get_refs_branch(self, mock_repo, mock_branches): github_mock = self.github mock_repo.return_value = github_mock.repo.return_value mock_branches.return_value = github_mock.branches.return_value branch, sha, branches = utils.get_refs(self.node_settings, 'master') assert_equal(branch, 'master') branch_sha = self._get_sha_for_branch('master') assert_equal(sha, branch_sha) assert_equal(branches, github_mock.branches.return_value) def test_before_remove_contributor_authenticator(self): url = self.project.api_url + 'beforeremovecontributors/' res = self.app.post_json( url, { 'id': self.project.creator._id }, auth=self.user.auth, ).maybe_follow() # One prompt for transferring auth, one for removing self assert_equal(len(res.json['prompts']), 2) def test_before_remove_contributor_not_authenticator(self): url = self.project.api_url + 'beforeremovecontributors/' res = self.app.post_json( url, { 'id': self.non_authenticator._id }, auth=self.user.auth, ).maybe_follow() assert_equal(len(res.json['prompts']), 0) def test_before_fork(self): url = self.project.api_url + 'fork/before/' res = self.app.get(url, auth=self.user.auth).maybe_follow() assert_equal(len(res.json['prompts']), 1) @mock.patch('website.addons.github.model.AddonGitHubUserSettings.has_auth') def test_before_register(self, mock_has_auth): mock_has_auth.return_value = True url = self.project.api_url + 'beforeregister/' res = self.app.get(url, auth=self.user.auth).maybe_follow() assert_equal(len(res.json['prompts']), 1) def test_get_refs_sha_no_branch(self): with assert_raises(HTTPError): utils.get_refs(self.node_settings, sha='12345') def test_get_refs_registered_missing_branch(self): github_mock = self.github self.node_settings.registration_data = { 'branches': [branch.to_json() for branch in github_mock.branches.return_value] } self.node_settings.owner.is_registration = True with assert_raises(HTTPError): utils.get_refs(self.node_settings, branch='nothere') # Tests for _check_permissions # make a user with no authorization; make sure check_permissions returns false def test_permissions_no_auth(self): github_mock = self.github # project is set to private right now connection = github_mock non_authenticated_user = UserFactory() non_authenticated_auth = Auth(user=non_authenticated_user) branch = 'master' assert_false( check_permissions(self.node_settings, non_authenticated_auth, connection, branch)) # make a repository that doesn't allow push access for this user; # make sure check_permissions returns false @mock.patch('website.addons.github.model.AddonGitHubUserSettings.has_auth') @mock.patch('website.addons.github.api.GitHub.repo') def test_permissions_no_access(self, mock_repo, mock_has_auth): github_mock = self.github mock_has_auth.return_value = True connection = github_mock branch = 'master' mock_repository = mock.NonCallableMock() mock_repository.user = '******' mock_repository.repo = 'mock-repo' mock_repository.to_json.return_value = { 'user': '******', 'repo': 'mock-repo', 'permissions': { 'push': False, # this is key }, } mock_repo.return_value = mock_repository assert_false( check_permissions(self.node_settings, self.consolidated_auth, connection, branch, repo=mock_repository)) # make a branch with a different commit than the commit being passed into check_permissions @mock.patch('website.addons.github.model.AddonGitHubUserSettings.has_auth') def test_permissions_not_head(self, mock_has_auth): github_mock = self.github mock_has_auth.return_value = True connection = github_mock mock_branch = mock.NonCallableMock() mock_branch.commit.sha = '67890' sha = '12345' assert_false( check_permissions(self.node_settings, self.consolidated_auth, connection, mock_branch, sha=sha)) # make sure permissions are not granted for editing a registration @mock.patch('website.addons.github.model.AddonGitHubUserSettings.has_auth') def test_permissions(self, mock_has_auth): github_mock = self.github mock_has_auth.return_value = True connection = github_mock self.node_settings.owner.is_registration = True assert_false( check_permissions(self.node_settings, self.consolidated_auth, connection, 'master')) # TODO: Write me def test_dummy_folder(self): pass def test_dummy_folder_parent(self): pass def test_dummy_folder_refs(self): pass # TODO: Write me def test_github_contents(self): pass def check_hook_urls(self, urls, node, path, sha): assert_equal( urls['view'], node.web_url_for( 'github_view_file', path=path, sha=sha, ), ) assert_equal( urls['download'], node.web_url_for( 'github_download_file', path=path, sha=sha, ), ) @mock.patch('website.addons.github.views.hooks.utils.verify_hook_signature' ) def test_hook_callback_add_file_not_thro_osf(self, mock_verify): url = "/api/v1/project/{0}/github/hook/".format(self.project._id) self.app.post_json( url, { "test": True, "commits": [{ "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "distinct": True, "message": "foo", "timestamp": "2014-01-08T14:15:51-08:00", "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "author": { "name": "Illidan", "email": "*****@*****.**" }, "committer": { "name": "Testor", "email": "*****@*****.**", "username": "******" }, "added": ["PRJWN3TV"], "removed": [], "modified": [], }] }, content_type="application/json", ).maybe_follow() self.project.reload() assert_equal(self.project.logs[-1].action, "github_file_added") urls = self.project.logs[-1].params['urls'] self.check_hook_urls( urls, self.project, path='PRJWN3TV', sha='b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', ) @mock.patch('website.addons.github.views.hooks.utils.verify_hook_signature' ) def test_hook_callback_modify_file_not_thro_osf(self, mock_verify): url = "/api/v1/project/{0}/github/hook/".format(self.project._id) self.app.post_json(url, { "test": True, "commits": [{ "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "distinct": True, "message": " foo", "timestamp": "2014-01-08T14:15:51-08:00", "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "author": { "name": "Illidan", "email": "*****@*****.**" }, "committer": { "name": "Testor", "email": "*****@*****.**", "username": "******" }, "added": [], "removed": [], "modified": ["PRJWN3TV"] }] }, content_type="application/json").maybe_follow() self.project.reload() assert_equal(self.project.logs[-1].action, "github_file_updated") urls = self.project.logs[-1].params['urls'] self.check_hook_urls( urls, self.project, path='PRJWN3TV', sha='b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce', ) @mock.patch('website.addons.github.views.hooks.utils.verify_hook_signature' ) def test_hook_callback_remove_file_not_thro_osf(self, mock_verify): url = "/api/v1/project/{0}/github/hook/".format(self.project._id) self.app.post_json(url, { "test": True, "commits": [{ "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "distinct": True, "message": "foo", "timestamp": "2014-01-08T14:15:51-08:00", "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "author": { "name": "Illidan", "email": "*****@*****.**" }, "committer": { "name": "Testor", "email": "*****@*****.**", "username": "******" }, "added": [], "removed": ["PRJWN3TV"], "modified": [] }] }, content_type="application/json").maybe_follow() self.project.reload() assert_equal(self.project.logs[-1].action, "github_file_removed") urls = self.project.logs[-1].params['urls'] assert_equal(urls, {}) @mock.patch('website.addons.github.views.hooks.utils.verify_hook_signature' ) def test_hook_callback_add_file_thro_osf(self, mock_verify): url = "/api/v1/project/{0}/github/hook/".format(self.project._id) self.app.post_json(url, { "test": True, "commits": [{ "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "distinct": True, "message": "Added via the Open Science Framework", "timestamp": "2014-01-08T14:15:51-08:00", "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "author": { "name": "Illidan", "email": "*****@*****.**" }, "committer": { "name": "Testor", "email": "*****@*****.**", "username": "******" }, "added": ["PRJWN3TV"], "removed": [], "modified": [] }] }, content_type="application/json").maybe_follow() self.project.reload() assert_not_equal(self.project.logs[-1].action, "github_file_added") @mock.patch('website.addons.github.views.hooks.utils.verify_hook_signature' ) def test_hook_callback_modify_file_thro_osf(self, mock_verify): url = "/api/v1/project/{0}/github/hook/".format(self.project._id) self.app.post_json(url, { "test": True, "commits": [{ "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "distinct": True, "message": "Updated via the Open Science Framework", "timestamp": "2014-01-08T14:15:51-08:00", "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "author": { "name": "Illidan", "email": "*****@*****.**" }, "committer": { "name": "Testor", "email": "*****@*****.**", "username": "******" }, "added": [], "removed": [], "modified": ["PRJWN3TV"] }] }, content_type="application/json").maybe_follow() self.project.reload() assert_not_equal(self.project.logs[-1].action, "github_file_updated") @mock.patch('website.addons.github.views.hooks.utils.verify_hook_signature' ) def test_hook_callback_remove_file_thro_osf(self, mock_verify): url = "/api/v1/project/{0}/github/hook/".format(self.project._id) self.app.post_json(url, { "test": True, "commits": [{ "id": "b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "distinct": True, "message": "Deleted via the Open Science Framework", "timestamp": "2014-01-08T14:15:51-08:00", "url": "https://github.com/tester/addontesting/commit/b08dbb5b6fcd74a592e5281c9d28e2020a1db4ce", "author": { "name": "Illidan", "email": "*****@*****.**" }, "committer": { "name": "Testor", "email": "*****@*****.**", "username": "******" }, "added": [], "removed": ["PRJWN3TV"], "modified": [] }] }, content_type="application/json").maybe_follow() self.project.reload() assert_not_equal(self.project.logs[-1].action, "github_file_removed") @mock.patch('website.addons.github.api.GitHub.history') @mock.patch('website.addons.github.api.GitHub.contents') @mock.patch('website.addons.github.api.GitHub.repo') def test_view_not_found_does_not_create_guid(self, mock_repo, mock_contents, mock_history): github_mock = self.github mock_repo.return_value = github_mock.repo.return_value mock_contents.return_value = github_mock.contents.return_value[ 'octokit'] mock_history.return_value = [] guid_count = GithubGuidFile.find().count() # View file for the first time # Because we've overridden mock_history above, it doesn't matter if the # file exists. url = self.project.web_url_for('github_view_file', path='test.py') res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal( 404, res.status_code, ) guids = GithubGuidFile.find() # GUID count has not changed assert_equal( guids.count(), guid_count, ) @mock.patch('website.addons.github.api.GitHub.history') @mock.patch('website.addons.github.api.GitHub.contents') @mock.patch('website.addons.github.api.GitHub.repo') def test_view_creates_guid(self, mock_repo, mock_contents, mock_history): github_mock = self.github mock_repo.return_value = github_mock.repo.return_value mock_contents.return_value = github_mock.contents.return_value[ 'octokit'] mock_history.return_value = github_mock.commits.return_value guid_count = GithubGuidFile.find().count() # View file for the first time # Because we've overridden mock_history above, it doesn't matter if the # file exists. url = self.project.web_url_for('github_view_file', path='test.py') res = self.app.get(url, auth=self.user.auth) guids = GithubGuidFile.find() # GUID count has been incremented by one assert_equal(guids.count(), guid_count + 1) file_guid = guids[guids.count() - 1]._id file_url = web_url_for('resolve_guid', guid=file_guid) # Client has been redirected to GUID assert_equal(302, res.status_code) assert_equal(file_url, urlparse.urlparse(res.location).path) # View the file res = self.app.get(file_url, auth=self.user.auth) assert_equal(200, res.status_code) # View file for the second time self.app.get(file_url, auth=self.user.auth) # GUID count has not been incremented assert_equal(GithubGuidFile.find().count(), guid_count + 1)
class TestGoogleDriveConfigViews(OsfTestCase): def setUp(self): super(TestGoogleDriveConfigViews, self).setUp() self.account = GoogleDriveAccountFactory() self.user = AuthUserFactory(external_accounts=[self.account]) self.user_settings = self.user.get_or_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.node_settings.user_settings = self.user_settings self.node_settings.save() self.user_settings.save() # Log user in self.app.authenticate(*self.user.auth) def test_list_googledrive_accounts_returns_accounts_single(self): url = api_url_for('list_googledrive_user_accounts') res = self.app.get(url) assert_equal(res.status_code, 200) assert_equal(len(res.json['accounts']), 1) assert_equal(res.json['accounts'][0]['provider_id'], self.account.provider_id) assert_equal(res.json['accounts'][0]['provider_name'], self.account.provider_name) def test_list_googledrive_accounts_returns_accounts_multiple(self): external_account = GoogleDriveAccountFactory() self.user.external_accounts.append( external_account) # self.account is already present self.user.save() url = api_url_for('list_googledrive_user_accounts') res = self.app.get(url) assert_equal(res.status_code, 200) assert_equal(len(res.json['accounts']), 2) def test_googledrive_config_get_return_correct_urls(self): url = self.project.api_url_for('googledrive_config_get') res = self.app.get(url) assert_equal(res.status_code, http.OK) result = res.json['result'] assert_equal( result['urls']['accounts'], self.project.api_url_for('list_googledrive_user_accounts')) assert_equal(result['urls']['auth'], api_url_for('oauth_connect', service_name='googledrive')) assert_equal(result['urls']['config'], self.project.api_url_for('googledrive_config_put')) assert_equal(result['urls']['deauthorize'], self.project.api_url_for('googledrive_remove_user_auth')) assert_equal(result['urls']['files'], self.project.web_url_for('collect_file_trees')) assert_equal(result['urls']['folders'], self.project.api_url_for('googledrive_folders')) assert_equal(result['urls']['importAuth'], self.project.api_url_for('googledrive_import_user_auth')) assert_equal(result['urls']['settings'], web_url_for('user_addons')) def test_googledrive_config_get_has_auth(self): self.node_settings.set_auth(external_account=self.account, user=self.user) self.node_settings.save() url = self.project.api_url_for('googledrive_config_get') res = self.app.get(url) assert_equal(res.status_code, 200) result = res.json['result'] assert_true(result['nodeHasAuth']) def test_googledrive_config_get_does_not_has_auth(self): url = self.project.api_url_for('googledrive_config_get') res = self.app.get(url) result = res.json['result'] assert_false(result['nodeHasAuth']) def test_googledrive_config_put(self): self.node_settings.set_auth(external_account=self.account, user=self.user) self.node_settings.save() 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_path, 'Google Drive/ 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'], ' My Folder') def test_googledrive_import_user_auth(self): url = self.project.api_url_for('googledrive_import_user_auth', auth=self.user.auth) self.app.put_json(url, {'external_account_id': self.account._id}) self.node_settings.reload() assert_equal(self.node_settings.external_account, self.account) def test_googledrive_remove_user_auth(self): self.node_settings.set_auth(external_account=self.account, user=self.user) self.node_settings.save() assert_equal(self.node_settings.external_account, self.account) url = self.project.api_url_for('googledrive_remove_user_auth', auth=self.user.auth) self.app.delete(url) self.node_settings.reload() assert_equal(self.node_settings.external_account, None)
class TestWikiUuid(OsfTestCase): def setUp(self): super(TestWikiUuid, self).setUp() self.user = AuthUserFactory() self.project = ProjectFactory(is_public=True, creator=self.user) self.wname = 'foo.bar' self.wkey = to_mongo_key(self.wname) def test_uuid_generated_once(self): assert_is_none(self.project.wiki_private_uuids.get(self.wkey)) url = self.project.web_url_for('project_wiki_view', wname=self.wname) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) self.project.reload() private_uuid = self.project.wiki_private_uuids.get(self.wkey) assert_true(private_uuid) assert_not_in(private_uuid, res.body) assert_in(get_sharejs_uuid(self.project, self.wname), res.body) # Revisit page; uuid has not changed res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) self.project.reload() assert_equal(private_uuid, self.project.wiki_private_uuids.get(self.wkey)) def test_uuid_not_visible_without_write_permission(self): self.project.update_node_wiki(self.wname, 'some content', Auth(self.user)) self.project.save() assert_is_none(self.project.wiki_private_uuids.get(self.wkey)) url = self.project.web_url_for('project_wiki_view', wname=self.wname) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) self.project.reload() private_uuid = self.project.wiki_private_uuids.get(self.wkey) assert_true(private_uuid) assert_not_in(private_uuid, res.body) assert_in(get_sharejs_uuid(self.project, self.wname), res.body) # Users without write permission should not be able to access res = self.app.get(url) assert_equal(res.status_code, 200) assert_not_in(get_sharejs_uuid(self.project, self.wname), res.body) def test_uuid_not_generated_without_write_permission(self): self.project.update_node_wiki(self.wname, 'some content', Auth(self.user)) self.project.save() assert_is_none(self.project.wiki_private_uuids.get(self.wkey)) url = self.project.web_url_for('project_wiki_view', wname=self.wname) res = self.app.get(url) assert_equal(res.status_code, 200) self.project.reload() private_uuid = self.project.wiki_private_uuids.get(self.wkey) assert_is_none(private_uuid) def test_uuids_differ_between_pages(self): wname1 = 'foo.bar' url1 = self.project.web_url_for('project_wiki_view', wname=wname1) res1 = self.app.get(url1, auth=self.user.auth) assert_equal(res1.status_code, 200) wname2 = 'bar.baz' url2 = self.project.web_url_for('project_wiki_view', wname=wname2) res2 = self.app.get(url2, auth=self.user.auth) assert_equal(res2.status_code, 200) self.project.reload() uuid1 = get_sharejs_uuid(self.project, wname1) uuid2 = get_sharejs_uuid(self.project, wname2) assert_not_equal(uuid1, uuid2) assert_in(uuid1, res1) assert_in(uuid2, res2) assert_not_in(uuid1, res2) assert_not_in(uuid2, res1) def test_uuids_differ_between_forks(self): url = self.project.web_url_for('project_wiki_view', wname=self.wname) project_res = self.app.get(url, auth=self.user.auth) assert_equal(project_res.status_code, 200) self.project.reload() fork = self.project.fork_node(Auth(self.user)) assert_true(fork.is_fork_of(self.project)) fork_url = fork.web_url_for('project_wiki_view', wname=self.wname) fork_res = self.app.get(fork_url, auth=self.user.auth) assert_equal(fork_res.status_code, 200) fork.reload() # uuids are stored the same internally assert_equal( self.project.wiki_private_uuids.get(self.wkey), fork.wiki_private_uuids.get(self.wkey) ) project_uuid = get_sharejs_uuid(self.project, self.wname) fork_uuid = get_sharejs_uuid(fork, self.wname) assert_not_equal(project_uuid, fork_uuid) assert_in(project_uuid, project_res) assert_in(fork_uuid, fork_res) assert_not_in(project_uuid, fork_res) assert_not_in(fork_uuid, project_res) @mock.patch('website.addons.wiki.utils.broadcast_to_sharejs') def test_migration_does_not_affect_forks(self, mock_sharejs): original_uuid = generate_private_uuid(self.project, self.wname) self.project.update_node_wiki(self.wname, 'Hello world', Auth(self.user)) fork = self.project.fork_node(Auth(self.user)) assert_equal(original_uuid, fork.wiki_private_uuids.get(self.wkey)) migrate_uuid(self.project, self.wname) assert_not_equal(original_uuid, self.project.wiki_private_uuids.get(self.wkey)) assert_equal(original_uuid, fork.wiki_private_uuids.get(self.wkey)) @mock.patch('website.addons.wiki.utils.broadcast_to_sharejs') def test_uuid_persists_after_delete(self, mock_sharejs): assert_is_none(self.project.wiki_private_uuids.get(self.wkey)) # Create wiki page self.project.update_node_wiki(self.wname, 'Hello world', Auth(self.user)) # Visit wiki edit page edit_url = self.project.web_url_for('project_wiki_view', wname=self.wname) res = self.app.get(edit_url, auth=self.user.auth) assert_equal(res.status_code, 200) self.project.reload() original_private_uuid = self.project.wiki_private_uuids.get(self.wkey) original_sharejs_uuid = get_sharejs_uuid(self.project, self.wname) # Delete wiki delete_url = self.project.api_url_for('project_wiki_delete', wname=self.wname) res = self.app.delete(delete_url, auth=self.user.auth) assert_equal(res.status_code, 200) self.project.reload() assert_equal(original_private_uuid, self.project.wiki_private_uuids.get(self.wkey)) # Revisit wiki edit page res = self.app.get(edit_url, auth=self.user.auth) assert_equal(res.status_code, 200) self.project.reload() assert_equal(original_private_uuid, self.project.wiki_private_uuids.get(self.wkey)) assert_in(original_sharejs_uuid, res.body) @mock.patch('website.addons.wiki.utils.broadcast_to_sharejs') def test_uuid_persists_after_rename(self, mock_sharejs): new_wname = 'bar.baz' new_wkey = to_mongo_key(new_wname) assert_is_none(self.project.wiki_private_uuids.get(self.wkey)) assert_is_none(self.project.wiki_private_uuids.get(new_wkey)) # Create wiki page self.project.update_node_wiki(self.wname, 'Hello world', Auth(self.user)) wiki_page = self.project.get_wiki_page(self.wname) # Visit wiki edit page original_edit_url = self.project.web_url_for('project_wiki_view', wname=self.wname) res = self.app.get(original_edit_url, auth=self.user.auth) assert_equal(res.status_code, 200) self.project.reload() original_private_uuid = self.project.wiki_private_uuids.get(self.wkey) original_sharejs_uuid = get_sharejs_uuid(self.project, self.wname) # Rename wiki rename_url = self.project.api_url_for('project_wiki_rename', wname=self.wname) res = self.app.put_json( rename_url, {'value': new_wname, 'pk': wiki_page._id}, auth=self.user.auth, ) assert_equal(res.status_code, 200) self.project.reload() assert_is_none(self.project.wiki_private_uuids.get(self.wkey)) assert_equal(original_private_uuid, self.project.wiki_private_uuids.get(new_wkey)) # Revisit original wiki edit page res = self.app.get(original_edit_url, auth=self.user.auth) assert_equal(res.status_code, 200) self.project.reload() assert_not_equal(original_private_uuid, self.project.wiki_private_uuids.get(self.wkey)) assert_not_in(original_sharejs_uuid, res.body)
class RegistrationEmbargoViewsTestCase(OsfTestCase): def setUp(self): super(RegistrationEmbargoViewsTestCase, self).setUp() ensure_schemas() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.draft = DraftRegistrationFactory(branched_from=self.project) self.registration = RegistrationFactory(project=self.project, creator=self.user) current_month = 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_register_draft_without_embargo_creates_registration_approval(self, mock_enqueue): res = self.app.post( self.project.api_url_for('register_draft_registration', draft_id=self.draft._id), self.valid_make_public_payload, content_type='application/json', auth=self.user.auth ) assert_equal(res.status_code, 202) registration = 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): self.project.is_public = True self.project.save() component = NodeFactory( creator=self.user, parent=self.project, title='Component', is_public=True ) subproject = ProjectFactory( creator=self.user, parent=self.project, title='Subproject', is_public=True ) subproject_component = NodeFactory( creator=self.user, parent=subproject, title='Subcomponent', is_public=True ) res = self.app.post( self.project.api_url_for('register_draft_registration', draft_id=self.draft._id), self.valid_make_public_payload, content_type='application/json', auth=self.user.auth ) self.project.reload() assert_equal(res.status_code, 202) assert_equal(res.json['urls']['registrations'], self.project.web_url_for('node_registrations')) # Last node directly registered from self.project registration = Node.find( Q('registered_from', 'eq', self.project) ).sort('-registered_date')[0] assert_true(registration.is_registration) assert_false(registration.is_public) for node in registration.get_descendants_recursive(): assert_true(node.is_registration) assert_false(node.is_public) @mock.patch('framework.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('register_draft_registration', draft_id=self.draft._id), self.valid_make_public_payload, content_type='application/json', auth=self.user.auth ) self.project.reload() # Last node directly registered from self.project registration = 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('register_draft_registration', draft_id=self.draft._id), self.valid_embargo_payload, content_type='application/json', auth=self.user.auth ) assert_equal(res.status_code, 202) registration = 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): self.project.is_public = True self.project.save() component = NodeFactory( creator=self.user, parent=self.project, title='Component', is_public=True ) subproject = ProjectFactory( creator=self.user, parent=self.project, title='Subproject', is_public=True ) subproject_component = NodeFactory( creator=self.user, parent=subproject, title='Subcomponent', is_public=True ) res = self.app.post( self.project.api_url_for('register_draft_registration', draft_id=self.draft._id), self.valid_embargo_payload, content_type='application/json', auth=self.user.auth ) self.project.reload() assert_equal(res.status_code, 202) assert_equal(res.json['urls']['registrations'], self.project.web_url_for('node_registrations')) # Last node directly registered from self.project registration = Node.find( Q('registered_from', 'eq', self.project) ).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) 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('register_draft_registration', draft_id=self.draft._id), self.invalid_embargo_date_payload, content_type='application/json', auth=self.user.auth, expect_errors=True ) assert_equal(res.status_code, 400) @mock.patch('framework.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('register_draft_registration', draft_id=self.draft._id), self.valid_embargo_payload, content_type='application/json', auth=self.user.auth ) self.project.reload() # Logs: Created, registered, embargo initiated assert_equal(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 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_view', wname='home') res = self.app.get(url) assert_equal(res.status_code, 200) def test_wiki_url_404_with_no_write_permission(self): url = self.project.web_url_for('project_wiki_view', wname='somerandomid') res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 404) @mock.patch('website.addons.wiki.utils.broadcast_to_sharejs') def test_wiki_deleted_404_with_no_write_permission(self, mock_sharejs): self.project.update_node_wiki('funpage', 'Version 1', Auth(self.user)) self.project.save() url = self.project.web_url_for('project_wiki_view', wname='funpage') res = self.app.get(url) assert_equal(res.status_code, 200) delete_url = self.project.api_url_for('project_wiki_delete', wname='funpage') self.app.delete(delete_url, auth=self.user.auth) res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 404) def test_wiki_url_with_path_get_returns_200(self): self.project.update_node_wiki('funpage', 'Version 1', Auth(self.user)) self.project.update_node_wiki('funpage', 'Version 2', Auth(self.user)) self.project.save() url = self.project.web_url_for( 'project_wiki_view', wname='funpage', ) + '?view&compare=1&edit' res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) def test_wiki_url_with_edit_get_returns_404_with_no_write_permission(self): self.project.update_node_wiki('funpage', 'Version 1', Auth(self.user)) self.project.update_node_wiki('funpage', 'Version 2', Auth(self.user)) self.project.save() url = self.project.web_url_for( 'project_wiki_view', wname='funpage', compare=1, ) res = self.app.get(url) assert_equal(res.status_code, 200) url = self.project.web_url_for( 'project_wiki_view', wname='funpage', ) + '?edit' res = self.app.get(url, expect_errors=True) assert_equal(res.status_code, 403) 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_view', wname='home') res = self.app.get(url) assert_equal(res.status_code, 200) def test_wiki_draft_returns_200(self): url = self.project.api_url_for('wiki_page_draft', wname='somerandomid') res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) def test_wiki_content_returns_200(self): url = self.project.api_url_for('wiki_page_content', wname='somerandomid') res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) @mock.patch('website.addons.wiki.model.NodeWikiPage.rendered_before_update', new_callable=mock.PropertyMock) def test_wiki_content_use_python_render(self, mock_rendered_before_update): content = 'Some content' self.project.update_node_wiki('somerandomid', content, Auth(self.user)) self.project.save() mock_rendered_before_update.return_value = True url = self.project.api_url_for('wiki_page_content', wname='somerandomid') res = self.app.get(url, auth=self.user.auth) assert_equal(content, res.json['wiki_content']) assert_in(content, res.json['wiki_rendered']) mock_rendered_before_update.return_value = False res = self.app.get(url, auth=self.user.auth) assert_equal(content, res.json['wiki_content']) assert_equal('', res.json['wiki_rendered']) def test_wiki_url_for_component_returns_200(self): component = NodeFactory(project=self.project, is_public=True) url = component.web_url_for('project_wiki_view', 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(parent=project, creator=project.creator) no_wiki = NodeFactory(parent=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_view', 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): # note: forward slashes not allowed in page_name page_name = fake.catch_phrase().replace('/', ' ') 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): # note: forward slashes not allowed in page_name page_name = fake.catch_phrase().replace('/' , ' ') page_content = 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_view', wname='home') res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) def test_project_wiki_view_scope(self): self.project.update_node_wiki('home', 'Version 1', Auth(self.user)) self.project.update_node_wiki('home', 'Version 2', Auth(self.user)) self.project.save() url = self.project.web_url_for('project_wiki_view', wname='home', view=2) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) url = self.project.web_url_for('project_wiki_view', wname='home', view=3) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) url = self.project.web_url_for('project_wiki_view', wname='home', view=0) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) 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_view', wname='home') + '?compare' res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) def test_project_wiki_compare_scope(self): self.project.update_node_wiki('home', 'Version 1', Auth(self.user)) self.project.update_node_wiki('home', 'Version 2', Auth(self.user)) self.project.save() url = self.project.web_url_for('project_wiki_view', wname='home', compare=2) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) url = self.project.web_url_for('project_wiki_view', wname='home', compare=3) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) url = self.project.web_url_for('project_wiki_view', wname='home', compare=0) res = self.app.get(url, auth=self.user.auth, expect_errors=True) assert_equal(res.status_code, 400) 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_view', 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_view', 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_view', 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_view', 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) def test_wiki_widget_no_content(self): url = self.project.api_url_for('wiki_widget', wid='home') res = self.app.get(url, auth=self.user.auth) assert_is_none(res.json['wiki_content']) def test_wiki_widget_short_content_no_cutoff(self): short_content = 'a' * 150 self.project.update_node_wiki('home', short_content, Auth(self.user)) url = self.project.api_url_for('wiki_widget', wid='home') res = self.app.get(url, auth=self.user.auth) assert_in(short_content, res.json['wiki_content']) assert_not_in('...', res.json['wiki_content']) assert_false(res.json['more']) def test_wiki_widget_long_content_cutoff(self): long_content = 'a' * 600 self.project.update_node_wiki('home', long_content, Auth(self.user)) url = self.project.api_url_for('wiki_widget', wid='home') res = self.app.get(url, auth=self.user.auth) assert_less(len(res.json['wiki_content']), 520) # wiggle room for closing tags assert_in('...', res.json['wiki_content']) assert_true(res.json['more']) @mock.patch('website.addons.wiki.model.NodeWikiPage.rendered_before_update', new_callable=mock.PropertyMock) def test_wiki_widget_use_python_render(self, mock_rendered_before_update): # New pages use js renderer mock_rendered_before_update.return_value = False self.project.update_node_wiki('home', 'updated content', Auth(self.user)) url = self.project.api_url_for('wiki_widget', wid='home') res = self.app.get(url, auth=self.user.auth) assert_false(res.json['use_python_render']) # Old pages use python renderer mock_rendered_before_update.return_value = True res = self.app.get(url, auth=self.user.auth) assert_true(res.json['use_python_render']) def test_read_only_users_cannot_view_edit_pane(self): url = self.project.web_url_for('project_wiki_view', wname='home') # No write permissions res = self.app.get(url) assert_equal(res.status_code, 200) assert_not_in('data-osf-panel="Edit"', res.text) # Write permissions res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 200) assert_in('data-osf-panel="Edit"', res.text)
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 RegistrationEmbargoViewsTestCase(OsfTestCase): def setUp(self): super(RegistrationEmbargoViewsTestCase, self).setUp() ensure_schemas() self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.draft = DraftRegistrationFactory(branched_from=self.project) self.registration = RegistrationFactory(project=self.project, creator=self.user) current_month = 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.celery_tasks.handlers.enqueue_task') def test_register_draft_without_embargo_creates_registration_approval(self, mock_enqueue): res = self.app.post( self.project.api_url_for('register_draft_registration', draft_id=self.draft._id), self.valid_make_public_payload, content_type='application/json', auth=self.user.auth ) assert_equal(res.status_code, 202) registration = 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.celery_tasks.handlers.enqueue_task') def test_POST_register_make_public_immediately_creates_private_pending_registration_for_public_project(self, mock_enqueue): self.project.is_public = True self.project.save() component = NodeFactory( creator=self.user, parent=self.project, title='Component', is_public=True ) subproject = ProjectFactory( creator=self.user, parent=self.project, title='Subproject', is_public=True ) subproject_component = NodeFactory( creator=self.user, parent=subproject, title='Subcomponent', is_public=True ) res = self.app.post( self.project.api_url_for('register_draft_registration', draft_id=self.draft._id), self.valid_make_public_payload, content_type='application/json', auth=self.user.auth ) self.project.reload() assert_equal(res.status_code, 202) assert_equal(res.json['urls']['registrations'], self.project.web_url_for('node_registrations')) # Last node directly registered from self.project registration = Node.find( Q('registered_from', 'eq', self.project) ).sort('-registered_date')[0] assert_true(registration.is_registration) assert_false(registration.is_public) for node in registration.get_descendants_recursive(): assert_true(node.is_registration) assert_false(node.is_public) @mock.patch('framework.celery_tasks.handlers.enqueue_task') def test_POST_register_make_public_does_not_make_children_public(self, mock_enqueue): 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('register_draft_registration', draft_id=self.draft._id), self.valid_make_public_payload, content_type='application/json', auth=self.user.auth ) self.project.reload() # Last node directly registered from self.project registration = self.project.registrations_all[-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.celery_tasks.handlers.enqueue_task') def test_POST_register_embargo_is_not_public(self, mock_enqueue): res = self.app.post( self.project.api_url_for('register_draft_registration', draft_id=self.draft._id), self.valid_embargo_payload, content_type='application/json', auth=self.user.auth ) assert_equal(res.status_code, 202) registration = 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.celery_tasks.handlers.enqueue_task') def test_POST_register_embargo_does_not_make_project_or_children_public(self, mock_enqueue): self.project.is_public = True self.project.save() component = NodeFactory( creator=self.user, parent=self.project, title='Component', is_public=True ) subproject = ProjectFactory( creator=self.user, parent=self.project, title='Subproject', is_public=True ) subproject_component = NodeFactory( creator=self.user, parent=subproject, title='Subcomponent', is_public=True ) res = self.app.post( self.project.api_url_for('register_draft_registration', draft_id=self.draft._id), self.valid_embargo_payload, content_type='application/json', auth=self.user.auth ) self.project.reload() assert_equal(res.status_code, 202) assert_equal(res.json['urls']['registrations'], self.project.web_url_for('node_registrations')) # Last node directly registered from self.project registration = Node.find( Q('registered_from', 'eq', self.project) ).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) for node in registration.get_descendants_recursive(): assert_true(node.is_registration) assert_false(node.is_public) @mock.patch('framework.celery_tasks.handlers.enqueue_task') def test_POST_invalid_embargo_end_date_returns_HTTPBad_Request(self, mock_enqueue): res = self.app.post( self.project.api_url_for('register_draft_registration', draft_id=self.draft._id), self.invalid_embargo_date_payload, content_type='application/json', auth=self.user.auth, expect_errors=True ) assert_equal(res.status_code, 400) @mock.patch('framework.celery_tasks.handlers.enqueue_task') def test_valid_POST_embargo_adds_to_parent_projects_log(self, mock_enquque): initial_project_logs = len(self.project.logs) self.app.post( self.project.api_url_for('register_draft_registration', draft_id=self.draft._id), self.valid_embargo_payload, content_type='application/json', auth=self.user.auth ) self.project.reload() # Logs: Created, registered, embargo initiated assert_equal(len(self.project.logs), initial_project_logs + 1) def test_embargoed_registration_cannot_be_made_public(self): # Initiate and approve embargo self.registration.embargo_registration( self.user, datetime.datetime.utcnow() + datetime.timedelta(days=10) ) approval_token = self.registration.embargo.approval_state[self.user._id]['approval_token'] self.registration.embargo.approve_embargo(self.user, approval_token) self.registration.save() res = self.app.post( self.registration.api_url_for('project_set_privacy', permissions='public'), auth=self.user.auth, expect_errors=True ) assert_equal(res.status_code, 400) assert_equal(res.json['message_long'], 'An embargoed registration cannot be made public.') 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 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 TestLegacyViews(OsfTestCase): def setUp(self): super(TestLegacyViews, self).setUp() self.path = "mercury.png" self.user = AuthUserFactory() self.project = ProjectFactory(creator=self.user) self.node_addon = self.project.get_addon("osfstorage") file_record = self.node_addon.get_root().append_file(self.path) self.expected_path = file_record._id self.node_addon.save() file_record.save() def test_view_file_redirect(self): url = "/{0}/osffiles/{1}/".format(self.project._id, self.path) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( "addon_view_or_download_file", action="view", path=self.expected_path, provider="osfstorage" ) assert_urls_equal(res.location, expected_url) def test_download_file_redirect(self): url = "/{0}/osffiles/{1}/download/".format(self.project._id, self.path) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( "addon_view_or_download_file", path=self.expected_path, action="download", provider="osfstorage" ) assert_urls_equal(res.location, expected_url) def test_download_file_version_redirect(self): url = "/{0}/osffiles/{1}/version/3/download/".format(self.project._id, self.path) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( "addon_view_or_download_file", version=3, path=self.expected_path, action="download", provider="osfstorage" ) assert_urls_equal(res.location, expected_url) def test_api_download_file_redirect(self): url = "/api/v1/project/{0}/osffiles/{1}/".format(self.project._id, self.path) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( "addon_view_or_download_file", path=self.expected_path, action="download", provider="osfstorage" ) assert_urls_equal(res.location, expected_url) def test_api_download_file_version_redirect(self): url = "/api/v1/project/{0}/osffiles/{1}/version/3/".format(self.project._id, self.path) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( "addon_view_or_download_file", version=3, path=self.expected_path, action="download", provider="osfstorage" ) assert_urls_equal(res.location, expected_url) def test_no_provider_name(self): url = "/{0}/files/{1}".format(self.project._id, self.path) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( "addon_view_or_download_file", action="view", path=self.expected_path, provider="osfstorage" ) assert_urls_equal(res.location, expected_url) def test_action_as_param(self): url = "/{}/osfstorage/files/{}/?action=download".format(self.project._id, self.path) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( "addon_view_or_download_file", path=self.expected_path, action="download", provider="osfstorage" ) assert_urls_equal(res.location, expected_url) def test_other_addon_redirect(self): url = "/project/{0}/mycooladdon/files/{1}/".format(self.project._id, self.path) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( "addon_view_or_download_file", action="view", path=self.path, provider="mycooladdon" ) assert_urls_equal(res.location, expected_url) def test_other_addon_redirect_download(self): url = "/project/{0}/mycooladdon/files/{1}/download/".format(self.project._id, self.path) res = self.app.get(url, auth=self.user.auth) assert_equal(res.status_code, 301) expected_url = self.project.web_url_for( "addon_view_or_download_file", path=self.path, action="download", provider="mycooladdon" ) assert_urls_equal(res.location, expected_url)