Пример #1
0
 def test_create_comment_content_does_not_exceed_max_length_complex(self, node, user, auth):
     Comment.create(
         auth=auth,
         user=user,
         node=node,
         target=node.guids.all()[0],
         content=''.join(['c' for c in range(settings.COMMENT_MAXLENGTH - 12)]) + '[@George Ant](http://localhost:5000/' + user._id + '/)'
     )
Пример #2
0
 def test_create_comment_content_cannot_exceed_max_length_simple(self, node, user, auth):
     with pytest.raises(ValidationError):
         Comment.create(
             auth=auth,
             user=user,
             node=node,
             target=node.guids.all()[0],
             content=''.join(['c' for c in range(settings.COMMENT_MAXLENGTH + 3)])
         )
Пример #3
0
 def test_create_comment_content_cannot_exceed_max_length_simple(self, node, user, auth):
     with pytest.raises(ValidationError):
         Comment.create(
             auth=auth,
             user=user,
             node=node,
             target=node.guids.all()[0],
             content=''.join(['c' for c in range(settings.COMMENT_MAXLENGTH + 3)])
         )
Пример #4
0
 def test_create_comment_content_cannot_exceed_max_length_complex(self, node, user, auth):
     with pytest.raises(ValidationError):
         Comment.create(
             auth=auth,
             user=user,
             node=node,
             target=node.guids.all()[0],
             content=''.join(['c' for c in range(settings.COMMENT_MAXLENGTH - 8)]) + '[@George Ant](http://localhost:5000/' + user._id + '/)'
         )
Пример #5
0
 def test_create_comment_content_cannot_be_whitespace(self, node, user, auth):
     with pytest.raises(ValidationError) as error:
         Comment.create(
             auth=auth,
             user=user,
             node=node,
             target=node.guids.all()[0],
             content='    '
         )
     assert error.value.messages[0] == 'Value must not be empty.'
Пример #6
0
 def test_create_sends_mention_added_signal_if_mentions(self, node, user, auth):
     with capture_signals() as mock_signals:
         Comment.create(
             auth=auth,
             user=user,
             node=node,
             target=node.guids.all()[0],
             content='This is a comment with a bad mention [@Unconfirmed User](http://localhost:5000/' + user._id + '/).'
         )
     assert mock_signals.signals_sent() == ({comment_added, mention_added})
Пример #7
0
 def test_create_sends_comment_added_signal(self, node, user, auth):
     with capture_signals() as mock_signals:
         Comment.create(
             auth=auth,
             user=user,
             node=node,
             target=node.guids.all()[0],
             content='This is a comment.'
         )
     assert mock_signals.signals_sent() == ({comment_added})
Пример #8
0
 def test_create_comment_content_cannot_be_whitespace(self, node, user, auth):
     with pytest.raises(ValidationError) as error:
         Comment.create(
             auth=auth,
             user=user,
             node=node,
             target=node.guids.all()[0],
             content='    '
         )
     assert error.value.messages[0] == 'Value must not be empty.'
Пример #9
0
 def test_create_sends_comment_added_signal(self, node, user, auth):
     with capture_signals() as mock_signals:
         Comment.create(
             auth=auth,
             user=user,
             node=node,
             target=node.guids.all()[0],
             content='This is a comment.'
         )
     assert mock_signals.signals_sent() == ({comment_added})
Пример #10
0
 def test_create_sends_mention_added_signal_if_mentions(self, node, user, auth):
     with capture_signals() as mock_signals:
         Comment.create(
             auth=auth,
             user=user,
             node=node,
             target=node.guids.all()[0],
             content='This is a comment with a bad mention [@Unconfirmed User](http://localhost:5000/' + user._id + '/).'
         )
     assert mock_signals.signals_sent() == ({comment_added, mention_added})
Пример #11
0
 def test_create_comment_content_cannot_be_empty(self, node, user, auth):
     with pytest.raises(ValidationError) as error:
         Comment.create(
             auth=auth,
             user=user,
             node=node,
             target=node.guids.all()[0],
             content=''
         )
     assert error.value.messages[0] == 'This field cannot be blank.'
Пример #12
0
 def test_create_comment_content_cannot_be_empty(self, node, user, auth):
     with pytest.raises(ValidationError) as error:
         Comment.create(
             auth=auth,
             user=user,
             node=node,
             target=node.guids.all()[0],
             content=''
         )
     assert error.value.messages[0] == 'This field cannot be blank.'
