Exemple #1
0
    def test_get_summary_private_fork_should_include_is_fork(self):
        user = UserFactory()
        # non-contributor cannot see private fork of public project
        node = ProjectFactory(is_public=True)
        consolidated_auth = Auth(user=node.creator)
        fork = node.fork_node(consolidated_auth)

        res = _get_summary(fork, auth=Auth(user), primary=True, link_id=None)
        # serialized result should have is_fork
        assert_true(res["summary"]["is_fork"])
    def test_get_summary_private_fork_should_include_is_fork(self):
        user = UserFactory()
        # non-contributor cannot see private fork of public project
        node = ProjectFactory(is_public=True)
        consolidated_auth = Auth(user=node.creator)
        fork = node.fork_node(consolidated_auth)

        res = _get_summary(fork, auth=Auth(user), primary=True, link_id=None)
        # serialized result should have is_fork
        assert_true(res['summary']['is_fork'])
    def test_get_all_parents(self):
        user = UserFactory()
        auth = Auth(user=user)
        project1 = ProjectFactory(creator=user)
        project2 = project1.fork_node(auth=auth)
        project3 = project2.register_node(schema=None, auth=auth, template="foo", data="bar")
        parent_list = get_all_parents(project3)

        assert len(parent_list) is 2
        assert project1 in parent_list
        assert project2 in parent_list
Exemple #4
0
    def test_get_node_name(self):
        user = UserFactory()
        auth = Auth(user=user)
        another_user = UserFactory()
        another_auth = Auth(user=another_user)

        # Public (Can View)
        public_project = ProjectFactory(is_public=True)
        collector = rubeus.NodeFileCollector(node=public_project,
                                             auth=another_auth)
        node_name = u'{0}: {1}'.format(
            public_project.project_or_component.capitalize(),
            sanitize.unescape_entities(public_project.title))
        assert_equal(collector._get_node_name(public_project), node_name)

        # Private  (Can't View)
        registration_private = RegistrationFactory(creator=user)
        registration_private.is_public = False
        registration_private.save()
        collector = rubeus.NodeFileCollector(node=registration_private,
                                             auth=another_auth)
        assert_equal(collector._get_node_name(registration_private),
                     u'Private Registration')

        content = ProjectFactory(creator=user)
        node = ProjectFactory(creator=user)

        forked_private = node.fork_node(auth=auth)
        forked_private.is_public = False
        forked_private.save()
        collector = rubeus.NodeFileCollector(node=forked_private,
                                             auth=another_auth)
        assert_equal(collector._get_node_name(forked_private), u'Private Fork')

        pointer_private = node.add_pointer(content, auth=auth)
        pointer_private.is_public = False
        pointer_private.save()
        collector = rubeus.NodeFileCollector(node=pointer_private,
                                             auth=another_auth)
        assert_equal(collector._get_node_name(pointer_private),
                     u'Private Link')

        private_project = ProjectFactory(is_public=False)
        collector = rubeus.NodeFileCollector(node=private_project,
                                             auth=another_auth)
        assert_equal(collector._get_node_name(private_project),
                     u'Private Component')

        private_node = NodeFactory(is_public=False)
        collector = rubeus.NodeFileCollector(node=private_node,
                                             auth=another_auth)
        assert_equal(collector._get_node_name(private_node),
                     u'Private Component')
    def test_get_parent(self):
        user = UserFactory()
        auth = Auth(user=user)
        project1 = ProjectFactory(creator=user)
        project2 = project1.fork_node(auth=auth)
        forked_from = get_parent(project2)

        assert forked_from is project1

        project3 = project2.register_node(schema=None, auth=auth, template="foo", data="bar")
        registered_from = get_parent(project3)

        assert registered_from is project2
Exemple #6
0
    def test_get_summary_private_fork_private_project_should_include_is_fork(self):
        # contributor on a private project
        user = UserFactory()
        node = ProjectFactory(is_public=False)
        node.add_contributor(user)

        # contributor cannot see private fork of this project
        consolidated_auth = Auth(user=node.creator)
        fork = node.fork_node(consolidated_auth)

        res = _get_summary(fork, auth=Auth(user), primary=True, link_id=None)
        # serialized result should have is_fork
        assert_false(res["summary"]["can_view"])
        assert_true(res["summary"]["is_fork"])
    def test_get_summary_private_fork_private_project_should_include_is_fork(
            self):
        # contributor on a private project
        user = UserFactory()
        node = ProjectFactory(is_public=False)
        node.add_contributor(user)

        # contributor cannot see private fork of this project
        consolidated_auth = Auth(user=node.creator)
        fork = node.fork_node(consolidated_auth)

        res = _get_summary(fork, auth=Auth(user), primary=True, link_id=None)
        # serialized result should have is_fork
        assert_false(res['summary']['can_view'])
        assert_true(res['summary']['is_fork'])
    def test_get_all_parents(self):
        user = UserFactory()
        auth = Auth(user=user)
        project1 = ProjectFactory(creator=user)
        project2 = project1.fork_node(auth=auth)
        project3 = project2.register_node(
            schema=None,
            auth=auth,
            template="foo",
            data="bar",
        )
        parent_list = get_all_parents(project3)

        assert len(parent_list) is 2
        assert project1 in parent_list
        assert project2 in parent_list
    def test_get_parent(self):
        user = UserFactory()
        auth = Auth(user=user)
        project1 = ProjectFactory(creator=user)
        project2 = project1.fork_node(auth=auth)
        forked_from = get_parent(project2)

        assert forked_from is project1

        project3 = project2.register_node(
            schema=None,
            auth=auth,
            template="foo",
            data="bar",
        )
        registered_from = get_parent(project3)

        assert registered_from is project2
Exemple #10
0
    def test_get_node_name(self):
        user = UserFactory()
        auth = Auth(user=user)
        another_user = UserFactory()
        another_auth = Auth(user=another_user)

        # Public (Can View)
        public_project = ProjectFactory(is_public=True)
        collector = rubeus.NodeFileCollector(node=public_project, auth=another_auth)
        node_name = u"{0}: {1}".format(
            public_project.project_or_component.capitalize(), sanitize.unescape_entities(public_project.title)
        )
        assert_equal(collector._get_node_name(public_project), node_name)

        # Private  (Can't View)
        registration_private = RegistrationFactory(creator=user)
        registration_private.is_public = False
        registration_private.save()
        collector = rubeus.NodeFileCollector(node=registration_private, auth=another_auth)
        assert_equal(collector._get_node_name(registration_private), u"Private Registration")

        content = ProjectFactory(creator=user)
        node = ProjectFactory(creator=user)

        forked_private = node.fork_node(auth=auth)
        forked_private.is_public = False
        forked_private.save()
        collector = rubeus.NodeFileCollector(node=forked_private, auth=another_auth)
        assert_equal(collector._get_node_name(forked_private), u"Private Fork")

        pointer_private = node.add_pointer(content, auth=auth)
        pointer_private.is_public = False
        pointer_private.save()
        collector = rubeus.NodeFileCollector(node=pointer_private, auth=another_auth)
        assert_equal(collector._get_node_name(pointer_private), u"Private Link")

        private_project = ProjectFactory(is_public=False)
        collector = rubeus.NodeFileCollector(node=private_project, auth=another_auth)
        assert_equal(collector._get_node_name(private_project), u"Private Component")

        private_node = NodeFactory(is_public=False)
        collector = rubeus.NodeFileCollector(node=private_node, auth=another_auth)
        assert_equal(collector._get_node_name(private_node), u"Private Component")
    def test_wiki_pages_with_invalid_nodes_are_removed_after_cloning(self):
        project = ProjectFactory(creator=self.user, is_public=True)
        wiki = NodeWikiFactory(node=project)
        fork = project.fork_node(auth=Auth(self.user))
        fork.wiki_pages_versions = project.wiki_pages_versions
        fork.wiki_pages_current = project.wiki_pages_current
        fork.save()

        # Remove original node - wiki.node no longer points to an existing project
        Node.remove_one(project._id)

        # clone wiki page
        main()
        fork.reload()
        cloned_wiki_id = fork.wiki_pages_versions[wiki.page_name][0]
        cloned_wiki = NodeWikiPage.load(cloned_wiki_id)
        assert_equal(cloned_wiki.node._id, fork._id)

        # move original wiki page to unmigratedwikipages collection
        assert_false(db.nodewikipage.find_one({"_id": wiki._id}))
        assert_true(db.unmigratedwikipages.find_one({"_id": wiki._id}))
