Files
ss-tools/backend/tests/services/clean_release/test_policy_engine.py
busya f75c15dbc6 test: massive coverage expansion — 15 new test modules + assistant tool fixes + orthogonal testing
- 10 translate plugin test files (100% coverage on 12 modules)
- assistant/handler tools: 85+ tests covering dispatch, registry, resolvers, routes, llm_planner, 13 tool handlers
- clean release: artifact_catalog_loader, mappers, approval, publication tests
- API routes: translate_helpers, validation_service extensions, datasets to 100%
- notifications: providers/service tests
- services: profile_preference_service
- docs/orthogonal-test-report.md — full speckit.tests audit
- Fixes: 3 git_base async mock failures, 4 assistant handler permission-check patches
- .gitignore: coverage artifacts
2026-06-15 15:38:59 +03:00

326 lines
14 KiB
Python

# #region Test.CleanRelease.PolicyEngine [C:3] [TYPE Module] [SEMANTICS test,clean-release,policy,validation,classification]
# @BRIEF Tests for CleanPolicyEngine — validate_policy, classify_artifact, validate_resource_source, evaluate_candidate.
# @RELATION BINDS_TO -> [PolicyEngine]
import pytest
from unittest.mock import MagicMock
from datetime import UTC, datetime
from src.models.clean_release import CleanPolicySnapshot, ResourceSourceEntry, ResourceSourceRegistry, SourceRegistrySnapshot
from src.services.clean_release.policy_engine import CleanPolicyEngine, PolicyValidationResult, SourceValidationResult
def _make_policy(**overrides) -> CleanPolicySnapshot:
"""Create a clean policy snapshot with defaults."""
params = {
"id": "policy-1",
"policy_id": "policy-1",
"policy_version": "1.0",
"content_json": {
"profile": "enterprise-clean",
"prohibited_artifact_categories": ["malware", "proprietary"],
"required_system_categories": ["system-lib"],
"external_source_forbidden": True,
},
"registry_snapshot_id": "registry-1",
"immutable": True,
}
params.update(overrides)
return CleanPolicySnapshot(**params)
def _make_registry(**overrides) -> SourceRegistrySnapshot:
"""Create a source registry snapshot with defaults."""
params = {
"id": "registry-1",
"registry_id": "registry-1",
"registry_version": "1.0",
"allowed_hosts": ["repo.internal.local", "artifacts.internal.local"],
"immutable": True,
}
params.update(overrides)
return SourceRegistrySnapshot(**params)
def _make_resource_registry(hosts: list[str] | None = None) -> ResourceSourceRegistry:
"""Create a ResourceSourceRegistry with entries."""
if hosts is None:
hosts = ["internal.local", "repo.internal.local"]
now = datetime.now(UTC)
entries = [
ResourceSourceEntry(source_id=f"src-{i}", host=h, protocol="https", purpose="internal", enabled=True)
for i, h in enumerate(hosts)
]
return ResourceSourceRegistry(
registry_id="reg-res-1", name="Test Resource Registry", entries=entries,
updated_at=now, updated_by="system",
)
class TestValidatePolicy:
"""CleanPolicyEngine.validate_policy — policy consistency validation."""
# #region test_validate_policy_ok [C:2] [TYPE Function]
def test_validate_policy_ok(self):
"""Valid enterprise-clean policy → ok=True."""
policy = _make_policy()
registry = _make_registry()
engine = CleanPolicyEngine(policy=policy, registry=registry)
result = engine.validate_policy()
assert result.ok is True
assert result.blocking_reasons == []
# #endregion test_validate_policy_ok
# #region test_validate_missing_registry_ref [C:2] [TYPE Function]
def test_validate_missing_registry_ref(self):
"""Missing registry_snapshot_id → reason added."""
policy = _make_policy(registry_snapshot_id="")
registry = _make_registry()
engine = CleanPolicyEngine(policy=policy, registry=registry)
result = engine.validate_policy()
assert result.ok is False
assert any("registry" in r.lower() for r in result.blocking_reasons)
# #endregion test_validate_missing_registry_ref
# #region test_validate_missing_prohibited [C:2] [TYPE Function]
def test_validate_missing_prohibited(self):
"""Enterprise policy without prohibited categories → reason added."""
policy = _make_policy(content_json={"profile": "enterprise-clean"})
registry = _make_registry()
engine = CleanPolicyEngine(policy=policy, registry=registry)
result = engine.validate_policy()
assert any("prohibited" in r.lower() for r in result.blocking_reasons)
# #endregion test_validate_missing_prohibited
# #region test_validate_missing_external_forbidden [C:2] [TYPE Function]
def test_validate_missing_external_forbidden(self):
"""Enterprise policy without external_source_forbidden → reason added."""
policy = _make_policy(content_json={
"profile": "enterprise-clean",
"prohibited_artifact_categories": ["malware"],
})
registry = _make_registry()
engine = CleanPolicyEngine(policy=policy, registry=registry)
result = engine.validate_policy()
assert any("external" in r.lower() for r in result.blocking_reasons)
# #endregion test_validate_missing_external_forbidden
# #region test_validate_registry_ref_mismatch [C:2] [TYPE Function]
def test_validate_registry_ref_mismatch(self):
"""Registry ref mismatch → reason added."""
policy = _make_policy(registry_snapshot_id="reg-other")
registry = _make_registry(id="registry-1")
engine = CleanPolicyEngine(policy=policy, registry=registry)
result = engine.validate_policy()
assert any("mismatch" in r.lower() or "ref" in r.lower() for r in result.blocking_reasons)
# #endregion test_validate_registry_ref_mismatch
# #region test_validate_empty_allowed_hosts [C:2] [TYPE Function]
def test_validate_empty_allowed_hosts(self):
"""Registry with no allowed hosts → reason added."""
policy = _make_policy()
registry = _make_registry(allowed_hosts=[])
engine = CleanPolicyEngine(policy=policy, registry=registry)
result = engine.validate_policy()
assert any("host" in r.lower() for r in result.blocking_reasons)
# #endregion test_validate_empty_allowed_hosts
# #region test_validate_standard_profile_no_prohibited_check [C:2] [TYPE Function]
def test_validate_standard_profile_no_prohibited_check(self):
"""Standard profile doesn't require prohibited categories."""
policy = _make_policy(content_json={"profile": "standard"})
registry = _make_registry()
engine = CleanPolicyEngine(policy=policy, registry=registry)
result = engine.validate_policy()
assert not any("prohibited" in r.lower() for r in result.blocking_reasons)
# #endregion test_validate_standard_profile_no_prohibited_check
class TestClassifyArtifact:
"""CleanPolicyEngine.classify_artifact — artifact classification."""
# #region test_classify_required_system [C:2] [TYPE Function]
def test_classify_required_system(self):
"""Required system category → required-system."""
policy = _make_policy()
registry = _make_registry()
engine = CleanPolicyEngine(policy=policy, registry=registry)
result = engine.classify_artifact({"category": "system-lib"})
assert result == "required-system"
# #endregion test_classify_required_system
# #region test_classify_prohibited [C:2] [TYPE Function]
def test_classify_prohibited(self):
"""Prohibited category → excluded-prohibited."""
policy = _make_policy()
registry = _make_registry()
engine = CleanPolicyEngine(policy=policy, registry=registry)
result = engine.classify_artifact({"category": "malware"})
assert result == "excluded-prohibited"
# #endregion test_classify_prohibited
# #region test_classify_allowed [C:2] [TYPE Function]
def test_classify_allowed(self):
"""Unlisted category → allowed."""
policy = _make_policy()
registry = _make_registry()
engine = CleanPolicyEngine(policy=policy, registry=registry)
result = engine.classify_artifact({"category": "documentation"})
assert result == "allowed"
# #endregion test_classify_allowed
# #region test_classify_empty_category [C:2] [TYPE Function]
def test_classify_empty_category(self):
"""Empty category → allowed."""
policy = _make_policy()
registry = _make_registry()
engine = CleanPolicyEngine(policy=policy, registry=registry)
result = engine.classify_artifact({"category": ""})
assert result == "allowed"
# #endregion test_classify_empty_category
# #region test_classify_from_legacy_policy [C:2] [TYPE Function]
def test_classify_from_legacy_policy(self):
"""Policy without content_json but with direct attributes → works."""
policy = _make_policy(content_json={})
policy.prohibited_artifact_categories = ["bad"]
policy.required_system_categories = ["core"]
registry = _make_registry()
engine = CleanPolicyEngine(policy=policy, registry=registry)
assert engine.classify_artifact({"category": "bad"}) == "excluded-prohibited"
assert engine.classify_artifact({"category": "core"}) == "required-system"
assert engine.classify_artifact({"category": "other"}) == "allowed"
# #endregion test_classify_from_legacy_policy
class TestValidateResourceSource:
"""CleanPolicyEngine.validate_resource_source — source endpoint validation."""
# #region test_empty_endpoint [C:2] [TYPE Function]
def test_empty_endpoint(self):
"""Empty endpoint → violation with blocked_release=True."""
policy = _make_policy()
registry = _make_registry()
engine = CleanPolicyEngine(policy=policy, registry=registry)
result = engine.validate_resource_source("")
assert result.ok is False
assert result.violation is not None
assert result.violation["blocked_release"] is True
# #endregion test_empty_endpoint
# #region test_endpoint_in_allowlist [C:2] [TYPE Function]
def test_endpoint_in_allowlist(self):
"""Endpoint in allowed_hosts → ok=True."""
policy = _make_policy()
registry = _make_registry()
engine = CleanPolicyEngine(policy=policy, registry=registry)
result = engine.validate_resource_source("repo.internal.local")
assert result.ok is True
assert result.violation is None
# #endregion test_endpoint_in_allowlist
# #region test_endpoint_not_in_allowlist [C:2] [TYPE Function]
def test_endpoint_not_in_allowlist(self):
"""Endpoint outside allowlist → violation."""
policy = _make_policy()
registry = _make_registry()
engine = CleanPolicyEngine(policy=policy, registry=registry)
result = engine.validate_resource_source("external.bad.com")
assert result.ok is False
assert result.violation["location"] == "external.bad.com"
# #endregion test_endpoint_not_in_allowlist
# #region test_endpoint_case_insensitive_matching [C:2] [TYPE Function]
def test_endpoint_case_insensitive_matching(self):
"""Endpoint matching is case-insensitive — endpoint is lowered before comparison."""
policy = _make_policy()
registry = _make_registry(allowed_hosts=["repo.internal.local"])
engine = CleanPolicyEngine(policy=policy, registry=registry)
# Different case → still found because endpoint is lowered
result = engine.validate_resource_source("REPO.INTERNAL.LOCAL")
assert result.ok is True
# Exact case → also found
result = engine.validate_resource_source("repo.internal.local")
assert result.ok is True
# #endregion test_endpoint_case_insensitive_matching
# #region test_registry_with_resource_source [C:2] [TYPE Function]
def test_registry_with_resource_source(self):
"""Using ResourceSourceRegistry instead of SourceRegistrySnapshot."""
registry = _make_resource_registry(hosts=["internal.local"])
policy = _make_policy()
engine = CleanPolicyEngine(policy=policy, registry=registry)
result = engine.validate_resource_source("internal.local")
assert result.ok is True
# #endregion test_registry_with_resource_source
class TestEvaluateCandidate:
"""CleanPolicyEngine.evaluate_candidate — full candidate evaluation."""
# #region test_evaluate_candidate_clean [C:2] [TYPE Function]
def test_evaluate_candidate_clean(self):
"""Clean candidate with valid sources → no violations."""
policy = _make_policy()
registry = _make_registry()
engine = CleanPolicyEngine(policy=policy, registry=registry)
artifacts = [
{"path": "lib/core.so", "category": "system-lib"},
{"path": "doc/readme.md", "category": "documentation"},
]
sources = ["repo.internal.local"]
classified, violations = engine.evaluate_candidate(artifacts, sources)
assert len(classified) == 2
assert len(violations) == 0
assert classified[0]["classification"] == "required-system"
assert classified[1]["classification"] == "allowed"
# #endregion test_evaluate_candidate_clean
# #region test_evaluate_candidate_with_violations [C:2] [TYPE Function]
def test_evaluate_candidate_with_violations(self):
"""Candidate with prohibited artifacts and bad sources → violations."""
policy = _make_policy()
registry = _make_registry()
engine = CleanPolicyEngine(policy=policy, registry=registry)
artifacts = [
{"path": "lib/malware.exe", "category": "malware"},
{"path": "lib/ok.so", "category": "system-lib"},
]
sources = ["repo.internal.local", "external.bad.com"]
classified, violations = engine.evaluate_candidate(artifacts, sources)
assert len(classified) == 2
assert len(violations) >= 1
assert violations[0]["category"] == "data-purity"
# #endregion test_evaluate_candidate_with_violations
# #region test_evaluate_candidate_empty [C:2] [TYPE Function]
def test_evaluate_candidate_empty(self):
"""Empty artifacts and sources → no violations."""
policy = _make_policy()
registry = _make_registry()
engine = CleanPolicyEngine(policy=policy, registry=registry)
classified, violations = engine.evaluate_candidate([], [])
assert classified == []
assert violations == []
# #endregion test_evaluate_candidate_empty
class TestPolicyValidationResult:
"""PolicyValidationResult and SourceValidationResult dataclasses."""
# #region test_policy_validation_result [C:2] [TYPE Function]
def test_policy_validation_result(self):
"""PolicyValidationResult dataclass."""
r = PolicyValidationResult(ok=True, blocking_reasons=[])
assert r.ok is True
assert r.blocking_reasons == []
# #endregion test_policy_validation_result
# #region test_source_validation_result [C:2] [TYPE Function]
def test_source_validation_result(self):
"""SourceValidationResult dataclass."""
r = SourceValidationResult(ok=False, violation={"code": "EXT"})
assert r.ok is False
assert r.violation["code"] == "EXT"
# #endregion test_source_validation_result