v1.5.0: IRM — инциденты, задачи, эскалации
- docs/IRM.md; Alembic 002: incidents, tasks, escalation_policies - Модули incidents/tasks/escalations: API, UI, register_events(bus, pool) - Авто-инцидент из alert.received; тесты test_irm_modules.py Made-with: Cursor
This commit is contained in:
69
tests/test_irm_modules.py
Normal file
69
tests/test_irm_modules.py
Normal file
@ -0,0 +1,69 @@
|
||||
"""IRM-модули: API без БД и обработчик инцидента по событию."""
|
||||
|
||||
from unittest.mock import AsyncMock, MagicMock
|
||||
from uuid import uuid4
|
||||
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
from onguard24.domain.entities import Alert, Severity
|
||||
from onguard24.domain.events import AlertReceived
|
||||
|
||||
|
||||
def test_incidents_api_list_no_db(client: TestClient) -> None:
|
||||
r = client.get("/api/v1/modules/incidents/")
|
||||
assert r.status_code == 200
|
||||
assert r.json() == {"items": [], "database": "disabled"}
|
||||
|
||||
|
||||
def test_tasks_api_list_no_db(client: TestClient) -> None:
|
||||
r = client.get("/api/v1/modules/tasks/")
|
||||
assert r.status_code == 200
|
||||
assert r.json()["database"] == "disabled"
|
||||
|
||||
|
||||
def test_escalations_api_list_no_db(client: TestClient) -> None:
|
||||
r = client.get("/api/v1/modules/escalations/")
|
||||
assert r.status_code == 200
|
||||
assert r.json()["database"] == "disabled"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_incident_inserted_on_alert_received() -> None:
|
||||
"""При пуле БД подписка создаёт инцидент (INSERT)."""
|
||||
inserted: dict = {}
|
||||
|
||||
async def fake_execute(_query, *args):
|
||||
inserted["args"] = args
|
||||
return "INSERT 0 1"
|
||||
|
||||
mock_conn = AsyncMock()
|
||||
mock_conn.execute = fake_execute
|
||||
mock_cm = AsyncMock()
|
||||
mock_cm.__aenter__ = AsyncMock(return_value=mock_conn)
|
||||
mock_cm.__aexit__ = AsyncMock(return_value=None)
|
||||
mock_pool = MagicMock()
|
||||
mock_pool.acquire = MagicMock(return_value=mock_cm)
|
||||
|
||||
from onguard24.domain.events import InMemoryEventBus
|
||||
from onguard24.modules import incidents as inc_mod
|
||||
|
||||
bus = InMemoryEventBus()
|
||||
inc_mod.register_events(bus, mock_pool)
|
||||
|
||||
uid = uuid4()
|
||||
ev = AlertReceived(
|
||||
alert=Alert(source="grafana", title="CPU high", severity=Severity.WARNING),
|
||||
raw_payload_ref=uid,
|
||||
)
|
||||
await bus.publish(ev)
|
||||
|
||||
assert inserted.get("args") is not None
|
||||
assert inserted["args"][0] == "CPU high"
|
||||
assert inserted["args"][1] == "warning"
|
||||
assert inserted["args"][2] == uid
|
||||
|
||||
|
||||
def test_incidents_post_requires_db(client: TestClient) -> None:
|
||||
r = client.post("/api/v1/modules/incidents/", json={"title": "x"})
|
||||
assert r.status_code == 503
|
||||
@ -32,6 +32,9 @@ def test_rail_lists_all_registered_ui_modules(client: TestClient) -> None:
|
||||
assert r.status_code == 200
|
||||
t = r.text
|
||||
expected = (
|
||||
("incidents", "Инциденты"),
|
||||
("tasks", "Задачи"),
|
||||
("escalations", "Эскалации"),
|
||||
("schedules", "Календарь дежурств"),
|
||||
("contacts", "Контакты"),
|
||||
("statusboard", "Светофор"),
|
||||
@ -43,7 +46,14 @@ def test_rail_lists_all_registered_ui_modules(client: TestClient) -> None:
|
||||
|
||||
def test_each_module_page_single_active_nav_item(client: TestClient) -> None:
|
||||
"""На странице модуля ровно один пункт с aria-current (текущий раздел)."""
|
||||
for slug in ("schedules", "contacts", "statusboard"):
|
||||
for slug in (
|
||||
"incidents",
|
||||
"tasks",
|
||||
"escalations",
|
||||
"schedules",
|
||||
"contacts",
|
||||
"statusboard",
|
||||
):
|
||||
r = client.get(f"/ui/modules/{slug}/")
|
||||
assert r.status_code == 200
|
||||
assert r.text.count('aria-current="page"') == 1
|
||||
|
||||
Reference in New Issue
Block a user