Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/tests #109

Merged
merged 8 commits into from
Oct 4, 2024
111 changes: 111 additions & 0 deletions django_logging/tests/commands/test_generate_pretty_json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import json
import os
import sys
from io import StringIO
from pathlib import Path
from typing import Any

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

pytestmark = [
pytest.mark.commands,
pytest.mark.commands_generate_pretty_json,
pytest.mark.skipif(sys.version_info < PYTHON_VERSION, reason=PYTHON_VERSION_REASON),
]


class TestJsonReformatCommand:
"""
Test suite for the Django management command that reformats JSON files in a log directory.

This test suite verifies the functionality of the command, which searches for `.json` files,
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"})
def test_command_successful_processing(
self, temp_json_log_directory: str, settings: Any
) -> None:
"""
Test the successful processing and pretty-printing of JSON files.

This test verifies that the command:
1. Processes JSON files in the 'json' directory.
2. Writes pretty JSON arrays into the 'pretty' subdirectory.
3. Logs the successful processing of files.

Args:
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

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

# Check output
assert "Processing file" in out.getvalue()
assert (
"reformatted and generated new pretty file successfully" in 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"
)
formatted_file = os.path.join(pretty_dir, "formatted_test.json")
assert os.path.exists(formatted_file)

# Load and verify the content of the generated pretty file
with open(formatted_file) as f:
data = json.load(f)
assert isinstance(data, list)
assert len(data) == 2
assert data[0]["key"] == "value"

@override_settings(DJANGO_LOGGING={"LOG_DIR": "/non_existent_dir"})
def test_command_file_not_found_error(self, settings: Any) -> None:
"""
Test handling of FileNotFoundError when the log directory does not exist.

This test checks that the command logs an error when it fails to find the specified log directory.

Args:
settings (django.conf.Settings): Django settings.
"""
out = StringIO()
call_command("generate_pretty_json", stdout=out)

# 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:
"""
Test the command's handling of invalid JSON files.

This test verifies that the command logs a JSONDecodeError when it encounters invalid JSON content.

Args:
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

# Create a faulty JSON file with invalid syntax.
faulty_json_file = Path(temp_json_log_directory) / "json" / "faulty.json"
faulty_json_file.write_text(
"""
{"key": "value", \n "key2" }

"""
) # Invalid JSON

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

assert "faulty.json" in out.getvalue()
assert 'Incomplete JSON object: {"key": "value","key2" }' in out.getvalue()
83 changes: 83 additions & 0 deletions django_logging/tests/commands/test_generate_pretty_xml.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import os
import sys
from io import StringIO
from typing import Any

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

pytestmark = [
pytest.mark.commands,
pytest.mark.commands_generate_pretty_xml,
pytest.mark.skipif(sys.version_info < PYTHON_VERSION, reason=PYTHON_VERSION_REASON),
]


class TestGeneratePrettyXMLCommand:
"""
Test suite for the `generate_pretty_xml` management command.

This test suite verifies the functionality of the command, which searches for `.xml` files,
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"})
def test_command_successful_processing(
self, temp_xml_log_directory: str, settings: Any
) -> None:
"""
Test the successful processing and reformatting of XML files.

This test verifies that the command:
1. Processes XML files in the 'xml' directory.
2. Writes reformatted XML files into the 'pretty' subdirectory.
3. Logs the successful processing of files.

Args:
----
temp_xml_log_directory (str): Path to the temporary log directory.
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

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

# Check command output for success message
assert "Processing file" in out.getvalue()
assert "File test.xml reformatted successfully." in out.getvalue()

# Verify that the reformatted XML file exists in the pretty directory
pretty_dir = os.path.join(
settings.DJANGO_LOGGING["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."

# Check the content of the generated pretty XML file
with open(formatted_file) as f:
content = f.read()
assert "<logs>" in content
assert "<entry>Test Entry</entry>" in content
assert "</logs>" in content

@override_settings(DJANGO_LOGGING={"LOG_DIR": "/non_existent_dir"})
def test_command_directory_not_found(self, settings: Any) -> None:
"""
Test that the command handles the case when the XML directory is missing.

This test checks that the command outputs an appropriate error message when the directory does not exist.

