Skip to content

Commit e31ab9b

Browse files
committed
feat(core): add alert-type humanizer and override-map plumbing
1 parent ecb66f5 commit e31ab9b

2 files changed

Lines changed: 45 additions & 0 deletions

File tree

socketsecurity/core/__init__.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
import os
3+
import re
34
import sys
45
import tarfile
56
import tempfile
@@ -44,6 +45,26 @@
4445
version = __version__
4546
log = logging.getLogger("socketdev")
4647

48+
_ALERT_TYPE_TITLE_OVERRIDES = {
49+
"gptDidYouMean": "Possible typosquat attack (GPT)",
50+
}
51+
52+
_HUMANIZE_BOUNDARY = re.compile(r"(?<=[a-z0-9])(?=[A-Z])|(?<=[A-Z])(?=[A-Z][a-z])")
53+
54+
55+
def _humanize_alert_type(alert_type: str) -> str:
56+
"""Convert a camelCase/PascalCase alert type into a Title-Cased label.
57+
58+
Used as a last-resort fallback when the SDK does not have metadata for an
59+
alert type and there is no explicit override. Adjacent capitals are kept
60+
together so acronyms like 'SQL' survive ('SQLInjection' -> 'SQL Injection').
61+
"""
62+
if not alert_type:
63+
return ""
64+
parts = _HUMANIZE_BOUNDARY.split(alert_type)
65+
return " ".join(part[:1].upper() + part[1:] for part in parts if part)
66+
67+
4768
class Core:
4869
"""Main class for interacting with Socket Security API and processing scan results."""
4970

tests/core/test_package_and_alerts.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,3 +322,27 @@ def test_get_license_text_via_purl_uses_org_scoped_endpoint(self, core, mock_sdk
322322
)
323323
assert result["npm/lodash@4.18.1"].licenseAttrib == [{"name": "MIT"}]
324324
assert result["npm/lodash@4.18.1"].licenseDetails == [{"license": "MIT"}]
325+
326+
327+
class TestHumanizeAlertType:
328+
def test_humanizes_camel_case(self):
329+
from socketsecurity.core import _humanize_alert_type
330+
assert _humanize_alert_type("gptDidYouMean") == "Gpt Did You Mean"
331+
332+
def test_humanizes_single_word(self):
333+
from socketsecurity.core import _humanize_alert_type
334+
assert _humanize_alert_type("malware") == "Malware"
335+
336+
def test_humanizes_pascal_case(self):
337+
from socketsecurity.core import _humanize_alert_type
338+
assert _humanize_alert_type("UnsafeShellAccess") == "Unsafe Shell Access"
339+
340+
def test_empty_input_returns_empty_string(self):
341+
from socketsecurity.core import _humanize_alert_type
342+
assert _humanize_alert_type("") == ""
343+
344+
def test_handles_acronyms_conservatively(self):
345+
"""Adjacent capitals are kept together: SQLInjection -> 'SQL Injection'."""
346+
from socketsecurity.core import _humanize_alert_type
347+
assert _humanize_alert_type("SQLInjection") == "SQL Injection"
348+

0 commit comments

Comments
 (0)