Skip to content

Commit 5d5409d

Browse files
committed
Add tests
Signed-off-by: Sampurna Pyne <sampurnapyne1710@gmail.com>
1 parent f2dd1f7 commit 5d5409d

5 files changed

Lines changed: 247 additions & 0 deletions

File tree

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
from django.test import TestCase
2+
3+
from insights.charts.importer_panel import exploits_queryset
4+
from insights.charts.importer_panel import packages_queryset
5+
from vulnerabilities.models import AdvisoryExploit
6+
from vulnerabilities.models import AdvisoryV2
7+
from vulnerabilities.models import ImpactedPackage
8+
from vulnerabilities.models import ImpactedPackageAffecting
9+
from vulnerabilities.models import PackageV2
10+
11+
12+
def create_adv(avid, unique_id):
13+
return AdvisoryV2.objects.create(
14+
avid=f"github_osv/{avid}",
15+
datasource_id="github_osv",
16+
unique_content_id=unique_id,
17+
is_latest=True,
18+
pipeline_id="github_osv_pipeline",
19+
advisory_id=avid,
20+
url="https://example.com/" + avid,
21+
)
22+
23+
24+
class TestImporterPanelQuerysets(TestCase):
25+
def test_packages_queryset(self):
26+
advisory_with_package = create_adv("GHSA-1", "1")
27+
pkg1 = PackageV2.objects.create(type="npm", name="test1", version="1.0.0")
28+
impact1 = ImpactedPackage.objects.create(advisory=advisory_with_package)
29+
ImpactedPackageAffecting.objects.create(impacted_package=impact1, package=pkg1)
30+
31+
advisory_with_ghost_package = create_adv("GHSA-2", "2")
32+
pkg2 = PackageV2.objects.create(type="npm", name="test2", version="2.0.0", is_ghost=True)
33+
impact2 = ImpactedPackage.objects.create(advisory=advisory_with_ghost_package)
34+
ImpactedPackageAffecting.objects.create(impacted_package=impact2, package=pkg2)
35+
36+
advisory_without_package = create_adv("GHSA-3", "3")
37+
38+
qs = list(packages_queryset())
39+
40+
self.assertEqual(len(qs), 1)
41+
stats = qs[0]
42+
self.assertEqual(stats["datasource_id"], "github_osv")
43+
self.assertEqual(stats["total_advisories"], 3)
44+
self.assertEqual(stats["advisories_with_packages"], 2) # First two have packages
45+
self.assertEqual(stats["advisories_with_ghost_packages"], 1)
46+
47+
def test_exploits_queryset(self):
48+
advisory_with_kev = create_adv("GHSA-1", "1")
49+
AdvisoryExploit.objects.create(advisory=advisory_with_kev, data_source="KEV")
50+
51+
advisory_with_metasploit = create_adv("GHSA-2", "2")
52+
AdvisoryExploit.objects.create(advisory=advisory_with_metasploit, data_source="Metasploit")
53+
54+
advisory_with_exploitdb = create_adv("GHSA-3", "3")
55+
AdvisoryExploit.objects.create(advisory=advisory_with_exploitdb, data_source="Exploit-DB")
56+
57+
advisory_without_exploits = create_adv("GHSA-4", "4")
58+
59+
qs = list(exploits_queryset())
60+
61+
self.assertEqual(len(qs), 1)
62+
stats = qs[0]
63+
self.assertEqual(stats["datasource_id"], "github_osv")
64+
65+
# GHSA-4 shouldn't count in these
66+
self.assertEqual(stats["advisories_with_kev"], 1)
67+
self.assertEqual(stats["advisories_with_metasploit"], 1)
68+
self.assertEqual(stats["advisories_with_exploitdb"], 1)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from django.test import TestCase
2+
3+
from insights.insights_snapshot_pipeline import InsightsSnapshotPipeline
4+
from insights.models import DailySnapshot
5+
from insights.tests.test_importer_panel import create_adv
6+
from vulnerabilities.models import AdvisorySeverity
7+
from vulnerabilities.models import PackageV2
8+
9+
10+
class TestInsightsSnapshotPipeline(TestCase):
11+
def test_pipeline_execution_with_data(self):
12+
"""Test pipeline populates insights based on existing data."""
13+
14+
PackageV2.objects.create(type="pypi", name="django", version="1.0.0")
15+
PackageV2.objects.create(type="npm", name="lodash", version="1.0.0")
16+
17+
# Create Advisory for Importer and Severity charts
18+
advisory_1 = create_adv("GHSA-1234", "1")
19+
severity_1 = AdvisorySeverity.objects.create(scoring_system="cvssv3.1", value="9.8")
20+
advisory_1.severities.add(severity_1)
21+
22+
pipeline = InsightsSnapshotPipeline()
23+
pipeline.execute()
24+
25+
self.assertEqual(DailySnapshot.objects.count(), 1)
26+
snapshot = DailySnapshot.objects.first()
27+
28+
# Verify captured package types (pypi, npm) and 'global'
29+
self.assertEqual(snapshot.package_insights.count(), 3)
30+
31+
# Verify ImporterInsight was created for 'github_osv'
32+
self.assertEqual(snapshot.importer_insights.count(), 1)
33+
self.assertTrue(snapshot.importer_insights.filter(importer="github_osv").exists())
34+
35+
# Verify SeverityInsight was generated
36+
self.assertTrue(hasattr(snapshot, "severity_insight"))
37+
self.assertEqual(snapshot.severity_insight.buckets[9], 1)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from django.test import TestCase
2+
3+
from insights.charts.package_panel import ecosystem_distribution_queryset
4+
from insights.charts.package_panel import top_packages_queryset
5+
from vulnerabilities.models import AdvisoryV2
6+
from vulnerabilities.models import ImpactedPackage
7+
from vulnerabilities.models import ImpactedPackageAffecting
8+
from vulnerabilities.models import PackageV2
9+
10+
11+
class TestPackagePanelQuerysets(TestCase):
12+
def test_ecosystem_distribution_queryset(self):
13+
PackageV2.objects.create(type="npm", name="test1", version="1.0.0")
14+
PackageV2.objects.create(type="npm", name="test2", version="1.0.0")
15+
PackageV2.objects.create(type="pypi", name="test3", version="1.0.0")
16+
PackageV2.objects.create(type="gem", name="test4", version="1.0.0")
17+
18+
tracked_types = ["npm", "pypi"]
19+
20+
qs = list(ecosystem_distribution_queryset(tracked_types))
21+
stats = {item["type"]: item["total_package_count"] for item in qs}
22+
23+
self.assertEqual(len(stats), 2) # gem should be excluded
24+
self.assertEqual(stats["npm"], 2)
25+
self.assertEqual(stats["pypi"], 1)
26+
27+
def test_top_packages_queryset(self):
28+
django_v1 = PackageV2.objects.create(type="pypi", name="django", version="1.0.0")
29+
django_v2 = PackageV2.objects.create(type="pypi", name="django", version="2.0.0")
30+
flask_v1 = PackageV2.objects.create(type="pypi", name="flask", version="1.0.0")
31+
32+
def create_impact(advisory_id, package):
33+
adv = AdvisoryV2.objects.create(
34+
avid=f"github_osv/{advisory_id}",
35+
datasource_id="github_osv",
36+
unique_content_id=advisory_id,
37+
is_latest=True,
38+
pipeline_id="github_osv_pipeline",
39+
advisory_id=advisory_id,
40+
url=f"https://github.com/advisories/{advisory_id}",
41+
)
42+
impact = ImpactedPackage.objects.create(advisory=adv)
43+
ImpactedPackageAffecting.objects.create(impacted_package=impact, package=package)
44+
45+
create_impact("GHSA-1111", django_v1)
46+
create_impact("GHSA-2222", django_v2)
47+
create_impact("GHSA-3333", django_v2)
48+
create_impact("GHSA-4444", flask_v1)
49+
50+
qs = list(top_packages_queryset("pypi"))
51+
52+
self.assertEqual(len(qs), 2)
53+
self.assertEqual(qs[0]["name"], "django")
54+
self.assertEqual(qs[0]["count"], 3)
55+
self.assertEqual(qs[1]["name"], "flask")
56+
self.assertEqual(qs[1]["count"], 1)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from django.test import TestCase
2+
3+
from insights.charts.severity_panel import iter_severity_insights
4+
from vulnerabilities.models import AdvisorySeverity
5+
from vulnerabilities.models import AdvisoryV2
6+
7+
8+
class TestSeverityPanelQuerysets(TestCase):
9+
def test_iter_severity_insights(self):
10+
advisory1 = AdvisoryV2.objects.create(
11+
avid="github_osv/GHSA-1",
12+
datasource_id="github_osv",
13+
unique_content_id="1",
14+
is_latest=True,
15+
pipeline_id="github_osv_pipeline",
16+
advisory_id="GHSA-1",
17+
url="https://example.com/GHSA-1",
18+
)
19+
severity1 = AdvisorySeverity.objects.create(scoring_system="cvssv3.1", value="9.8")
20+
advisory1.severities.add(severity1)
21+
22+
advisory2 = AdvisoryV2.objects.create(
23+
avid="github_osv/GHSA-2",
24+
datasource_id="github_osv",
25+
unique_content_id="2",
26+
is_latest=True,
27+
pipeline_id="github_osv_pipeline",
28+
advisory_id="GHSA-2",
29+
url="https://example.com/GHSA-2",
30+
)
31+
severity2 = AdvisorySeverity.objects.create(scoring_system="cvssv3.1", value="4.5")
32+
advisory2.severities.add(severity2)
33+
34+
qs = list(iter_severity_insights())
35+
36+
self.assertEqual(len(qs), 1)
37+
insight = qs[0]
38+
39+
self.assertEqual(insight.buckets[9], 1)
40+
self.assertEqual(insight.buckets[4], 1)
41+
self.assertEqual(sum(insight.buckets), 2)