Пример #13
0
 def setUp(self):
     super(TestSpamListView, self).setUp()
     Comment.remove()
     self.project = ProjectFactory(is_public=True)
     self.user_1 = AuthUserFactory()
     self.user_2 = AuthUserFactory()
     self.project.add_contributor(self.user_1)
     self.project.add_contributor(self.user_2)
     self.project.save()
     self.user_1.save()
     self.user_2.save()
     date = timezone.now()
     self.comment_1 = CommentFactory(node=self.project, user=self.user_1)
     self.comment_2 = CommentFactory(node=self.project, user=self.user_1)
     self.comment_3 = CommentFactory(node=self.project, user=self.user_1)
     self.comment_4 = CommentFactory(node=self.project, user=self.user_1)
     self.comment_5 = CommentFactory(node=self.project, user=self.user_2)
     self.comment_6 = CommentFactory(node=self.project, user=self.user_2)
     self.comment_1.report_abuse(
         user=self.user_2,
         save=True,
         category='spam',
         date=date - timedelta(seconds=5)
     )
     self.comment_2.report_abuse(
         user=self.user_2,
         save=True,
         category='spam',
         date=date - timedelta(seconds=4)
     )
     self.comment_3.report_abuse(
         user=self.user_2,
         save=True,
         category='spam',
         date=date - timedelta(seconds=3)
     )
     self.comment_4.report_abuse(
         user=self.user_2,
         save=True,
         category='spam',
         date=date - timedelta(seconds=2)
     )
     self.comment_5.report_abuse(
         user=self.user_1,
         save=True,
         category='spam',
         date=date - timedelta(seconds=1)
     )
     self.comment_6.report_abuse(user=self.user_1, save=True,
                                 category='spam')
     self.request = RequestFactory().get('/fake_path')
     self.view = SpamList()
     self.view = setup_view(self.view, self.request, user_id=self.user_1._id)
Пример #14
0
 def test_create_does_not_send_mention_added_signal_if_nonuser_mentioned(self, node, user, auth):
     with pytest.raises(ValidationError) as error:
         with capture_signals() as mock_signals:
             Comment.create(
                 auth=auth,
                 user=user,
                 node=node,
                 target=node.guids.all()[0],
                 content='This is a comment with a bad mention [@Not a User](http://localhost:5000/qwert/).'
             )
     assert mock_signals.signals_sent() == set([])
     assert error.value.message == 'User does not exist or is not active.'
Пример #15
0
 def test_create_does_not_send_mention_added_signal_if_nonuser_mentioned(self, node, user, auth):
     with pytest.raises(ValidationError) as error:
         with capture_signals() as mock_signals:
             Comment.create(
                 auth=auth,
                 user=user,
                 node=node,
                 target=node.guids.all()[0],
                 content='This is a comment with a bad mention [@Not a User](http://localhost:5000/qwert/).'
             )
     assert mock_signals.signals_sent() == set([])
     assert error.value.message == 'User does not exist or is not active.'
Пример #16
0
 def test_create_does_not_send_mention_added_signal_if_noncontributor_mentioned(self, node, user, auth):
     with pytest.raises(ValidationError) as error:
         with capture_signals() as mock_signals:
             user = UserFactory()
             Comment.create(
                 auth=auth,
                 user=user,
                 node=node,
                 target=node.guids.all()[0],
                 content='This is a comment with a bad mention [@Non-contributor User](http://localhost:5000/' + user._id + '/).'
             )
     assert mock_signals.signals_sent() == set([])
     assert error.value.message == 'Mentioned user is not a contributor.'
Пример #17
0
 def test_create_does_not_send_mention_added_signal_if_noncontributor_mentioned(self, node, user, auth):
     with pytest.raises(ValidationError) as error:
         with capture_signals() as mock_signals:
             user = UserFactory()
             Comment.create(
                 auth=auth,
                 user=user,
                 node=node,
                 target=node.guids.all()[0],
                 content='This is a comment with a bad mention [@Non-contributor User](http://localhost:5000/' + user._id + '/).'
             )
     assert mock_signals.signals_sent() == set([])
     assert error.value.message == 'Mentioned user is not a contributor.'
