|
| 1 | +"""Tests for the --disable-ignore flag.""" |
| 2 | + |
| 3 | +import pytest |
| 4 | +from dataclasses import dataclass |
| 5 | + |
| 6 | +from socketsecurity.config import CliConfig |
| 7 | +from socketsecurity.core.classes import Comment, Diff, Issue |
| 8 | +from socketsecurity.core.messages import Messages |
| 9 | +from socketsecurity.core.scm_comments import Comments |
| 10 | + |
| 11 | + |
| 12 | +# --- CLI flag parsing tests --- |
| 13 | + |
| 14 | +class TestDisableIgnoreFlag: |
| 15 | + def test_flag_defaults_to_false(self): |
| 16 | + config = CliConfig.from_args(["--api-token", "test"]) |
| 17 | + assert config.disable_ignore is False |
| 18 | + |
| 19 | + def test_flag_parsed_with_dashes(self): |
| 20 | + config = CliConfig.from_args(["--api-token", "test", "--disable-ignore"]) |
| 21 | + assert config.disable_ignore is True |
| 22 | + |
| 23 | + def test_flag_parsed_with_underscores(self): |
| 24 | + config = CliConfig.from_args(["--api-token", "test", "--disable_ignore"]) |
| 25 | + assert config.disable_ignore is True |
| 26 | + |
| 27 | + def test_flag_independent_of_disable_blocking(self): |
| 28 | + config = CliConfig.from_args([ |
| 29 | + "--api-token", "test", |
| 30 | + "--disable-ignore", |
| 31 | + "--disable-blocking", |
| 32 | + ]) |
| 33 | + assert config.disable_ignore is True |
| 34 | + assert config.disable_blocking is True |
| 35 | + |
| 36 | + |
| 37 | +# --- Alert suppression tests --- |
| 38 | + |
| 39 | +def _make_alert(**overrides) -> Issue: |
| 40 | + defaults = dict( |
| 41 | + pkg_name="lodash", |
| 42 | + pkg_version="4.17.21", |
| 43 | + pkg_type="npm", |
| 44 | + severity="high", |
| 45 | + title="Known Malware", |
| 46 | + description="Test description", |
| 47 | + type="malware", |
| 48 | + url="https://socket.dev/test", |
| 49 | + manifests="package.json", |
| 50 | + props={}, |
| 51 | + key="test-key", |
| 52 | + purl="pkg:npm/lodash@4.17.21", |
| 53 | + error=True, |
| 54 | + warn=False, |
| 55 | + ignore=False, |
| 56 | + monitor=False, |
| 57 | + suggestion="Remove this package", |
| 58 | + next_step_title="Next steps", |
| 59 | + emoji="🚨", |
| 60 | + ) |
| 61 | + defaults.update(overrides) |
| 62 | + return Issue(**defaults) |
| 63 | + |
| 64 | + |
| 65 | +def _make_comment(body: str, comment_id: int = 1) -> Comment: |
| 66 | + return Comment( |
| 67 | + id=comment_id, |
| 68 | + body=body, |
| 69 | + body_list=body.split("\n"), |
| 70 | + reactions={"+1": 0}, |
| 71 | + user={"login": "test-user", "id": 123}, |
| 72 | + ) |
| 73 | + |
| 74 | + |
| 75 | +class TestRemoveAlertsRespectedByFlag: |
| 76 | + """Verify that Comments.remove_alerts behaves correctly so the |
| 77 | + disable_ignore conditional in socketcli.py has the right effect.""" |
| 78 | + |
| 79 | + def test_remove_alerts_suppresses_matching_alert(self): |
| 80 | + """Without --disable-ignore, matching alerts are removed.""" |
| 81 | + alert = _make_alert() |
| 82 | + ignore_comment = _make_comment("SocketSecurity ignore npm/lodash@4.17.21") |
| 83 | + comments = Comments.check_for_socket_comments({ignore_comment.id: ignore_comment}) |
| 84 | + result = Comments.remove_alerts(comments, [alert]) |
| 85 | + assert len(result) == 0 |
| 86 | + |
| 87 | + def test_alerts_preserved_when_no_ignore_comments(self): |
| 88 | + """With --disable-ignore the caller skips remove_alerts entirely, |
| 89 | + which is equivalent to passing empty comments.""" |
| 90 | + alert = _make_alert() |
| 91 | + result = Comments.remove_alerts({}, [alert]) |
| 92 | + assert len(result) == 1 |
| 93 | + assert result[0].pkg_name == "lodash" |
| 94 | + |
| 95 | + def test_ignore_all_suppresses_all_alerts(self): |
| 96 | + alert1 = _make_alert() |
| 97 | + alert2 = _make_alert(pkg_name="express", pkg_version="4.18.2", |
| 98 | + purl="pkg:npm/express@4.18.2") |
| 99 | + ignore_comment = _make_comment("SocketSecurity ignore-all") |
| 100 | + comments = Comments.check_for_socket_comments({ignore_comment.id: ignore_comment}) |
| 101 | + result = Comments.remove_alerts(comments, [alert1, alert2]) |
| 102 | + assert len(result) == 0 |
| 103 | + |
| 104 | + |
| 105 | +# --- Comment output tests --- |
| 106 | + |
| 107 | +@dataclass |
| 108 | +class _FakeConfig: |
| 109 | + disable_ignore: bool = False |
| 110 | + scm: str = "github" |
| 111 | + |
| 112 | + |
| 113 | +class TestSecurityCommentIgnoreInstructions: |
| 114 | + def _make_diff_with_alert(self) -> Diff: |
| 115 | + diff = Diff() |
| 116 | + diff.id = "test-scan-id" |
| 117 | + diff.diff_url = "https://socket.dev/test" |
| 118 | + diff.new_alerts = [_make_alert()] |
| 119 | + return diff |
| 120 | + |
| 121 | + def test_ignore_instructions_shown_by_default(self): |
| 122 | + diff = self._make_diff_with_alert() |
| 123 | + config = _FakeConfig(disable_ignore=False) |
| 124 | + comment = Messages.security_comment_template(diff, config) |
| 125 | + assert "@SocketSecurity ignore" in comment |
| 126 | + assert "Mark as acceptable risk" in comment |
| 127 | + |
| 128 | + def test_ignore_instructions_hidden_when_disabled(self): |
| 129 | + diff = self._make_diff_with_alert() |
| 130 | + config = _FakeConfig(disable_ignore=True) |
| 131 | + comment = Messages.security_comment_template(diff, config) |
| 132 | + assert "@SocketSecurity ignore" not in comment |
| 133 | + assert "Mark as acceptable risk" not in comment |
| 134 | + |
| 135 | + def test_ignore_instructions_shown_when_config_is_none(self): |
| 136 | + diff = self._make_diff_with_alert() |
| 137 | + comment = Messages.security_comment_template(diff, config=None) |
| 138 | + assert "@SocketSecurity ignore" in comment |
0 commit comments