Skip to content

Commit 3f5b186

Browse files
committed
Add tests
Signed-off-by: Tushar Goel <tushar.goel.dav@gmail.com>
1 parent b94655c commit 3f5b186

File tree

1 file changed

+190
-0
lines changed

1 file changed

+190
-0
lines changed
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
#
2+
# Copyright (c) nexB Inc. and others. All rights reserved.
3+
# VulnerableCode is a trademark of nexB Inc.
4+
# SPDX-License-Identifier: Apache-2.0
5+
# See http://www.apache.org/licenses/LICENSE-2.0 for the license text.
6+
# See https://github.com/aboutcode-org/vulnerablecode for support or download.
7+
# See https://aboutcode.org for more information about nexB OSS projects.
8+
#
9+
10+
import uuid
11+
import pytest
12+
from datetime import timedelta
13+
from django.utils.timezone import now
14+
15+
from vulnerabilities.models import AdvisoryV2
16+
17+
18+
@pytest.fixture
19+
def advisory_factory(db):
20+
"""
21+
Factory to create AdvisoryV2 objects with minimal required fields.
22+
"""
23+
24+
def _create(*, avid, advisory_id, collected_at):
25+
return AdvisoryV2.objects.create(
26+
datasource_id="test_source",
27+
advisory_id=advisory_id,
28+
avid=avid,
29+
unique_content_id=str(uuid.uuid4()),
30+
url="https://example.com/advisory",
31+
date_collected=collected_at,
32+
)
33+
34+
return _create
35+
36+
37+
@pytest.fixture
38+
def timestamps():
39+
now_ts = now()
40+
return {
41+
"old": now_ts - timedelta(days=3),
42+
"mid": now_ts - timedelta(days=1),
43+
"new": now_ts,
44+
}
45+
46+
47+
@pytest.mark.django_db
48+
def test_latest_for_avid_returns_latest_by_date_collected(
49+
advisory_factory, timestamps, django_assert_num_queries
50+
):
51+
avid = "source/ADV-1"
52+
53+
older = advisory_factory(
54+
avid=avid,
55+
advisory_id="ADV-1",
56+
collected_at=timestamps["old"],
57+
)
58+
newer = advisory_factory(
59+
avid=avid,
60+
advisory_id="ADV-1",
61+
collected_at=timestamps["new"],
62+
)
63+
64+
with django_assert_num_queries(1):
65+
result = AdvisoryV2.objects.latest_for_avid(avid)
66+
67+
assert result.id == newer.id
68+
assert result.id != older.id
69+
70+
71+
@pytest.mark.django_db
72+
def test_latest_for_avid_tie_breaks_by_id(
73+
advisory_factory, timestamps, django_assert_num_queries
74+
):
75+
avid = "source/ADV-2"
76+
ts = timestamps["mid"]
77+
78+
first = advisory_factory(
79+
avid=avid,
80+
advisory_id="ADV-2",
81+
collected_at=ts,
82+
)
83+
second = advisory_factory(
84+
avid=avid,
85+
advisory_id="ADV-2",
86+
collected_at=ts,
87+
)
88+
89+
with django_assert_num_queries(1):
90+
result = AdvisoryV2.objects.latest_for_avid(avid)
91+
92+
assert result.id == second.id
93+
94+
95+
@pytest.mark.django_db
96+
def test_latest_per_avid_returns_one_row_per_avid(
97+
advisory_factory, timestamps, django_assert_num_queries
98+
):
99+
advisory_factory(
100+
avid="source/A",
101+
advisory_id="A",
102+
collected_at=timestamps["old"],
103+
)
104+
latest_a = advisory_factory(
105+
avid="source/A",
106+
advisory_id="A",
107+
collected_at=timestamps["new"],
108+
)
109+
110+
latest_b = advisory_factory(
111+
avid="source/B",
112+
advisory_id="B",
113+
collected_at=timestamps["mid"],
114+
)
115+
116+
with django_assert_num_queries(1):
117+
qs = AdvisoryV2.objects.latest_per_avid()
118+
results = list(qs)
119+
120+
assert len(results) == 2
121+
ids = {obj.id for obj in results}
122+
assert ids == {latest_a.id, latest_b.id}
123+
124+
125+
@pytest.mark.django_db
126+
def test_latest_per_avid_excludes_older_versions(
127+
advisory_factory, timestamps
128+
):
129+
avid = "source/C"
130+
131+
older = advisory_factory(
132+
avid=avid,
133+
advisory_id="C",
134+
collected_at=timestamps["old"],
135+
)
136+
latest = advisory_factory(
137+
avid=avid,
138+
advisory_id="C",
139+
collected_at=timestamps["new"],
140+
)
141+
142+
results = list(AdvisoryV2.objects.latest_per_avid())
143+
144+
assert latest in results
145+
assert older not in results
146+
147+
148+
@pytest.mark.django_db
149+
def test_latest_for_avids_filters_and_collapses_correctly(
150+
advisory_factory, timestamps, django_assert_num_queries
151+
):
152+
advisory_factory(
153+
avid="source/A",
154+
advisory_id="A",
155+
collected_at=timestamps["old"],
156+
)
157+
latest_a = advisory_factory(
158+
avid="source/A",
159+
advisory_id="A",
160+
collected_at=timestamps["new"],
161+
)
162+
163+
latest_b = advisory_factory(
164+
avid="source/B",
165+
advisory_id="B",
166+
collected_at=timestamps["mid"],
167+
)
168+
169+
advisory_factory(
170+
avid="source/C",
171+
advisory_id="C",
172+
collected_at=timestamps["new"],
173+
)
174+
175+
with django_assert_num_queries(1):
176+
qs = AdvisoryV2.objects.latest_for_avids({"source/A", "source/B"})
177+
results = list(qs)
178+
179+
assert len(results) == 2
180+
ids = {obj.id for obj in results}
181+
assert ids == {latest_a.id, latest_b.id}
182+
183+
184+
@pytest.mark.django_db
185+
def test_latest_for_avids_with_empty_input_returns_empty_queryset(
186+
django_assert_num_queries
187+
):
188+
with django_assert_num_queries(0):
189+
qs = AdvisoryV2.objects.latest_for_avids(set())
190+
assert qs.count() == 0

0 commit comments

Comments
 (0)