from modularodm import Q
from modularodm.exceptions import ValidationError as MODMValidationError
from django.core.exceptions import ValidationError as DjangoValidationError
import pytest

from osf_models.models import Node, Tag, NodeLog
from osf_models.utils.auth import Auth
from .factories import NodeFactory, UserFactory

@pytest.mark.django_db
class TestNodeMODMCompat:

    def test_basic_querying(self):
        node_1 = NodeFactory(is_public=False)
        node_2 = NodeFactory(is_public=True)

        results = Node.find()
        assert len(results) == 2

        private = Node.find(Q('is_public', 'eq', False))
        assert node_1 in private
        assert node_2 not in private

    def test_compound_query(self):
        node = NodeFactory(is_public=True, title='foo')

        assert node in Node.find(Q('is_public', 'eq', True) & Q('title', 'eq', 'foo'))
        assert node not in Node.find(Q('is_public', 'eq', False) & Q('title', 'eq', 'foo'))

    def test_title_validation(self):
        node = NodeFactory.build(title='')
        with pytest.raises(MODMValidationError):
            node.save()
        with pytest.raises(DjangoValidationError) as excinfo:
            node.save()
        assert excinfo.value.message_dict == {'title': ['This field cannot be blank.']}

        too_long = 'a' * 201
        node = NodeFactory.build(title=too_long)
        with pytest.raises(DjangoValidationError) as excinfo:
            node.save()
        assert excinfo.value.message_dict == {'title': ['Title cannot exceed 200 characters.']}

    def test_remove_one(self):
        node = NodeFactory()
        node2 = NodeFactory()
        assert len(Node.find()) == 2  # sanity check
        Node.remove_one(node)
        assert len(Node.find()) == 1
        assert node2 in Node.find()

    def test_querying_on_guid_id(self):
        node = NodeFactory()
        assert len(node._id) == 5
        assert node in Node.find(Q('_id', 'eq', node._id))


@pytest.mark.django_db
class TestTagging:

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

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

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

    def test_add_tag(self, node, auth):
        node.add_tag('FoO', auth=auth)
        node.save()

        tag = Tag.objects.get(name='FoO')
        assert node.tags.count() == 1
        assert tag in node.tags.all()

        last_log = node.logs.all().order_by('-date')[0]
        assert last_log.action == NodeLog.TAG_ADDED
        assert last_log.params['tag'] == 'FoO'
        assert last_log.params['node'] == node._id

    def test_add_system_tag(self, node, auth):
        original_log_count = node.logs.count()
        node.add_system_tag('FoO')
        node.save()

        tag = Tag.objects.get(name='FoO')
        assert node.tags.count() == 1
        assert tag in node.tags.all()

        assert tag.system is True

        new_log_count = node.logs.count()
        assert original_log_count == new_log_count

@@ -2700,33 +2700,27 @@
 g(self, node
-, auth
 ):%0A
+
         orig
@@ -2964,16 +2964,39 @@
 s True%0A%0A
+        # No log added%0A
         
@@ -3021,32 +3021,32 @@
 de.logs.count()%0A
-
         assert o
@@ -3080,8 +3080,223 @@
 g_count%0A
+%0A    def test_system_tags_property(self, node, auth):%0A        node.add_system_tag('FoO')%0A        node.add_tag('bAr', auth=auth)%0A%0A        assert 'FoO' in node.system_tags%0A        assert 'bAr' not in node.system_tags%0A

Add test for Node.system_tags