from django.core.urlresolvers import reverse

from mtp.apps.roleplays.factories import (
    AssessingRoleplayFactory,
    RoleplayFactory,
    StepFactory,
)
from mtp.apps.trainings.factories import TrainingFactory
from mtp.apps.workshops.factories import (
    AssessingWorkshopFactory,
    WorkshopFactory,
)

from .test_cases import MTPSimpleAssessmentTestCase


class AssessableFormsTestCase(MTPSimpleAssessmentTestCase):
    """Test case that tests the cms forms for assessable objects."""

    @classmethod
    def setUpTestData(cls):
        super().setUpTestData()

        cls.assessing_training = cls.training
        cls.non_assessing_training = TrainingFactory(
            owner=cls.trainer,
            job_profile=None
        )

        # We need assessing and non-assessing activities.
        cls.assessing_workshop = AssessingWorkshopFactory(
            training=cls.training
        )
        cls.assessing_roleplay = AssessingRoleplayFactory(
            training=cls.training
        )
        cls.assessing_roleplay_step = StepFactory(
            roleplay=cls.assessing_roleplay
        )

        cls.non_assessing_workshop = WorkshopFactory(
            training=cls.non_assessing_training
        )
        cls.non_assessing_roleplay = RoleplayFactory(
            training=cls.non_assessing_training
        )
        cls.non_assessing_roleplay_step = StepFactory(
            roleplay=cls.non_assessing_roleplay
        )

    def setUp(self):
        super().setUp()

        self.login_as_trainer()

    def _assert_assessing_box_exists(self, html):
        """Helper: Ensure the ``is_assessing`` checkbox is present in the html."""

        checkbox = html.find('input', attrs={
            'type': 'checkbox',
            'name': 'is_assessing',
        })
        self.assertIsNotNone(checkbox)
        return checkbox

    def _assert_assessing_box_is_checked(self, checkbox):
        """Helper: Ensure the ``is_assessing`` checkbox is checked."""

        self.assertEqual(checkbox.attrs.get('checked'), 'checked')

    def _assert_assessing_box_is_not_checked(self, checkbox):
        """Helper: Ensure the ``is_assessing`` checkbox is not checked."""

        self.assertNotEqual(checkbox.attrs.get('checked'), 'checked')

    def _assert_response_contains_checked_assessing_box(self, url):
        """Helper: Ensure the response contains a checked ``is_assessing``
        checkbox."""

        html = self._parse_url(url)
        checkbox = self._assert_assessing_box_exists(html)
        self._assert_assessing_box_is_checked(checkbox)

    def _assert_response_contains_unchecked_assessing_box(self, url):
        """Helper: Ensure the response contains an unchecked ``is_assessing``
        checkbox."""

        html = self._parse_url(url)
        checkbox = self._assert_assessing_box_exists(html)
        self._assert_assessing_box_is_not_checked(checkbox)

    def test_assessable_activity_in_assessable_training_defaults_to_assessing(self):
        """Test that the cms checks the ``is_assessing`` checkbox when creating
        an assessing activity in the context of an assessing training."""

        create_roleplay_url = reverse('trainings:roleplay-create', kwargs={
            'training_uuid': self.assessing_training.id,
        })
        self._assert_response_contains_checked_assessing_box(create_roleplay_url)

        create_workshop_url = reverse('trainings:workshop-create', kwargs={
            'training_uuid': self.assessing_training.id,
        })
        self._assert_response_contains_checked_assessing_box(create_workshop_url)

    def test_assessable_activity_in_non_assessable_training_defaults_to_non_assessing(self):
        """Test that the cms does not check the ``is_assessing`` checkbox when
        creating an assessing activity in the context of a non-assessing
        training."""

        create_roleplay_url = reverse('trainings:roleplay-create', kwargs={
            'training_uuid': self.non_assessing_training.id,
        })
        self._assert_response_contains_unchecked_assessing_box(create_roleplay_url)

        create_workshop_url = reverse('trainings:workshop-create', kwargs={
            'training_uuid': self.non_assessing_training.id,
        })
        self._assert_response_contains_unchecked_assessing_box(create_workshop_url)

    def test_assessable_part_in_assessable_activity_defaults_to_assessing(self):
        """Test that the cms checks the ``is_assessing`` checkbox when creating
        an activity part in the context of an assessing activity."""

        create_criterion_url = reverse('roleplays:criterion-create', kwargs={
            'roleplay_uuid': self.assessing_roleplay.id,
            'step_uuid': self.assessing_roleplay_step.id,
        })
        self._assert_response_contains_checked_assessing_box(create_criterion_url)

        create_question_url = reverse('workshops:step-question-create', kwargs={
            'workshop_uuid': self.assessing_workshop.id,
        })
        self._assert_response_contains_checked_assessing_box(create_question_url)

    def test_assessable_part_in_non_assessable_activity_defaults_to_non_assessing(self):
        """Test that the cms does not check the ``is_assessing`` checkbox when
        creating an activity part in the context of a non-assessing activity."""

        create_criterion_url = reverse('roleplays:criterion-create', kwargs={
            'roleplay_uuid': self.non_assessing_roleplay.id,
            'step_uuid': self.non_assessing_roleplay_step.id,
        })
        self._assert_response_contains_unchecked_assessing_box(create_criterion_url)

        create_question_url = reverse('workshops:step-question-create', kwargs={
            'workshop_uuid': self.non_assessing_workshop.id,
        })
        self._assert_response_contains_unchecked_assessing_box(create_question_url)
