@@ -156,4 +156,87 @@ def test_disable_blocking_overrides_strict_blocking(self):
156156 diff .unchanged_alerts = [Issue (error = True , warn = False )]
157157
158158 # Should pass because disable_blocking takes precedence
159- assert handler .report_pass (diff )
159+ assert handler .report_pass (diff )
160+
161+ def test_sarif_file_output (self , tmp_path ):
162+ """Test that --sarif-file writes SARIF report to a file"""
163+ from socketsecurity .config import CliConfig
164+ from unittest .mock import Mock
165+
166+ sarif_path = tmp_path / "report.sarif"
167+
168+ config = Mock (spec = CliConfig )
169+ config .sarif_file = str (sarif_path )
170+ config .sbom_file = None
171+
172+ handler = OutputHandler (config , Mock ())
173+
174+ diff = Diff ()
175+ diff .id = "test-scan-id"
176+ diff .new_alerts = [Issue (
177+ pkg_name = "test-package" ,
178+ pkg_version = "1.0.0" ,
179+ severity = "high" ,
180+ title = "Test Vulnerability" ,
181+ description = "Test description" ,
182+ type = "malware" ,
183+ url = "https://socket.dev/test" ,
184+ manifests = "package.json" ,
185+ pkg_type = "npm" ,
186+ key = "test-key" ,
187+ purl = "pkg:npm/test-package@1.0.0" ,
188+ error = True ,
189+ )]
190+
191+ handler .output_console_sarif (diff )
192+
193+ assert sarif_path .exists ()
194+ with open (sarif_path ) as f :
195+ sarif_data = json .load (f )
196+ assert sarif_data ["version" ] == "2.1.0"
197+ assert "$schema" in sarif_data
198+ assert len (sarif_data ["runs" ]) == 1
199+
200+ def test_sarif_no_file_when_not_configured (self , tmp_path ):
201+ """Test that no file is written when --sarif-file is not set"""
202+ from socketsecurity .config import CliConfig
203+ from unittest .mock import Mock
204+
205+ config = Mock (spec = CliConfig )
206+ config .sarif_file = None
207+ config .sbom_file = None
208+
209+ handler = OutputHandler (config , Mock ())
210+
211+ diff = Diff ()
212+ diff .id = "test-scan-id"
213+ diff .new_alerts = []
214+
215+ handler .output_console_sarif (diff )
216+
217+ # No files should be created in tmp_path
218+ assert list (tmp_path .iterdir ()) == []
219+
220+ def test_sarif_file_nested_directory (self , tmp_path ):
221+ """Test that --sarif-file creates parent directories if needed"""
222+ from socketsecurity .config import CliConfig
223+ from unittest .mock import Mock
224+
225+ sarif_path = tmp_path / "nested" / "dir" / "report.sarif"
226+
227+ config = Mock (spec = CliConfig )
228+ config .sarif_file = str (sarif_path )
229+ config .sbom_file = None
230+
231+ handler = OutputHandler (config , Mock ())
232+
233+ diff = Diff ()
234+ diff .id = "test-scan-id"
235+ diff .new_alerts = []
236+
237+ handler .output_console_sarif (diff )
238+
239+ assert sarif_path .exists ()
240+ with open (sarif_path ) as f :
241+ sarif_data = json .load (f )
242+ assert sarif_data ["version" ] == "2.1.0"
0 commit comments