Skip to content

Commit e4374c1

Browse files
committed
add tests
Signed-off-by: uttam282005 <uttam282005@gmail.com>
1 parent ebf150c commit e4374c1

2 files changed

Lines changed: 173 additions & 0 deletions

File tree

scanpipe/tests/pipes/test_output.py

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,84 @@ def test_scanpipe_pipes_outputs_to_json(self):
208208
output_file = output.to_json(project=project)
209209
self.assertIn(output_file.name, project.output_root)
210210

211+
def test_scanpipe_pipes_outputs_to_json_strips_symbols(self):
212+
"""Test that JSON output removes symbols from resources and messages."""
213+
project = make_project(name="SymbolTest")
214+
215+
resource_data = {
216+
"path": "test.js",
217+
"extra_data": {
218+
"source_symbols": ["func1", "func2"],
219+
"source_strings": ["hello world"],
220+
"source_comments": ["// test"],
221+
"other_field": "should_remain"
222+
}
223+
}
224+
resource = CodebaseResource.objects.create(project=project, **resource_data)
225+
226+
message_details = {
227+
"source_symbols": ["sym1"],
228+
"resource_path": "test.js"
229+
}
230+
make_message(project, details=message_details, description="Test message")
231+
232+
output_file = output.to_json(project=project)
233+
with output_file.open() as f:
234+
results = json.loads(f.read())
235+
236+
resource_output = results["files"][0]
237+
self.assertNotIn("source_symbols", resource_output["extra_data"])
238+
self.assertNotIn("source_strings", resource_output["extra_data"])
239+
self.assertNotIn("source_comments", resource_output["extra_data"])
240+
self.assertIn("other_field", resource_output["extra_data"])
241+
self.assertEqual("should_remain", resource_output["extra_data"]["other_field"])
242+
243+
message_output = results["headers"][0]["messages"][0]
244+
self.assertNotIn("source_symbols", message_output["details"])
245+
self.assertIn("resource_path", message_output["details"])
246+
247+
resource.refresh_from_db()
248+
self.assertIn("source_symbols", resource.extra_data)
249+
250+
def test_scanpipe_pipes_outputs_to_symbols_json(self):
251+
project = make_project(name="SymbolsOnly")
252+
CodebaseResource.objects.create(
253+
project=project,
254+
path="has_symbols.js",
255+
extra_data={
256+
"source_symbols": ["func1", "func2"],
257+
"source_strings": ["test"],
258+
"other_data": "value"
259+
}
260+
)
261+
CodebaseResource.objects.create(
262+
project=project,
263+
path="no_symbols.txt",
264+
extra_data={"other_data": "value"}
265+
)
266+
output_file = output.to_symbols_json(project)
267+
with output_file.open() as f:
268+
results = json.loads(f.read())
269+
270+
self.assertIn("headers", results)
271+
self.assertIn("files", results)
272+
273+
# Should only have 1 file (the one with symbols)
274+
self.assertEqual(1, len(results["files"]))
275+
276+
# Verify it's the right file
277+
file_output = results["files"][0]
278+
self.assertEqual("has_symbols.js", file_output["path"])
279+
280+
# Verify symbols ARE included (not stripped)
281+
self.assertIn("source_symbols", file_output["extra_data"])
282+
self.assertEqual(["func1", "func2"], file_output["extra_data"]["source_symbols"])
283+
self.assertIn("source_strings", file_output["extra_data"])
284+
285+
# Verify headers are present
286+
self.assertEqual(1, len(results["headers"]))
287+
self.assertEqual("scanpipe", results["headers"][0]["tool_name"])
288+
211289
def test_scanpipe_pipes_outputs_to_xlsx(self):
212290
fixtures = self.data / "asgiref" / "asgiref-3.3.0_fixtures.json"
213291
call_command("loaddata", fixtures, **{"verbosity": 0})
@@ -271,6 +349,54 @@ def test_scanpipe_pipes_outputs_get_xlsx_report(self):
271349
]
272350
self.assertEqual(expected_sheet_names, workbook.sheetnames)
273351