Пример #18
0
 def test_create_sends_mention_added_signal_if_group_member_mentions(self, node, user, auth):
     manager = AuthUserFactory()
     group = OSFGroupFactory(creator=manager)
     node.add_osf_group(group)
     assert node.is_contributor_or_group_member(manager) is True
     with capture_signals() as mock_signals:
         Comment.create(
             auth=auth,
             user=user,
             node=node,
             target=node.guids.all()[0],
             content='This is a comment with a group member mention [@Group Member](http://localhost:5000/' + manager._id + '/).'
         )
     assert mock_signals.signals_sent() == ({comment_added, mention_added})
    def get_paginated_response(self, data):
        """Add number of unread comments to links.meta when viewing list of comments filtered by
        a target node, file or wiki page."""
        response = super(CommentPagination, self).get_paginated_response(data)
        response_dict = response.data
        kwargs = self.request.parser_context['kwargs'].copy()

        if self.request.query_params.get('related_counts', False):
            target_id = self.request.query_params.get('filter[target]', None)
            node_id = kwargs.get('node_id', None)
            node = AbstractNode.load(node_id)
            user = self.request.user
            if target_id and not user.is_anonymous and node.is_contributor_or_group_member(user):
                root_target = Guid.load(target_id)
                if root_target:
                    page = getattr(root_target.referent, 'root_target_page', None)
                    if page:
                        if not len(data):
                            unread = 0
                        else:
                            unread = Comment.find_n_unread(user=user, node=node, page=page, root_id=target_id)
                        if self.request.version < '2.1':
                            response_dict['links']['meta']['unread'] = unread
                        else:
                            response_dict['meta']['unread'] = unread
        return Response(response_dict)
Пример #20
0
    def test_comments_move_when_file_moved_to_osfstorage(self, project, user):
        osfstorage = project.get_addon('osfstorage')
        root_node = osfstorage.get_root()
        osf_file = root_node.append_file('file.txt')
        osf_file.create_version(user, {
            'object': '06d80e',
            'service': 'cloud',
            osfstorage_settings.WATERBUTLER_RESOURCE: 'osf',
        }, {
            'size': 1337,
            'contentType': 'img/png',
            'etag': 'abcdefghijklmnop'
        }).save()

        source = {
            'path': '/file.txt',
            'node': project,
            'provider': self.provider
        }
        destination = {
            'path': osf_file.path,
            'node': project,
            'provider': 'osfstorage'
        }
        self._create_file_with_comment(node=source['node'], path=source['path'], user=user)
        payload = self._create_payload('move', user, source, destination, self.file._id, destination_file_id=destination['path'].strip('/'))
        update_file_guid_referent(self=None, node=destination['node'], event_type='addon_file_moved', payload=payload)
        self.guid.reload()

        file_node = BaseFileNode.resolve_class('osfstorage', BaseFileNode.FILE).get_or_create(destination['node'], destination['path'])
        assert self.guid._id == file_node.get_guid()._id
        file_comments = Comment.find(Q('root_target', 'eq', self.guid.pk))
        assert file_comments.count() == 1
Пример #21
0
    def test_comments_move_when_folder_moved_to_different_provider(self, destination_provider, destination_path, project, user):
        if self.provider == destination_provider:
            return True

        project.add_addon(destination_provider, auth=Auth(user))
        project.save()
        self.addon_settings = project.get_addon(destination_provider)
        self.addon_settings.folder = '/AddonFolder'
        self.addon_settings.save()

        source = {
            'path': '/',
            'node': project,
            'provider': self.provider
        }
        destination = {
            'path': '/subfolder/',
            'node': project,
            'provider': destination_provider,
            'children': [{
                    'path': '/subfolder/file.txt',
                    'node': project,
                    'provider': destination_provider
            }]
        }
        file_name = 'file.txt'
        self._create_file_with_comment(node=source['node'], path='{}{}'.format(source['path'], file_name), user=user)
        payload = self._create_payload('move', user, source, destination, self.file._id)
        update_file_guid_referent(self=None, node=destination['node'], event_type='addon_file_moved', payload=payload)
        self.guid.reload()

        file_node = BaseFileNode.resolve_class(destination_provider, BaseFileNode.FILE).get_or_create(destination['node'], destination_path)
        assert self.guid._id == file_node.get_guid()._id
        file_comments = Comment.find(Q('root_target', 'eq', self.guid.pk))
        assert file_comments.count() == 1
Пример #22
0
    def test_create_does_not_send_mention_added_signal_if_unconfirmed_contributor_mentioned(self, node, user, auth):
        with pytest.raises(ValidationError) as error:
            with capture_signals() as mock_signals:
                user = UnregUserFactory()
                user.save()
                node.add_unregistered_contributor(user.fullname, user.email, Auth(node.creator), permissions=[permissions.READ], save=True)

                Comment.create(
                    auth=auth,
                    user=user,
                    node=node,
                    target=node.guids.all()[0],
                    content='This is a comment with a bad mention [@Unconfirmed User](http://localhost:5000/' + user._id + '/).'
                )
        assert mock_signals.signals_sent() == ({contributor_added})
        assert error.value.message == 'User does not exist or is not active.'