Exemple #12
0
    def test_wiki_pages_with_invalid_nodes_are_removed_after_cloning(self):
        project = ProjectFactory(creator=self.user, is_public=True)
        wiki = NodeWikiFactory(node=project)
        fork = project.fork_node(auth=Auth(self.user))
        fork.wiki_pages_versions = project.wiki_pages_versions
        fork.wiki_pages_current = project.wiki_pages_current
        fork.save()

        # Remove original node - wiki.node no longer points to an existing project
        Node.remove_one(project._id)

        # clone wiki page
        main()
        fork.reload()
        cloned_wiki_id = fork.wiki_pages_versions[wiki.page_name][0]
        cloned_wiki = NodeWikiPage.load(cloned_wiki_id)
        assert_equal(cloned_wiki.node._id, fork._id)

        # move original wiki page to unmigratedwikipages collection
        assert_false(db.nodewikipage.find_one({'_id': wiki._id}))
        assert_true(db.unmigratedwikipages.find_one({'_id': wiki._id}))
Exemple #13
0
class TestWikiUtils(OsfTestCase):

    def setUp(self):
        super(TestWikiUtils, self).setUp()
        self.project = ProjectFactory()

    def test_get_sharejs_uuid(self):
        wname = 'foo.bar'
        wname2 = 'bar.baz'
        private_uuid = generate_private_uuid(self.project, wname)
        sharejs_uuid = get_sharejs_uuid(self.project, wname)

        # Provides consistent results
        assert_equal(sharejs_uuid, get_sharejs_uuid(self.project, wname))

        # Provides obfuscation
        assert_not_in(wname, sharejs_uuid)
        assert_not_in(sharejs_uuid, wname)
        assert_not_in(private_uuid, sharejs_uuid)
        assert_not_in(sharejs_uuid, private_uuid)

        # Differs based on share uuid provided
        assert_not_equal(sharejs_uuid, get_sharejs_uuid(self.project, wname2))

        # Differs across projects and forks
        project = ProjectFactory()
        assert_not_equal(sharejs_uuid, get_sharejs_uuid(project, wname))
        fork = self.project.fork_node(Auth(self.project.creator))
        assert_not_equal(sharejs_uuid, get_sharejs_uuid(fork, wname))

    def test_generate_share_uuid(self):
        wname = 'bar.baz'
        wkey = to_mongo_key(wname)
        assert_is_none(self.project.wiki_private_uuids.get(wkey))
        share_uuid = generate_private_uuid(self.project, wname)
        self.project.reload()
        assert_equal(self.project.wiki_private_uuids[wkey], share_uuid)

        new_uuid = generate_private_uuid(self.project, wname)
        self.project.reload()
        assert_not_equal(share_uuid, new_uuid)
        assert_equal(self.project.wiki_private_uuids[wkey], new_uuid)

    def test_format_wiki_version(self):
        assert_is_none(format_wiki_version(None, 5, False))
        assert_is_none(format_wiki_version('', 5, False))
        assert_equal(format_wiki_version('3', 5, False), 3)
        assert_equal(format_wiki_version('4', 5, False), 'previous')
        assert_equal(format_wiki_version('5', 5, False), 'current')
        assert_equal(format_wiki_version('previous', 5, False), 'previous')
        assert_equal(format_wiki_version('current', 5, False), 'current')
        assert_equal(format_wiki_version('preview', 5, True), 'preview')
        assert_equal(format_wiki_version('current', 0, False), 'current')
        assert_equal(format_wiki_version('preview', 0, True), 'preview')

        with assert_raises(InvalidVersionError):
            format_wiki_version('1', 0, False)
        with assert_raises(InvalidVersionError):
            format_wiki_version('previous', 0, False)
        with assert_raises(InvalidVersionError):
            format_wiki_version('6', 5, False)
        with assert_raises(InvalidVersionError):
            format_wiki_version('0', 5, False)
        with assert_raises(InvalidVersionError):
            format_wiki_version('preview', 5, False)
        with assert_raises(InvalidVersionError):
            format_wiki_version('nonsense', 5, True)
