diff --git a/tests/commands/test_send_logs.py b/tests/commands/test_send_logs.py index 7b54d10..f4ed85e 100644 --- a/tests/commands/test_send_logs.py +++ b/tests/commands/test_send_logs.py @@ -1,15 +1,13 @@ import os -import tempfile import shutil - -from unittest.mock import patch, ANY, Mock +import tempfile +from unittest.mock import ANY, Mock, patch import pytest from django.core.exceptions import ImproperlyConfigured from django.core.management import call_command from django.test import TestCase - pytestmark = [pytest.mark.commands, pytest.mark.commands_send_logs] @@ -125,7 +123,7 @@ def test_handle_missing_log_dir(self, mock_validate_email_settings: Mock) -> Non call_command("send_logs", "test@example.com") self.assertIn( - f'ERROR:django_logging.management.commands.send_logs:Log directory "{non_existent_dir}" does not exist.', + f"ERROR:django_logging.management.commands.send_logs:Log directory '{non_existent_dir}' does not exist.", cm.output, ) mock_validate_email_settings.assert_not_called() diff --git a/tests/conftest.py b/tests/conftest.py index bcc541d..308db44 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,20 +1,20 @@ from tests.fixtures import ( - debug_log_record, - error_log_record, + admin_email_mock_settings, colored_formatter, + debug_log_record, email_handler, - request_middleware, - request_factory, + email_mock_settings, + error_log_record, get_response, - mock_settings, - reset_settings, log_config, log_manager, + magic_mock_logger, + mock_email_settings, mock_logger, - notifier_mock_logger, - email_mock_settings, + mock_settings, mock_smtp, - admin_email_mock_settings, - magic_mock_logger, - mock_email_settings + notifier_mock_logger, + request_factory, + request_middleware, + reset_settings, ) diff --git a/tests/filters/test_log_level_filter.py b/tests/filters/test_log_level_filter.py index 71542b7..ef389fe 100644 --- a/tests/filters/test_log_level_filter.py +++ b/tests/filters/test_log_level_filter.py @@ -1,11 +1,10 @@ import logging + import pytest + from django_logging.filters import LoggingLevelFilter -pytestmark = [ - pytest.mark.filters, - pytest.mark.filters_level_filter -] +pytestmark = [pytest.mark.filters, pytest.mark.filters_level_filter] class TestLoggingLevelFilter: diff --git a/tests/fixtures/__init__.py b/tests/fixtures/__init__.py index cb0d5e6..5b8601d 100644 --- a/tests/fixtures/__init__.py +++ b/tests/fixtures/__init__.py @@ -1,10 +1,14 @@ -from .log_record_fixture import debug_log_record, error_log_record from .colored_formatter_fixture import colored_formatter -from .email_handler_fixture import email_handler -from .request_middleware_fixture import request_middleware, request_factory, get_response -from .settings_fixture import mock_settings, reset_settings from .conf_fixture import log_config, log_manager -from .logger_fixture import mock_logger -from .email_notifier_fixture import mock_smtp, email_mock_settings, notifier_mock_logger -from .log_and_notify_fixture import admin_email_mock_settings, magic_mock_logger +from .email_handler_fixture import email_handler +from .email_notifier_fixture import email_mock_settings, mock_smtp, notifier_mock_logger from .email_settings_fixture import mock_email_settings +from .log_and_notify_fixture import admin_email_mock_settings, magic_mock_logger +from .log_record_fixture import debug_log_record, error_log_record +from .logger_fixture import mock_logger +from .request_middleware_fixture import ( + get_response, + request_factory, + request_middleware, +) +from .settings_fixture import mock_settings, reset_settings diff --git a/tests/fixtures/log_and_notify_fixture.py b/tests/fixtures/log_and_notify_fixture.py index f1cd2db..8565b48 100644 --- a/tests/fixtures/log_and_notify_fixture.py +++ b/tests/fixtures/log_and_notify_fixture.py @@ -2,7 +2,6 @@ from unittest.mock import MagicMock import pytest - from django.conf import settings diff --git a/tests/fixtures/log_record_fixture.py b/tests/fixtures/log_record_fixture.py index 35f571b..cab0438 100644 --- a/tests/fixtures/log_record_fixture.py +++ b/tests/fixtures/log_record_fixture.py @@ -1,4 +1,5 @@ -from logging import LogRecord, DEBUG, ERROR +from logging import DEBUG, ERROR, LogRecord + import pytest @@ -39,4 +40,4 @@ def error_log_record() -> LogRecord: msg="Test message", args=(), exc_info=None, - ) \ No newline at end of file + ) diff --git a/tests/fixtures/logger_fixture.py b/tests/fixtures/logger_fixture.py index 0a9ef67..cf021fb 100644 --- a/tests/fixtures/logger_fixture.py +++ b/tests/fixtures/logger_fixture.py @@ -1,6 +1,6 @@ from logging import Logger, getLogger from typing import Generator -from unittest.mock import patch, Mock +from unittest.mock import Mock, patch import pytest diff --git a/tests/fixtures/settings_fixture.py b/tests/fixtures/settings_fixture.py index 6ba31a8..a26642c 100644 --- a/tests/fixtures/settings_fixture.py +++ b/tests/fixtures/settings_fixture.py @@ -1,8 +1,7 @@ -from typing import Generator, Dict +from typing import Dict, Generator from unittest.mock import patch import pytest - from django.conf import settings diff --git a/tests/formatters/test_colored_formatter.py b/tests/formatters/test_colored_formatter.py index bec9446..fe4682a 100644 --- a/tests/formatters/test_colored_formatter.py +++ b/tests/formatters/test_colored_formatter.py @@ -1,15 +1,11 @@ import logging - -from unittest.mock import patch, MagicMock +from unittest.mock import MagicMock, patch import pytest from django_logging.formatters import ColoredFormatter -pytestmark = [ - pytest.mark.formatters, - pytest.mark.colored_formatter - ] +pytestmark = [pytest.mark.formatters, pytest.mark.colored_formatter] class TestColoredFormatter: diff --git a/tests/handlers/test_email_handler.py b/tests/handlers/test_email_handler.py index 5e47404..45c37ea 100644 --- a/tests/handlers/test_email_handler.py +++ b/tests/handlers/test_email_handler.py @@ -1,7 +1,7 @@ import logging -import pytest -from unittest.mock import patch, MagicMock, ANY +from unittest.mock import ANY, MagicMock, patch +import pytest from django.conf import settings from django_logging.handlers.email_handler import EmailHandler diff --git a/tests/middleware/test_request_middleware.py b/tests/middleware/test_request_middleware.py index 60f7a84..eecb50f 100644 --- a/tests/middleware/test_request_middleware.py +++ b/tests/middleware/test_request_middleware.py @@ -5,8 +5,8 @@ from django.contrib.auth import get_user_model from django.contrib.auth.models import AnonymousUser from django.test import RequestFactory -from django_logging.middleware import RequestLogMiddleware +from django_logging.middleware import RequestLogMiddleware pytestmark = [pytest.mark.middleware, pytest.mark.request_middleware] diff --git a/tests/settings/test_checks.py b/tests/settings/test_checks.py index b674f74..8668bbf 100644 --- a/tests/settings/test_checks.py +++ b/tests/settings/test_checks.py @@ -2,8 +2,9 @@ from unittest.mock import patch import pytest -from django.core.checks import Error from django.conf import settings +from django.core.checks import Error + from django_logging.settings.checks import check_logging_settings pytestmark = [pytest.mark.settings, pytest.mark.settings_checks] diff --git a/tests/settings/test_conf.py b/tests/settings/test_conf.py index 19e0f19..14b1e2f 100644 --- a/tests/settings/test_conf.py +++ b/tests/settings/test_conf.py @@ -1,10 +1,11 @@ -import pytest -from unittest import mock import os +from shutil import rmtree +from unittest import mock -from django_logging.settings.conf import LogConfig, LogManager -from django_logging.constants import FORMAT_OPTIONS +import pytest +from django_logging.constants import FORMAT_OPTIONS +from django_logging.settings.conf import LogConfig, LogManager pytestmark = [pytest.mark.settings, pytest.mark.settings_conf] @@ -92,7 +93,7 @@ def test_create_log_files(self, log_manager: LogManager) -> None: expected_file_path = os.path.join( "/tmp/logs", f"{log_level.lower()}.log" ) - open_mock.assert_any_call(expected_file_path, "w") + open_mock.assert_any_call(expected_file_path, "w", encoding="utf-8") log_manager.log_files[log_level] = expected_file_path @@ -143,6 +144,9 @@ def test_set_conf(self, log_manager: LogManager) -> None: assert "handlers" in config["root"] assert "disable_existing_loggers" in config + # Remove the log dir created by test + rmtree("/tmp", ignore_errors=True) + def test_log_manager_get_log_file(self, log_manager: LogManager) -> None: """ Test retrieval of log file paths. diff --git a/tests/utils/test_context_manager.py b/tests/utils/test_context_manager.py index 29a440b..a758130 100644 --- a/tests/utils/test_context_manager.py +++ b/tests/utils/test_context_manager.py @@ -1,11 +1,9 @@ import logging from unittest import mock + import pytest -from django_logging.utils.context_manager import ( - config_setup, - _restore_logging_config, -) +from django_logging.utils.context_manager import _restore_logging_config, config_setup pytestmark = [pytest.mark.utils, pytest.mark.utils_context_manager] @@ -29,7 +27,9 @@ def test_config_setup_auto_initialization_enabled(self) -> None: return_value=True, ): with pytest.raises(ValueError) as excinfo: + # fmt: off with config_setup(): "" + # fmt: on assert ( str(excinfo.value) @@ -64,18 +64,18 @@ def test_config_setup_applies_custom_config( ): with mock.patch( "django_logging.utils.context_manager.get_config", - return_value=( - ["INFO"], - "/tmp/logs", - {"INFO": 1}, - "DEBUG", - 2, - False, - "", - False, - [], - 1, - ), + return_value={ + "log_levels": ["INFO"], + "log_dir": "/tmp/logs", + "log_file_formats": {"INFO": 1}, + "console_level": "DEBUG", + "console_format": 2, + "colorize_console": False, + "log_date_format": "", + "log_email_notifier_enable": False, + "log_email_notifier_log_levels": [], + "log_email_notifier_log_format": 1, + }, ): with mock.patch( "django_logging.utils.context_manager.LogManager" @@ -117,18 +117,18 @@ def test_config_context_restores_original_config( ): with mock.patch( "django_logging.utils.context_manager.get_config", - return_value=( - ["INFO"], - "/tmp/logs", - {"INFO": 1}, - "DEBUG", - 2, - False, - "", - False, - [], - 1, - ), + return_value={ + "log_levels": ["INFO"], + "log_dir": "/tmp/logs", + "log_file_formats": {"INFO": 1}, + "console_level": "DEBUG", + "console_format": 2, + "colorize_console": False, + "log_date_format": "", + "log_email_notifier_enable": False, + "log_email_notifier_log_levels": [], + "log_email_notifier_log_format": 1, + }, ): with mock.patch("django_logging.utils.context_manager.LogManager"): with config_setup(): diff --git a/tests/utils/test_email_notifier.py b/tests/utils/test_email_notifier.py index 7d9d7a4..c0997b1 100644 --- a/tests/utils/test_email_notifier.py +++ b/tests/utils/test_email_notifier.py @@ -1,6 +1,9 @@ -import pytest import threading -from unittest.mock import MagicMock +from smtplib import SMTPException +from unittest.mock import ANY, MagicMock + +import pytest + from django_logging.utils.log_email_notifier.notifier import send_email_async pytestmark = [pytest.mark.utils, pytest.mark.utils_email_notifier] @@ -101,7 +104,7 @@ def test_send_email_async_failure( - The success message was not logged. """ mock_info, mock_warning = notifier_mock_logger - mock_smtp.side_effect = Exception("SMTP failure") + mock_smtp.side_effect = SMTPException("SMTP failure") email_sent_event = threading.Event() @@ -112,6 +115,6 @@ def test_send_email_async_failure( email_sent_event.wait() mock_warning.assert_called_once_with( - "Email Notifier failed to send Log Record: SMTP failure" + "Email Notifier failed to send Log Record: %s", ANY ) mock_info.assert_not_called() diff --git a/tests/utils/test_get_conf.py b/tests/utils/test_get_conf.py index 8742393..cf00904 100644 --- a/tests/utils/test_get_conf.py +++ b/tests/utils/test_get_conf.py @@ -1,13 +1,14 @@ from typing import Dict +from unittest.mock import patch import pytest -from unittest.mock import patch from django.conf import settings + from django_logging.utils.get_conf import ( get_config, - use_email_notifier_template, is_auto_initialization_enabled, is_initialization_message_enabled, + use_email_notifier_template, ) pytestmark = [pytest.mark.utils, pytest.mark.utils_get_conf] @@ -31,23 +32,49 @@ def test_get_conf(self, mock_settings: Dict) -> None: - The returned configuration matches the expected values for logging levels, directory, file formats, console settings, email notifier settings, etc. """ - expected = [ - ["DEBUG", "INFO"], # log_levels - "/custom/log/dir", # log_dir - { + expected = { + "log_levels": ["DEBUG", "INFO"], + "log_dir": "/custom/log/dir", + "log_file_formats": { "DEBUG": "%(asctime)s - %(name)s - %(levelname)s - %(message)s" - }, # log_file_formats - "WARNING", # console_level - "%(levelname)s - %(message)s", # console_format - True, # colorize_console - "%Y-%m-%d", # log_date_format - True, # log_email_notifier_enable - ["ERROR", None], # log_email_notifier_log_levels - "custom_format", # log_email_notifier_log_format - ] + }, + "console_level": "WARNING", + "console_format": "%(levelname)s - %(message)s", + "colorize_console": True, + "log_date_format": "%Y-%m-%d", + "log_email_notifier_enable": True, + "log_email_notifier_log_levels": ["ERROR", None], + "log_email_notifier_log_format": "custom_format", + } + print(expected) result = get_config() assert result == expected + result = get_config(extra_info=True) + + expected_extra = { + "log_levels": ["DEBUG", "INFO"], + "log_dir": "/custom/log/dir", + "log_file_formats": { + "DEBUG": "%(asctime)s - %(name)s - %(levelname)s - %(message)s" + }, + "console_level": "WARNING", + "console_format": "%(levelname)s - %(message)s", + "colorize_console": True, + "log_date_format": "%Y-%m-%d", + "log_email_notifier_enable": True, + "log_email_notifier_log_levels": ["ERROR", None], + "log_email_notifier_log_format": "custom_format", + "log_email_notifier": { + "ENABLE": True, + "NOTIFY_ERROR": True, + "NOTIFY_CRITICAL": False, + "LOG_FORMAT": "custom_format", + }, + } + + assert result == expected_extra + def test_use_email_notifier_template(self, mock_settings: Dict) -> None: """ Test that the `use_email_notifier_template` function correctly reads the `USE_TEMPLATE` setting. diff --git a/tests/utils/test_log_and_notify.py b/tests/utils/test_log_and_notify.py index c584222..2bd2dc3 100644 --- a/tests/utils/test_log_and_notify.py +++ b/tests/utils/test_log_and_notify.py @@ -1,15 +1,17 @@ import logging +from typing import Dict +from unittest.mock import MagicMock, patch import pytest -from unittest.mock import patch, MagicMock from django.conf import settings + from django_logging.utils.log_email_notifier.log_and_notify import log_and_notify_admin pytestmark = [pytest.mark.utils, pytest.mark.utils_log_and_notify] class TestLogAndNotify: - def mock_log_config(self, email_notifier_enable: bool = True) -> MagicMock: + def mock_log_config(self, email_notifier_enable: bool = True) -> Dict: """ Helper function to create a mock LogConfig object. @@ -20,13 +22,13 @@ def mock_log_config(self, email_notifier_enable: bool = True) -> MagicMock: Returns: -------- - MagicMock - A mock object with specified settings. + Dict + A dictionary with the specified settings. """ - return MagicMock( - log_email_notifier_enable=email_notifier_enable, - log_email_notifier_log_format=1, - ) + return { + "log_email_notifier_enable": email_notifier_enable, + "log_email_notifier_log_format": 1, + } def test_log_and_notify_email_notifier_disabled( self, magic_mock_logger: MagicMock diff --git a/tests/utils/test_set_conf.py b/tests/utils/test_set_conf.py index c350296..e8d061e 100644 --- a/tests/utils/test_set_conf.py +++ b/tests/utils/test_set_conf.py @@ -1,10 +1,9 @@ -from unittest.mock import patch, MagicMock import os +from unittest.mock import MagicMock, patch import pytest from django_logging.constants.ansi_colors import AnsiColors - from django_logging.utils.set_conf import set_config pytestmark = [pytest.mark.utils, pytest.mark.utils_set_conf] @@ -207,10 +206,14 @@ def test_set_config_exception_handling( ) mock_warning.assert_called_once_with( "\n" - f"========================{AnsiColors.RED_BACKGROUND}DJANGO LOGGING{AnsiColors.RESET}" - f"========================\n" - f"{AnsiColors.RED}[CONFIGURATION ERROR]{AnsiColors.RESET}" - f" A configuration issue has been detected.\n" + "========================%sDJANGO LOGGING%s" + "========================\n" + "%s[CONFIGURATION ERROR]%s" + " A configuration issue has been detected.\n" "System checks will be run to provide more detailed information.\n" - "==============================================================\n" + "==============================================================\n", + AnsiColors.RED_BACKGROUND, + AnsiColors.RESET, + AnsiColors.RED, + AnsiColors.RESET, ) diff --git a/tests/validators/test_config_validators.py b/tests/validators/test_config_validators.py index c4adb05..570f57e 100644 --- a/tests/validators/test_config_validators.py +++ b/tests/validators/test_config_validators.py @@ -4,13 +4,13 @@ from django_logging.constants.config_types import LogLevels from django_logging.validators.config_validators import ( - validate_directory, - validate_log_levels, - validate_format_string, - validate_format_option, validate_boolean_setting, validate_date_format, + validate_directory, validate_email_notifier, + validate_format_option, + validate_format_string, + validate_log_levels, ) pytestmark = [pytest.mark.validators, pytest.mark.config_validator] diff --git a/tests/validators/test_email_settings_validator.py b/tests/validators/test_email_settings_validator.py index 3fefb85..30b9d5b 100644 --- a/tests/validators/test_email_settings_validator.py +++ b/tests/validators/test_email_settings_validator.py @@ -1,7 +1,7 @@ from typing import Dict +from unittest.mock import patch import pytest -from unittest.mock import patch from django.conf import settings from django_logging.validators.email_settings_validator import check_email_settings