Skip to content

Commit a7e8654

Browse files
committed
Add unit tests for Overview and Data Quality Panel
Signed-off-by: Sampurna Pyne <sampurnapyne1710@gmail.com>
1 parent c4d5b86 commit a7e8654

3 files changed

Lines changed: 186 additions & 0 deletions

File tree

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import datetime
2+
3+
from django.test import TestCase
4+
from django.utils import timezone
5+
6+
from insights.charts.data_quality_panel import data_quality_todos_resolutions_queryset
7+
from insights.charts.data_quality_panel import open_issues_to_datasource_queryset
8+
from vulnerabilities.models import AdvisoryToDoV2
9+
from vulnerabilities.models import AdvisoryV2
10+
from vulnerabilities.models import ToDoRelatedAdvisoryV2
11+
12+
13+
class TestDataQualityPanelQuerysets(TestCase):
14+
def setUp(self):
15+
self.adv1 = AdvisoryV2.objects.create(
16+
avid="github_osv/GHSA-1",
17+
datasource_id="github_osv",
18+
unique_content_id="1",
19+
is_latest=True,
20+
pipeline_id="github_osv_pipeline",
21+
advisory_id="GHSA-1",
22+
url="https://example.com/GHSA-1",
23+
)
24+
self.adv2 = AdvisoryV2.objects.create(
25+
avid="nvd/CVE-2023-1234",
26+
datasource_id="nvd",
27+
unique_content_id="2",
28+
is_latest=True,
29+
pipeline_id="nvd_pipeline",
30+
advisory_id="CVE-2023-1234",
31+
url="https://nvd.nist.gov/vuln/detail/CVE-2023-1234",
32+
)
33+
34+
now = timezone.now()
35+
36+
self.todo1 = AdvisoryToDoV2.objects.create(
37+
alias="GHSA-1-TODO",
38+
related_advisories_id="hash1",
39+
issue_type="MISSING_AFFECTED_PACKAGE",
40+
is_resolved=False,
41+
created_at=now - datetime.timedelta(days=60),
42+
)
43+
ToDoRelatedAdvisoryV2.objects.create(todo=self.todo1, advisory=self.adv1)
44+
45+
self.todo2 = AdvisoryToDoV2.objects.create(
46+
alias="CVE-2023-1234-TODO",
47+
related_advisories_id="hash2",
48+
issue_type="CONFLICTING_SEVERITY_SCORES",
49+
is_resolved=False,
50+
created_at=now - datetime.timedelta(days=45),
51+
)
52+
ToDoRelatedAdvisoryV2.objects.create(todo=self.todo2, advisory=self.adv2)
53+
54+
self.todo3 = AdvisoryToDoV2.objects.create(
55+
alias="GHSA-1-TODO-2",
56+
related_advisories_id="hash3",
57+
issue_type="CONFLICTING_SEVERITY_SCORES",
58+
is_resolved=True,
59+
created_at=now - datetime.timedelta(days=60),
60+
resolved_at=now - datetime.timedelta(days=15),
61+
)
62+
ToDoRelatedAdvisoryV2.objects.create(todo=self.todo3, advisory=self.adv1)
63+
64+
def test_open_issues_to_datasource_queryset(self):
65+
"""Test open issue query correctly aggregates unresolved to-dos by type and source."""
66+
qs = list(open_issues_to_datasource_queryset())
67+
68+
self.assertEqual(len(qs), 2)
69+
70+
missing_pkg_todo = next(t for t in qs if t["issue_type"] == "MISSING_AFFECTED_PACKAGE")
71+
self.assertEqual(missing_pkg_todo["advisories__datasource_id"], "github_osv")
72+
self.assertEqual(missing_pkg_todo["count"], 1)
73+
74+
conflicting_sev_todo = next(
75+
t for t in qs if t["issue_type"] == "CONFLICTING_SEVERITY_SCORES"
76+
)
77+
self.assertEqual(conflicting_sev_todo["advisories__datasource_id"], "nvd")
78+
self.assertEqual(conflicting_sev_todo["count"], 1)
79+
80+
def test_data_quality_todos_resolutions_queryset(self):
81+
"""Test timeline query separately aggregates opened and resolved to-dos by month."""
82+
open_todos_qs, resolved_todos_qs = data_quality_todos_resolutions_queryset()
83+
84+
open_todos = list(open_todos_qs)
85+
resolved_todos = list(resolved_todos_qs)
86+
87+
self.assertEqual(sum(t["count"] for t in open_todos), 3)
88+
self.assertEqual(sum(t["count"] for t in resolved_todos), 1)
89+
90+
resolved = resolved_todos[0]
91+
self.assertEqual(resolved["advisories__datasource_id"], "github_osv")
92+
self.assertEqual(resolved["count"], 1)

insights/tests/test_insights_snapshot_pipeline.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
from django.test import TestCase
2+
from django.utils import timezone
23

34
from insights.insights_snapshot_pipeline import InsightsSnapshotPipeline
45
from insights.models import DailySnapshot
56
from insights.tests.test_importer_panel import create_adv
67
from vulnerabilities.models import AdvisorySeverity
8+
from vulnerabilities.models import AdvisoryToDoV2
79
from vulnerabilities.models import PackageV2
10+
from vulnerabilities.models import ToDoRelatedAdvisoryV2
811