class ModelTests(OsfTestCase):
    def setUp(self):
        OsfTestCase.setUp(self)
        self.user = UserFactory()
        self.node = ProjectFactory(creator=self.user)
        self.citation = AlternativeCitation(name="name", text="text")
        self.citation.save()
        self.node.alternative_citations.append(self.citation)

    def test_model_success(self):
        alt_citation = AlternativeCitation(name="test", text="citation")
        alt_citation.save()
        self.node.alternative_citations.append(alt_citation)
        assert_equal(len(self.node.alternative_citations), 2)

    def test_model_no_name(self):
        alt_citation = AlternativeCitation(text="citation")
        with assert_raises(ValidationError):
            alt_citation.save()
            self.node.alternative_citations.append(alt_citation)
        assert_equal(len(self.node.alternative_citations), 1)

    def test_model_no_text(self):
        alt_citation = AlternativeCitation(name="test")
        with assert_raises(ValidationError):
            alt_citation.save()
            self.node.alternative_citations.append(alt_citation)
        assert_equal(len(self.node.alternative_citations), 1)

    def test_model_no_fields(self):
        alt_citation = AlternativeCitation()
        with assert_raises(ValidationError):
            alt_citation.save()
            self.node.alternative_citations.append(alt_citation)
        assert_equal(len(self.node.alternative_citations), 1)

    def test_model_change_name(self):
        citation = self.node.alternative_citations[0]
        citation.name = "New name"
        citation.save()
        self.node.save()
        assert_equal(self.node.alternative_citations[0].name, "New name")

    def test_model_change_text(self):
        citation = self.node.alternative_citations[0]
        citation.text = "New citation text"
        citation.save()
        self.node.save()
        assert_equal(self.node.alternative_citations[0].text, "New citation text")

    def test_model_fork(self):
        fork = self.node.fork_node(auth=Auth(self.user))
        assert_equal(len(self.node.alternative_citations), len(fork.alternative_citations), 1)
        assert_equal(self.node.alternative_citations[0].name, fork.alternative_citations[0].name, "name")
        assert_equal(self.node.alternative_citations[0].text, fork.alternative_citations[0].text, "text")
        assert_not_equal(self.node.alternative_citations[0]._id, fork.alternative_citations[0]._id)

    def test_model_fork_change_name(self):
        fork = self.node.fork_node(auth=Auth(self.user))
        assert_equal(len(self.node.alternative_citations), len(fork.alternative_citations), 1)
        fork.alternative_citations[0].name = "new name"
        assert_not_equal(self.node.alternative_citations[0].name, fork.alternative_citations[0].name)
        assert_equal(self.node.alternative_citations[0].text, fork.alternative_citations[0].text, "text")
        assert_not_equal(self.node.alternative_citations[0]._id, fork.alternative_citations[0]._id)

    def test_model_fork_change_text(self):
        fork = self.node.fork_node(auth=Auth(self.user))
        assert_equal(len(self.node.alternative_citations), len(fork.alternative_citations), 1)
        fork.alternative_citations[0].text = "new text"
        assert_not_equal(self.node.alternative_citations[0].text, fork.alternative_citations[0].text)
        assert_equal(self.node.alternative_citations[0].name, fork.alternative_citations[0].name, "name")
        assert_not_equal(self.node.alternative_citations[0]._id, fork.alternative_citations[0]._id)
Exemple #15
0
class TestCloneWikiPages(OsfTestCase):

    def setUp(self):
        super(TestCloneWikiPages, self).setUp()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user, is_public=True)

    def set_up_project_with_wiki_page(self):
        self.project_with_wikis = ProjectFactory(creator=self.user, is_public=True)
        self.wiki = NodeWikiFactory(node=self.project_with_wikis)
        self.current_wiki = NodeWikiFactory(node=self.project_with_wikis, version=2, is_current=True)
        return self.project_with_wikis

    def tearDown(self):
        super(TestCloneWikiPages, self).tearDown()
        db.node.remove({})

    def test_project_no_wiki_pages(self):
        main()
        assert_equal(self.project.wiki_pages_versions, {})
        assert_equal(self.project.wiki_pages_current, {})

    def test_forked_project_no_wiki_pages(self):
        fork = self.project.fork_node(auth=Auth(self.user))
        main()
        assert_equal(fork.wiki_pages_versions, {})
        assert_equal(fork.wiki_pages_current, {})

    def test_registration_no_wiki_pages(self):
        registration = RegistrationFactory()
        main()
        assert_equal(registration.wiki_pages_versions, {})
        assert_equal(registration.wiki_pages_current, {})

    def test_project_wiki_pages_do_not_get_cloned(self):
        project = self.set_up_project_with_wiki_page()
        main()
        assert_equal(project.wiki_pages_versions, {self.wiki.page_name: [self.wiki._id, self.current_wiki._id]})
        assert_equal(project.wiki_pages_current, {self.current_wiki.page_name: self.current_wiki._id})

    def test_wiki_pages_that_do_not_exist_do_not_get_cloned(self):
        project = ProjectFactory(creator=self.user, is_public=True)
        wiki = NodeWikiFactory(node=project)
        NodeWikiPage.remove_one(wiki._id)
        # deleted wiki record in node.wiki_pages_versions
        assert_in(wiki._id, project.wiki_pages_versions[wiki.page_name])
        main()
        project.reload()
        # wiki_id gets removed from node.wiki_pages_versions
        assert_not_in(wiki._id, project.wiki_pages_versions[wiki.page_name])

    def test_wiki_pages_with_invalid_nodes_are_removed_after_cloning(self):
        project = ProjectFactory(creator=self.user, is_public=True)
        wiki = NodeWikiFactory(node=project)
        fork = project.fork_node(auth=Auth(self.user))
        fork.wiki_pages_versions = project.wiki_pages_versions
        fork.wiki_pages_current = project.wiki_pages_current
        fork.save()

        # Remove original node - wiki.node no longer points to an existing project
        Node.remove_one(project._id)

        # clone wiki page
        main()
        fork.reload()
        cloned_wiki_id = fork.wiki_pages_versions[wiki.page_name][0]
        cloned_wiki = NodeWikiPage.load(cloned_wiki_id)
        assert_equal(cloned_wiki.node._id, fork._id)

        # move original wiki page to unmigratedwikipages collection
        assert_false(db.nodewikipage.find_one({'_id': wiki._id}))
        assert_true(db.unmigratedwikipages.find_one({'_id': wiki._id}))

    def test_forked_project_wiki_pages_created_post_fork_do_not_get_cloned(self):
        fork_creator = AuthUserFactory()
        fork = self.project.fork_node(auth=Auth(fork_creator))
        wiki = NodeWikiFactory(node=fork)
        current_wiki = NodeWikiFactory(node=fork, version=2, is_current=True)
        main()
        assert_equal(fork.wiki_pages_versions, {wiki.page_name: [wiki._id, current_wiki._id]})
        assert_equal(fork.wiki_pages_current, {wiki.page_name: current_wiki._id})

    def test_forked_project_wiki_pages_created_pre_fork_get_cloned(self):
        project = self.set_up_project_with_wiki_page()
        fork = project.fork_node(auth=Auth(self.user))
        # reset wiki pages for test
        fork.wiki_pages_versions = project.wiki_pages_versions
        fork.wiki_pages_current = project.wiki_pages_current
        fork.save()

        main()
        # update_wiki_pages(self.find_node_record(fork._id))
        fork.reload()
        wiki_versions = fork.wiki_pages_versions[self.wiki.page_name]
        current_wiki = NodeWikiPage.load(fork.wiki_pages_current[self.current_wiki.page_name])
        assert_equal(current_wiki.node, fork)
        assert_not_equal(current_wiki._id, self.current_wiki._id)

        wiki_version = NodeWikiPage.load(wiki_versions[0])
        assert_equal(wiki_version.node, fork)
        assert_not_equal(wiki_version._id, self.current_wiki._id)

    def test_registration_wiki_pages_created_pre_registration_get_cloned(self):
        project = self.set_up_project_with_wiki_page()
        registration = project.register_node(get_default_metaschema(), Auth(self.user), '', None)
        # reset wiki pages for test
        registration.wiki_pages_versions = project.wiki_pages_versions
        registration.wiki_pages_current = project.wiki_pages_current
        registration.save()

        main()
        registration.reload()
        wiki_versions = registration.wiki_pages_versions[self.wiki.page_name]

        current_wiki = NodeWikiPage.load(registration.wiki_pages_current[self.current_wiki.page_name])
        assert_equal(current_wiki.node, registration)
        assert_not_equal(current_wiki._id, self.current_wiki._id)

        wiki_version = NodeWikiPage.load(wiki_versions[0])
        assert_equal(wiki_version.node, registration)
        assert_not_equal(wiki_version._id, self.current_wiki._id)
