Files
breakpilot-compliance/backend-compliance/compliance/tests/test_use_case_controls.py
T
Benjamin Admin 926dc02a09
CI / test-python-backend (push) Successful in 30s
CI / test-python-document-crawler (push) Has been skipped
CI / guardrail-integrity (push) Has been skipped
CI / test-python-dsms-gateway (push) Has been skipped
CI / secret-scan (push) Has been skipped
CI / dep-audit (push) Has been skipped
CI / sbom-scan (push) Has been skipped
CI / build-sha-integrity (push) Successful in 12s
CI / validate-canonical-controls (push) Successful in 12s
CI / loc-budget (push) Successful in 25s
CI / go-lint (push) Has been skipped
CI / detect-changes (push) Successful in 15s
CI / python-lint (push) Has been skipped
CI / nodejs-lint (push) Has been skipped
CI / branch-name (push) Has been skipped
CI / nodejs-build (push) Successful in 3m9s
CI / test-go (push) Has been skipped
CI / iace-gt-coverage (push) Has been skipped
feat(use-case-controls): relevant als Stufe statt Hard-Filter + Provenance
Der harte relevant=true-Filter versteckte ~25% des Korpus (40.926 Atome),
~70% davon echte Pflichten (500er-Validierung). relevant wird zur Stufe:

- Service: tier-Param (core=Default schuetzt Agent/CRA; all=alles inkl. review),
  ORDER BY relevant DESC; pro Control relevant/tier/source_type
  (own_library bei license_rule=3, sonst derived) + source_regulation/article;
  core_count/review_count. Pure Helper tier_label + source_type (+ Tests).
- Route: optionaler tier-Query (default core) — contract-safe (additiv).
- Frontend: Coverage-Drill-down /sdk/coverage/[useCase] — Kern-Pflichten vs.
  "zur fachlichen Pruefung", je mit Herkunfts-Badge; Uebersicht zeigt Delta.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 20:58:25 +02:00

74 lines
2.5 KiB
Python

"""Tests for the shared use-case → controls retrieval layer.
The SQL paths are verified e2e against the seeded DB; here we pin the pure,
deterministic ranking logic and the validation guard.
"""
import pytest
from compliance.domain import NotFoundError
from compliance.services.use_case_controls import (
UseCaseControlsService,
relevance_score,
source_type,
tier_label,
)
_NET_KW = ("firewall", "tls", "port", "segmentation", "network", "header")
def test_relevance_primary_only_baseline():
# primary flag alone (no confidence, no keyword hit) → 0.5
assert relevance_score("x", "y", _NET_KW, True, None) == 0.5
def test_relevance_non_primary_baseline_is_zero():
assert relevance_score("x", "y", _NET_KW, False, None) == 0.0
def test_relevance_confidence_contributes():
# non-primary, no keyword: 0.3 * confidence
assert relevance_score("x", "y", _NET_KW, False, 1.0) == 0.3
assert relevance_score("x", "y", _NET_KW, False, 0.5) == 0.15
def test_relevance_keyword_hits_are_capped_at_three():
# three+ distinct keyword hits saturate the content term at +0.2
title = "Firewall and TLS on every port and network segmentation header"
assert relevance_score(title, "", _NET_KW, False, None) == 0.2
def test_relevance_keyword_match_is_case_insensitive_over_title_and_objective():
score = relevance_score("FIREWALL", "tls config", _NET_KW, False, None)
# two hits → 2/3 * 0.2 ≈ 0.133
assert score == pytest.approx(0.133, abs=0.001)
def test_relevance_is_clamped_to_one():
title = "firewall tls port" # 3 hits → +0.2
assert relevance_score(title, "", _NET_KW, True, 1.0) == 1.0
def test_relevance_no_keyword_tokens_yields_zero_content_term():
assert relevance_score("anything", "here", (), True, 1.0) == 0.8
def test_controls_for_unknown_use_case_raises_not_found():
svc = UseCaseControlsService(db=None) # guard runs before any DB access
with pytest.raises(NotFoundError):
svc.controls_for_use_case("does_not_exist")
def test_tier_label_maps_relevance_to_soft_tier():
assert tier_label(True) == "core"
assert tier_label(False) == "review"
def test_source_type_own_library_vs_derived():
# license_rule 3 = self-written framework, no commercial source
assert source_type(3) == "own_library"
# license 1 (public domain/EU/NIST) and 2 (CC-BY) are derived from a document
assert source_type(1) == "derived"
assert source_type(2) == "derived"
assert source_type(None) == "derived"