Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
13 changes: 13 additions & 0 deletions docs/cli-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,19 @@ If you don't want to provide the Socket API Token every time then you can use th
| `--exclude-license-details` | False | False | Exclude license details from the diff report (boosts performance for large repos) |
| `--version` | False | False | Show program's version number and exit |

#### Standard Socket JSON scan references

Standard Socket JSON output adds `diff_scan_id`, `old_scan_id`, `new_scan_id`,
`old_scan_url`, and `new_scan_url`. These fields are JSON null when the
corresponding reference is unavailable, including fallback comparisons,
full scans, and no-run results. `full_scan_id` retains its legacy meaning: the
new full-scan ID (or the existing no-run sentinel), not the comparison ID.

`new_scan_url` is the canonical server URL for the new full scan. It can differ
from `report_url`, which is the display link and may include output options such
as license-detail settings. These additions apply to standard Socket JSON, not
FOSSA compatibility output.

#### Security Configuration
| Parameter | Required | Default | Description |
|:-------------------------|:---------|:--------|:------------------------------|
Expand Down
15 changes: 15 additions & 0 deletions socketsecurity/core/report_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ class ReportReferences:
report_url: Optional[str]
diff_url: Optional[str]
is_full_scan: bool
diff_scan_id: Optional[str] = None
old_scan_id: Optional[str] = None
new_scan_id: Optional[str] = None
old_scan_url: Optional[str] = None
new_scan_url: Optional[str] = None

def console_link(self) -> Optional[tuple[str, str]]:
if self.is_full_scan:
Expand All @@ -37,6 +42,11 @@ def build_report_references(diff_report: Diff) -> ReportReferences:
report_url=getattr(diff_report, "report_url", None),
diff_url=getattr(diff_report, "diff_url", ""),
is_full_scan=getattr(diff_report, "is_full_scan", False),
diff_scan_id=getattr(diff_report, "diff_scan_id", None),
old_scan_id=getattr(diff_report, "old_scan_id", None),
new_scan_id=getattr(diff_report, "new_scan_id", None),
old_scan_url=getattr(diff_report, "old_scan_url", None),
new_scan_url=getattr(diff_report, "new_scan_url", None),
)


