feat(scoring): composite recency decay and severity weights persisted in DB [FASE-5.1]
This commit is contained in:
102
backend/tests/test_phase5_snapshots.py
Normal file
102
backend/tests/test_phase5_snapshots.py
Normal file
@@ -0,0 +1,102 @@
|
||||
"""Tests for Phase 5 snapshot evolution and breakdown fields."""
|
||||
|
||||
from datetime import datetime, timedelta, timezone
|
||||
|
||||
from app.models.coverage_snapshot import CoverageSnapshot
|
||||
from app.models.enums import TechniqueStatus
|
||||
from app.models.technique import Technique
|
||||
from app.services.snapshot_service import create_snapshot, get_coverage_evolution
|
||||
|
||||
|
||||
def test_create_snapshot_includes_tactic_breakdown(db, admin_user):
|
||||
tech = Technique(
|
||||
mitre_id="T1059",
|
||||
name="Command and Scripting Interpreter",
|
||||
tactic="execution",
|
||||
status_global=TechniqueStatus.validated,
|
||||
)
|
||||
db.add(tech)
|
||||
db.commit()
|
||||
|
||||
snap = create_snapshot(db, name="Phase5 test", user_id=admin_user.id)
|
||||
|
||||
assert snap.by_tactic
|
||||
assert "execution" in snap.by_tactic
|
||||
assert snap.by_status
|
||||
assert snap.coverage_percentage >= 0
|
||||
assert snap.never_tested_count >= 0
|
||||
|
||||
|
||||
def test_coverage_evolution_filters_by_months(db, admin_user):
|
||||
now = datetime.now(timezone.utc)
|
||||
old = CoverageSnapshot(
|
||||
name="old",
|
||||
organization_score=50.0,
|
||||
total_techniques=10,
|
||||
validated_count=5,
|
||||
partial_count=1,
|
||||
not_covered_count=1,
|
||||
in_progress_count=1,
|
||||
not_evaluated_count=2,
|
||||
coverage_percentage=50.0,
|
||||
by_tactic={"execution": {"total": 10, "validated": 5}},
|
||||
by_status={"validated": 5},
|
||||
stale_count=0,
|
||||
never_tested_count=2,
|
||||
created_by=admin_user.id,
|
||||
)
|
||||
old.created_at = now - timedelta(days=400)
|
||||
recent = CoverageSnapshot(
|
||||
name="recent",
|
||||
organization_score=70.0,
|
||||
total_techniques=10,
|
||||
validated_count=7,
|
||||
partial_count=1,
|
||||
not_covered_count=0,
|
||||
in_progress_count=1,
|
||||
not_evaluated_count=1,
|
||||
coverage_percentage=70.0,
|
||||
by_tactic={"execution": {"total": 10, "validated": 7}},
|
||||
by_status={"validated": 7},
|
||||
stale_count=1,
|
||||
never_tested_count=1,
|
||||
created_by=admin_user.id,
|
||||
)
|
||||
db.add_all([old, recent])
|
||||
db.commit()
|
||||
|
||||
evolution = get_coverage_evolution(db, months=6)
|
||||
assert len(evolution) == 1
|
||||
assert evolution[0]["org_score"] == 70.0
|
||||
assert evolution[0]["coverage_pct"] == 70.0
|
||||
assert evolution[0]["stale_count"] == 1
|
||||
|
||||
|
||||
def test_evolution_endpoint(client, db, admin_user, admin_token):
|
||||
snap = CoverageSnapshot(
|
||||
name="api-evolution",
|
||||
organization_score=60.0,
|
||||
total_techniques=5,
|
||||
validated_count=3,
|
||||
partial_count=0,
|
||||
not_covered_count=0,
|
||||
in_progress_count=0,
|
||||
not_evaluated_count=2,
|
||||
coverage_percentage=60.0,
|
||||
by_tactic={},
|
||||
by_status={"validated": 3},
|
||||
stale_count=0,
|
||||
never_tested_count=2,
|
||||
)
|
||||
db.add(snap)
|
||||
db.commit()
|
||||
|
||||
response = client.get(
|
||||
"/api/v1/snapshots/evolution?months=12",
|
||||
headers={"Authorization": f"Bearer {admin_token}"},
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert isinstance(data, list)
|
||||
assert len(data) >= 1
|
||||
assert "org_score" in data[0]
|
||||
Reference in New Issue
Block a user