Exemple #16
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)
class TestCloneWikiPages(OsfTestCase):
    def setUp(self):
        super(TestCloneWikiPages, self).setUp()
        self.user = AuthUserFactory()
        self.project = ProjectFactory(creator=self.user, is_public=True)

    def set_up_project_with_wiki_page(self):
        self.project_with_wikis = ProjectFactory(creator=self.user, is_public=True)
        self.wiki = NodeWikiFactory(node=self.project_with_wikis)
        self.current_wiki = NodeWikiFactory(node=self.project_with_wikis, version=2, is_current=True)
        return self.project_with_wikis

    def tearDown(self):
        super(TestCloneWikiPages, self).tearDown()
        db.node.remove({})

    def test_project_no_wiki_pages(self):
        main()
        assert_equal(self.project.wiki_pages_versions, {})
        assert_equal(self.project.wiki_pages_current, {})

    def test_forked_project_no_wiki_pages(self):
        fork = self.project.fork_node(auth=Auth(self.user))
        main()
        assert_equal(fork.wiki_pages_versions, {})
        assert_equal(fork.wiki_pages_current, {})

    def test_registration_no_wiki_pages(self):
        registration = RegistrationFactory()
        main()
        assert_equal(registration.wiki_pages_versions, {})
        assert_equal(registration.wiki_pages_current, {})

    def test_project_wiki_pages_do_not_get_cloned(self):
        project = self.set_up_project_with_wiki_page()
        main()
        assert_equal(project.wiki_pages_versions, {self.wiki.page_name: [self.wiki._id, self.current_wiki._id]})
        assert_equal(project.wiki_pages_current, {self.current_wiki.page_name: self.current_wiki._id})

    def test_wiki_pages_that_do_not_exist_do_not_get_cloned(self):
        project = ProjectFactory(creator=self.user, is_public=True)
        wiki = NodeWikiFactory(node=project)
        NodeWikiPage.remove_one(wiki._id)
        # deleted wiki record in node.wiki_pages_versions
        assert_in(wiki._id, project.wiki_pages_versions[wiki.page_name])
        main()
        project.reload()
        # wiki_id gets removed from node.wiki_pages_versions
        assert_not_in(wiki._id, project.wiki_pages_versions[wiki.page_name])

    def test_wiki_pages_with_invalid_nodes_are_removed_after_cloning(self):
        project = ProjectFactory(creator=self.user, is_public=True)
        wiki = NodeWikiFactory(node=project)
        fork = project.fork_node(auth=Auth(self.user))
        fork.wiki_pages_versions = project.wiki_pages_versions
        fork.wiki_pages_current = project.wiki_pages_current
        fork.save()

        # Remove original node - wiki.node no longer points to an existing project
        Node.remove_one(project._id)

        # clone wiki page
        main()
        fork.reload()
        cloned_wiki_id = fork.wiki_pages_versions[wiki.page_name][0]
        cloned_wiki = NodeWikiPage.load(cloned_wiki_id)
        assert_equal(cloned_wiki.node._id, fork._id)

        # move original wiki page to unmigratedwikipages collection
        assert_false(db.nodewikipage.find_one({"_id": wiki._id}))
        assert_true(db.unmigratedwikipages.find_one({"_id": wiki._id}))

    def test_forked_project_wiki_pages_created_post_fork_do_not_get_cloned(self):
        fork_creator = AuthUserFactory()
        fork = self.project.fork_node(auth=Auth(fork_creator))
        wiki = NodeWikiFactory(node=fork)
        current_wiki = NodeWikiFactory(node=fork, version=2, is_current=True)
        main()
        assert_equal(fork.wiki_pages_versions, {wiki.page_name: [wiki._id, current_wiki._id]})
        assert_equal(fork.wiki_pages_current, {wiki.page_name: current_wiki._id})

    def test_forked_project_wiki_pages_created_pre_fork_get_cloned(self):
        project = self.set_up_project_with_wiki_page()
        fork = project.fork_node(auth=Auth(self.user))
        # reset wiki pages for test
        fork.wiki_pages_versions = project.wiki_pages_versions
        fork.wiki_pages_current = project.wiki_pages_current
        fork.save()

        main()
        # update_wiki_pages(self.find_node_record(fork._id))
        fork.reload()
        wiki_versions = fork.wiki_pages_versions[self.wiki.page_name]
        current_wiki = NodeWikiPage.load(fork.wiki_pages_current[self.current_wiki.page_name])
        assert_equal(current_wiki.node, fork)
        assert_not_equal(current_wiki._id, self.current_wiki._id)

        wiki_version = NodeWikiPage.load(wiki_versions[0])
        assert_equal(wiki_version.node, fork)
        assert_not_equal(wiki_version._id, self.current_wiki._id)

    def test_registration_wiki_pages_created_pre_registration_get_cloned(self):
        project = self.set_up_project_with_wiki_page()
        registration = project.register_node(get_default_metaschema(), Auth(self.user), "", None)
        # reset wiki pages for test
        registration.wiki_pages_versions = project.wiki_pages_versions
        registration.wiki_pages_current = project.wiki_pages_current
        registration.save()

        main()
        registration.reload()
        wiki_versions = registration.wiki_pages_versions[self.wiki.page_name]

        current_wiki = NodeWikiPage.load(registration.wiki_pages_current[self.current_wiki.page_name])
        assert_equal(current_wiki.node, registration)
        assert_not_equal(current_wiki._id, self.current_wiki._id)

        wiki_version = NodeWikiPage.load(wiki_versions[0])
        assert_equal(wiki_version.node, registration)
        assert_not_equal(wiki_version._id, self.current_wiki._id)
class TestMigrateForks(OsfTestCase):
    def setUp(self):
        super(TestMigrateForks, self).setUp()
        # Create registration with correct settings
        self.user = UserFactory()
        self.consolidated_auth = Auth(user=self.user)

        # Create base project
        self.base_project = ProjectFactory(
            creator=self.user,
            piwik_site_id=1,
        )

        self.base_component = NodeFactory(
            project=self.base_project,
            creator=self.user,
            piwik_site_id=2,
        )

        # Create valid fork
        self.fork_project = self.base_project.fork_node(
            auth=self.consolidated_auth
        )
        self.fork_project.piwik_site_id = 3
        self.fork_project.save()

        self.fork_component = self.fork_project.nodes[0]
        self.fork_component.piwik_site_id = 4
        self.fork_component.save()

        # Create broken fork
        self.bad_fork_project = self.base_project.fork_node(
            auth=self.consolidated_auth
        )
        self.bad_fork_project.piwik_site_id = self.base_project.piwik_site_id
        self.bad_fork_project.save()

        self.bad_fork_component = self.bad_fork_project.nodes[0]
        self.bad_fork_component.piwik_site_id = self.base_component.piwik_site_id
        self.bad_fork_component.save()

        responses.start()
        responses.add(
            responses.GET,
            '{host}index.php?module=API&method=SitesManager.getAllSites&format=JSON&token_auth={auth_token}'.format(
                host=PIWIK_HOST,
                auth_token=PIWIK_ADMIN_TOKEN,
            ),
            status=200,
            content_type='application/json',
            body=json.dumps({
                '1': {'name': 'Node: ' + self.base_project._id},
                '2': {'name': 'Node: ' + self.base_component._id},
                '3': {'name': 'Node: ' + self.fork_project._id},
                '4': {'name': 'Node: ' + self.fork_component._id},
            }),
            match_querystring=True,
        )

    def tearDown(self):
        super(TestMigrateForks, self).tearDown()
        Node.remove()
        responses.stop()
        responses.reset()
        piwik_cache._cache = None

    def test_get_broken_forks(self):
        nodes = set(get_broken_forks())

        assert_equal(2, len(nodes))
        assert_equal(
            {self.bad_fork_project, self.bad_fork_component},
            nodes,
        )

    def test_fix_forks(self):
        assert_equal(
            2,
            fix_nodes(get_broken_forks())
        )


        Node._clear_caches()

        broken_nodes = list(get_broken_forks())

        assert_equal(0, len(broken_nodes))
        assert_is_none(self.bad_fork_project.piwik_site_id)
        assert_is_none(self.bad_fork_component.piwik_site_id)

        assert_is_not_none(self.fork_project.piwik_site_id)
        assert_is_not_none(self.fork_component.piwik_site_id)