Expand Down Expand Up @@ -131,6 +141,11 @@ def build_socket_json_report(
report["full_scan_id"] = references.full_scan_id
report["diff_url"] = references.diff_url
report["report_url"] = references.report_url
report["diff_scan_id"] = references.diff_scan_id
report["old_scan_id"] = references.old_scan_id
report["new_scan_id"] = references.new_scan_id
report["old_scan_url"] = references.old_scan_url
report["new_scan_url"] = references.new_scan_url
report["repo"] = repo if isinstance(repo, str) or repo is None else None
report["branch"] = branch if isinstance(branch, str) or branch is None else None
report["commit_sha"] = (
Expand Down
39 changes: 39 additions & 0 deletions tests/core/test_diff_identity_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

from socketsecurity.config import CliConfig
from socketsecurity.core import Core
from socketsecurity.core.report_output import build_socket_json_report
from socketsecurity.core.socket_config import SocketConfig
from tests.support.socket_api_fixture import (
SocketApiFixture,
Expand Down Expand Up @@ -426,6 +427,24 @@ def create_full_scan(_request: SocketRequest) -> SocketResponse:
)
assert diff.new_scan_url == expected_new_scan_url
assert diff.report_url == expected_report_url
report = build_socket_json_report(
diff,
CliConfig(
api_token="fictional-local-only",
repo="fixture-repo",
legal=False,
),
)
assert report["full_scan_id"] == "new-full-scan-id"
assert report["diff_scan_id"] == (
"new-comparison-id" if comparison_succeeds else None
)
assert report["old_scan_id"] == "temporary-baseline-id"
assert report["new_scan_id"] == "new-full-scan-id"
assert report["diff_url"] == diff.diff_url
assert report["old_scan_url"] == diff.old_scan_url
assert report["new_scan_url"] == expected_new_scan_url
assert report["report_url"] == expected_report_url
if comparison_succeeds and not null_urls:
assert diff.diff_url == "https://reports.example.invalid/diff?canonical=1#comparison"
assert diff.old_scan_url == "https://reports.example.invalid/before?source=get"
Expand Down Expand Up @@ -539,6 +558,17 @@ def test_full_scan_identity_is_preserved_with_findings_disabled_or_enabled(
assert result.new_scan_url == "https://socket.dev/scan/full-scan-id"
assert result.old_scan_url is None
assert result.report_url == result.diff_url == result.new_scan_url
report = build_socket_json_report(
result,
cli_config
or CliConfig(api_token="fictional-local-only", repo="fixture-repo"),
)
assert report["full_scan_id"] == "full-scan-id"
assert report["diff_scan_id"] is None
assert report["old_scan_id"] is None
assert report["new_scan_id"] == "full-scan-id"
assert report["old_scan_url"] is None
assert report["new_scan_url"] == "https://socket.dev/scan/full-scan-id"
if enable_json:
assert result.packages["artifact-fixture-id"].purl == "npm/sample-package@1.0.0"
findings_requests = [
Expand Down Expand Up @@ -567,4 +597,13 @@ def test_no_change_paths_keep_sentinels_without_transport_calls(
assert result.diff_scan_id is None
assert result.old_scan_url is None
assert result.new_scan_url is None
report = build_socket_json_report(
result, CliConfig(api_token="fictional-local-only", repo="fixture-repo")
)
assert report["diff_scan_id"] is None
assert report["old_scan_id"] is None
assert report["new_scan_id"] is None
assert report["old_scan_url"] is None
assert report["new_scan_url"] is None
assert report["full_scan_id"] == result.id
assert len(socket_api.requests) == request_count_after_setup
84 changes: 83 additions & 1 deletion tests/unit/test_report_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,23 @@ def _diff(
diff_url: str | None = "https://socket.dev/orgs/fictional/diffs/diff-456",
is_full_scan: bool = False,
alerts_fetched: bool = True,
diff_scan_id: str | None = None,
old_scan_id: str | None = None,
new_scan_id: str | None = "full-123",
old_scan_url: str | None = None,
new_scan_url: str | None = None,
) -> Diff:
return Diff(
id="full-123",
new_scan_id="full-123",
report_url=report_url,
diff_url=diff_url,
is_full_scan=is_full_scan,
alerts_fetched=alerts_fetched,
diff_scan_id=diff_scan_id,
old_scan_id=old_scan_id,
new_scan_id=new_scan_id,
old_scan_url=old_scan_url,
new_scan_url=new_scan_url,
new_alerts=list(new_alerts or []),
unchanged_alerts=list(unchanged_alerts or []),
)
Expand Down Expand Up @@ -245,6 +254,11 @@ def test_default_socket_json_key_set_and_metadata_remain_unchanged():
"branch",
"commit_sha",
"legal_mode",
"diff_scan_id",
"old_scan_id",
"new_scan_id",
"old_scan_url",
"new_scan_url",
}
assert report == {
"scan_failed": False,
Expand All @@ -256,9 +270,77 @@ def test_default_socket_json_key_set_and_metadata_remain_unchanged():
"branch": "feature/example",
"commit_sha": "abc123",
"legal_mode": True,
"diff_scan_id": None,
"old_scan_id": None,
"new_scan_id": "full-123",
"old_scan_url": None,
"new_scan_url": None,
}


def test_scan_references_are_distinct_nullable_and_preserve_input():
diff = _diff(
diff_scan_id="comparison-789",
old_scan_id="baseline-456",
new_scan_id="full-123",
old_scan_url="https://reports.example.test/before?x=1#base",
new_scan_url="https://reports.example.test/after?x=2#new",
)
original = copy.deepcopy(diff.__dict__)

report = build_socket_json_report(diff, _config())

assert report == {
"scan_failed": False,
"new_alerts": [],
"full_scan_id": "full-123",
"diff_url": "https://socket.dev/orgs/fictional/diffs/diff-456",
"report_url": "https://socket.dev/orgs/fictional/reports/full-123",
"repo": "fictional-repo",
"branch": "",
"commit_sha": "",
"legal_mode": False,
"diff_scan_id": "comparison-789",
"old_scan_id": "baseline-456",
"new_scan_id": "full-123",
"old_scan_url": "https://reports.example.test/before?x=1#base",
"new_scan_url": "https://reports.example.test/after?x=2#new",
}
assert json.loads(json.dumps(report))["old_scan_id"] == "baseline-456"
assert diff.__dict__ == original


def test_missing_references_remain_null_without_url_inference():
diff = _diff(
report_url="https://reports.example.test/display",
diff_url=None,
diff_scan_id=None,
old_scan_id=None,
new_scan_id=None,
old_scan_url=None,
new_scan_url=None,
)

report = build_socket_json_report(diff, _config())

assert report["diff_scan_id"] is None
assert report["new_scan_id"] is None
assert report["new_scan_url"] is None
assert report["diff_url"] is None
assert report["report_url"] == "https://reports.example.test/display"


def test_canonical_scan_url_is_distinct_from_display_report_url():
canonical_url = "https://reports.example.test/scan?id=full-123#result"
display_url = "https://reports.example.test/scan?id=full-123&include_license_details=false#result"
diff = _diff(report_url=display_url, new_scan_url=canonical_url)

report = build_socket_json_report(diff, _config())

assert report["new_scan_url"] == canonical_url
assert report["report_url"] == display_url


def test_missing_reference_fields_keep_existing_json_defaults():
diff = Diff(new_alerts=[])

Expand Down
Loading