Args:
----
settings (django.conf.Settings): Django settings.
"""
out = StringIO()
call_command("generate_pretty_xml", stdout=out)

# Verify error output
assert "does not exist." in out.getvalue()
98 changes: 98 additions & 0 deletions django_logging/tests/commands/test_logs_size_audit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import sys
from io import StringIO
from unittest.mock import MagicMock, patch

import pytest
from django.core.management import call_command

from django_logging.tests.constants import PYTHON_VERSION, PYTHON_VERSION_REASON

pytestmark = [
pytest.mark.commands,
pytest.mark.commands_logs_size_audit,
pytest.mark.skipif(sys.version_info < PYTHON_VERSION, reason=PYTHON_VERSION_REASON),
]


class TestCheckLogSizeCommand:
"""
Test suite for the `check_log_size` management command.
"""

@patch("os.path.exists", return_value=True)
@patch("os.walk")
def test_command_log_directory_size_under_limit(
self, mock_os_walk: MagicMock, temp_log_directory: str
) -> None:
"""
Test that the command correctly handles the case when the log directory size is under the limit.

This test verifies that the command calculates the log directory size correctly and does not send
an email when the size is below the limit.

Args:
mock_os_walk (MagicMock): Mock for `os.walk`.
temp_log_directory (str): Temporary log directory fixture.
"""
# Mock the os.walk to return an empty directory
mock_os_walk.return_value = [(temp_log_directory, [], [])]

# Execute the command and capture the output
out = StringIO()
with patch("django.conf.settings.DJANGO_LOGGING", {"LOG_DIR_SIZE_LIMIT": 100}):
call_command("logs_size_audit", stdout=out)

assert "Log directory size is under the limit" in out.getvalue()

@patch("os.path.exists", return_value=True)
@patch("os.walk")
@patch("django_logging.management.commands.logs_size_audit.send_email_async")
def test_command_log_directory_size_exceeds_limit(
self,
mock_send_email: MagicMock,
mock_os_walk: MagicMock,
temp_log_directory: str,
) -> None:
"""
Test that the command sends a warning email when the log directory size exceeds the limit.

This test verifies that the command calculates the log directory size correctly and sends
an email notification when the size exceeds the limit.

Args:
----
mock_send_email (MagicMock): Mock for the `send_warning_email` method.
mock_os_walk (MagicMock): Mock for `os.walk`.
temp_log_directory (str): Temporary log directory fixture.
"""
# Mock the os.walk to simulate a large directory
mock_os_walk.return_value = [
(temp_log_directory, [], ["log1.txt", "log2.txt"]),
]
# Mock the file sizes to exceed the limit
with patch("os.path.getsize", side_effect=[60 * 1024 * 1024, 50 * 1024 * 1024]):
out = StringIO()
with patch("django.conf.settings.ADMIN_EMAIL", "[email protected]"):
with patch("django.conf.settings.DJANGO_LOGGING", {"LOG_DIR_SIZE_LIMIT": 100}):
call_command("logs_size_audit", stdout=out)

# Verify that the warning email was sent
mock_send_email.assert_called_once()
assert "Warning email sent successfully" in out.getvalue()

@patch("os.path.exists", return_value=False)
def test_command_log_directory_not_found(self, temp_log_directory: str) -> None:
"""
Test that the command handles the case where the log directory does not exist.

This test verifies that the command logs an error message and exits gracefully
when the log directory is missing.

Args:
----
temp_log_directory (str): Temporary log directory fixture.
"""
out = StringIO()
call_command("logs_size_audit", stdout=out)

assert "Log directory not found" in out.getvalue()
7 changes: 7 additions & 0 deletions django_logging/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
email_handler,
email_mock_settings,
error_log_record,
error_with_exc_log_record,
flat_formatter,
get_response,
json_formatter,
log_config,
log_manager,
magic_mock_logger,
Expand All @@ -17,6 +20,10 @@
request_factory,
request_middleware,
reset_settings,
temp_json_log_directory,
temp_log_directory,
temp_xml_log_directory,
xml_formatter,
)
from django_logging.tests.setup import configure_django_settings

Expand Down
Empty file.
Loading