Exemple #19
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)
class ModelTests(OsfTestCase):
    def setUp(self):
        OsfTestCase.setUp(self)
        self.user = UserFactory()
        self.node = ProjectFactory(creator=self.user)
        self.citation = AlternativeCitation(name='name', text='text')
        self.citation.save()
        self.node.alternative_citations.append(self.citation)

    def test_model_success(self):
        alt_citation = AlternativeCitation(name='test', text='citation')
        alt_citation.save()
        self.node.alternative_citations.append(alt_citation)
        assert_equal(len(self.node.alternative_citations), 2)

    def test_model_no_name(self):
        alt_citation = AlternativeCitation(text='citation')
        with assert_raises(ValidationError):
            alt_citation.save()
            self.node.alternative_citations.append(alt_citation)
        assert_equal(len(self.node.alternative_citations), 1)

    def test_model_no_text(self):
        alt_citation = AlternativeCitation(name='test')
        with assert_raises(ValidationError):
            alt_citation.save()
            self.node.alternative_citations.append(alt_citation)
        assert_equal(len(self.node.alternative_citations), 1)

    def test_model_no_fields(self):
        alt_citation = AlternativeCitation()
        with assert_raises(ValidationError):
            alt_citation.save()
            self.node.alternative_citations.append(alt_citation)
        assert_equal(len(self.node.alternative_citations), 1)

    def test_model_change_name(self):
        citation = self.node.alternative_citations[0]
        citation.name = "New name"
        citation.save()
        self.node.save()
        assert_equal(self.node.alternative_citations[0].name, "New name")

    def test_model_change_text(self):
        citation = self.node.alternative_citations[0]
        citation.text = "New citation text"
        citation.save()
        self.node.save()
        assert_equal(self.node.alternative_citations[0].text,
                     "New citation text")

    def test_model_fork(self):
        fork = self.node.fork_node(auth=Auth(self.user))
        assert_equal(len(self.node.alternative_citations),
                     len(fork.alternative_citations), 1)
        assert_equal(self.node.alternative_citations[0].name,
                     fork.alternative_citations[0].name, 'name')
        assert_equal(self.node.alternative_citations[0].text,
                     fork.alternative_citations[0].text, 'text')
        assert_not_equal(self.node.alternative_citations[0]._id,
                         fork.alternative_citations[0]._id)

    def test_model_fork_change_name(self):
        fork = self.node.fork_node(auth=Auth(self.user))
        assert_equal(len(self.node.alternative_citations),
                     len(fork.alternative_citations), 1)
        fork.alternative_citations[0].name = "new name"
        assert_not_equal(self.node.alternative_citations[0].name,
                         fork.alternative_citations[0].name)
        assert_equal(self.node.alternative_citations[0].text,
                     fork.alternative_citations[0].text, 'text')
        assert_not_equal(self.node.alternative_citations[0]._id,
                         fork.alternative_citations[0]._id)

    def test_model_fork_change_text(self):
        fork = self.node.fork_node(auth=Auth(self.user))
        assert_equal(len(self.node.alternative_citations),
                     len(fork.alternative_citations), 1)
        fork.alternative_citations[0].text = "new text"
        assert_not_equal(self.node.alternative_citations[0].text,
                         fork.alternative_citations[0].text)
        assert_equal(self.node.alternative_citations[0].name,
                     fork.alternative_citations[0].name, 'name')
        assert_not_equal(self.node.alternative_citations[0]._id,
                         fork.alternative_citations[0]._id)
Exemple #21
0
class TestWikiUtils(OsfTestCase):

    def setUp(self):
        super(TestWikiUtils, self).setUp()
        self.project = ProjectFactory()

    def test_get_sharejs_uuid(self):
        wname = 'foo.bar'
        wname2 = 'bar.baz'
        private_uuid = generate_private_uuid(self.project, wname)
        sharejs_uuid = get_sharejs_uuid(self.project, wname)

        # Provides consistent results
        assert_equal(sharejs_uuid, get_sharejs_uuid(self.project, wname))

        # Provides obfuscation
        assert_not_in(wname, sharejs_uuid)
        assert_not_in(sharejs_uuid, wname)
        assert_not_in(private_uuid, sharejs_uuid)
        assert_not_in(sharejs_uuid, private_uuid)

        # Differs based on share uuid provided
        assert_not_equal(sharejs_uuid, get_sharejs_uuid(self.project, wname2))

        # Differs across projects and forks
        project = ProjectFactory()
        assert_not_equal(sharejs_uuid, get_sharejs_uuid(project, wname))
        fork = self.project.fork_node(Auth(self.project.creator))
        assert_not_equal(sharejs_uuid, get_sharejs_uuid(fork, wname))

    def test_generate_share_uuid(self):
        wname = 'bar.baz'
        wkey = to_mongo_key(wname)
        assert_is_none(self.project.wiki_private_uuids.get(wkey))
        share_uuid = generate_private_uuid(self.project, wname)
        self.project.reload()
        assert_equal(self.project.wiki_private_uuids[wkey], share_uuid)

        new_uuid = generate_private_uuid(self.project, wname)
        self.project.reload()
        assert_not_equal(share_uuid, new_uuid)
        assert_equal(self.project.wiki_private_uuids[wkey], new_uuid)

    def test_format_wiki_version(self):
        assert_is_none(format_wiki_version(None, 5, False))
        assert_is_none(format_wiki_version('', 5, False))
        assert_equal(format_wiki_version('3', 5, False), 3)
        assert_equal(format_wiki_version('4', 5, False), 'previous')
        assert_equal(format_wiki_version('5', 5, False), 'current')
        assert_equal(format_wiki_version('previous', 5, False), 'previous')
        assert_equal(format_wiki_version('current', 5, False), 'current')
        assert_equal(format_wiki_version('preview', 5, True), 'preview')
        assert_equal(format_wiki_version('current', 0, False), 'current')
        assert_equal(format_wiki_version('preview', 0, True), 'preview')

        with assert_raises(InvalidVersionError):
            format_wiki_version('1', 0, False)
        with assert_raises(InvalidVersionError):
            format_wiki_version('previous', 0, False)
        with assert_raises(InvalidVersionError):
            format_wiki_version('6', 5, False)
        with assert_raises(InvalidVersionError):
            format_wiki_version('0', 5, False)
        with assert_raises(InvalidVersionError):
            format_wiki_version('preview', 5, False)
        with assert_raises(InvalidVersionError):
            format_wiki_version('nonsense', 5, True)
