"""This module holds the tests for the Nissan-specific ``assessments`` app."""

from django.core.urlresolvers import reverse
from django.test import override_settings

from mtp.apps.assessments.factories.certifications import (
    CertificationProgramUserStatusFactory,
)
from mtp.apps.assessments.models.certifications import CertificationProgramUserStatus
from mtp.apps.common.tests.test_cases import MTPTestCase


class CertificationResultsBulkTestCase(MTPTestCase):
    """Base test case for common setup data"""

    @classmethod
    def setUpTestData(cls):
        """Setup our ``CertificationProgramUserStatus`` test instances"""

        super().setUpTestData()

        cls.cpu = CertificationProgramUserStatusFactory()
        cls.cpu.user.external_id = 'XXX'
        cls.cpu.user.save()

        cls.cpu_2 = CertificationProgramUserStatusFactory()
        cls.cpu_2.user.external_id = 'YYY'
        cls.cpu_2.user.save()

        # A third user, duplicate from our second user
        cls.cpu_3 = CertificationProgramUserStatusFactory()
        cls.cpu_2.user.flag_user_as_duplicate(cls.cpu_3.user, cls.admin)


@override_settings(ROOT_URLCONF='mtp.custom.nissan.apps.assessments.tests.test_urls')
class CertificationResultsBulkSkipViewTestCase(CertificationResultsBulkTestCase):
    """Test case that tests the ``CertificationResultsBulkSkipView`` view."""

    def test_certification_status_should_be_set_to_skip_status(self):
        """Test that bulk set to SKIP sync_status works."""

        self.login_as_admin()

        response = self.client.post(reverse('assessments:certification-results-bulk-skip'), {
            'certification_result': [self.cpu.pk, self.cpu_2.pk, self.cpu_3.pk],
            'sync_status': CertificationProgramUserStatus.SYNC_STATUSES.SKIP
        })

        # redirect to list
        self.assertEqual(response.status_code, 302)

        # should be skip
        self.cpu.refresh_from_db()
        self.assertEqual(
            self.cpu.sync_status,
            CertificationProgramUserStatus.SYNC_STATUSES.SKIP
        )
        # sync_trigger_user should be set to current user
        self.assertEqual(
            self.cpu.sync_trigger_user,
            self.admin
        )

        self.cpu_2.refresh_from_db()
        self.assertEqual(
            self.cpu_2.sync_status,
            CertificationProgramUserStatus.SYNC_STATUSES.SKIP
        )
        # sync_trigger_user should be set to current user
        self.assertEqual(
            self.cpu_2.sync_trigger_user,
            self.admin
        )

        self.cpu_3.refresh_from_db()
        self.assertEqual(
            self.cpu_3.sync_status,
            CertificationProgramUserStatus.SYNC_STATUSES.SKIP
        )
        # sync_trigger_user should be set to current user
        self.assertEqual(
            self.cpu_3.sync_trigger_user,
            self.admin
        )

    def test_certification_status_should_not_be_changed_if_wrong_status(self):
        """Test that bulk set to SKIP fails when source status is not PENDING or SENT_KO"""

        allowed_source_sync_statuses = [
            CertificationProgramUserStatus.SYNC_STATUSES.PENDING,
            CertificationProgramUserStatus.SYNC_STATUSES.SENT_KO,
        ]

        for sync_status, __ in CertificationProgramUserStatus.SYNC_STATUSES:

            if sync_status not in allowed_source_sync_statuses:
                self.cpu.sync_status = sync_status
                self.cpu.save()

                response = self.client.post(
                    reverse('assessments:certification-results-bulk-skip'),
                    {
                        'certification_result': [self.cpu.pk],
                        'sync_status': CertificationProgramUserStatus.SYNC_STATUSES.SKIP
                    }
                )

                # redirect to list
                self.assertEqual(response.status_code, 302)

                # should not be skip
                self.cpu.refresh_from_db()
                self.assertEqual(self.cpu.sync_status, sync_status)

    def test_certification_status_should_not_be_changed_if_no_external_id_or_original(self):
        """Test that bulk set to SKIP fails if no external_id or an original with one"""

        wrong_cpu = CertificationProgramUserStatusFactory()
        self.assertEqual(wrong_cpu.user.original_or_self_external_id, '')

        response = self.client.post(
            reverse('assessments:certification-results-bulk-skip'),
            {
                'certification_result': [wrong_cpu.pk],
                'sync_status': CertificationProgramUserStatus.SYNC_STATUSES.SKIP,
            }
        )

        # redirect to list
        self.assertEqual(response.status_code, 302)

        # should not be skip
        wrong_cpu.refresh_from_db()
        self.assertEqual(
            wrong_cpu.sync_status,
            CertificationProgramUserStatus.SYNC_STATUSES.PENDING
        )


@override_settings(ROOT_URLCONF='mtp.custom.nissan.apps.assessments.tests.test_urls')
class CertificationResultsBulkSendToLMSViewTestCase(CertificationResultsBulkTestCase):
    """Test case that tests the ``CertificationResultsBulkSendToLMSView`` view."""

    def test_certification_status_should_be_set_to_queued_status(self):
        """Test that bulk set to QUEUED sync_status works."""

        self.login_as_admin()

        response = self.client.post(reverse('assessments:certification-results-bulk-send-to-lms'), {
            'certification_result': [self.cpu.pk, self.cpu_2.pk, self.cpu_3.pk],
            'sync_status': CertificationProgramUserStatus.SYNC_STATUSES.QUEUED
        })

        # redirect to list
        self.assertEqual(response.status_code, 302)

        # should be queued
        self.cpu.refresh_from_db()
        self.assertEqual(
            self.cpu.sync_status,
            CertificationProgramUserStatus.SYNC_STATUSES.QUEUED
        )
        # sync_trigger_user should be set to current user
        self.assertEqual(
            self.cpu.sync_trigger_user,
            self.admin
        )

        # should be queued
        self.cpu_2.refresh_from_db()
        self.assertEqual(
            self.cpu_2.sync_status,
            CertificationProgramUserStatus.SYNC_STATUSES.QUEUED
        )
        # sync_trigger_user should be set to current user
        self.assertEqual(
            self.cpu_2.sync_trigger_user,
            self.admin
        )

        # should be queued
        self.cpu_3.refresh_from_db()
        self.assertEqual(
            self.cpu_3.sync_status,
            CertificationProgramUserStatus.SYNC_STATUSES.QUEUED
        )
        # sync_trigger_user should be set to current user
        self.assertEqual(
            self.cpu_3.sync_trigger_user,
            self.admin
        )

    def test_certification_status_should_not_be_changed_if_wrong_status(self):
        """Test that bulk set to QUEUED fails when source status is not PENDING or SENT_KO"""

        allowed_source_sync_statuses = [
            CertificationProgramUserStatus.SYNC_STATUSES.PENDING,
            CertificationProgramUserStatus.SYNC_STATUSES.SENT_KO,
        ]

        for sync_status, __ in CertificationProgramUserStatus.SYNC_STATUSES:

            if sync_status not in allowed_source_sync_statuses:
                self.cpu.sync_status = sync_status
                self.cpu.save()

                response = self.client.post(
                    reverse('assessments:certification-results-bulk-send-to-lms'),
                    {
                        'certification_result': [self.cpu.pk],
                        'sync_status': CertificationProgramUserStatus.SYNC_STATUSES.QUEUED
                    }
                )

                # redirect to list
                self.assertEqual(response.status_code, 302)

                # should not be skip
                self.cpu.refresh_from_db()
                self.assertEqual(self.cpu.sync_status, sync_status)
