"""This module holds the tests for the models of the ``evaluations`` app."""

from collections import defaultdict

from mtp.apps.accounts.constants import INTERNAL_GROUP_TRAINER, INTERNAL_GROUP_TRAINEE
from mtp.apps.accounts.models import Group
from mtp.apps.common.tests.test_cases import MTPTestCase

from ..factories import EvaluationFactory
from ..models import EvaluationGroupPermission


class EvaluationModelTestCase(MTPTestCase):
    """Test for the ``Evaluation`` model"""

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

        super().setUpTestData()

        # Keep track of the groups
        cls.trainer_group = Group.objects.get(name=INTERNAL_GROUP_TRAINER)
        cls.trainee_group = Group.objects.get(name=INTERNAL_GROUP_TRAINEE)

        # New evaluation
        cls.evaluation = EvaluationFactory()

    def get_evaluation_permissions(self, evaluation):
        """Shortcut method to get the evaluation permissions as a un dict"""

        permissions_by_group = defaultdict(list)
        for permission in EvaluationGroupPermission.objects.filter(evaluation=self.evaluation):
            permissions_by_group[permission.group].append(permission.permission)

        return permissions_by_group

    def test_save_evaluation_should_correctly_set_the_roles(self):
        """test the save method from the evaluation"""

        # Per default, the evaluation is set as ``MAY_EVALUATE_OTHERS``
        self.assertEqual(self.evaluation.evaluation_type,
                         self.evaluation.EVALUATION_TYPES.MAY_EVALUATE_OTHERS)

        perms_list = EvaluationGroupPermission.PERMISSION_TYPES
        evaluations_perms = self.get_evaluation_permissions(self.evaluation)

        # We got the correct permissions for both the trainers, trainees
        self.assertCountEqual(
            evaluations_perms[self.trainer_group],
            [
                perms_list.MAY_MODERATE,
                perms_list.MAY_EVALUATE_SELF,
                perms_list.MAY_EVALUATE_OTHERS
            ]
        )
        self.assertCountEqual(
            evaluations_perms[self.trainee_group],
            [perms_list.MAY_EVALUATE_OTHERS, perms_list.MAY_PARTICIPATE]
        )

        # Change the evaluation with ``MAY_EVALUATE_SELF`` flag
        self.evaluation.evaluation_type = self.evaluation.EVALUATION_TYPES.MAY_EVALUATE_SELF
        self.evaluation.save()

        evaluations_perms = self.get_evaluation_permissions(self.evaluation)

        # We got the correct permissions for both the trainers, trainees
        self.assertCountEqual(
            evaluations_perms[self.trainer_group],
            [
                perms_list.MAY_MODERATE,
                perms_list.MAY_EVALUATE_SELF,
                perms_list.MAY_EVALUATE_OTHERS
            ]
        )
        self.assertCountEqual(
            evaluations_perms[self.trainee_group],
            [perms_list.MAY_EVALUATE_SELF, perms_list.MAY_PARTICIPATE]
        )

        # Change the evaluation with ``MAY_EVALUATE_ALL`` flag
        self.evaluation.evaluation_type = self.evaluation.EVALUATION_TYPES.MAY_EVALUATE_ALL
        self.evaluation.save()

        evaluations_perms = self.get_evaluation_permissions(self.evaluation)

        # We got the correct permissions for both the trainers, trainees
        self.assertCountEqual(
            evaluations_perms[self.trainer_group],
            [
                perms_list.MAY_MODERATE,
                perms_list.MAY_EVALUATE_SELF,
                perms_list.MAY_EVALUATE_OTHERS
            ]
        )
        self.assertCountEqual(
            evaluations_perms[self.trainee_group],
            [
                perms_list.MAY_EVALUATE_SELF,
                perms_list.MAY_EVALUATE_OTHERS,
                perms_list.MAY_PARTICIPATE
            ]
        )
