Skip to content

Commit

Permalink
⚡🔨 refactor(commands): Update commands log_dir to fetch from Settings…
Browse files Browse the repository at this point in the history
…Manager
  • Loading branch information
MEHRSHAD-MIRSHEKARY committed Oct 15, 2024
1 parent 3c9e9a5 commit 4c4e9f5
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 50 deletions.
9 changes: 2 additions & 7 deletions django_logging/management/commands/generate_pretty_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
import os
from typing import Dict, Tuple

from django.conf import settings
from django.core.management.base import BaseCommand

from django_logging.constants import DefaultLoggingSettings
from django_logging.constants.config_types import LogDir
from django_logging.settings import settings_manager
from django_logging.utils.command.process_file import process_files, setup_directories


Expand All @@ -33,10 +31,7 @@ def handle(self, *args: Tuple, **kwargs: Dict) -> None:
**kwargs: Additional keyword arguments (not used).
"""
default_settings = DefaultLoggingSettings()
log_dir: LogDir = settings.DJANGO_LOGGING.get(
"LOG_DIR", os.path.join(os.getcwd(), default_settings.log_dir)
)
log_dir = settings_manager.log_dir

try:
json_dir, pretty_dir = setup_directories(log_dir, "json")
Expand Down
9 changes: 2 additions & 7 deletions django_logging/management/commands/generate_pretty_xml.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import os
from typing import Any, Dict, Tuple

from django.conf import settings
from django.core.management.base import BaseCommand

from django_logging.constants import DefaultLoggingSettings
from django_logging.constants.config_types import LogDir
from django_logging.settings import settings_manager
from django_logging.utils.command.process_file import process_files, setup_directories


Expand All @@ -31,10 +29,7 @@ def handle(self, *args: Tuple[Any], **kwargs: Dict[str, Any]) -> None:
**kwargs: Keyword arguments passed to the command.
"""
default_settings = DefaultLoggingSettings()
log_dir: LogDir = settings.DJANGO_LOGGING.get(
"LOG_DIR", os.path.join(os.getcwd(), default_settings.log_dir)
)
log_dir = settings_manager.log_dir

try:
xml_dir, pretty_dir = setup_directories(log_dir, "xml")
Expand Down
10 changes: 2 additions & 8 deletions django_logging/management/commands/send_logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
from django.core.mail import EmailMessage
from django.core.management.base import BaseCommand

from django_logging.constants import DefaultLoggingSettings
from django_logging.constants.config_types import LogDir
from django_logging.settings import settings_manager
from django_logging.validators.email_settings_validator import check_email_settings

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -50,12 +49,7 @@ def handle(self, *args: Tuple, **kwargs: Dict) -> None:
"""
email: str = kwargs["email"] # type: ignore

default_settings = DefaultLoggingSettings()
log_settings = getattr(settings, "DJANGO_LOGGING", {})

log_dir: LogDir = log_settings.get(
"LOG_DIR", os.path.join(os.getcwd(), default_settings.log_dir)
)
log_dir = settings_manager.log_dir

if not os.path.exists(log_dir):
self.stdout.write(
Expand Down
33 changes: 19 additions & 14 deletions django_logging/tests/commands/test_generate_pretty_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
from io import StringIO
from pathlib import Path
from typing import Any
from unittest.mock import patch, Mock

import pytest
from django.core.management import call_command
from django.test import override_settings

from django_logging.tests.constants import PYTHON_VERSION, PYTHON_VERSION_REASON

Expand All @@ -26,9 +26,11 @@ class TestJsonReformatCommand:
parses multiple JSON objects, and saves them in a 'pretty' subdirectory in a valid JSON array format.
"""

@override_settings(DJANGO_LOGGING={"LOG_DIR": "/tmp/test_logs"})
@patch(
"django_logging.management.commands.generate_pretty_json.settings_manager"
)
def test_command_successful_processing(
self, temp_json_log_directory: str, settings: Any
self, settings: Mock, temp_json_log_directory: str
) -> None:
"""
Test the successful processing and pretty-printing of JSON files.
Expand All @@ -42,23 +44,21 @@ def test_command_successful_processing(
temp_json_log_directory (str): Path to the temporary log directory.
settings (django.conf.Settings): Django settings.
"""
settings.DJANGO_LOGGING["LOG_DIR"] = temp_json_log_directory
settings.log_dir = temp_json_log_directory

