import pytest
from mode.utils.mocks import Mock, mask_module, patch_module

from faust.fixups import fixups
from faust.fixups.django import Fixup


class Test_Fixup:
    @pytest.fixture()
    def fixup(self, *, app):
        return Fixup(app)

    def test_fixup_env_enabled(self, *, app, fixup, monkeypatch):
        monkeypatch.setenv("DJANGO_SETTINGS_MODULE", "settings")
        with patch_module("django"):
            assert fixup.enabled()
            assert any(isinstance(f, Fixup) for f in fixups(app))

    def test_fixup_env_enabled_no_django(self, *, app, fixup, monkeypatch):
        monkeypatch.setenv("DJANGO_SETTINGS_MODULE", "settings")
        with mask_module("django"):
            with pytest.warns(UserWarning):
                assert not fixup.enabled()
                assert not any(isinstance(f, Fixup) for f in fixups(app))

    def test_fixup_env_disabled(self, *, app, fixup, monkeypatch):
        monkeypatch.delenv("DJANGO_SETTINGS_MODULE", raising=False)
        assert not fixup.enabled()
        assert not any(isinstance(f, Fixup) for f in fixups(app))

    def test_wait_for_django_calls_django_setup(self, *, fixup, monkeypatch):
        with patch_module("django", "django.conf", "django.conf.settings"):
            import django
            from django.conf import settings

            settings.configure()
            settings.DEBUG = False
            fixup.wait_for_django()
            django.setup.assert_called_once_with()
            settings.DEBUG = True
            with pytest.warns(UserWarning):
                fixup.wait_for_django()

    def test_autodiscover_modules(self, *, fixup):
        with patch_module("django", "django.conf", "django.core", "django.apps"):
            from django.apps import apps

            config1 = Mock()
            config1.name = "config1"
            config2 = Mock()
            config2.name = "config2"
            apps.get_app_configs.return_value = [config1, config2]

            assert fixup.autodiscover_modules() == ["config1", "config2"]

    def test_on_worker_init(self, *, fixup):
        with patch_module("django", "django.conf", "django.core", "django.core.checks"):
            import django
            from django.conf import settings
            from django.core.checks import run_checks

            settings.DEBUG = False
            fixup.on_worker_init()
            django.setup.assert_called_once_with()
            run_checks.assert_called_once_with()

            settings.DEBUG = True
            with pytest.warns(UserWarning):
                fixup.on_worker_init()

    def test_apps(self, *, fixup):
        with patch_module("django", "django.apps"):
            from django.apps import apps

            assert fixup.apps is apps

    def test_settings(self, *, fixup):
        with patch_module("django", "django.conf"):
            from django.conf import settings

            assert fixup.settings is settings
