"""This module holds the test cases for the views of the ``media`` app"""

import json

from ..models import Presentation, Video

from .test_cases import MediaTestCase


class VideoViewsTestCase(MediaTestCase):
    """Test case fo the views related to the ``Video`` model"""

    def setUp(self):
        """Login as a trainer"""

        super().setUp()

        self.login_as_trainer()

    def test_create_view_should_work(self):
        """Test that the ``VideoCreateView`` is working"""

        create_url = Video.get_create_url(self.training)

        with self.training.override_version_state(self.training.VERSION_STATES.DRAFT):
            response = self.client.post(
                create_url, {
                    'name': 'new video',
                    'video': self.create_fake_file('video.mp4')
                },
                format='multipart'
            )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(
            json.loads(response.content.decode('utf-8')),
            {
                'valid': True,
                'success_url': self.training.get_activity_list_url()
            }
        )

        self.assertTrue(Video.objects.filter(name='new video').exists())

    def test_create_view_should_return_an_error_if_the_file_is_not_a_video(self):
        """Test that we should not be able to upload a non-video file to the video"""

        create_url = Video.get_create_url(self.training)

        response = self.client.post(
            create_url, {
                'name': 'new video',
                'video': self.create_fake_file('not-a-video.pdf')
            },
            format='multipart'
        )

        json_response = json.loads(response.content.decode('utf-8'))

        self.assertFalse(json_response['valid'])
        self.assertEqual(
            json_response['errors'],
            {
                'video': [
                    'Unsupported file type. Please upload one of the following: '
                    'video/mp4'
                ]
            }
        )

    def test_update_view_should_work(self):
        """Test that the ``VideoUpdateView`` is working"""

        old_video_name = self.video.name
        old_video_file_name = self.video.media.file.name
        old_video_file_content = self.video.media.file.read()

        response = self.client.post(
            self.video.get_edit_url(), {
                'name': 'new name',
                'video': self.create_fake_file('new_file.mp4')
            },
            format='multipart'
        )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(
            json.loads(response.content.decode('utf-8')),
            {
                'valid': True,
                'success_url': self.video.get_detail_url()
            }
        )

        self.video.refresh_from_db()
        self.video.media.refresh_from_db()

        self.assertNotEqual(self.video.name, old_video_name)
        self.assertEqual(self.video.name, 'new name')

        self.assertNotEqual(self.video.media.file.name, old_video_file_name)
        self.assertEqual(
            self.video.media.file.name,
            'media_app/video/%s.mp4' % self.video.media.id
        )

        new_file_content = self.video.media.file.read()

        self.assertNotEqual(new_file_content, old_video_file_content)
        self.assertEqual(new_file_content, b'somebinarydata')

    def test_detail_view_should_work(self):
        """Test that the ``VideoDetailView`` is working"""

        response = self.client.get(self.video.get_detail_url())

        self.assertEqual(response.status_code, 200)


class PresentationTestCase(MediaTestCase):
    """Test case fo the views related to the ``Presentation`` model"""

    def setUp(self):
        """Login as a trainer"""

        super().setUp()

        self.login_as_trainer()

    def test_create_view_should_work(self):
        """Test that the ``PresentationCreateView`` is working"""

        create_url = Presentation.get_create_url(self.training)

        response = self.client.post(
            create_url, {
                'name': 'new presentation',
                'pdf': self.create_fake_file('document.pdf'),
                'restricted_pdf': self.create_fake_file('restricted_document.pdf'),
                'is_accessible_by_trainees': True
            },
            format='multipart'
        )

        self.assertEqual(response.status_code, 200)
        self.assertEqual(
            json.loads(response.content.decode('utf-8')),
            {
                'valid': True,
                'success_url': self.training.get_activity_list_url()
            }
        )

        presentation = Presentation.objects.get(name='new presentation')
        self.assertEqual(
            presentation.pdf.file.name,
            'media_app/pdf/%s.pdf' % presentation.pdf.id
        )
        self.assertEqual(
            presentation.restricted_pdf.file.name,
            'media_app/pdf/%s.pdf' % presentation.restricted_pdf.id
        )

    def test_create_view_should_return_an_error_if_the_file_are_not_a_pdf(self):
        """Test that we should not be able to upload a non-pdf file to the presentation"""

        create_url = Presentation.get_create_url(self.training)

        response = self.client.post(
            create_url, {
                'name': 'new presentation',
                'pdf': self.create_fake_file('document.mov'),
                'is_accessible_by_trainees': True
            },
            format='multipart'
        )

        json_response = json.loads(response.content.decode('utf-8'))

        self.assertFalse(json_response['valid'])
        self.assertEqual(
            json_response['errors'],
            {
                'pdf': [
                    'Unsupported file type. Please upload one of the following: application/pdf'
                ]
            }
        )

    def test_update_view_should_work(self):
        """Test that the ``PresentationUpdateView`` is working"""

        old_presentation_name = self.presentation.name
        old_pdf_file_name = self.pdf_media.file.name
        old_pdf_file_content = self.pdf_media.file.read()
        old_restricted_pdf_file_name = self.restricted_pdf_media.file.name
        old_restricted_pdf_file_content = self.restricted_pdf_media.file.read()

        with self.training.override_version_state(self.training.VERSION_STATES.DRAFT):
            response = self.client.post(
                self.presentation.get_edit_url(),
                {
                    'name': 'new presentation name',
                    'pdf': self.create_fake_file('new_document.pdf'),
                    'restricted_pdf': self.create_fake_file('new_restricted_document.pdf'),
                    'is_accessible_by_trainees': False  # True per default
                }
            )

        self.assertEqual(
            json.loads(response.content.decode('utf-8')),
            {
                'valid': True,
                'success_url': self.presentation.get_detail_url()
            }
        )

        self.presentation.refresh_from_db()

        self.assertNotEqual(self.presentation.name, old_presentation_name)
        self.assertEqual(self.presentation.name, 'new presentation name')

        self.assertNotEqual(self.presentation.pdf.file.name, old_pdf_file_name)
        self.assertEqual(
            self.presentation.pdf.file.name,
            'media_app/pdf/%s.pdf' % self.presentation.pdf.id
        )

        presentation_pdf_file_content = self.presentation.pdf.file.read()
        self.assertNotEqual(
            presentation_pdf_file_content,
            old_pdf_file_content
        )
        self.assertEqual(presentation_pdf_file_content, b'somebinarydata')

        self.assertNotEqual(
            self.presentation.restricted_pdf.file.name,
            old_restricted_pdf_file_name
        )
        self.assertEqual(
            self.presentation.restricted_pdf.file.name,
            'media_app/pdf/%s.pdf' % self.presentation.restricted_pdf.id
        )

        presentation_restricted_pdf_file_content = self.presentation.restricted_pdf.file.read()
        self.assertNotEqual(
            presentation_restricted_pdf_file_content,
            old_restricted_pdf_file_content
        )
        self.assertEqual(presentation_restricted_pdf_file_content, b'somebinarydata')

    def test_detail_view_should_work(self):
        """Test that the ``PresentationDetailView`` is working"""

        response = self.client.get(self.presentation.get_detail_url())

        self.assertEqual(response.status_code, 200)