Пример #23
0
def update_file_guid_referent(self, node, event_type, payload, user=None):
    if event_type not in ('addon_file_moved', 'addon_file_renamed'):
        return  # Nothing to do

    source, destination = payload['source'], payload['destination']
    source_node, destination_node = Node.load(source['node']['_id']), Node.load(destination['node']['_id'])

    if source['provider'] in settings.ADDONS_BASED_ON_IDS:
        if event_type == 'addon_file_renamed':
            return  # Node has not changed and provider has not changed

        # Must be a move
        if source['provider'] == destination['provider'] and source_node == destination_node:
            return  # Node has not changed and provider has not changed

    file_guids = BaseFileNode.resolve_class(source['provider'], BaseFileNode.ANY).get_file_guids(
        materialized_path=source['materialized'] if source['provider'] != 'osfstorage' else source['path'],
        provider=source['provider'],
        node=source_node
    )

    for guid in file_guids:
        obj = Guid.load(guid)
        if source_node != destination_node and Comment.find(Q('root_target._id', 'eq', guid)).count() != 0:
            update_comment_node(guid, source_node, destination_node)

        if source['provider'] != destination['provider'] or source['provider'] != 'osfstorage':
            old_file = BaseFileNode.load(obj.referent._id)
            obj.referent = create_new_file(obj, source, destination, destination_node)
            obj.save()
            if old_file and not TrashedFileNode.load(old_file._id):
                old_file.delete()
Пример #24
0
    def get_unread_comments_count(self, obj):
        user = get_user_auth(self.context['request']).user
        node_comments = Comment.find_n_unread(user=user, node=obj, page='node')

        return {
            'node': node_comments
        }
Пример #25
0
 def test_find_unread_new_comments(self):
     project = ProjectFactory()
     user = UserFactory()
     project.add_contributor(user, save=True)
     CommentFactory(node=project, user=project.creator)
     n_unread = Comment.find_n_unread(user=user, node=project, page='node')
     assert n_unread == 1
Пример #26
0
    def get_paginated_response(self, data):
        """Add number of unread comments to links.meta when viewing list of comments filtered by
        a target node, file or wiki page."""
        response = super(CommentPagination, self).get_paginated_response(data)
        response_dict = response.data
        kwargs = self.request.parser_context['kwargs'].copy()

        if self.request.query_params.get('related_counts', False):
            target_id = self.request.query_params.get('filter[target]', None)
            node_id = kwargs.get('node_id', None)
            node = Node.load(node_id)
            user = self.request.user
            if target_id and not user.is_anonymous and node.is_contributor(user):
                root_target = Guid.load(target_id)
                if root_target:
                    page = getattr(root_target.referent, 'root_target_page', None)
                    if page:
                        if not len(data):
                            unread = 0
                        else:
                            unread = Comment.find_n_unread(user=user, node=node, page=page, root_id=target_id)
                        if self.request.version < '2.1':
                            response_dict['links']['meta']['unread'] = unread
                        else:
                            response_dict['meta']['unread'] = unread
        return Response(response_dict)
Пример #27
0
 def test_find_unread_new_comments(self):
     project = ProjectFactory()
     user = UserFactory()
     project.add_contributor(user, save=True)
     CommentFactory(node=project, user=project.creator)
     n_unread = Comment.find_n_unread(user=user, node=project, page='node')
     assert n_unread == 1
Пример #28
0
 def setUp(self):
     super(TestSpamListView, self).setUp()
     Comment.remove()
     self.project = ProjectFactory(is_public=True)
     self.user_1 = AuthUserFactory()
     self.user_2 = AuthUserFactory()
     self.project.add_contributor(self.user_1)
     self.project.add_contributor(self.user_2)
     self.project.save()
     self.user_1.save()
     self.user_2.save()
     date = timezone.now()
     self.comment_1 = CommentFactory(node=self.project, user=self.user_1)
     self.comment_2 = CommentFactory(node=self.project, user=self.user_1)
     self.comment_3 = CommentFactory(node=self.project, user=self.user_1)
     self.comment_4 = CommentFactory(node=self.project, user=self.user_1)
     self.comment_5 = CommentFactory(node=self.project, user=self.user_2)
     self.comment_6 = CommentFactory(node=self.project, user=self.user_2)
     self.comment_1.report_abuse(user=self.user_2,
                                 save=True,
                                 category='spam',
                                 date=date - timedelta(seconds=5))
     self.comment_2.report_abuse(user=self.user_2,
                                 save=True,
                                 category='spam',
                                 date=date - timedelta(seconds=4))
     self.comment_3.report_abuse(user=self.user_2,
                                 save=True,
                                 category='spam',
                                 date=date - timedelta(seconds=3))
     self.comment_4.report_abuse(user=self.user_2,
                                 save=True,
                                 category='spam',
                                 date=date - timedelta(seconds=2))
     self.comment_5.report_abuse(user=self.user_1,
                                 save=True,
                                 category='spam',
                                 date=date - timedelta(seconds=1))
     self.comment_6.report_abuse(user=self.user_1,
                                 save=True,
                                 category='spam')
     self.request = RequestFactory().get('/fake_path')
     self.view = SpamList()
     self.view = setup_view(self.view,
                            self.request,
                            user_id=self.user_1._id)
