"""This module holds the tests for the serializers of the ``brainstormers`` app"""

from mtp.apps.brainstormers.constants import BRAINSTORMER_TYPE_CHOICES
from mtp.apps.brainstormers.models import Brainstormer
from mtp.apps.brainstormers.tests.test_cases import BrainstormerTestCase

from ..serializers import (
    BrainstormerPropositionSerializer,
    BrainstormerPropositionGroupSerializer,
    BrainstormerSerializer,
)


class BrainstormerSerializerTest(BrainstormerTestCase):
    """Test case for the ``BrainstormerSerializer`` serializer"""

    def test_serializer_read_should_work(self):
        """Test that the serializer should output correct data"""

        serializer = BrainstormerSerializer(self.brainstormer)
        self.assertEqual(
            serializer.data,
            {
                'id': self.brainstormer.id,
                'name': self.brainstormer.name,
                'description': self.brainstormer.description,
                'training': None,
                'session': self.brainstormer.session.id,
                'activity_type': BRAINSTORMER_TYPE_CHOICES.for_value(
                    self.brainstormer.brainstormer_type
                ).constant.lower(),
                'sort_order': 1,
                'brainstormer_type': self.brainstormer.brainstormer_type,
                'anonymous': self.brainstormer.anonymous,
                'proposals': [
                    BrainstormerPropositionSerializer(proposition).data
                    for proposition in self.brainstormer.propositions.non_deleted()
                ],
                'proposal_groups': [
                    BrainstormerPropositionGroupSerializer(group).data
                    for group in self.brainstormer.groups.non_deleted()
                ],
            }
        )

    def test_serializer_create_should_work(self):
        """Test that the serializer should allow us to create a new brainstormer"""

        brainstomer_data = {
            'description': 'test',
            'session': self.training_session.id,
        }

        # Test that the create is working correctly for each type of brainstormer
        for choice in BRAINSTORMER_TYPE_CHOICES.choices:
            choice_value = choice[0]
            with self.subTest(brainstormer_type=choice_value):

                brainstomer_data['name'] = choice_value
                brainstomer_data['brainstormer_type'] = choice_value

                serializer = BrainstormerSerializer(data=brainstomer_data)
                self.assertTrue(serializer.is_valid())

                serializer.save()
                self.assertTrue(Brainstormer.objects.filter(name=choice_value).exists())


class BrainstormerPropositionGroupSerializerTestCase(BrainstormerTestCase):
    """Test cases for the ``BrainstormerPropositionGroupSerializer`` serializer"""

    @classmethod
    def setUpTestData(cls):
        """Set up the test data"""

        super().setUpTestData()

        # We will need sample data to serialize
        cls.brainstormer_proposition_groups = {
            'brainstormer': cls.brainstormer.pk,
            'order': 0,
            'x': 10.10,
            'y': 11.10
        }

    def test_serializer_with_valid_data(self):
        """test the serializer with valid data"""

        serialized = BrainstormerPropositionGroupSerializer(
            data=self.brainstormer_proposition_groups)

        self.assertTrue(serialized.is_valid())


class BrainstomerPropositionSerializerTestCase(BrainstormerTestCase):
    """Test case for the ``BrainstomerPropositionSerializer`` serializer"""

    def test_serializer_output_should_not_include_the_deleted_likes(self):
        """Test that the serializer should not include the deleted likes"""

        # At first, no likes on this proposition
        self.assertEqual(
            len(BrainstormerPropositionSerializer(self.proposition).data['likes']),
            0
        )

        # One like
        self.trainee.like(self.proposition)
        self.assertEqual(
            len(BrainstormerPropositionSerializer(self.proposition).data['likes']),
            1
        )

        # One "un-like"
        self.trainee.unlike(self.proposition)
        self.assertEqual(
            len(BrainstormerPropositionSerializer(self.proposition).data['likes']),
            0
        )
