"""This module holds the test cases for the documents-related api views"""

from django.core.urlresolvers import reverse

from mtp.apps.api.tests.test_cases import MTPAPITestCase
from mtp.apps.documents.factories import NoteFactory
from mtp.apps.documents.models import Note


class NoteSaveApiTestCase(MTPAPITestCase):
    """Test cases for the ``save_notes`` api enpoint"""

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

        super().setUpTestData()

        cls.notes_data = {
            'session_id': cls.training_session.pk,
            'type': 'type of the note',
            'text': 'text of the note',
            'x': '1.1',
            'y': '1.2',
            'w': '1.3',
            'h': '1.4'
        }

        cls.save_notes_url = reverse('api:save_notes', kwargs={'user_uuid': cls.trainee.pk})

    def test_calling_save_note_route_should_create_new_note(self):
        """Test that the ``save_notes`` route should save a new ``Note``"""

        status_code, json_response = self.get_api_response(
            self.save_notes_url,
            'post',
            self.notes_data
        )

        self.assertEqual(status_code, 200)

        # The user should have a new note
        self.assertEqual(
            Note.objects.filter(user=self.trainee).count(),
            1
        )

        note = Note.objects.filter(user=self.trainee).first()

        # The json response is correct
        self.assertEqual(
            json_response,
            {
                'id': note.pk
            }
        )

        # The note properties are correctly saved
        self.assertEqual(note.session.pk, self.notes_data['session_id'])
        self.assertEqual(note.note_type, self.notes_data['type'])
        self.assertEqual(note.text, self.notes_data['text'])
        self.assertEqual(note.coord_x, float(self.notes_data['x']))
        self.assertEqual(note.coord_y, float(self.notes_data['y']))
        self.assertEqual(note.width, float(self.notes_data['w']))
        self.assertEqual(note.height, float(self.notes_data['h']))


class NoteUpdateApiTestCase(MTPAPITestCase):
    """Test cases for the ``update_notes`` api enpoint"""

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

        super().setUpTestData()

        # Create a new ``Note`` for this user
        cls.note = NoteFactory(user=cls.trainee)

        cls.update_notes_url = reverse('api:update_notes', kwargs={
            'user_uuid': cls.trainee.pk,
            'note_uuid': cls.note.pk
        })

    def setUp(self):
        """Set up"""

        super().setUp()

        self.notes_data = {
            'type': 'type of the note',
            'text': 'text of the note',
            'x': '1.1',
            'y': '1.2',
        }

    def test_calling_update_with_post_should_update_the_note(self):
        """Test that calling the ``update_notes`` with post should update the note"""

        status_code, json_response = self.get_api_response(
            self.update_notes_url,
            'post',
            self.notes_data
        )

        self.assertEqual(status_code, 200)

        # The json response is correct
        self.assertEqual(
            json_response,
            {
                'id': self.note.pk
            }
        )

        self.note.refresh_from_db()

        # The note properties are correctly updated
        self.assertEqual(self.note.note_type, self.notes_data['type'])
        self.assertEqual(self.note.text, self.notes_data['text'])
        self.assertEqual(self.note.coord_x, float(self.notes_data['x']))
        self.assertEqual(self.note.coord_y, float(self.notes_data['y']))

    def test_calling_update_with_delete_should_delete_the_note(self):
        """Test that calling the ``update_notes`` with delete should update the note"""

        # The user got one note
        self.assertEqual(
            Note.objects.filter(user=self.trainee).count(),
            1
        )

        # IS THIS THE REAL WORLD ?
        self.notes_data['_method'] = 'DELETE'

        status_code, __ = self.get_api_response(
            self.update_notes_url,
            'post',
            self.notes_data
        )

        self.assertEqual(status_code, 200)

        # The note should be deleted
        self.assertEqual(
            Note.objects.filter(user=self.trainee).count(),
            0
        )
