Refactor map color threshold storage into dedicated settings service

This commit is contained in:
2026-04-17 15:13:07 +02:00
parent 13b3fde274
commit c21cf82e9e
11 changed files with 467 additions and 349 deletions

View File

@@ -2,6 +2,7 @@
from __future__ import annotations
from contextlib import ExitStack
from pathlib import Path
from typing import Any
from unittest.mock import AsyncMock, patch
@@ -15,7 +16,7 @@ from app.models.config import (
LogPreviewRequest,
RegexTestRequest,
)
from app.services import config_service
from app.services import config_service, health_service, log_service
from app.services.config_service import (
ConfigValidationError,
JailNotFoundError,
@@ -650,7 +651,10 @@ class TestReadFail2BanLog:
def __init__(self, **_kw: Any) -> None:
self.send = AsyncMock(side_effect=_send)
return patch("app.services.config_service.Fail2BanClient", _FakeClient)
stack = ExitStack()
stack.enter_context(patch("app.services.config_service.Fail2BanClient", _FakeClient))
stack.enter_context(patch("app.services.log_service.Fail2BanClient", _FakeClient))
return stack
async def test_returns_log_lines_from_file(self, tmp_path: Any) -> None:
"""read_fail2ban_log returns lines from the file and counts totals."""
@@ -660,8 +664,8 @@ class TestReadFail2BanLog:
# Patch _SAFE_LOG_PREFIXES to allow tmp_path
with self._patch_client(log_target=str(log_file)), \
patch("app.services.config_service._SAFE_LOG_PREFIXES", (log_dir,)):
result = await config_service.read_fail2ban_log(_SOCKET, 200)
patch("app.services.log_service._SAFE_LOG_PREFIXES", (log_dir,)):
result = await log_service.read_fail2ban_log(_SOCKET, 200)
assert result.log_path == str(log_file.resolve())
assert result.total_lines >= 3
@@ -675,8 +679,8 @@ class TestReadFail2BanLog:
log_dir = str(tmp_path)
with self._patch_client(log_target=str(log_file)), \
patch("app.services.config_service._SAFE_LOG_PREFIXES", (log_dir,)):
result = await config_service.read_fail2ban_log(_SOCKET, 200, "Found")
patch("app.services.log_service._SAFE_LOG_PREFIXES", (log_dir,)):
result = await log_service.read_fail2ban_log(_SOCKET, 200, "Found")
assert all("Found" in ln for ln in result.lines)
assert result.total_lines >= 3 # total is unfiltered
@@ -685,13 +689,13 @@ class TestReadFail2BanLog:
"""read_fail2ban_log raises ConfigOperationError for STDOUT target."""
with self._patch_client(log_target="STDOUT"), \
pytest.raises(config_service.ConfigOperationError, match="STDOUT"):
await config_service.read_fail2ban_log(_SOCKET, 200)
await log_service.read_fail2ban_log(_SOCKET, 200)
async def test_syslog_target_raises_operation_error(self) -> None:
"""read_fail2ban_log raises ConfigOperationError for SYSLOG target."""
with self._patch_client(log_target="SYSLOG"), \
pytest.raises(config_service.ConfigOperationError, match="SYSLOG"):
await config_service.read_fail2ban_log(_SOCKET, 200)
await log_service.read_fail2ban_log(_SOCKET, 200)
async def test_path_outside_safe_dir_raises_operation_error(self, tmp_path: Any) -> None:
"""read_fail2ban_log rejects a log_target outside allowed directories."""
@@ -700,9 +704,9 @@ class TestReadFail2BanLog:
# Allow only /var/log — tmp_path is deliberately not in the safe list.
with self._patch_client(log_target=str(log_file)), \
patch("app.services.config_service._SAFE_LOG_PREFIXES", ("/var/log",)), \
patch("app.services.log_service._SAFE_LOG_PREFIXES", ("/var/log",)), \
pytest.raises(config_service.ConfigOperationError, match="outside the allowed"):
await config_service.read_fail2ban_log(_SOCKET, 200)
await log_service.read_fail2ban_log(_SOCKET, 200)
async def test_missing_log_file_raises_operation_error(self, tmp_path: Any) -> None:
"""read_fail2ban_log raises ConfigOperationError when the file does not exist."""
@@ -710,9 +714,9 @@ class TestReadFail2BanLog:
log_dir = str(tmp_path)
with self._patch_client(log_target=missing), \
patch("app.services.config_service._SAFE_LOG_PREFIXES", (log_dir,)), \
patch("app.services.log_service._SAFE_LOG_PREFIXES", (log_dir,)), \
pytest.raises(config_service.ConfigOperationError, match="not found"):
await config_service.read_fail2ban_log(_SOCKET, 200)
await log_service.read_fail2ban_log(_SOCKET, 200)
# ---------------------------------------------------------------------------
@@ -743,8 +747,8 @@ class TestGetServiceStatus:
def __init__(self, **_kw: Any) -> None:
self.send = AsyncMock(side_effect=_send)
with patch("app.services.config_service.Fail2BanClient", _FakeClient):
result = await config_service.get_service_status(
with patch("app.services.health_service.Fail2BanClient", _FakeClient):
result = await health_service.get_service_status(
_SOCKET,
probe_fn=AsyncMock(return_value=online_status),
)
@@ -765,7 +769,7 @@ class TestGetServiceStatus:
offline_status = ServerStatus(online=False)
result = await config_service.get_service_status(
result = await health_service.get_service_status(
_SOCKET,
probe_fn=AsyncMock(return_value=offline_status),
)