Skip to content

Commit a7392c2

Browse files
committed
fix: improve license detection details view to handle null file matches
Signed-off-by: berzz26 <aumtamboli2233@gmail.com>
1 parent c77f686 commit a7392c2

2 files changed

Lines changed: 144 additions & 1 deletion

File tree

scanpipe/tests/test_views.py

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1437,6 +1437,135 @@ def test_scanpipe_views_license_detection_details_view_match_texts(self):
14371437
self.assertContains(response, "Rule text")
14381438
self.assertContains(response, "license: MIT")
14391439

1440+
def test_scanpipe_views_license_detection_details_view_match_texts_null_from_file(self):
1441+
matches = [
1442+
{
1443+
"score": 100.0,
1444+
"start_line": 1,
1445+
"end_line": 1,
1446+
"matched_length": 3,
1447+
"match_coverage": 100.0,
1448+
"matcher": "1-spdx-id",
1449+
"license_expression": "isc",
1450+
"rule_identifier": "isc_9931cb7ad33c2eb18f322c94660b670a84186baa.RULE",
1451+
"matched_text": "ISC",
1452+
"from_file": None,
1453+
}
1454+
]
1455+
license_detection = DiscoveredLicense.objects.create(
1456+
project=self.project1,
1457+
license_expression="isc",
1458+
license_expression_spdx="ISC",
1459+
identifier="isc-null-from-file",
1460+
matches=matches,
1461+
detection_count=2,
1462+
file_regions=[
1463+
{"path": "a/package.json", "start_line": 1, "end_line": 1},
1464+
{"path": "b/package-lock.json", "start_line": 1, "end_line": 1},
1465+
],
1466+
)
1467+
1468+
url = reverse(
1469+
"license_detail",
1470+
args=[self.project1.slug, license_detection.identifier],
1471+
)
1472+
response = self.client.get(url)
1473+
1474+
self.assertContains(response, "Matches by file")
1475+
self.assertContains(response, "a/package.json")
1476+
self.assertContains(response, "b/package-lock.json")
1477+
self.assertContains(response, "ISC")
1478+
self.assertNotContains(response, "No match text is available for this file region.")
1479+
self.assertNotContains(response, "No origin resource path")
1480+
1481+
def test_scanpipe_views_license_detection_details_view_match_texts_mixed_from_file(self):
1482+
matches = [
1483+
{
1484+
"score": 100.0,
1485+
"start_line": 1,
1486+
"end_line": 1,
1487+
"matched_length": 4,
1488+
"match_coverage": 100.0,
1489+
"matcher": "1-hash",
1490+
"license_expression": "mit",
1491+
"rule_identifier": "mit_1.RULE",
1492+
"matched_text": "License: MIT",
1493+
"from_file": "LICENSE",
1494+
},
1495+
{
1496+
"score": 100.0,
1497+
"start_line": 5,
1498+
"end_line": 5,
1499+
"matched_length": 3,
1500+
"match_coverage": 100.0,
1501+
"matcher": "1-spdx-id",
1502+
"license_expression": "apache-2.0",
1503+
"rule_identifier": "apache2_99.RULE",
1504+
"matched_text": "Apache-2.0",
1505+
"from_file": None,
1506+
},
1507+
]
1508+
license_detection = DiscoveredLicense.objects.create(
1509+
project=self.project1,
1510+
license_expression="mit AND apache-2.0",
1511+
license_expression_spdx="MIT AND Apache-2.0",
1512+
identifier="mixed-from-file",
1513+
matches=matches,
1514+
detection_count=3,
1515+
file_regions=[
1516+
{"path": "LICENSE", "start_line": 1, "end_line": 1},
1517+
{"path": "setup.py", "start_line": 5, "end_line": 5},
1518+
],
1519+
)
1520+
1521+
url = reverse(
1522+
"license_detail",
1523+
args=[self.project1.slug, license_detection.identifier],
1524+
)
1525+
response = self.client.get(url)
1526+
1527+
self.assertContains(response, "Matches by file")
1528+
self.assertContains(response, "LICENSE")
1529+
self.assertContains(response, "setup.py")
1530+
self.assertContains(response, "License: MIT")
1531+
self.assertContains(response, "Apache-2.0")
1532+
self.assertNotContains(response, "No match text is available for this file region.")
1533+
1534+
def test_scanpipe_views_license_detection_details_view_match_texts_no_file_regions(self):
1535+
matches = [
1536+
{
1537+
"score": 100.0,
1538+
"start_line": 1,
1539+
"end_line": 1,
1540+
"matched_length": 3,
1541+
"match_coverage": 100.0,
1542+
"matcher": "1-spdx-id",
1543+
"license_expression": "isc",
1544+
"rule_identifier": "isc_99.RULE",
1545+
"matched_text": "ISC",
1546+
"from_file": None,
1547+
}
1548+
]
1549+
license_detection = DiscoveredLicense.objects.create(
1550+
project=self.project1,
1551+
license_expression="isc",
1552+
license_expression_spdx="ISC",
1553+
identifier="isc-no-regions",
1554+
matches=matches,
1555+
file_regions=[],
1556+
)
1557+
1558+
url = reverse(
1559+
"license_detail",
1560+
args=[self.project1.slug, license_detection.identifier],
1561+
)
1562+
response = self.client.get(url)
1563+
1564+
self.assertContains(response, "Matches by file")
1565+
self.assertContains(response, "ISC")
1566+
self.assertContains(response, "No origin resource path")
1567+
self.assertNotContains(response, "No match text is available for this file region.")
1568+
14401569
def test_scanpipe_views_resource_details_view_inlines_detection_match_texts(self):
14411570
license_detections = [
14421571
{

scanpipe/views.py

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2548,12 +2548,18 @@ def get_file_match_groups(self):
25482548
matches_by_file = self.get_matches_by_file(self.object.matches)
25492549
file_match_groups = []
25502550

2551+
null_from_file_matches = matches_by_file.pop("", [])
2552+
25512553
for file_region in self.object.file_regions:
25522554
path = file_region.get("path") or ""
2555+
matches = matches_by_file.pop(path, [])
2556+
if not matches and null_from_file_matches:
2557+
matches = null_from_file_matches
2558+
25532559
file_match_groups.append(
25542560
{
25552561
"file_region": file_region,
2556-
"matches": matches_by_file.pop(path, []),
2562+
"matches": matches,
25572563
}
25582564
)
25592565

@@ -2565,6 +2571,14 @@ def get_file_match_groups(self):
25652571
}
25662572
)
25672573

2574+
if not file_match_groups and null_from_file_matches:
2575+
file_match_groups.append(
2576+
{
2577+
"file_region": {},
2578+
"matches": null_from_file_matches,
2579+
}
2580+
)
2581+
25682582
return file_match_groups
25692583

25702584
def get_context_data(self, **kwargs):

0 commit comments

Comments
 (0)