"""This module holds the test cases for the managers and QuerySets of the ``trainings`` app"""

from mtp.apps.accounts.constants import GROUPTYPE_BUSINESS_UNIT, GROUPTYPE_JOB_PROFILE
from mtp.apps.accounts.factories import (
    AdminFactory, GroupFactory,
    GroupTypeFactory, GroupRole,
    GroupRoleFactory, TrainerFactory
)
from mtp.apps.common.tests.test_cases import MTPTestCase

from ..factories import TrainingFactory, TrainingSessionFactory
from ..models import TrainingSession


class TrainingSessionQuerySetVisibleByUserTestCase(MTPTestCase):
    """Test case for the ``visible_by_user`` method of the ``TrainingSessionQuerySet``"""

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

        super().setUpTestData()

        job_profile_group_type = GroupTypeFactory(name=GROUPTYPE_JOB_PROFILE)
        job_profile = GroupFactory(type=job_profile_group_type)

        business_unit_group_type = GroupTypeFactory(name=GROUPTYPE_BUSINESS_UNIT)
        business_unit = GroupFactory(type=business_unit_group_type)

        # The first admin will be the job_profile manager
        GroupRoleFactory(
            user=cls.admin,
            group=job_profile,
            role=GroupRole.ROLES.MANAGER
        )

        # The second admin will be the business_unit manager
        cls.admin_2 = AdminFactory()
        GroupRoleFactory(
            user=cls.admin_2,
            group=business_unit,
            role=GroupRole.ROLES.MANAGER
        )

        # The trainer is a member of the business unit
        GroupRoleFactory(
            user=cls.trainer,
            group=business_unit
        )

        # Admin 1 training
        admin_1_training = TrainingFactory(
            job_profile=job_profile
        )

        # Training session for the admin 1
        admin_1_training_session = TrainingSessionFactory(
            training=admin_1_training
        )

        # Admin 2 training
        admin_2_training = TrainingFactory(
            business_unit=business_unit,
            job_profile=job_profile
        )

        # Training session for the admin 2
        admin_2_training_session = TrainingSessionFactory(
            training=admin_2_training
        )

        # Trainer training, linked to the business unit
        trainer_training_business_unit = TrainingFactory(
            owner=cls.trainer,
            business_unit=business_unit,
            job_profile=job_profile
        )

        # Training session for the trainer, using this training
        trainer_training_session = TrainingSessionFactory(
            training=trainer_training_business_unit
        )

        # New "stand-alone" training (not linked with the business unit)
        trainer_training = TrainingFactory(owner=cls.trainer)

        # Training session for the trainer, using this training
        trainer_training_session_2 = TrainingSessionFactory(
            training=trainer_training
        )

        # Training session for the trainer...
        trainee_training_session = TrainingSessionFactory(
            training=trainer_training
        )

        # ...with one trainee
        trainee_training_session.users.add(cls.trainee)

        cls.visible_by_job_profile_manager = [
            admin_1_training_session,
            admin_2_training_session,
            trainer_training_session,
            cls.training_session,  # Coming from ``MTPTestCase``
        ]

        cls.visible_by_business_unit_manager = [
            admin_2_training_session,
            trainer_training_session,
        ]

        cls.visible_by_trainer = [
            trainer_training_session,
            trainer_training_session_2,
            trainee_training_session,
            cls.training_session,  # Coming from ``MTPTestCase``
        ]

        cls.visible_by_trainee_1 = [
            trainee_training_session,
            cls.training_session,  # Coming from ``MTPTestCase``
        ]

    def test_queryset_as_job_profile_manager(self):
        """Test the QuerySet result with the job_profile manager"""

        self.assertCountEqual(
            TrainingSession.objects.visible_by_user(self.admin),
            self.visible_by_job_profile_manager
        )

    def test_queryset_as_business_unit_manager(self):
        """Test the QuerySet result with the business_unit manager"""

        self.assertCountEqual(
            TrainingSession.objects.visible_by_user(self.admin_2),
            self.visible_by_business_unit_manager
        )

    def test_queryset_as_trainer(self):
        """Test the QuerySet result with the trainer user"""

        # Test with the first trainer
        self.assertCountEqual(
            TrainingSession.objects.visible_by_user(self.trainer),
            self.visible_by_trainer
        )

        # Test with another trainer, newly created
        self.assertCountEqual(
            TrainingSession.objects.visible_by_user(TrainerFactory()),
            []
        )

    def test_queryset_as_trainee(self):
        """Test the QuerySet result with the trainee user"""

        # Test with the first trainee
        self.assertCountEqual(
            TrainingSession.objects.visible_by_user(self.trainee),
            self.visible_by_trainee_1
        )

        # Test with the second trainee (not added to any session)
        self.assertCountEqual(
            TrainingSession.objects.visible_by_user(self.trainees[1]),
            []
        )