Пример #29
0
 def get_unread_comments_count(self, obj):
     user = self.context['request'].user
     if user.is_anonymous:
         return 0
     return Comment.find_n_unread(user=user,
                                  node=obj.target,
                                  page='files',
                                  root_id=obj.get_guid()._id)
Пример #30
0
 def test_find_unread_includes_comment_replies(self):
     project = ProjectFactory()
     user = UserFactory()
     project.add_contributor(user, save=True)
     comment = CommentFactory(node=project, user=user)
     CommentFactory(node=project, target=Guid.load(comment._id), user=project.creator)
     n_unread = Comment.find_n_unread(user=user, node=project, page='node')
     assert n_unread == 1
Пример #31
0
 def test_find_unread_does_not_include_deleted_comments(self):
     project = ProjectFactory()
     user = AuthUserFactory()
     project.add_contributor(user)
     project.save()
     CommentFactory(node=project, user=project.creator, is_deleted=True)
     n_unread = Comment.find_n_unread(user=user, node=project, page='node')
     assert n_unread == 0
Пример #32
0
 def test_find_unread_does_not_include_deleted_comments(self):
     project = ProjectFactory()
     user = AuthUserFactory()
     project.add_contributor(user)
     project.save()
     CommentFactory(node=project, user=project.creator, is_deleted=True)
     n_unread = Comment.find_n_unread(user=user, node=project, page='node')
     assert n_unread == 0
Пример #33
0
 def test_find_unread_includes_comment_replies(self):
     project = ProjectFactory()
     user = UserFactory()
     project.add_contributor(user, save=True)
     comment = CommentFactory(node=project, user=user)
     CommentFactory(node=project, target=Guid.load(comment._id), user=project.creator)
     n_unread = Comment.find_n_unread(user=user, node=project, page='node')
     assert n_unread == 1
Пример #34
0
    def test_create_does_not_send_mention_added_signal_if_unconfirmed_contributor_mentioned(self, node, user, auth):
        with pytest.raises(ValidationError) as error:
            with capture_signals() as mock_signals:
                user = UserFactory()
                user.is_registered = False
                user.is_claimed = False
                user.save()
                node.add_contributor(user, visible=False, permissions=[permissions.READ], save=True)

                Comment.create(
                    auth=auth,
                    user=user,
                    node=node,
                    target=node.guids.all()[0],
                    content='This is a comment with a bad mention [@Unconfirmed User](http://localhost:5000/' + user._id + '/).'
                )
        assert mock_signals.signals_sent() == ({contributor_added})
        assert error.value.message == 'User does not exist or is not active.'
Пример #35
0
    def test_create_comment(self, request, user, project, comment_content, expected_signals, expected_error_msg):
        if hasattr(comment_content, '_pytestfixturefunction'):
            comment_content = request.getfixturevalue(comment_content.__name__)

        auth = Auth(user)
        error_msg = None
        with capture_signals() as mock_signals:
            try:
                Comment.create(
                    auth=auth,
                    user=user,
                    node=project,
                    target=project.guids.all()[0],
                    content=comment_content
                )
            except Exception as e:
                error_msg = str(e)

        assert expected_signals == mock_signals.signals_sent()
        assert error_msg == expected_error_msg
Пример #36
0
    def test_create(self):
        first_comment = CommentFactory()
        auth = Auth(user=first_comment.user)

        comment = Comment.create(
            auth=auth,
            user=first_comment.user,
            node=first_comment.node,
            target=first_comment.target,
            root_target=first_comment.root_target,
            page='node',
            content='This is a comment, and ya cant teach that.'
        )
        assert comment.user == first_comment.user
        assert comment.node == first_comment.node
        assert comment.target == first_comment.target
        assert comment.node.logs.count() == 2
        assert comment.node.logs.latest().action == NodeLog.COMMENT_ADDED
        assert not first_comment.ever_mentioned.exists()
