stage-14: pytest test suite over the worker lines
38 tests covering the pure worker-line logic: Classifyline rules, Routeline TLP/country/incident-type gates, Sealine seal/unseal round-trip, Proofline confidence scoring, Mapline CVEResolver escalation, Trainline dataset well-posedness (the v1/v3 input-signal bugs are now regression-guarded), and the Scoutline feed parsers. pytest added as a dev extra. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
59
tests/test_classify.py
Normal file
59
tests/test_classify.py
Normal file
@@ -0,0 +1,59 @@
|
||||
"""Classifyline rule tests."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from psyc.lines.classify import classify
|
||||
from psyc.models import IncidentType, InternalClass, Severity, TLP
|
||||
from conftest import make_case
|
||||
|
||||
|
||||
def test_urlhaus_feed_is_malware():
|
||||
case = classify(make_case(feed="urlhaus", urls=["http://1.2.3.4/x"]))
|
||||
assert case.classification.incident_type is IncidentType.MALWARE
|
||||
assert case.classification.tlp is TLP.GREEN
|
||||
|
||||
|
||||
def test_cisa_kev_feed_is_exploit():
|
||||
case = classify(make_case(feed="cisa-kev", cves=["CVE-2026-0001"]))
|
||||
assert case.classification.incident_type is IncidentType.EXPLOIT
|
||||
|
||||
|
||||
def test_feodo_feed_is_botnet():
|
||||
case = classify(make_case(feed="feodo", ips=["1.2.3.4"]))
|
||||
assert case.classification.incident_type is IncidentType.BOTNET
|
||||
|
||||
|
||||
def test_malware_severity_tracks_url_status():
|
||||
online = make_case(feed="urlhaus", urls=["http://1.2.3.4/x"])
|
||||
online.source_metadata["url_status"] = "online"
|
||||
assert classify(online).classification.severity is Severity.HIGH
|
||||
|
||||
offline = make_case(feed="urlhaus", urls=["http://1.2.3.4/x"])
|
||||
offline.source_metadata["url_status"] = "offline"
|
||||
assert classify(offline).classification.severity is Severity.MEDIUM
|
||||
|
||||
|
||||
def test_ransomware_kev_is_critical():
|
||||
case = make_case(feed="cisa-kev", cves=["CVE-2026-0001"])
|
||||
case.source_metadata["ransomware"] = "Known"
|
||||
assert classify(case).classification.severity is Severity.CRITICAL
|
||||
|
||||
|
||||
def test_critical_infrastructure_forces_critical():
|
||||
case = make_case(feed="urlhaus", urls=["http://1.2.3.4/x"])
|
||||
case.victim.critical_infrastructure = True
|
||||
assert classify(case).classification.severity is Severity.CRITICAL
|
||||
|
||||
|
||||
def test_internal_class_from_severity():
|
||||
assert classify(make_case(feed="cisa-kev", cves=["CVE-2026-1"])).classification.internal_class is InternalClass.C
|
||||
crit = make_case(feed="urlhaus", urls=["http://1.2.3.4/x"])
|
||||
crit.victim.critical_infrastructure = True
|
||||
assert classify(crit).classification.internal_class is InternalClass.A
|
||||
|
||||
|
||||
def test_classify_is_idempotent():
|
||||
case = classify(make_case(feed="urlhaus", urls=["http://1.2.3.4/x"]))
|
||||
first = case.classification.model_copy(deep=True)
|
||||
classify(case)
|
||||
assert case.classification == first
|
||||
Reference in New Issue
Block a user