<commit_before>import pytest

from modularodm.exceptions import ValidationError

from website import settings
from website.util import permissions
from website.project.signals import comment_added, mention_added, contributor_added
from framework.exceptions import PermissionsError
from tests.base import capture_signals
from osf_models.models import Comment, NodeLog, Guid
from osf_models.modm_compat import Q
from osf_models.utils.auth import Auth
from .factories import (
    CommentFactory,
    ProjectFactory,
    NodeFactory,
    UserFactory,
    AuthUserFactory
)

# All tests will require a databse
pytestmark = pytest.mark.django_db

@pytest.fixture()
def user():
    return UserFactory()

@pytest.fixture()
def node(user):
    return NodeFactory(creator=user)

@pytest.fixture()
def auth(user):
    return Auth(user)

def test_comments_have_longer_guid():
    comment = CommentFactory()
    assert len(comment._id) == 12

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._id))[0] == comment


class TestCommentModel:

    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 [] == first_comment.ever_mentioned

    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.guid,
                content=''.join(['c' for c in range(settings.COMMENT_MAXLENGTH + 3)])
            )

    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.guid,
                content=''.join(['c' for c in range(settings.COMMENT_MAXLENGTH - 8)]) + '[@George Ant](http://localhost:5000/' + user._id + '/)'
            )

    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.guid,
            content=''.join(['c' for c in range(settings.COMMENT_MAXLENGTH - 12)]) + '[@George Ant](http://localhost:5000/' + user._id + '/)'
        )

    def test_create_comment_content_cannot_be_none(self, node, user, auth):

        with pytest.raises(ValidationError) as error:
            Comment.create(
                auth=auth,
                user=user,
                node=node,
                target=node.guid,
                content=None
            )
        assert error.value.messages[0] == 'This field cannot be null.'

    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.guid,
                content=''
            )
        assert error.value.messages[0] == 'This field cannot be blank.'

    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.guid,
                content='    '
            )
        assert error.value.messages[0] == 'Value must not be empty.'

    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.guid,
                content='This is a comment.'
            )
        assert mock_signals.signals_sent() == ({comment_added})

    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.guid,
                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})

    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.guid,
                    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.'

    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.guid,
                    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.'

    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.guid,
                    content='This is a comment with a bad mention [@Not a User](http://localhost:5000/qwert/).'
                )<commit_msg>Move calls to target for one of the noe's guids, add comment bout origin<commit_after>import pytest
from nose.tools import *  # noqa PEP8 asserts
from nose_parameterized import parameterized
from collections import OrderedDict

from modularodm.exceptions import ValidationError


from website import settings
from website.util import permissions
from website.project.views.comment import update_file_guid_referent
from website.project.signals import comment_added, mention_added, contributor_added
from website.files.models.box import BoxFile
from website.files.models.dropbox import DropboxFile
from website.files.models.github import GithubFile
from website.files.models.googledrive import GoogleDriveFile
from website.files.models.osfstorage import OsfStorageFile
from website.files.models.s3 import S3File
from framework.exceptions import PermissionsError
from tests.base import capture_signals
from osf_models.models import Comment, NodeLog, Guid
from osf_models.modm_compat import Q
from osf_models.utils.auth import Auth
from .factories import (
    CommentFactory,
    ProjectFactory,
    NodeFactory,
    UserFactory,
    AuthUserFactory
)

# All tests will require a databse
pytestmark = pytest.mark.django_db

@pytest.fixture()
def user():
    return UserFactory()

@pytest.fixture()
def node(user):
    return NodeFactory(creator=user)

@pytest.fixture()
def auth(user):
    return Auth(user)

def test_comments_have_longer_guid():
    comment = CommentFactory()
    assert len(comment._id) == 12

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._id))[0] == comment


# copied from tests/test_comments.py
class TestCommentModel:

    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 [] == first_comment.ever_mentioned

    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)])
            )

    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 + '/)'
            )

    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 + '/)'
        )

    def test_create_comment_content_cannot_be_none(self, node, user, auth):

        with pytest.raises(ValidationError) as error:
            Comment.create(
                auth=auth,
                user=user,
                node=node,
                target=node.guids.all()[0],
                content=None
            )
        assert error.value.messages[0] == 'This field cannot be null.'

    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.'

    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.'

    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})

    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})

    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.'

    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.'

    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/).'
                )
{'fraction_non_alphanumeric': 0.09409618141535253, 'fraction_numerical': 0.00547373908510361, 'mean_word_length': 2.1224821973550356, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3845951', 'n_tokens_mistral': 4372, 'n_tokens_neox': 4133, 'n_words': 922}