"""
Tests for the custom Django system checks implemented in the vq_django_auth app.

These tests verify that our system checks correctly identify configuration issues
and enforce security best practices through Django's check framework.

Key aspects tested:
- Password validation configuration
- Compatibility with token authentication
"""

from django.core.checks import (
    Error,
    Warning,
)

from tests.utils import override_api_settings
from vq_django_auth import checks
from vq_django_auth.choices import AuthMethod


def test_security_check_warns_about_missing_password_validators(settings):
    """
    Security check warns when password validators are missing

    Given:
    - No password validators are configured in settings
    When:
    - The security checks are run
    Then:
    - A warning should be generated about missing password validators
    """
    settings.AUTH_PASSWORD_VALIDATORS = []

    # Run the check
    errors = checks.auth_security_check()

    # Verify that a warning was generated
    password_warnings = [e for e in errors if e.id == "vq_django_auth.W002"]
    assert len(password_warnings) == 1
    warning = password_warnings[0]
    assert isinstance(warning, Warning)
    assert "password validators" in warning.msg.lower()


def test_security_check_passes_with_password_validators(settings):
    """
    Security check passes when password validators are configured

    Given:
    - Password validators are properly configured in settings
    When:
    - The security checks are run
    Then:
    - No warning should be generated about password validators
    """
    settings.AUTH_PASSWORD_VALIDATORS = [
        {"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"}
    ]

    errors = checks.auth_security_check()

    # Verify no warning was generated for password validators
    password_warnings = [e for e in errors if e.id == "vq_django_auth.W002"]
    assert len(password_warnings) == 0


@override_api_settings(AUTH_METHOD=AuthMethod.TOKEN)
def test_compatibility_check_fails_without_authtoken(settings):
    """
    Compatibility check fails when using token model without authtoken app

    Given:
    - DefaultTokenModel is used in settings
    - rest_framework.authtoken is not in INSTALLED_APPS
    When:
    - The compatibility checks are run
    Then:
    - An error should be generated requiring authtoken app
    """

    settings.INSTALLED_APPS = ["rest_framework"]

    # Run the check
    errors = checks.auth_compatibility_check()

    # Verify an error was generated
    authtoken_errors = [e for e in errors if e.id == "vq_django_auth.E003"]
    assert len(authtoken_errors) > 0
    error = authtoken_errors[0]
    assert isinstance(error, Error)
    assert "rest_framework.authtoken" in error.msg


@override_api_settings(AUTH_METHOD=AuthMethod.TOKEN)
def test_compatibility_check_passes_with_authtoken(settings):
    """
    Compatibility check passes with proper authtoken configuration

    Given:
    - DefaultTokenModel is used in settings
    - rest_framework.authtoken is included in INSTALLED_APPS
    When:
    - The compatibility checks are run
    Then:
    - No error should be generated about authtoken
    """
    # Set up our testing environment
    settings.INSTALLED_APPS = [
        "rest_framework",
        "rest_framework.authtoken",
    ]

    # Run the check
    errors = checks.auth_compatibility_check()

    # Verify no error was generated
    authtoken_errors = [e for e in errors if e.id == "vq_django_auth.E001"]
    assert len(authtoken_errors) == 0


@override_api_settings(AUTH_METHOD=None)
def test_auth_method_check_error_if_none():
    errors = checks.auth_compatibility_check()

    authtoken_errors = [e for e in errors if e.id == "vq_django_auth.E001"]
    assert len(authtoken_errors) == 1


@override_api_settings(AUTH_METHOD="yay")
def test_auth_compatibility_error_if_not_in_enum():
    errors = checks.auth_compatibility_check()

    authtoken_errors = [e for e in errors if e.id == "vq_django_auth.E002"]
    assert len(authtoken_errors) == 1