Exemple #22
0
class MendeleyNodeSettingsTestCase(OsfTestCase):

    def setUp(self):
        super(MendeleyNodeSettingsTestCase, self).setUp()
        self.node = ProjectFactory()
        self.node_settings = model.MendeleyNodeSettings(owner=self.node)
        self.node_settings.save()
        self.user = self.node.creator
        self.user_settings = self.user.get_or_add_addon('mendeley')

    def tearDown(self):
        super(MendeleyNodeSettingsTestCase, self).tearDown()
        self.user_settings.remove()
        self.node_settings.remove()
        self.node.remove()
        self.user.remove()

    @mock.patch('website.addons.mendeley.model.Mendeley')
    def test_api_not_cached(self, mock_mendeley):
        # The first call to .api returns a new object
        api = self.node_settings.api
        mock_mendeley.assert_called_once()
        assert_equal(api, mock_mendeley())

    @mock.patch('website.addons.mendeley.model.Mendeley')
    def test_api_cached(self, mock_mendeley):
        # Repeated calls to .api returns the same object
        self.node_settings._api = 'testapi'
        api = self.node_settings.api
        assert_false(mock_mendeley.called)
        assert_equal(api, 'testapi')

    def test_set_auth(self):
        external_account = ExternalAccountFactory()
        self.user.external_accounts.append(external_account)
        self.user.save()

        # this should be reset after the call
        self.node_settings.mendeley_list_id = 'anything'

        self.node_settings.set_auth(
            external_account=external_account,
            user=self.user
        )

        # this instance is updated
        assert_equal(
            self.node_settings.external_account,
            external_account
        )
        assert_equal(
            self.node_settings.user_settings,
            self.user_settings
        )
        assert_is_none(
            self.node_settings.mendeley_list_id
        )

        # user_settings was updated
        # TODO: The call to grant_oauth_access in set_auth should be mocked
        assert_true(
            self.user_settings.verify_oauth_access(
                node=self.node,
                external_account=external_account,
            )
        )

    def test_set_auth_wrong_user(self):
        external_account = ExternalAccountFactory()
        self.user.external_accounts.append(external_account)
        self.user.save()

        with assert_raises(PermissionsError):
            self.node_settings.set_auth(
                external_account=external_account,
                user=UserFactory()
            )

    def test_deauthorize(self):
        self.node_settings.external_account = ExternalAccountFactory()
        self.node_settings.mendeley_list_id = 'something'
        self.node_settings.user_settings = self.user_settings
        self.node_settings.save()

        assert_true(self.node_settings.mendeley_list_id)
        self.node_settings.deauthorize(auth=Auth(self.user))
        self.node_settings.save()
        assert_is(self.node_settings.user_settings, None)
        assert_is(self.node_settings.mendeley_list_id, None)

        last_log = self.node.logs[-1]
        assert_equal(last_log.action, 'mendeley_node_deauthorized')
        params = last_log.params
        assert_in('node', params)
        assert_in('project', params)

    def test_clear_auth(self):
        self.node_settings.external_account = ExternalAccountFactory()
        self.node_settings.mendeley_list_id = 'something'
        self.node_settings.user_settings = self.user_settings
        self.node_settings.save()

        self.node_settings.clear_auth()

        assert_is_none(self.node_settings.external_account)
        assert_is_none(self.node_settings.mendeley_list_id)
        assert_is_none(self.node_settings.user_settings)

    def test_set_target_folder(self):
        folder_id = 'fake-folder-id'
        folder_name = 'fake-folder-name'

        external_account = ExternalAccountFactory()
        self.user.external_accounts.append(external_account)
        self.user.save()

        self.node_settings.set_auth(
            external_account=external_account,
            user=self.user,
        )

        assert_is_none(self.node_settings.mendeley_list_id)

        self.node_settings.set_target_folder(
            folder_id,
            folder_name,
            auth=Auth(user=self.user),
        )

        # instance was updated
        assert_equal(
            self.node_settings.mendeley_list_id,
            'fake-folder-id',
        )

        # user_settings was updated
        # TODO: the call to grant_oauth_access should be mocked
        assert_true(
            self.user_settings.verify_oauth_access(
                node=self.node,
                external_account=external_account,
                metadata={'folder': 'fake-folder-id'}
            )
        )

        log = self.node.logs[-1]
        assert_equal(log.action, 'mendeley_folder_selected')
        assert_equal(log.params['folder_id'], folder_id)
        assert_equal(log.params['folder_name'], folder_name)

    def test_has_auth_false(self):
        external_account = ExternalAccountFactory()

        assert_false(self.node_settings.has_auth)

        # both external_account and user_settings must be set to have auth
        self.node_settings.external_account = external_account
        assert_false(self.node_settings.has_auth)

        self.node_settings.external_account = None
        self.node_settings.user_settings = self.user_settings
        assert_false(self.node_settings.has_auth)

        # set_auth must be called to have auth
        self.node_settings.external_account = external_account
        self.node_settings.user_settings = self.user_settings
        assert_false(self.node_settings.has_auth)

    def test_has_auth_true(self):
        external_account = ExternalAccountFactory()
        self.user.external_accounts.append(external_account)

        self.node_settings.set_auth(external_account, self.user)

        # mendeley_list_id should have no effect
        self.node_settings.mendeley_list_id = None
        assert_true(self.node_settings.has_auth)

        # mendeley_list_id should have no effect
        self.node_settings.mendeley_list_id = 'totally fake ID'
        assert_true(self.node_settings.has_auth)

    def test_selected_folder_name_root(self):
        self.node_settings.mendeley_list_id = 'ROOT'

        assert_equal(
            self.node_settings.selected_folder_name,
            "All Documents"
        )

    def test_selected_folder_name_empty(self):
        self.node_settings.mendeley_list_id = None

        assert_equal(
            self.node_settings.selected_folder_name,
            ''
        )

    @mock.patch('website.addons.mendeley.model.Mendeley._folder_metadata')
    def test_selected_folder_name(self, mock_folder_metadata):
        # Mock the return from api call to get the folder's name
        mock_folder = mock.Mock()
        mock_folder.name = 'Fake Folder'

        # Add the mocked return object to the mocked api client
        mock_folder_metadata.return_value = mock_folder

        self.node_settings.mendeley_list_id = 'fake-list-id'

        assert_equal(
            self.node_settings.selected_folder_name,
            'Fake Folder'
        )

    # TODO: Make these tests generic and move to core

    @mock.patch('framework.status.push_status_message')
    def test_remove_contributor_authorizer(self, mock_push_status):
        external_account = ExternalAccountFactory()
        self.user.external_accounts.append(external_account)
        self.node_settings.set_auth(external_account, self.user)

        contributor = UserFactory()
        self.node.add_contributor(contributor, permissions=['read', 'write', 'admin'])
        self.node.remove_contributor(self.node.creator, auth=Auth(user=contributor))

        assert_false(self.node_settings.has_auth)
        assert_false(self.user_settings.verify_oauth_access(self.node, external_account))

    def test_remove_contributor_not_authorizer(self):
        external_account = ExternalAccountFactory()
        self.user.external_accounts.append(external_account)
        self.node_settings.set_auth(external_account, self.user)

        contributor = UserFactory()
        self.node.add_contributor(contributor)
        self.node.remove_contributor(contributor, auth=Auth(user=self.node.creator))

        assert_true(self.node_settings.has_auth)
        assert_true(self.user_settings.verify_oauth_access(self.node, external_account))

    @mock.patch('framework.status.push_status_message')
    def test_fork_by_authorizer(self, mock_push_status):
        external_account = ExternalAccountFactory()
        self.user.external_accounts.append(external_account)
        self.node_settings.set_auth(external_account, self.user)

        fork = self.node.fork_node(auth=Auth(user=self.node.creator))

        assert_true(fork.get_addon('mendeley').has_auth)
        assert_true(self.user_settings.verify_oauth_access(fork, external_account))

    @mock.patch('framework.status.push_status_message')
    def test_fork_not_by_authorizer(self, mock_push_status):
        external_account = ExternalAccountFactory()
        self.user.external_accounts.append(external_account)
        self.node_settings.set_auth(external_account, self.user)

        contributor = UserFactory()
        self.node.add_contributor(contributor)
        fork = self.node.fork_node(auth=Auth(user=contributor))

        assert_false(fork.get_addon('mendeley').has_auth)
        assert_false(self.user_settings.verify_oauth_access(fork, external_account))
