161 lines
6.0 KiB
Python
161 lines
6.0 KiB
Python
# #region Test.CleanRelease.AuditService [C:3] [TYPE Module] [SEMANTICS test,clean-release,audit]
|
|
# @BRIEF Tests for audit_service.py — audit_preparation, audit_check_run, audit_violation, audit_report.
|
|
# @RELATION BINDS_TO -> [AuditService]
|
|
|
|
from pathlib import Path
|
|
import sys
|
|
|
|
sys.path.insert(0, str(Path(__file__).parent.parent.parent.parent / "src"))
|
|
|
|
from unittest.mock import MagicMock, patch
|
|
import pytest
|
|
|
|
|
|
# #region TestAuditPreparation [C:2] [TYPE Module]
|
|
class TestAuditPreparation:
|
|
def test_audit_preparation_logs_and_appends(self):
|
|
from src.services.clean_release.audit_service import audit_preparation
|
|
repo = MagicMock()
|
|
repo.append_audit_event = MagicMock()
|
|
|
|
with patch("src.services.clean_release.audit_service.logger") as mock_logger:
|
|
audit_preparation(
|
|
candidate_id="cand-1",
|
|
status="PREPARED",
|
|
repository=repo,
|
|
actor="tester",
|
|
)
|
|
mock_logger.reason.assert_called_once()
|
|
repo.append_audit_event.assert_called_once()
|
|
event = repo.append_audit_event.call_args[0][0]
|
|
assert event["action"] == "PREPARATION"
|
|
assert event["candidate_id"] == "cand-1"
|
|
assert event["actor"] == "tester"
|
|
assert event["status"] == "PREPARED"
|
|
|
|
def test_audit_preparation_no_repo(self):
|
|
from src.services.clean_release.audit_service import audit_preparation
|
|
with patch("src.services.clean_release.audit_service.logger") as mock_logger:
|
|
audit_preparation(candidate_id="cand-2", status="FAILED")
|
|
mock_logger.reason.assert_called_once()
|
|
|
|
|
|
# #endregion TestAuditPreparation
|
|
|
|
|
|
# #region TestAuditCheckRun [C:2] [TYPE Module]
|
|
class TestAuditCheckRun:
|
|
def test_audit_check_run_logs_and_appends(self):
|
|
from src.services.clean_release.audit_service import audit_check_run
|
|
repo = MagicMock()
|
|
repo.append_audit_event = MagicMock()
|
|
|
|
with patch("src.services.clean_release.audit_service.logger") as mock_logger:
|
|
audit_check_run(
|
|
check_run_id="run-1",
|
|
final_status="COMPLIANT",
|
|
repository=repo,
|
|
candidate_id="cand-1",
|
|
actor="admin",
|
|
)
|
|
mock_logger.reflect.assert_called_once()
|
|
repo.append_audit_event.assert_called_once()
|
|
event = repo.append_audit_event.call_args[0][0]
|
|
assert event["action"] == "CHECK_RUN"
|
|
assert event["run_id"] == "run-1"
|
|
assert event["candidate_id"] == "cand-1"
|
|
|
|
def test_audit_check_run_no_candidate(self):
|
|
from src.services.clean_release.audit_service import audit_check_run
|
|
repo = MagicMock()
|
|
repo.append_audit_event = MagicMock()
|
|
|
|
with patch("src.services.clean_release.audit_service.logger") as mock_logger:
|
|
audit_check_run(
|
|
check_run_id="run-2",
|
|
final_status="BLOCKED",
|
|
repository=repo,
|
|
)
|
|
repo.append_audit_event.assert_called_once()
|
|
event = repo.append_audit_event.call_args[0][0]
|
|
assert event["candidate_id"] is None
|
|
|
|
|
|
# #endregion TestAuditCheckRun
|
|
|
|
|
|
# #region TestAuditViolation [C:2] [TYPE Module]
|
|
class TestAuditViolation:
|
|
def test_audit_violation_logs_explore(self):
|
|
"""Cover audit_violation lines 79-82."""
|
|
from src.services.clean_release.audit_service import audit_violation
|
|
repo = MagicMock()
|
|
repo.append_audit_event = MagicMock()
|
|
|
|
with patch("src.services.clean_release.audit_service.logger") as mock_logger:
|
|
audit_violation(
|
|
run_id="run-1",
|
|
stage_name="DATA_PURITY",
|
|
code="POL001",
|
|
repository=repo,
|
|
candidate_id="cand-1",
|
|
actor="tester",
|
|
)
|
|
mock_logger.explore.assert_called_once()
|
|
repo.append_audit_event.assert_called_once()
|
|
event = repo.append_audit_event.call_args[0][0]
|
|
assert event["action"] == "VIOLATION"
|
|
assert event["run_id"] == "run-1"
|
|
assert event["stage_name"] == "DATA_PURITY"
|
|
assert event["code"] == "POL001"
|
|
|
|
def test_audit_violation_no_repo(self):
|
|
"""audit_violation without repository does not crash."""
|
|
from src.services.clean_release.audit_service import audit_violation
|
|
with patch("src.services.clean_release.audit_service.logger") as mock_logger:
|
|
audit_violation(
|
|
run_id="run-2",
|
|
stage_name="SOURCE_ISOLATION",
|
|
code="EXT001",
|
|
)
|
|
mock_logger.explore.assert_called_once()
|
|
|
|
|
|
# #endregion TestAuditViolation
|
|
|
|
|
|
# #region TestAuditReport [C:2] [TYPE Module]
|
|
class TestAuditReport:
|
|
def test_audit_report_logs_and_appends(self):
|
|
from src.services.clean_release.audit_service import audit_report
|
|
repo = MagicMock()
|
|
repo.append_audit_event = MagicMock()
|
|
|
|
with patch("src.services.clean_release.audit_service.logger") as mock_logger:
|
|
audit_report(
|
|
report_id="report-1",
|
|
candidate_id="cand-1",
|
|
repository=repo,
|
|
run_id="run-1",
|
|
actor="tester",
|
|
)
|
|
mock_logger.explore.assert_called_once()
|
|
repo.append_audit_event.assert_called_once()
|
|
event = repo.append_audit_event.call_args[0][0]
|
|
assert event["action"] == "REPORT"
|
|
assert event["report_id"] == "report-1"
|
|
|
|
def test_audit_report_no_repo_does_not_crash(self):
|
|
from src.services.clean_release.audit_service import audit_report
|
|
with patch("src.services.clean_release.audit_service.logger") as mock_logger:
|
|
audit_report(
|
|
report_id="report-2",
|
|
candidate_id="cand-2",
|
|
)
|
|
mock_logger.explore.assert_called_once()
|
|
|
|
|
|
# #endregion TestAuditReport
|
|
|
|
# #endregion Test.CleanRelease.AuditService
|