"""This modules holds tests for ``accounts.utils`` module."""

from django.contrib.staticfiles import finders
from django.core import mail
from django.test.utils import override_settings

from mtp.apps.common.tests.test_cases import MTPTestCase

from ..models import MTPUser
from ..utils import validate_extra_secure_password, XLSTraineeImporter


class UtilsTestCase(MTPTestCase):
    """Test the utils module"""

    def test_validate_extra_secure_password(self):
        """
        Test the password validation function.
        """

        # This password is too short.
        password = 'aze'
        is_valid, __, code = validate_extra_secure_password(password)
        self.assertFalse(is_valid)
        self.assertEqual(code, 'invalid-length')

        # This password contains no uppercase letter.
        password = 'azertyui'
        is_valid, __, code = validate_extra_secure_password(password)
        self.assertFalse(is_valid)
        self.assertEqual(code, 'missing-characters')

        # This password contains no lowercase letter.
        password = 'AZERTYUI'
        is_valid, __, code = validate_extra_secure_password(password)
        self.assertFalse(is_valid)
        self.assertEqual(code, 'missing-characters')

        # This password contains no digit.
        password = 'AZERtyui'
        is_valid, __, code = validate_extra_secure_password(password)
        self.assertFalse(is_valid)
        self.assertEqual(code, 'missing-characters')

        # This password contains no special character.
        password = '4Z3Rtyui'
        is_valid, __, code = validate_extra_secure_password(password)
        self.assertFalse(is_valid)
        self.assertEqual(code, 'missing-characters')

        # This password is identical to the previous one.
        password = '4Z3Rtyu!'
        is_valid, __, code = validate_extra_secure_password(password, previous=password)
        self.assertFalse(is_valid)
        self.assertEqual(code, 'identical-previous')

        # This password looks good.
        password = '4Z3Rtyu!'
        is_valid, __, __ = validate_extra_secure_password(password)
        self.assertTrue(is_valid)

    def find_users_file_path(self):
        """Find the users import file"""

        # First, we find the sample import file
        users_file_path = finders.find('users_import.xls')

        # The sample file exists
        self.assertIsNotNone(users_file_path)

        return users_file_path

    def test_xls_import_trainee_commit_equal_false(self):
        """Test the users import from xls file with commit=False"""

        # We try to import the users from the file
        users = XLSTraineeImporter(self.find_users_file_path()).import_users()

        # The users list should contain 1 user
        self.assertEqual(len(users), 1)

        user = users[0]

        self.assertEqual(user.email, 'email@magency.fr')
        self.assertEqual(user.username, 'u1')
        self.assertEqual(user.first_name, 'User')
        self.assertEqual(user.last_name, 'ONE')

        # We should dont get any users when fetching from the db
        users = MTPUser.objects.filter(username=user.username)

        self.assertEqual(len(users), 0)

    def test_xls_import_trainee_commit_equal_true(self):
        """Test the users import from xls file with commit=True"""

        # We try to import the users from the file
        users = XLSTraineeImporter(self.find_users_file_path()).import_users(commit=True)

        # The users list should contain 1 user
        self.assertEqual(len(users), 1)

        user = users[0]

        self.assertEqual(user.email, 'email@magency.fr')
        self.assertEqual(user.username, 'u1')
        self.assertEqual(user.first_name, 'User')
        self.assertEqual(user.last_name, 'ONE')

        # We should got 1 user when fetching from the db
        users = MTPUser.objects.filter(username=user.username)

        self.assertEqual(len(users), 1)

    @override_settings(INSTANCE_IS_MASTER=True)
    def test_xls_import_trainee_send_mail_equal_true(self):
        """Test the users import from xls file with send_mail=True"""

        XLSTraineeImporter(self.find_users_file_path()).import_users(commit=True, send_mail=True)

        # We should have one mail to send
        self.assertEqual(len(mail.outbox), 1)

        # The recipient is the trainee
        self.assertEqual(mail.outbox[0].to[0], 'email@magency.fr')

        # If we re-import the same file, we got no new mails to send
        XLSTraineeImporter(self.find_users_file_path()).import_users(commit=True, send_mail=True)
        self.assertEqual(len(mail.outbox), 1)

    @override_settings(INSTANCE_IS_MASTER=True)
    def test_xls_import_trainee_send_mail_equal_false(self):
        """Test the users import from xls file with send_mail=False"""

        XLSTraineeImporter(self.find_users_file_path()).import_users(commit=True, send_mail=False)

        # We should have no mail to send
        self.assertEqual(len(mail.outbox), 0)

    def test_xls_import_trainee_should_correctly_set_the_created_from_attribute(self):
        """Test that creating a trainee from the import should set the correct ``created_from``"""

        users = XLSTraineeImporter(
            self.find_users_file_path()
        ).import_users(commit=True, send_mail=False)

        self.assertEqual(users[0].created_from, MTPUser.ORIGINS.CMS_IMPORT)

    def test_format_password_during_xls_import_trainee(self):
        """Test the ``format_password`` method in ``XLSTraineeImporter``."""

        self.assertEqual(
            XLSTraineeImporter.format_password('123456'),
            '123456'
        )

        self.assertEqual(
            XLSTraineeImporter.format_password('123456,9'),
            '123456,9'
        )

        self.assertEqual(
            XLSTraineeImporter.format_password(123456),
            '123456'
        )

        self.assertEqual(
            XLSTraineeImporter.format_password(123456.0),
            '123456'
        )

        self.assertEqual(
            XLSTraineeImporter.format_password(123456.9),
            '123456.9'
        )