out = StringIO()
call_command("generate_pretty_json", stdout=out)

# Check output
assert "Processing file" in out.getvalue()
assert "Processing file" in out.getvalue(), f"Output: {out.getvalue()}"
assert (
"reformatted and generated new pretty file successfully" in out.getvalue()
)
"reformatted and generated new pretty file successfully" in out.getvalue()
), f"Output: {out.getvalue()}"

# Verify that the formatted JSON file exists in the pretty directory
pretty_dir = os.path.join(
settings.DJANGO_LOGGING.get("LOG_DIR"), "json", "pretty"
)
pretty_dir = os.path.join(settings.log_dir, "json", "pretty")
formatted_file = os.path.join(pretty_dir, "formatted_test.json")
assert os.path.exists(formatted_file)
assert os.path.exists(formatted_file), f"File {formatted_file} not found."

# Load and verify the content of the generated pretty file
with open(formatted_file) as f:
Expand All @@ -67,7 +67,9 @@ def test_command_successful_processing(
assert len(data) == 2
assert data[0]["key"] == "value"

@override_settings(DJANGO_LOGGING={"LOG_DIR": "/non_existent_dir"})
@patch(
"django_logging.management.commands.generate_pretty_json.settings_manager"
)
def test_command_file_not_found_error(self, settings: Any) -> None:
"""
Test handling of FileNotFoundError when the log directory does not exist.
Expand All @@ -83,7 +85,10 @@ def test_command_file_not_found_error(self, settings: Any) -> None:
# Check if the command logs the directory not found error
assert "does not exist." in out.getvalue()

def test_command_invalid_json(self, temp_json_log_directory: str, settings: Any) -> None:
@patch(
"django_logging.management.commands.generate_pretty_json.settings_manager"
)
def test_command_invalid_json(self, settings: Any, temp_json_log_directory: str) -> None:
"""
Test the command's handling of invalid JSON files.
Expand All @@ -93,7 +98,7 @@ def test_command_invalid_json(self, temp_json_log_directory: str, settings: Any)
temp_json_log_directory (str): Path to the temporary log directory.
settings (django.conf.Settings): Django settings.
"""
settings.DJANGO_LOGGING["LOG_DIR"] = temp_json_log_directory
settings.log_dir = temp_json_log_directory

# Create a faulty JSON file with invalid syntax.
faulty_json_file = Path(temp_json_log_directory) / "json" / "faulty.json"
Expand Down
17 changes: 11 additions & 6 deletions django_logging/tests/commands/test_generate_pretty_xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
import sys
from io import StringIO
from typing import Any
from unittest.mock import patch

import pytest
from django.core.management import call_command
from django.test import override_settings

from django_logging.tests.constants import PYTHON_VERSION, PYTHON_VERSION_REASON

Expand All @@ -24,9 +24,11 @@ class TestGeneratePrettyXMLCommand:
reformats them by wrapping their content in a <logs> element, and saves them in a 'pretty' subdirectory.
"""

@override_settings(DJANGO_LOGGING={"LOG_DIR": "/tmp/test_logs"})
@patch(
"django_logging.management.commands.generate_pretty_xml.settings_manager"
)
def test_command_successful_processing(
self, temp_xml_log_directory: str, settings: Any
self, settings: Any, temp_xml_log_directory: str
) -> None:
"""
Test the successful processing and reformatting of XML files.
Expand All @@ -42,7 +44,7 @@ def test_command_successful_processing(
settings (django.conf.Settings): Django settings.
"""
# Update the settings to point to the temp log directory
settings.DJANGO_LOGGING["LOG_DIR"] = temp_xml_log_directory
settings.log_dir = temp_xml_log_directory

out = StringIO()
call_command("generate_pretty_xml", stdout=out)
Expand All @@ -53,7 +55,7 @@ def test_command_successful_processing(

# Verify that the reformatted XML file exists in the pretty directory
pretty_dir = os.path.join(
settings.DJANGO_LOGGING["LOG_DIR"], "xml", "pretty"
settings.log_dir, "xml", "pretty"
)
formatted_file = os.path.join(pretty_dir, "formatted_test.xml")
assert os.path.exists(formatted_file), "Reformatted file was not created."
Expand All @@ -65,7 +67,9 @@ def test_command_successful_processing(
assert "<entry>Test Entry</entry>" in content
assert "</logs>" in content

@override_settings(DJANGO_LOGGING={"LOG_DIR": "/non_existent_dir"})
@patch(
"django_logging.management.commands.generate_pretty_xml.settings_manager"
)
def test_command_directory_not_found(self, settings: Any) -> None:
"""
Test that the command handles the case when the XML directory is missing.
Expand All @@ -76,6 +80,7 @@ def test_command_directory_not_found(self, settings: Any) -> None:
----
settings (django.conf.Settings): Django settings.
"""
settings.log_dir = "/non_existent_dir"
out = StringIO()
call_command("generate_pretty_xml", stdout=out)

Expand Down
35 changes: 27 additions & 8 deletions django_logging/tests/commands/test_send_logs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import shutil
import sys
import tempfile
from unittest.mock import ANY, Mock, patch
from unittest.mock import Mock, patch

import pytest
from django.core.exceptions import ImproperlyConfigured
Expand All @@ -28,8 +28,12 @@ class SendLogsCommandTests(TestCase):
)
@patch("django_logging.management.commands.send_logs.shutil.make_archive")
@patch("django_logging.management.commands.send_logs.EmailMessage")
@patch(
"django_logging.management.commands.send_logs.settings_manager"
)
def test_handle_success(
self,
mock_settings_manager: Mock,
mock_email_message: Mock,
mock_make_archive: Mock,
mock_validate_email_settings: Mock,
Expand All @@ -40,6 +44,7 @@ def test_handle_success(
Args:
----
mock_settings_manager: Mock for the `SettingsManager` class used in the command.
mock_email_message: Mock for the `EmailMessage` class used to send the email.
mock_make_archive: Mock for the `shutil.make_archive` function that creates the log archive.
mock_validate_email_settings: Mock for the `validate_email_settings` method in the command.
Expand All @@ -55,13 +60,21 @@ def test_handle_success(
temp_file.close()
mock_make_archive.return_value = temp_file.name

with self.settings(DJANGO_LOGGING={"LOG_DIR": temp_log_dir}):
call_command("send_logs", "[email protected]")
mock_settings_manager.get_log_dir.return_value = temp_log_dir

# Mock the return value of make_archive to be the temp file path
mock_make_archive.return_value = temp_file.name

# Run the management command
call_command("send_logs", "[email protected]")

mock_validate_email_settings.assert_called_once()
mock_make_archive.assert_called_once_with(ANY, "zip", temp_log_dir)
mock_make_archive.assert_called_once()

# Assert that EmailMessage was instantiated and sent
mock_email_message.assert_called_once()

# Cleanup temporary files and directories
shutil.rmtree(temp_log_dir)
(
os.remove(temp_file.name + ".zip")
Expand Down Expand Up @@ -108,30 +121,36 @@ def test_handle_email_send_failure(
@patch(
"django_logging.management.commands.send_logs.Command.validate_email_settings"
)
def test_handle_missing_log_dir(self, mock_validate_email_settings: Mock) -> None:
@patch(
"django_logging.management.commands.send_logs.settings_manager"
)
def test_handle_missing_log_dir(self, mock_validate_email_settings: Mock, mock_settings_manager: Mock) -> None:
"""
Test that the `send_logs` command logs an error when the specified log directory does not exist
and skips the email validation step.
Args:
----
mock_validate_email_settings: Mock for the `validate_email_settings` method in the command.
mock_settings_manager: Mock for the `SettingsManager` class used in the command.
Asserts:
-------
- An error message is logged if the log directory does not exist.
- The `validate_email_settings` method is not called.
"""
non_existent_dir = "/non/existent/directory"
with self.settings(DJANGO_LOGGING={"LOG_DIR": non_existent_dir}):
mock_settings_manager.get_log_dir.return_value = non_existent_dir

with patch("os.path.exists", return_value=False):
with self.assertLogs(
"django_logging.management.commands.send_logs", level="ERROR"
) as cm:
call_command("send_logs", "[email protected]")

self.assertIn(
f"ERROR:django_logging.management.commands.send_logs:Log directory '{non_existent_dir}' does not exist.",
cm.output,
"ERROR:django_logging.management.commands.send_logs:Log directory" and "does not exist.",
cm.output[0],
)
mock_validate_email_settings.assert_not_called()

Expand Down

0 comments on commit 4c4e9f5

Please sign in to comment.