Subagents delivered tests across all uncovered backend modules: Schemas (100%): agent, auth, health, profile, settings, validation Services (98-100%): auth, profile, health, llm, mapping, resource, security, git, superset_lookup, sql_table_extractor, rbac API routes (new): auth, admin, health, environments, plugins, dashboards (helpers, projection, actions, listing), git (config, deps, env, helpers) Clean Release (100%): DTO, facade, policy_engine, stages, repos, preparation, source_isolation, compliance Git services: base, remote_providers Agent module: app, run, middleware, langgraph_setup Core: trace, cleanup, ws_log_handler, timezone, auth (config/oauth/security), matching Reports: normalizer, report_service, type_profiles Notifications: service, providers Also: - .gitignore: add .coverage, *.cover, coverage-* dirs - src/schemas/auth.py: fix AD group DN regex (comma in CN=...) - Remove co-located src/services/__tests__/ (caused pytest module collision)
125 lines
4.6 KiB
Python
125 lines
4.6 KiB
Python
# #region Test.Schemas.Health [C:2] [TYPE Module] [SEMANTICS test,schema,health]
|
|
# @BRIEF Tests for schemas/health.py — DashboardHealthItem, HealthSummaryResponse.
|
|
# @RELATION BINDS_TO -> [HealthSchemas]
|
|
# @TEST_EDGE: missing_field -> optional fields default correctly
|
|
# @TEST_EDGE: invalid_type -> status pattern validation rejects bad values
|
|
# @TEST_EDGE: serialization -> round-trip via model_dump/model_validate
|
|
|
|
from datetime import datetime, timezone
|
|
import pytest
|
|
from pydantic import ValidationError
|
|
|
|
from src.schemas.health import DashboardHealthItem, HealthSummaryResponse
|
|
|
|
|
|
class TestDashboardHealthItem:
|
|
"""DashboardHealthItem — health status for a single dashboard."""
|
|
|
|
def make_item(self, **overrides):
|
|
ts = datetime.now(timezone.utc)
|
|
defaults = dict(
|
|
dashboard_id="42",
|
|
environment_id="env-1",
|
|
status="PASS",
|
|
last_check=ts,
|
|
)
|
|
defaults.update(overrides)
|
|
return DashboardHealthItem(**defaults)
|
|
|
|
def test_minimal(self):
|
|
item = self.make_item()
|
|
assert item.dashboard_id == "42"
|
|
assert item.environment_id == "env-1"
|
|
assert item.status == "PASS"
|
|
assert item.record_id is None
|
|
assert item.dashboard_slug is None
|
|
assert item.task_id is None
|
|
assert item.run_id is None
|
|
assert item.execution_path is None
|
|
assert item.issues_count == 0
|
|
assert item.timings is None
|
|
assert item.token_usage is None
|
|
assert item.screenshot_paths is None
|
|
assert item.chunk_count is None
|
|
assert item.dashboard_name is None
|
|
|
|
@pytest.mark.parametrize("status", ["PASS", "WARN", "FAIL", "UNKNOWN"])
|
|
def test_valid_status_values(self, status):
|
|
item = self.make_item(status=status)
|
|
assert item.status == status
|
|
|
|
def test_invalid_status_raises(self):
|
|
with pytest.raises(ValidationError, match="pattern"):
|
|
self.make_item(status="INVALID")
|
|
|
|
def test_lowercase_status_raises(self):
|
|
with pytest.raises(ValidationError):
|
|
self.make_item(status="pass")
|
|
|
|
def test_with_all_v2_fields(self):
|
|
ts = datetime.now(timezone.utc)
|
|
item = DashboardHealthItem(
|
|
record_id="rec-1",
|
|
dashboard_id="42",
|
|
environment_id="env-1",
|
|
status="WARN",
|
|
last_check=ts,
|
|
task_id="task-1",
|
|
run_id="run-1",
|
|
policy_id="pol-1",
|
|
summary="Some warnings",
|
|
execution_path="screenshot",
|
|
issues_count=3,
|
|
timings={"total": 12.5},
|
|
token_usage={"prompt": 100},
|
|
screenshot_paths=["/screens/1.png"],
|
|
chunk_count=4,
|
|
dashboard_name="Sales Dashboard",
|
|
)
|
|
assert item.record_id == "rec-1"
|
|
assert item.execution_path == "screenshot"
|
|
assert item.issues_count == 3
|
|
assert item.chunk_count == 4
|
|
|
|
def test_serialize_roundtrip(self):
|
|
item = self.make_item()
|
|
data = item.model_dump()
|
|
restored = DashboardHealthItem.model_validate(data)
|
|
assert restored.dashboard_id == "42"
|
|
assert restored.status == "PASS"
|
|
|
|
def test_timings_token_usage_optional(self):
|
|
item = self.make_item(timings={"db": 1.0}, token_usage={"total": 50})
|
|
assert item.timings == {"db": 1.0}
|
|
assert item.token_usage == {"total": 50}
|
|
|
|
|
|
class TestHealthSummaryResponse:
|
|
"""HealthSummaryResponse — aggregated health summary."""
|
|
|
|
def test_empty(self):
|
|
resp = HealthSummaryResponse(items=[], pass_count=0, warn_count=0, fail_count=0, unknown_count=0)
|
|
assert resp.items == []
|
|
assert resp.pass_count == 0
|
|
|
|
def test_with_items(self):
|
|
ts = datetime.now(timezone.utc)
|
|
items = [
|
|
DashboardHealthItem(dashboard_id="1", environment_id="e1", status="PASS", last_check=ts),
|
|
DashboardHealthItem(dashboard_id="2", environment_id="e1", status="FAIL", last_check=ts),
|
|
]
|
|
resp = HealthSummaryResponse(items=items, pass_count=1, warn_count=0, fail_count=1, unknown_count=0)
|
|
assert len(resp.items) == 2
|
|
assert resp.pass_count == 1
|
|
assert resp.fail_count == 1
|
|
|
|
def test_serialize_roundtrip(self):
|
|
ts = datetime.now(timezone.utc)
|
|
items = [DashboardHealthItem(dashboard_id="1", environment_id="e1", status="PASS", last_check=ts)]
|
|
resp = HealthSummaryResponse(items=items, pass_count=1, warn_count=0, fail_count=0, unknown_count=0)
|
|
data = resp.model_dump()
|
|
restored = HealthSummaryResponse.model_validate(data)
|
|
assert restored.pass_count == 1
|
|
assert len(restored.items) == 1
|
|
# #endregion Test.Schemas.Health
|