Exemple #1
0
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)
Exemple #2
0
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; ">&lt;script&gt;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&gt;</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 = '&lt;script&gt;alert(''a problem'');&lt;/script&gt;'
        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)
Exemple #3
0
 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))
Exemple #4
0
 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)
Exemple #5
0
 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)
Exemple #6
0
 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)
     )
Exemple #7
0
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)
Exemple #8
0
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)
Exemple #9
0
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)
Exemple #10
0
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))
Exemple #11
0
 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),
     )
Exemple #12
0
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))
Exemple #13
0
 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),
     )
Exemple #14
0
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
        )
Exemple #15
0
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
        )
Exemple #16
0
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)
Exemple #17
0
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)
Exemple #18
0
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)
Exemple #20
0
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)
Exemple #21
0
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)
Exemple #23
0
    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)
Exemple #24
0
    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)
Exemple #25
0
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)
Exemple #27
0
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)
Exemple #28
0
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)
Exemple #31
0
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)
Exemple #32
0
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)
Exemple #33
0
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)
Exemple #34
0
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)
Exemple #35
0
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)
Exemple #36
0
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)
Exemple #37
0
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; ">&lt;script&gt;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&gt;</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 = '&lt;script&gt;alert(' 'a problem' ');&lt;/script&gt;'
        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)
Exemple #38
0
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)
Exemple #39
0
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)
Exemple #40
0
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)
Exemple #41
0
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)
Exemple #42
0
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)
Exemple #43
0
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),
            },
        )
Exemple #44
0
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)
Exemple #45
0
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)
Exemple #46
0
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)
Exemple #47
0
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)
Exemple #48
0
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)
Exemple #49
0
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)
Exemple #50
0
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)
Exemple #51
0
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)
Exemple #52
0
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)
Exemple #53
0
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)
Exemple #54
0
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'])
Exemple #55
0
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)
Exemple #56
0
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)
Exemple #57
0
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)