Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update output tests for strict-blocking and SARIF
Signed-off-by: lelia <lelia@socket.dev>
  • Loading branch information
lelia committed Mar 11, 2026
commit e0c766d795658eff7e1ad7cf1a56224999dabab7
96 changes: 77 additions & 19 deletions tests/unit/test_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def handler(self):
config.disable_blocking = False
config.strict_blocking = False
config.sarif_file = None
config.sarif_reachable_only = False
config.sarif_reachability = "all"
config.sarif_scope = "diff"
config.sarif_grouping = "instance"
config.sarif_reachability = "all"
Expand Down Expand Up @@ -63,6 +63,58 @@ def test_json_output_format(self, handler, caplog):
assert output["new_alerts"][0]["error"] is True
assert output["new_alerts"][0]["description"] == "Test description"

def test_json_output_includes_unchanged_alerts_with_strict_blocking(self, caplog):
import logging
from socketsecurity.config import CliConfig
from unittest.mock import Mock

config = Mock(spec=CliConfig)
config.disable_blocking = False
config.strict_blocking = True
config.sbom_file = None

handler = OutputHandler(config, Mock())

diff = Diff()
diff.id = "test-scan-id"
diff.diff_url = "https://socket.dev/test"
diff.new_alerts = [
Issue(
title="New",
severity="high",
description="new",
error=True,
key="new-key",
type="test-type",
pkg_type="npm",
pkg_name="new-package",
pkg_version="1.0.0",
purl="pkg:npm/new-package@1.0.0",
)
]
diff.unchanged_alerts = [
Issue(
title="Existing",
severity="high",
description="existing",
error=True,
key="existing-key",
type="test-type",
pkg_type="npm",
pkg_name="existing-package",
pkg_version="1.0.0",
purl="pkg:npm/existing-package@1.0.0",
)
]

with caplog.at_level(logging.INFO, logger="socketcli"):
handler.output_console_json(diff)

output = json.loads(caplog.messages[-1])
assert len(output["new_alerts"]) == 2
titles = {a["title"] for a in output["new_alerts"]}
assert titles == {"New", "Existing"}

def test_sbom_file_saving(self, handler, tmp_path):
# Test SBOM file is created correctly
diff = Diff()
Expand Down Expand Up @@ -214,8 +266,8 @@ def test_sarif_file_output(self, tmp_path):
sarif_data = json.load(f)
assert sarif_data["version"] == "2.1.0"

def test_sarif_reachable_only_filters_non_blocking(self, tmp_path):
"""Test that --sarif-reachable-only uses .socket.facts.json reachability."""
def test_sarif_reachability_reachable_filters_non_reachable(self, tmp_path):
"""Test that --sarif-reachability reachable uses .socket.facts.json reachability."""
from socketsecurity.config import CliConfig
from unittest.mock import Mock

Expand All @@ -224,7 +276,7 @@ def test_sarif_reachable_only_filters_non_blocking(self, tmp_path):

config = Mock(spec=CliConfig)
config.sarif_file = str(sarif_path)
config.sarif_reachable_only = True
config.sarif_reachability = "reachable"
config.sarif_scope = "diff"
config.sbom_file = None
config.target_path = str(tmp_path)
Expand Down Expand Up @@ -289,7 +341,7 @@ def make_issue(name, error, ghsa_id):
assert any("reachable-pkg" in r for r in rule_ids)
assert not any("unreachable-pkg" in r for r in rule_ids)