Пример #37
0
    def test_create(self):
        first_comment = CommentFactory()
        auth = Auth(user=first_comment.user)

        comment = Comment.create(
            auth=auth,
            user=first_comment.user,
            node=first_comment.node,
            target=first_comment.target,
            root_target=first_comment.root_target,
            page='node',
            content='This is a comment, and ya cant teach that.'
        )
        assert comment.user == first_comment.user
        assert comment.node == first_comment.node
        assert comment.target == first_comment.target
        assert comment.node.logs.count() == 2
        assert comment.node.logs.latest().action == NodeLog.COMMENT_ADDED
        assert not first_comment.ever_mentioned.exists()
Пример #38
0
 def test_comments_move_on_file_rename(self, project, user):
     source = {
         'path': '/file.txt',
         'node': project,
         'provider': self.provider
     }
     destination = {
         'path': '/file_renamed.txt',
         'node': project,
         'provider': self.provider
     }
     self._create_file_with_comment(node=source['node'], path=source['path'], user=user)
     payload = self._create_payload('move', user, source, destination, self.file._id)
     update_file_guid_referent(self=None, node=destination['node'], event_type='addon_file_renamed', payload=payload)
     self.guid.reload()
     file_node = BaseFileNode.resolve_class(self.provider, BaseFileNode.FILE).get_or_create(destination['node'], self._format_path(destination['path'], file_id=self.file._id))
     assert self.guid._id == file_node.get_guid()._id
     file_comments = Comment.find(Q('root_target', 'eq', self.guid.pk))
     assert file_comments.count() == 1
Пример #39
0
    def get_comment(self, check_permissions=True):
        pk = self.kwargs[self.comment_lookup_url_kwarg]
        try:
            comment = Comment.find_one(
                Q('guids___id', 'eq', pk) & Q('root_target', 'ne', None))
        except NoResultsFound:
            raise NotFound

        # Deleted root targets still appear as tuples in the database and are included in
        # the above query, requiring an additional check
        if comment.root_target.referent.is_deleted:
            comment.root_target = None
            comment.save()

        if comment.root_target is None:
            raise NotFound

        if check_permissions:
            # May raise a permission denied
            self.check_object_permissions(self.request, comment)
        return comment
Пример #40
0
    def create(self, validated_data):
        user = validated_data['user']
        auth = Auth(user)
        node = validated_data['node']
        target_id = self.context['request'].data.get('id')

        try:
            target = self.get_target(node._id, target_id)
        except ValueError:
            raise InvalidModelValueError(
                source={'pointer': '/data/relationships/target/data/id'},
                detail='Invalid comment target \'{}\'.'.format(target_id)
            )
        validated_data['target'] = target
        validated_data['content'] = validated_data.pop('get_content')
        try:
            comment = Comment.create(auth=auth, **validated_data)
        except PermissionsError:
            raise PermissionDenied('Not authorized to comment on this project.')
        except ModelValidationError as err:
            raise ValidationError(err.messages[0])
        return comment
Пример #41
0
    def create(self, validated_data):
        user = validated_data['user']
        auth = Auth(user)
        node = validated_data['node']
        target_id = self.context['request'].data.get('id')

        try:
            target = self.get_target(node._id, target_id)
        except ValueError:
            raise InvalidModelValueError(
                source={'pointer': '/data/relationships/target/data/id'},
                detail='Invalid comment target \'{}\'.'.format(target_id))
        validated_data['target'] = target
        validated_data['content'] = validated_data.pop('get_content')
        try:
            comment = Comment.create(auth=auth, **validated_data)
        except PermissionsError:
            raise PermissionDenied(
                'Not authorized to comment on this project.')
        except ModelValidationError as err:
            raise ValidationError(err.messages[0])
        return comment
Пример #42
0
    def test_comments_move_when_folder_moved_from_component_to_project(self, project, component, user):
        source = {
            'path': '/subfolder/',
            'node': component,
            'provider': self.provider
        }
        destination = {
            'path': '/subfolder/',
            'node': project,
            'provider': self.provider
        }
        file_name = 'file.txt'
        self._create_file_with_comment(node=source['node'], path='{}{}'.format(source['path'], file_name), user=user)
        self.file.move_under(destination['node'].get_addon(self.provider).get_root())
        payload = self._create_payload('move', user, source, destination, self.file._id)
        update_file_guid_referent(self=None, node=destination['node'], event_type='addon_file_moved', payload=payload)
        self.guid.reload()

        file_node = BaseFileNode.resolve_class(self.provider, BaseFileNode.FILE).get_or_create(destination['node'], self._format_path('{}{}'.format(destination['path'], file_name), file_id=self.file._id))
        assert self.guid._id == file_node.get_guid()._id
        file_comments = Comment.find(Q('root_target', 'eq', self.guid.pk))
        assert file_comments.count() == 1