insights/tests/test_views.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
from django.test import TestCase
2+
from django.urls import reverse
3+
4+
from insights.models import DailySnapshot
5+
from vulnerabilities.models import PackageV2
6+
7+
8+
class TestInsightsViews(TestCase):
9+
def test_dashboard_redirects_to_default_panel(self):
10+
"""Root insights URL should redirect to the first panel (overview_panel)."""
11+
response = self.client.get("/insights/")
12+
self.assertEqual(response.status_code, 302)
13+
self.assertTrue(response.url.endswith("/insights/overview_panel/"))
14+
15+
def test_dashboard_invalid_panel_redirects(self):
16+
"""Invalid panel ID should redirect to default."""
17+
response = self.client.get("/insights/non_existent_panel/")
18+
self.assertEqual(response.status_code, 302)
19+
self.assertTrue(response.url.endswith("/insights/overview_panel/"))
20+
21+
def test_dashboard_valid_panel_loads(self):
22+
"""Valid panels should load with a 200 OK."""
23+
response = self.client.get("/insights/package_panel/")
24+
self.assertEqual(response.status_code, 200)
25+
self.assertContains(response, "package_panel")
26+
27+
def test_dashboard_search_package_panel(self):
28+
"""Test CWE search on package panel."""
29+
PackageV2.objects.create(type="pypi", name="django", version="1.0.0")
30+
response = self.client.get("/insights/package_panel/?q=pkg:pypi/django")
31+
self.assertEqual(response.status_code, 200)
32+
self.assertIn("search_results_dict", response.context)
33+
34+
def test_dashboard_search_severity_panel(self):
35+
"""Test Severity search on severity panel."""
36+
PackageV2.objects.create(type="pypi", name="flask", version="1.0.0")
37+
response = self.client.get("/insights/severity_panel/?q=pkg:pypi/flask")
38+
self.assertEqual(response.status_code, 200)
39+
self.assertIn("search_results_dict", response.context)
40+
41+
def test_dashboard_search_no_results(self):
42+
"""Test search with no matching packages."""
43+
response = self.client.get("/insights/severity_panel/?q=pkg:pypi/does_not_exist")
44+
self.assertEqual(response.status_code, 200)
45+
self.assertEqual(response.context["search_error"], "No data available for this query.")

0 commit comments

Comments
 (0)