912

1013
class TestInsightsSnapshotPipeline(TestCase):
@@ -16,9 +19,20 @@ def test_pipeline_execution_with_data(self):
1619

1720
# Create Advisory for Importer and Severity charts
1821
advisory_1 = create_adv("GHSA-1234", "1")
22+
advisory_1.date_published = timezone.now()
23+
advisory_1.save()
1924
severity_1 = AdvisorySeverity.objects.create(scoring_system="cvssv3.1", value="9.8")
2025
advisory_1.severities.add(severity_1)
2126

27+
todo = AdvisoryToDoV2.objects.create(
28+
alias="GHSA-1234-TODO",
29+
related_advisories_id="hash1",
30+
issue_type="MISSING_AFFECTED_PACKAGE",
31+
is_resolved=False,
32+
created_at=timezone.now(),
33+
)
34+
ToDoRelatedAdvisoryV2.objects.create(todo=todo, advisory=advisory_1)
35+
2236
pipeline = InsightsSnapshotPipeline()
2337
pipeline.execute()
2438

@@ -35,3 +49,12 @@ def test_pipeline_execution_with_data(self):
3549
# Verify SeverityInsight was generated
3650
self.assertTrue(hasattr(snapshot, "severity_insight"))
3751
self.assertEqual(snapshot.severity_insight.buckets[9], 1)
52+
53+
self.assertTrue(hasattr(snapshot, "overview"))
54+
self.assertEqual(snapshot.overview.total_advisories, 1)
55+
self.assertEqual(len(snapshot.overview.last_30days), 31)
56+
self.assertEqual(snapshot.overview.yearly_insights.count(), 1)
57+
58+
self.assertEqual(snapshot.data_quality_issue_types.count(), 1)
59+
self.assertEqual(snapshot.data_quality_issue_types.first().datasource_id, "github_osv")
60+
self.assertEqual(snapshot.data_quality_todos_resolutions.count(), 1)
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import datetime
2+
3+
from django.test import TestCase
4+
from django.utils import timezone
5+
6+
from insights.charts.overview_panel import daily_growth_counts
7+
from insights.charts.overview_panel import kpi_card_queryset
8+
from insights.charts.overview_panel import yearly_distribution_queryset
9+
from insights.tests.test_importer_panel import create_adv
10+
from vulnerabilities.models import PackageV2
11+
12+
13+
class TestOverviewPanelQuerysets(TestCase):
14+
def setUp(self):
15+
PackageV2.objects.create(type="pypi", name="django", version="1.0.0")
16+
PackageV2.objects.create(type="npm", name="lodash", version="1.0.0")
17+
18+
self.now = timezone.now()
19+
20+
adv1 = create_adv("GHSA-1234", "1")
21+
adv1.date_published = self.now - datetime.timedelta(days=365 * 2)
22+
adv1.date_collected = self.now - datetime.timedelta(days=5)
23+
adv1.datasource_id = "github_osv"
24+
adv1.save()
25+
26+
adv2 = create_adv("GHSA-5678", "2")
27+
adv2.date_published = self.now
28+
adv2.date_collected = self.now
29+
adv2.datasource_id = "github_osv"
30+
adv2.save()
31+
32+
adv3 = create_adv("CVE-2023-7777", "3")
33+
adv3.date_published = self.now - datetime.timedelta(days=10)
34+
adv3.date_collected = self.now
35+
adv3.datasource_id = "nvd"
36+
adv3.save()
37+
38+
adv4 = create_adv("CVE-2024-9999", "4")
39+
adv4.date_published = self.now
40+
adv4.date_collected = self.now
41+
adv4.datasource_id = "nvd"
42+
adv4.save()
43+
44+
adv5 = create_adv("CVE-2024-8888", "5")
45+
adv5.date_published = self.now
46+
adv5.date_collected = self.now
47+
adv5.datasource_id = "nvd"
48+
adv5.save()
49+
50+
def test_kpi_card_queryset(self):
51+
"""Test KPI queries"""
52+
stats = kpi_card_queryset()
53+
self.assertEqual(stats["total_advisories"], 5)
54+
self.assertEqual(stats["total_packages"], 2)
55+
self.assertEqual(stats["total_data_sources"], 2)
56+
57+
def test_yearly_distribution_queryset(self):
58+
"""Test yearly distribution query aggregates advisories by publish year."""
59+
yearly_records = list(yearly_distribution_queryset())
60+
self.assertEqual(len(yearly_records), 2)
61+
62+
this_year = next(y for y in yearly_records if y["year"] == self.now.year)
63+
two_years_ago = next(y for y in yearly_records if y["year"] == self.now.year - 2)
64+
65+
self.assertEqual(this_year["count"], 4)
66+
self.assertEqual(two_years_ago["count"], 1)
67+
68+
def test_daily_growth_counts(self):
69+
"""Test daily ingestion query"""
70+
counts = daily_growth_counts(self.now)
71+
self.assertEqual(sum(counts), 5)

0 commit comments

Comments
 (0)