"""Signing in with a username or an email address."""
from django.contrib.auth import authenticate, get_user_model
from django.test import TestCase
from django.urls import reverse

User = get_user_model()


class UsernameOrEmailLoginTests(TestCase):
    def setUp(self):
        self.user = User.objects.create_user(
            username="rian80", email="rian@rian.ca", password="correct-horse-99"
        )

    def test_sign_in_with_username(self):
        self.assertIsNotNone(authenticate(username="rian80", password="correct-horse-99"))

    def test_sign_in_with_email(self):
        self.assertIsNotNone(authenticate(username="rian@rian.ca", password="correct-horse-99"))

    def test_email_is_case_insensitive(self):
        self.assertIsNotNone(authenticate(username="Rian@Rian.CA", password="correct-horse-99"))

    def test_username_is_case_insensitive(self):
        self.assertIsNotNone(authenticate(username="RIAN80", password="correct-horse-99"))

    def test_wrong_password_still_fails(self):
        self.assertIsNone(authenticate(username="rian@rian.ca", password="nope"))

    def test_unknown_identifier_fails(self):
        self.assertIsNone(authenticate(username="nobody@example.com", password="x"))

    def test_inactive_user_cannot_sign_in(self):
        self.user.is_active = False
        self.user.save()
        self.assertIsNone(authenticate(username="rian@rian.ca", password="correct-horse-99"))

    def test_shared_email_is_refused_rather_than_guessed(self):
        User.objects.create_user(
            username="other", email="rian@rian.ca", password="different-pw-11"
        )
        self.assertIsNone(authenticate(username="rian@rian.ca", password="correct-horse-99"))
        # An exact username is still unambiguous, so it works.
        self.assertIsNotNone(authenticate(username="rian80", password="correct-horse-99"))

    def test_login_form_accepts_email(self):
        response = self.client.post(
            reverse("login"),
            {"username": "rian@rian.ca", "password": "correct-horse-99"},
            secure=True,
        )
        self.assertEqual(response.status_code, 302)
        self.assertIn("_auth_user_id", self.client.session)