Пример #43
0
def _view_project(node, auth, primary=False,
                  embed_contributors=False, embed_descendants=False,
                  embed_registrations=False, embed_forks=False):
    """Build a JSON object containing everything needed to render
    project.view.mako.
    """
    node = Node.objects.filter(pk=node.pk).include('contributor__user__guids').get()
    user = auth.user

    parent = node.find_readable_antecedent(auth)
    if user:
        bookmark_collection = find_bookmark_collection(user)
        bookmark_collection_id = bookmark_collection._id
        in_bookmark_collection = bookmark_collection.linked_nodes.filter(pk=node.pk).exists()
    else:
        in_bookmark_collection = False
        bookmark_collection_id = ''
    view_only_link = auth.private_key or request.args.get('view_only', '').strip('/')
    anonymous = has_anonymous_link(node, auth)
    widgets, configs, js, css = _render_addon(node)
    redirect_url = node.url + '?view_only=None'

    disapproval_link = ''
    if (node.is_pending_registration and node.has_permission(user, ADMIN)):
        disapproval_link = node.root.registration_approval.stashed_urls.get(user._id, {}).get('reject', '')

    if (node.is_pending_embargo and node.has_permission(user, ADMIN)):
        disapproval_link = node.root.embargo.stashed_urls.get(user._id, {}).get('reject', '')

    # Before page load callback; skip if not primary call
    if primary:
        for addon in node.get_addons():
            messages = addon.before_page_load(node, user) or []
            for message in messages:
                status.push_status_message(message, kind='info', dismissible=False, trust=True)
    data = {
        'node': {
            'disapproval_link': disapproval_link,
            'id': node._primary_key,
            'title': node.title,
            'category': node.category_display,
            'category_short': node.category,
            'node_type': node.project_or_component,
            'description': node.description or '',
            'license': serialize_node_license_record(node.license),
            'url': node.url,
            'api_url': node.api_url,
            'absolute_url': node.absolute_url,
            'redirect_url': redirect_url,
            'display_absolute_url': node.display_absolute_url,
            'update_url': node.api_url_for('update_node'),
            'in_dashboard': in_bookmark_collection,
            'is_public': node.is_public,
            'is_archiving': node.archiving,
            'date_created': iso8601format(node.date_created),
            'date_modified': iso8601format(node.logs.latest().date) if node.logs.exists() else '',
            'tags': list(node.tags.filter(system=False).values_list('name', flat=True)),
            'children': bool(node.nodes_active),
            'is_registration': node.is_registration,
            'is_pending_registration': node.is_pending_registration,
            'is_retracted': node.is_retracted,
            'is_pending_retraction': node.is_pending_retraction,
            'retracted_justification': getattr(node.retraction, 'justification', None),
            'date_retracted': iso8601format(getattr(node.retraction, 'date_retracted', None)),
            'embargo_end_date': node.embargo_end_date.strftime('%A, %b. %d, %Y') if node.embargo_end_date else False,
            'is_pending_embargo': node.is_pending_embargo,
            'is_embargoed': node.is_embargoed,
            'is_pending_embargo_termination': node.is_embargoed and (
                node.embargo_termination_approval and
                node.embargo_termination_approval.is_pending_approval
            ),
            'registered_from_url': node.registered_from.url if node.is_registration else '',
            'registered_date': iso8601format(node.registered_date) if node.is_registration else '',
            'root_id': node.root._id if node.root else None,
            'registered_meta': node.registered_meta,
            'registered_schemas': serialize_meta_schemas(list(node.registered_schema.all())),
            'registration_count': node.registrations_all.count(),
            'is_fork': node.is_fork,
            'forked_from_id': node.forked_from._primary_key if node.is_fork else '',
            'forked_from_display_absolute_url': node.forked_from.display_absolute_url if node.is_fork else '',
            'forked_date': iso8601format(node.forked_date) if node.is_fork else '',
            'fork_count': node.forks.filter(is_deleted=False).count(),
            'templated_count': node.templated_list.count(),
            'private_links': [x.to_json() for x in node.private_links_active],
            'link': view_only_link,
            'anonymous': anonymous,
            'points': len(node.get_points(deleted=False, folders=False)),
            'comment_level': node.comment_level,
            'has_comments': bool(Comment.find(Q('node', 'eq', node))),
            'has_children': bool(Comment.find(Q('node', 'eq', node))),
            'identifiers': {
                'doi': node.get_identifier_value('doi'),
                'ark': node.get_identifier_value('ark'),
            },
            'institutions': get_affiliated_institutions(node) if node else [],
            'alternative_citations': [citation.to_json() for citation in node.alternative_citations.all()],
            'has_draft_registrations': node.has_active_draft_registrations,
            'contributors': list(node.contributors.values_list('guids___id', flat=True)),
            'is_preprint': node.is_preprint,
            'is_preprint_orphan': node.is_preprint_orphan,
            'has_published_preprint': node.preprints.filter(is_published=True).exists() if node else False,
            'preprint_file_id': node.preprint_file._id if node.preprint_file else None,
            'preprint_url': node.preprint_url
        },
        'parent_node': {
            'exists': parent is not None,
            'id': parent._primary_key if parent else '',
            'title': parent.title if parent else '',
            'category': parent.category_display if parent else '',
            'url': parent.url if parent else '',
            'api_url': parent.api_url if parent else '',
            'absolute_url': parent.absolute_url if parent else '',
            'registrations_url': parent.web_url_for('node_registrations') if parent else '',
            'is_public': parent.is_public if parent else '',
            'is_contributor': parent.is_contributor(user) if parent else '',
            'can_view': parent.can_view(auth) if parent else False
        },
        'user': {
            'is_contributor': node.is_contributor(user),
            'is_admin': node.has_permission(user, ADMIN),
            'is_admin_parent': parent.is_admin_parent(user) if parent else False,
            'can_edit': (node.can_edit(auth)
                         and not node.is_registration),
            'has_read_permissions': node.has_permission(user, READ),
            'permissions': node.get_permissions(user) if user else [],
            'id': user._id if user else None,
            'username': user.username if user else None,
            'fullname': user.fullname if user else '',
            'can_comment': node.can_comment(auth),
            'show_wiki_widget': _should_show_wiki_widget(node, user),
            'dashboard_id': bookmark_collection_id,
            'institutions': get_affiliated_institutions(user) if user else [],
        },
        'badges': _get_badge(user),
        # TODO: Namespace with nested dicts
        'addons_enabled': node.get_addon_names(),
        'addons': configs,
        'addon_widgets': widgets,
        'addon_widget_js': js,
        'addon_widget_css': css,
        'node_categories': [
            {'value': key, 'display_name': value}
            for key, value in settings.NODE_CATEGORY_MAP.iteritems()
        ]
    }
    if embed_contributors and not anonymous:
        data['node']['contributors'] = utils.serialize_visible_contributors(node)
    if embed_descendants:
        descendants, all_readable = _get_readable_descendants(auth=auth, node=node)
        data['user']['can_sort'] = all_readable
        data['node']['descendants'] = [
            serialize_node_summary(node=each, auth=auth, primary=not node.has_node_link_to(each), show_path=False)
            for each in descendants
        ]
    if embed_registrations:
        data['node']['registrations'] = [
            serialize_node_summary(node=each, auth=auth, show_path=False)
            for each in node.registrations_all.order_by('-registered_date').exclude(is_deleted=True).annotate(nlogs=Count('logs'))
        ]
    if embed_forks:
        data['node']['forks'] = [
            serialize_node_summary(node=each, auth=auth, show_path=False)
            for each in node.forks.exclude(type='osf.registration').exclude(is_deleted=True).order_by('-forked_date').annotate(nlogs=Count('logs'))
        ]
    return data
Пример #44
0
 def test_find_unread_is_zero_when_no_comments(self):
     n_unread = Comment.find_n_unread(user=UserFactory(), node=ProjectFactory(), page='node')
     assert n_unread == 0
Пример #45
0
 def get_unread_comments_count(self, obj):
     user = self.context['request'].user
     if user.is_anonymous:
         return 0
     return Comment.find_n_unread(user=user, node=obj.node, page='files', root_id=obj.get_guid()._id)
Пример #46
0
    def get_unread_comments_count(self, obj):
        user = get_user_auth(self.context['request']).user
        node_comments = Comment.find_n_unread(user=user, node=obj, page='node')

        return {'node': node_comments}
Пример #47
0
 def get_has_children(self, obj):
     return Comment.find(Q('target', 'eq', Guid.load(obj._id))).count() > 0
Пример #48
0
def test_comments_are_queryable_by_root_target():
    root_target = ProjectFactory()
    comment = CommentFactory(node=root_target)
    assert Comment.find(Q('root_target', 'eq', root_target.guids.first()))[0] == comment
Пример #49
0
 def test_find_unread_is_zero_when_no_comments(self):
     n_unread = Comment.find_n_unread(user=UserFactory(), node=ProjectFactory(), page='node')
     assert n_unread == 0