Tussilago/tests/test_settings_production.py

136 lines
5.8 KiB
Python

import importlib
import sys
from typing import Any
import pytest
def load_settings_for_runtime(
monkeypatch: pytest.MonkeyPatch,
*,
debug: bool,
testing: bool,
) -> dict[str, Any]:
"""Load the settings module with environment variables set for the given runtime.
Returns:
The settings as a dictionary. Note that this is not a full Django settings object, but just the module's global variables.
"""
# DJANGO_SECRET_KEY must be set to a non-empty value to not exit early with an error about missing secret key.
# If DJANGO_DEBUG is set to True or PYTEST_VERSION is set, the settings module will consider it a non-production runtime and load debug-only components.
monkeypatch.setenv(name="DJANGO_SECRET_KEY", value="test-secret-key")
monkeypatch.setenv(name="DJANGO_DEBUG", value="true" if debug else "false")
if testing:
monkeypatch.setenv(name="PYTEST_VERSION", value="9.0.0")
monkeypatch.setattr(target="sys.argv", name=["manage.py", "test"])
else:
monkeypatch.delenv(name="PYTEST_VERSION", raising=False)
monkeypatch.setattr(target="sys.argv", name=["manage.py", "runserver"])
# Remove the settings module from sys.modules to force it to be reloaded with the new environment variables.
sys.modules.pop("config.settings", None)
settings_module = importlib.import_module("config.settings")
return vars(settings_module).copy()
def test_production_runtime_disables_debug_stuff(
monkeypatch: pytest.MonkeyPatch,
) -> None:
"""Production mode must not load any debug-only components."""
settings: dict[str, Any] = load_settings_for_runtime(
monkeypatch=monkeypatch,
debug=False,
testing=False,
)
msg: str = f"Expected production runtime to have DEBUG=False and TESTING=False, but got DEBUG={settings['DEBUG']} and TESTING={settings['TESTING']}"
assert settings["DEBUG"] is False, msg
assert settings["TESTING"] is False, msg
middleware: list[str] = settings["MIDDLEWARE"]
msg = f"Expected MIDDLEWARE to be a list, but got {type(middleware)}"
assert isinstance(middleware, list), msg
msg = f"Expected production runtime to not have debug-only middleware, but got {middleware}"
assert "debug_toolbar.middleware.DebugToolbarMiddleware" not in middleware, msg
msg = f"Expected production runtime to not have django_browser_reload middleware, but got {middleware}"
assert "django_browser_reload.middleware.BrowserReloadMiddleware" not in middleware, msg # fmt: skip
msg = f"Expected production runtime to not have zeal middleware, but got {middleware}" # fmt: skip
assert "zeal.middleware.zeal_middleware" not in middleware, msg
installed_apps: list[str] = settings["INSTALLED_APPS"]
msg = f"Expected INSTALLED_APPS to be a list, but got {type(installed_apps)}"
assert isinstance(installed_apps, list), msg
msg = f"debug_toolbar should not be in INSTALLED_APPS in production runtime, but got {installed_apps}"
assert "debug_toolbar" not in installed_apps, msg
msg = f"django_browser_reload should not be in INSTALLED_APPS in production runtime, but got {installed_apps}"
assert "django_browser_reload" not in installed_apps, msg
msg = f"django_watchfiles should not be in INSTALLED_APPS in production runtime, but got {installed_apps}"
assert "django_watchfiles" not in installed_apps, msg
msg = f"zeal should not be in INSTALLED_APPS in production runtime, but got {installed_apps}"
assert "zeal" not in installed_apps, msg
msg = f"DEBUG_TOOLBAR_CONFIG should not be in settings in production runtime, but got {settings}"
assert "DEBUG_TOOLBAR_CONFIG" not in settings, msg
@pytest.mark.parametrize(
("debug", "testing"),
[
(True, False),
(False, True),
],
)
def test_dev_or_testing_runtime_enables_debug_stuff(
monkeypatch: pytest.MonkeyPatch,
debug: bool,
testing: bool,
) -> None:
"""Dev or test mode must load all debug-only components."""
settings: dict[str, Any] = load_settings_for_runtime(
monkeypatch=monkeypatch,
debug=debug,
testing=testing,
)
msg: str = f"Expected runtime to have DEBUG={debug} and TESTING={testing}, but got DEBUG={settings['DEBUG']} and TESTING={settings['TESTING']}"
assert settings["DEBUG"] is debug, msg
assert settings["TESTING"] is testing, msg
middleware: list[str] = settings["MIDDLEWARE"]
msg = f"Expected MIDDLEWARE to be a list, but got {type(middleware)}"
assert isinstance(middleware, list), msg
msg = f"Expected runtime to have debug-only middleware, but got {middleware}"
assert "debug_toolbar.middleware.DebugToolbarMiddleware" in middleware, msg
assert "django_browser_reload.middleware.BrowserReloadMiddleware" in middleware, msg
assert "zeal.middleware.zeal_middleware" in middleware, msg
installed_apps: list[str] = settings["INSTALLED_APPS"]
msg = f"Expected INSTALLED_APPS to be a list, but got {type(installed_apps)}"
assert isinstance(installed_apps, list), msg
msg = f"debug_toolbar should be in INSTALLED_APPS in dev/test runtime, but got {installed_apps}"
assert "debug_toolbar" in installed_apps, msg
assert "django_browser_reload" in installed_apps, msg
assert "django_watchfiles" in installed_apps, msg
assert "zeal" in installed_apps, msg
msg = f"DEBUG_TOOLBAR_CONFIG should be in settings in dev/test runtime, but got {settings}"
assert "DEBUG_TOOLBAR_CONFIG" in settings, msg
msg = f"Expected DEBUG_TOOLBAR_CONFIG to be a dict, but got {type(settings['DEBUG_TOOLBAR_CONFIG'])}"
assert isinstance(settings["DEBUG_TOOLBAR_CONFIG"], dict), msg
msg = f"Expected DEBUG_TOOLBAR_CONFIG to have ROOT_TAG_EXTRA_ATTRS='hx-preserve', but got {settings['DEBUG_TOOLBAR_CONFIG']}"
assert settings["DEBUG_TOOLBAR_CONFIG"] == {"ROOT_TAG_EXTRA_ATTRS": "hx-preserve"}