Exemple #23
0
class TestMigrateFiles(OsfTestCase):

    def setUp(self):
        super(TestMigrateFiles, self).setUp()
        self.project = ProjectFactory()
        self.user = self.project.creator
        self.auth_obj = Auth(user=self.user)
        self.project.delete_addon('osfstorage', auth=None, _force=True)
        for idx in range(5):
            content = 'i want {0} pizzas'.format(idx)
            self.project.add_file(
                auth=self.auth_obj,
                file_name='pizza.md',
                content=content,
                size=len(content),
                content_type='text/markdown',
            )

    def check_record(self, record):
        assert_true(record)
        assert_equal(len(record.versions), 5)
        for idx, version in enumerate(record.versions):
            assert_false(version.pending)
            expected = 'i want {0} pizzas'.format(idx)
            download_url = utils.get_waterbutler_download_url(idx + 1, version, record)
            resp = requests.get(download_url)
            assert_equal(expected, resp.content)

    def test_migrate(self):
        main(dry_run=False)
        node_settings = self.project.get_addon('osfstorage')
        assert_true(node_settings)
        record = model.OsfStorageFileRecord.find_by_path('pizza.md', node_settings)
        self.check_record(record)
        # Test idempotence of migration
        main(dry_run=False)
        assert_equal(len(record.versions), 5)

    def test_migrate_incomplete(self):
        node_settings = self.project.get_or_add_addon('osfstorage', auth=None, log=False)
        record = model.OsfStorageFileRecord.get_or_create('pizza.md', node_settings)
        node_file = NodeFile.load(self.project.files_versions['pizza_md'][0])
        content, _ = self.project.read_file_object(node_file)
        file_pointer = StringIO(content)
        hash_str = scripts_settings.UPLOAD_PRIMARY_HASH(content).hexdigest()
        record.create_pending_version(node_file.uploader, hash_str)
        main(dry_run=False)

    def test_migrate_fork(self):
        fork = self.project.fork_node(auth=self.auth_obj)
        main(dry_run=False)
        node_settings = self.project.get_addon('osfstorage')
        record = model.OsfStorageFileRecord.find_by_path('pizza.md', node_settings)
        self.check_record(record)
        fork_node_settings = fork.get_addon('osfstorage')
        fork_record = model.OsfStorageFileRecord.find_by_path('pizza.md', fork_node_settings)
        self.check_record(fork_record)

    def test_migrate_corrupt_fork_repo_deleted(self):
        fork = self.project.fork_node(auth=self.auth_obj)
        fork_repo = os.path.join(settings.UPLOADS_PATH, fork._id)
        shutil.rmtree(fork_repo)
        main(dry_run=False)
        node_settings = self.project.get_addon('osfstorage')
        record = model.OsfStorageFileRecord.find_by_path('pizza.md', node_settings)
        self.check_record(record)
        fork_node_settings = fork.get_addon('osfstorage')
        fork_record = model.OsfStorageFileRecord.find_by_path('pizza.md', fork_node_settings)
        self.check_record(fork_record)

    def test_migrate_corrupt_fork_git_dir_deleted(self):
        fork = self.project.fork_node(auth=self.auth_obj)
        fork_git_dir = os.path.join(settings.UPLOADS_PATH, fork._id, '.git')
        shutil.rmtree(fork_git_dir)
        main(dry_run=False)
        node_settings = self.project.get_addon('osfstorage')
        record = model.OsfStorageFileRecord.find_by_path('pizza.md', node_settings)
        self.check_record(record)
        fork_node_settings = fork.get_addon('osfstorage')
        fork_record = model.OsfStorageFileRecord.find_by_path('pizza.md', fork_node_settings)
        self.check_record(fork_record)