352+
def test_scanpipe_pipes_outputs_to_xlsx_strips_symbols(self):
353+
project = make_project(name="SymbolXLSX")
354+
CodebaseResource.objects.create(
355+
project=project,
356+
path="test.js",
357+
extra_data={
358+
"source_symbols": ["func1", "func2"],
359+
"source_strings": ["hello"],
360+
"source_comments": ["// test"],
361+
}
362+
)
363+
364+
message_details = {
365+
"source_symbols": ["symbol1", "symbol2"],
366+
"source_strings": ["string1"],
367+
"source_comments": ["# comment"],
368+
"resource_path": "test.js"
369+
}
370+
make_message(
371+
project,
372+
model="resource",
373+
details=message_details,
374+
description="Error with symbols"
375+
)
376+
377+
output_file = output.to_xlsx(project)
378+
workbook = openpyxl.load_workbook(output_file, read_only=True, data_only=True)
379+
380+
self.assertIn("MESSAGES", workbook.sheetnames)
381+
messages_sheet = workbook["MESSAGES"]
382+
383+
headers = [cell.value for cell in next(messages_sheet.iter_rows())]
384+
self.assertIn("details", headers)
385+
details_col_index = headers.index("details")
386+
387+
rows = list(messages_sheet.iter_rows(min_row=2, max_row=2, values_only=True))
388+
self.assertEqual(1, len(rows))
389+
390+
details_value = rows[0][details_col_index]
391+
392+
if details_value:
393+
self.assertNotIn("source_symbols", details_value)
394+
self.assertNotIn("source_strings", details_value)
395+
self.assertNotIn("source_comments", details_value)
396+
397+
# Verify other fields ARE present
398+
self.assertIn("resource_path", details_value)
399+
274400
def test_scanpipe_pipes_outputs_get_xlsx_fields_order(self):
275401
output_file = output.to_xlsx(project=make_project())
276402
workbook = openpyxl.load_workbook(output_file, read_only=True, data_only=True)
@@ -717,6 +843,35 @@ def test_scanpipe_pipes_outputs_render_template_file(self):
717843
rendered = output.render_template_file(template_location, context)
718844
self.assertEqual("value", rendered)
719845

846+
def test_strip_symbols_function(self):
847+
"""Test that strip_symbols removes symbol keys without mutation."""
848+
original = {
849+
"path": "test.py",
850+
"source_symbols": ["foo", "bar"],
851+
"source_strings": ["hello"],
852+
"source_comments": ["# comment"],
853+
"other_data": "keep_me"
854+
}
855+
856+
result = output.strip_symbols(original)
857+
# Verify symbols removed
858+
self.assertNotIn("source_symbols", result)
859+
self.assertNotIn("source_strings", result)
860+
self.assertNotIn("source_comments", result)
861+
862+
# Verify other data preserved
863+
self.assertEqual("test.py", result["path"])
864+
self.assertEqual("keep_me", result["other_data"])
865+
866+
# Verify original not mutated (important!)
867+
self.assertIn("source_symbols", original)
868+
self.assertEqual(["foo", "bar"], original["source_symbols"])
869+
870+
# Test edge cases
871+
self.assertIsNone(output.strip_symbols(None))
872+
self.assertEqual({}, output.strip_symbols({}))
873+
self.assertEqual("string", output.strip_symbols("string"))
874+
720875
def test_scanpipe_pipes_outputs_get_attribution_template(self):
721876
project = make_project(name="Analysis")
722877
template_location = str(output.get_attribution_template(project))

scanpipe/tests/test_api.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,24 @@ def test_scanpipe_api_project_action_results_download(self):
631631
expected = ["dependencies", "files", "headers", "packages", "relations"]
632632
self.assertEqual(expected, sorted(results.keys()))
633633

634+
def test_api_project_results_download_symbols_format(self):
635+
project = make_project(name="SymbolsAPI")
636+
CodebaseResource.objects.create(
637+
project=project,
638+
path="test.js",
639+
extra_data={"source_symbols": ["func"]}
640+
)
641+
642+
url = reverse("project-results-download", args=[project.uuid])
643+
response = self.client.get(url, {"output_format": "symbols"})
644+
645+
self.assertEqual(200, response.status_code)
646+
self.assertIn("application/json", response["Content-Type"])
647+
648+
results = json.loads(response.content)
649+
self.assertIn("files", results)
650+
self.assertGreater(len(results["files"]), 0)
651+
634652
@mock.patch("scanpipe.pipes.datetime", mocked_now)
635653
def test_scanpipe_api_project_action_results_download_output_formats(self):
636654
url = reverse("project-results-download", args=[self.project1.uuid])

0 commit comments

Comments
 (0)