def test_sarif_reachable_only_falls_back_to_blocking_when_facts_missing(self, tmp_path):
def test_sarif_reachability_reachable_falls_back_to_blocking_when_facts_missing(self, tmp_path):
"""Test that missing facts file falls back to historical blocking filter."""
from socketsecurity.config import CliConfig
from unittest.mock import Mock
Expand All @@ -298,7 +350,7 @@ def test_sarif_reachable_only_falls_back_to_blocking_when_facts_missing(self, tm

config = Mock(spec=CliConfig)
config.sarif_file = str(sarif_path)
config.sarif_reachable_only = True
config.sarif_reachability = "reachable"
config.sarif_scope = "diff"
config.sbom_file = None
config.target_path = str(tmp_path)
Expand Down Expand Up @@ -328,8 +380,8 @@ def test_sarif_reachable_only_falls_back_to_blocking_when_facts_missing(self, tm
assert any("blocking-pkg" in r for r in rule_ids)
assert not any("warn-pkg" in r for r in rule_ids)

def test_sarif_output_unchanged_by_strict_blocking_flag(self, tmp_path):
"""Strict blocking should not alter SARIF content for diff.new_alerts."""
def test_sarif_output_includes_unchanged_with_strict_blocking(self, tmp_path):
"""Strict blocking should include unchanged alerts in diff-scope SARIF output."""
from socketsecurity.config import CliConfig
from unittest.mock import Mock

Expand All @@ -339,7 +391,7 @@ def test_sarif_output_unchanged_by_strict_blocking_flag(self, tmp_path):
def build_handler(strict_blocking, output_path):
config = Mock(spec=CliConfig)
config.sarif_file = str(output_path)
config.sarif_reachable_only = False
config.sarif_reachability = "all"
config.sarif_scope = "diff"
config.sbom_file = None
config.strict_blocking = strict_blocking
Expand Down Expand Up @@ -375,18 +427,24 @@ def build_diff():
with open(sarif_path_strict_true) as f:
sarif_true = json.load(f)

assert sarif_false == sarif_true
false_rule_ids = [r["ruleId"] for r in sarif_false["runs"][0]["results"]]
true_rule_ids = [r["ruleId"] for r in sarif_true["runs"][0]["results"]]

def test_sarif_reachable_only_false_includes_all(self, tmp_path):
"""Test that without --sarif-reachable-only all alerts are included"""
assert any("pkg-a" in r for r in false_rule_ids)
assert not any("pkg-old" in r for r in false_rule_ids)
assert any("pkg-a" in r for r in true_rule_ids)
assert any("pkg-old" in r for r in true_rule_ids)

def test_sarif_reachability_all_includes_all(self, tmp_path):
"""Test that --sarif-reachability all includes all alerts."""
from socketsecurity.config import CliConfig
from unittest.mock import Mock

sarif_path = tmp_path / "report.sarif"

config = Mock(spec=CliConfig)
config.sarif_file = str(sarif_path)
config.sarif_reachable_only = False
config.sarif_reachability = "all"
config.sarif_scope = "diff"
config.sbom_file = None

Expand Down Expand Up @@ -501,7 +559,7 @@ def test_sarif_scope_full_before_after_reachable_filtering_snapshot(self, tmp_pa
def build_handler(output_path, reachable_only):
config = Mock(spec=CliConfig)
config.sarif_file = str(output_path)
config.sarif_reachable_only = reachable_only
config.sarif_reachability = "reachable" if reachable_only else "all"
config.sarif_scope = "full"
config.sbom_file = None
config.target_path = str(tmp_path)
Expand Down Expand Up @@ -557,7 +615,7 @@ def test_sarif_scope_full_works_when_diff_not_run(self, tmp_path):

config = Mock(spec=CliConfig)
config.sarif_file = str(out_path)
config.sarif_reachable_only = True
config.sarif_reachability = "reachable"
config.sarif_scope = "full"
config.sbom_file = None
config.target_path = str(tmp_path)
Expand Down Expand Up @@ -602,7 +660,7 @@ def test_sarif_scope_full_dedupes_duplicate_manifest_uris(self, tmp_path):

config = Mock(spec=CliConfig)
config.sarif_file = str(out_path)
config.sarif_reachable_only = True
config.sarif_reachability = "reachable"
config.sarif_scope = "full"
config.sbom_file = None
config.target_path = str(tmp_path)
Expand Down Expand Up @@ -644,7 +702,7 @@ def test_sarif_scope_full_with_sarif_file_suppresses_stdout(self, tmp_path, caps

config = Mock(spec=CliConfig)
config.sarif_file = str(out_path)
config.sarif_reachable_only = True
config.sarif_reachability = "reachable"
config.sarif_scope = "full"
config.sbom_file = None
config.target_path = str(tmp_path)
Expand Down Expand Up @@ -688,7 +746,7 @@ def test_sarif_scope_full_alert_grouping_dedupes_versions(self, tmp_path):

config = Mock(spec=CliConfig)
config.sarif_file = str(out_path)
config.sarif_reachable_only = False
config.sarif_reachability = "all"
config.sarif_scope = "full"
config.sarif_grouping = "alert"
config.sarif_reachability = "reachable"
Expand Down Expand Up @@ -738,7 +796,7 @@ def test_sarif_scope_full_potentially_filter(self, tmp_path):

config = Mock(spec=CliConfig)
config.sarif_file = str(out_path)
config.sarif_reachable_only = False
config.sarif_reachability = "all"
config.sarif_scope = "full"
config.sarif_grouping = "instance"
config.sarif_reachability = "potentially"
Expand Down