Exemple #24
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 #25
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 #26
0
class MendeleyNodeSettingsTestCase(OsfTestCase):
    def setUp(self):
        super(MendeleyNodeSettingsTestCase, self).setUp()
        self.node = ProjectFactory()
        self.node_settings = model.MendeleyNodeSettings(owner=self.node)
        self.node_settings.save()
        self.user = self.node.creator
        self.user_settings = self.user.get_or_add_addon('mendeley')

    def tearDown(self):
        super(MendeleyNodeSettingsTestCase, self).tearDown()
        self.user_settings.remove()
        self.node_settings.remove()
        self.node.remove()
        self.user.remove()

    @mock.patch('website.addons.mendeley.model.Mendeley')
    def test_api_not_cached(self, mock_mendeley):
        # The first call to .api returns a new object
        api = self.node_settings.api
        mock_mendeley.assert_called_once()
        assert_equal(api, mock_mendeley())

    @mock.patch('website.addons.mendeley.model.Mendeley')
    def test_api_cached(self, mock_mendeley):
        # Repeated calls to .api returns the same object
        self.node_settings._api = 'testapi'
        api = self.node_settings.api
        assert_false(mock_mendeley.called)
        assert_equal(api, 'testapi')

    def test_set_auth(self):
        external_account = MendeleyAccountFactory()
        self.user.external_accounts.append(external_account)
        self.user.save()

        # this should be reset after the call
        self.node_settings.mendeley_list_id = 'anything'

        self.node_settings.set_auth(external_account=external_account,
                                    user=self.user)

        # this instance is updated
        assert_equal(self.node_settings.external_account, external_account)
        assert_equal(self.node_settings.user_settings, self.user_settings)
        assert_is_none(self.node_settings.mendeley_list_id)

        # user_settings was updated
        # TODO: The call to grant_oauth_access in set_auth should be mocked
        assert_true(
            self.user_settings.verify_oauth_access(
                node=self.node,
                external_account=external_account,
            ))

    def test_set_auth_wrong_user(self):
        external_account = MendeleyAccountFactory()
        self.user.external_accounts.append(external_account)
        self.user.save()

        with assert_raises(PermissionsError):
            self.node_settings.set_auth(external_account=external_account,
                                        user=UserFactory())

    def test_deauthorize(self):
        self.node_settings.external_account = MendeleyAccountFactory()
        self.node_settings.mendeley_list_id = 'something'
        self.node_settings.user_settings = self.user_settings
        self.node_settings.save()

        assert_true(self.node_settings.mendeley_list_id)
        self.node_settings.deauthorize(auth=Auth(self.user))
        self.node_settings.save()
        assert_is(self.node_settings.user_settings, None)
        assert_is(self.node_settings.mendeley_list_id, None)

        last_log = self.node.logs[-1]
        assert_equal(last_log.action, 'mendeley_node_deauthorized')
        params = last_log.params
        assert_in('node', params)
        assert_in('project', params)

    def test_clear_auth(self):
        self.node_settings.external_account = MendeleyAccountFactory()
        self.node_settings.mendeley_list_id = 'something'
        self.node_settings.user_settings = self.user_settings
        self.node_settings.save()

        self.node_settings.clear_auth()

        assert_is_none(self.node_settings.external_account)
        assert_is_none(self.node_settings.mendeley_list_id)
        assert_is_none(self.node_settings.user_settings)

    def test_set_target_folder(self):
        folder_id = 'fake-folder-id'
        folder_name = 'fake-folder-name'

        external_account = MendeleyAccountFactory()
        self.user.external_accounts.append(external_account)
        self.user.save()

        self.node_settings.set_auth(
            external_account=external_account,
            user=self.user,
        )

        assert_is_none(self.node_settings.mendeley_list_id)

        self.node_settings.set_target_folder(
            folder_id,
            folder_name,
            auth=Auth(user=self.user),
        )

        # instance was updated
        assert_equal(
            self.node_settings.mendeley_list_id,
            'fake-folder-id',
        )

        # user_settings was updated
        # TODO: the call to grant_oauth_access should be mocked
        assert_true(
            self.user_settings.verify_oauth_access(
                node=self.node,
                external_account=external_account,
                metadata={'folder': 'fake-folder-id'}))

        log = self.node.logs[-1]
        assert_equal(log.action, 'mendeley_folder_selected')
        assert_equal(log.params['folder_id'], folder_id)
        assert_equal(log.params['folder_name'], folder_name)

    def test_has_auth_false(self):
        external_account = MendeleyAccountFactory()

        assert_false(self.node_settings.has_auth)

        # both external_account and user_settings must be set to have auth
        self.node_settings.external_account = external_account
        assert_false(self.node_settings.has_auth)

        self.node_settings.external_account = None
        self.node_settings.user_settings = self.user_settings
        assert_false(self.node_settings.has_auth)

        # set_auth must be called to have auth
        self.node_settings.external_account = external_account
        self.node_settings.user_settings = self.user_settings
        assert_false(self.node_settings.has_auth)

    def test_has_auth_true(self):
        external_account = MendeleyAccountFactory()
        self.user.external_accounts.append(external_account)

        self.node_settings.set_auth(external_account, self.user)

        # mendeley_list_id should have no effect
        self.node_settings.mendeley_list_id = None
        assert_true(self.node_settings.has_auth)

        # mendeley_list_id should have no effect
        self.node_settings.mendeley_list_id = 'totally fake ID'
        assert_true(self.node_settings.has_auth)

    def test_selected_folder_name_root(self):
        self.node_settings.mendeley_list_id = 'ROOT'

        assert_equal(self.node_settings.selected_folder_name, "All Documents")

    def test_selected_folder_name_empty(self):
        self.node_settings.mendeley_list_id = None

        assert_equal(self.node_settings.selected_folder_name, '')

    @mock.patch('website.addons.mendeley.model.Mendeley._folder_metadata')
    def test_selected_folder_name(self, mock_folder_metadata):
        # Mock the return from api call to get the folder's name
        mock_folder = mock.Mock()
        mock_folder.name = 'Fake Folder'

        # Add the mocked return object to the mocked api client
        mock_folder_metadata.return_value = mock_folder

        self.node_settings.mendeley_list_id = 'fake-list-id'

        assert_equal(self.node_settings.selected_folder_name, 'Fake Folder')

    # TODO: Make these tests generic and move to core

    @mock.patch('framework.status.push_status_message')
    def test_remove_contributor_authorizer(self, mock_push_status):
        external_account = MendeleyAccountFactory()
        self.user.external_accounts.append(external_account)
        self.user.save()
        self.node_settings.set_auth(external_account, self.user)

        contributor = UserFactory()
        self.node.add_contributor(contributor,
                                  permissions=['read', 'write', 'admin'])
        self.node.remove_contributor(self.node.creator,
                                     auth=Auth(user=contributor))

        assert_false(self.node_settings.has_auth)
        assert_false(
            self.user_settings.verify_oauth_access(self.node,
                                                   external_account))

    def test_remove_contributor_not_authorizer(self):
        external_account = MendeleyAccountFactory()
        self.user.external_accounts.append(external_account)
        self.node_settings.set_auth(external_account, self.user)

        contributor = UserFactory()
        self.node.add_contributor(contributor)
        self.node.remove_contributor(contributor,
                                     auth=Auth(user=self.node.creator))

        assert_true(self.node_settings.has_auth)
        assert_true(
            self.user_settings.verify_oauth_access(self.node,
                                                   external_account))

    @mock.patch('framework.status.push_status_message')
    def test_fork_by_authorizer(self, mock_push_status):
        external_account = MendeleyAccountFactory()
        self.user.external_accounts.append(external_account)
        self.node_settings.set_auth(external_account, self.user)

        fork = self.node.fork_node(auth=Auth(user=self.node.creator))

        assert_true(fork.get_addon('mendeley').has_auth)
        assert_true(
            self.user_settings.verify_oauth_access(fork, external_account))

    @mock.patch('framework.status.push_status_message')
    def test_fork_not_by_authorizer(self, mock_push_status):
        external_account = MendeleyAccountFactory()
        self.user.external_accounts.append(external_account)
        self.node_settings.set_auth(external_account, self.user)

        contributor = UserFactory()
        self.node.add_contributor(contributor)
        fork = self.node.fork_node(auth=Auth(user=contributor))

        assert_false(fork.get_addon('mendeley').has_auth)
        assert_false(
            self.user_settings.verify_oauth_access(fork, external_account))