Skip to content

Commit 41f5aee

Browse files
committed
Add tests for bulk api endpoints
Signed-off-by: Shivam Sandbhor <shivam.sandbhor@gmail.com>
1 parent 136476b commit 41f5aee

3 files changed

Lines changed: 117 additions & 12 deletions

File tree

vulnerabilities/api.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -129,15 +129,13 @@ class PackageViewSet(viewsets.ReadOnlyModelViewSet):
129129
filter_backends = (filters.DjangoFilterBackend,)
130130
filterset_class = PackageFilterSet
131131

132-
# `fetch` is a placeholder
133-
# TODO: Find a good name for this endpoint
134132
@action(detail=False, methods=["post"])
135-
def fetch(self, request):
133+
def bulk_search(self, request):
136134
filter_list = Q()
137135
response = {}
138136
# TODO: Do some validation here of request body
139137

140-
for purl in request.data["packages"]:
138+
for purl in request.POST.getlist("packages"):
141139
filter_list |= Q(
142140
**{k: v for k, v in PackageURL.from_string(purl).to_dict().items() if v}
143141
)
@@ -167,20 +165,17 @@ class VulnerabilityViewSet(viewsets.ReadOnlyModelViewSet):
167165
filter_backends = (filters.DjangoFilterBackend,)
168166
filterset_class = VulnerabilityFilterSet
169167

170-
# `fetch` is a placeholder
171-
# TODO: Find a good name for this endpoint
172168
@action(detail=False, methods=["post"])
173-
def fetch(self, request):
169+
def bulk_search(self, request):
174170
filter_list = []
175171
response = {}
176172
# TODO: Do some validation here of request body
177-
for cve_id in request.data["vulnerabilities"]:
173+
174+
for cve_id in request.POST.getlist("vulnerabilities"):
178175
filter_list.append(cve_id)
179176
# This handles the case when the said cve doesnt exist in db
180177
response[cve_id] = {}
181-
182-
res = Vulnerability.objects.filter(cve_id__in=[cve_id])
178+
res = Vulnerability.objects.filter(cve_id__in=filter_list)
183179
for vuln in res:
184180
response[vuln.cve_id] = VulnerabilitySerializer(vuln, context={"request": request}).data
185-
186181
return Response(response)

vulnerabilities/fixtures/debian.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
},
7474
{
7575
"model": "vulnerabilities.packagerelatedvulnerability",
76-
"pk": 1,
76+
"pk": 10,
7777
"fields": {
7878
"vulnerability": 2,
7979
"package": 2,

vulnerabilities/tests/test_api.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
# Visit https://github.com/nexB/vulnerablecode/ for support and download.
2323

2424
import os
25+
from collections import OrderedDict
2526
from random import choices
2627
from unittest.mock import MagicMock
2728
from urllib.parse import quote
@@ -31,6 +32,8 @@
3132

3233
from vulnerabilities.api import PackageSerializer
3334
from vulnerabilities.models import Package
35+
from rest_framework.test import APIRequestFactory
36+
from rest_framework.test import APIClient
3437

3538

3639
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
@@ -188,3 +191,110 @@ def test_package_serializer(self):
188191
purls = {r["purl"] for r in response}
189192
self.assertIn("pkg:deb/debian/mimetex@1.50-1.1?distro=jessie", purls)
190193
self.assertIn("pkg:deb/debian/mimetex@1.74-1?distro=jessie", purls)
194+
195+
196+
class TestBulkAPIResponse(TestCase):
197+
fixtures = ["debian.json"]
198+
199+
def test_bulk_vulnerabilities_api(self):
200+
request_body = {"vulnerabilities": ["CVE-2009-1382", "CVE-2014-8242", "RANDOM-CVE"]}
201+
expected_response = {
202+
"CVE-2009-1382": {
203+
"url": "http://testserver/api/vulnerabilities/2/",
204+
"references": [],
205+
"resolved_packages": [
206+
OrderedDict(
207+
[
208+
("url", "http://testserver/api/packages/2/"),
209+
("purl", "pkg:deb/debian/mimetex@1.74-1?distro=jessie"),
210+
]
211+
),
212+
OrderedDict(
213+
[
214+
("url", "http://testserver/api/packages/3/"),
215+
("purl", "pkg:deb/debian/mimetex@1.50-1.1?distro=jessie"),
216+
]
217+
),
218+
],
219+
"unresolved_packages": [],
220+
"cve_id": "CVE-2009-1382",
221+
"summary": "",
222+
"cvss": None,
223+
},
224+
"CVE-2014-8242": {
225+
"url": "http://testserver/api/vulnerabilities/1/",
226+
"references": [],
227+
"resolved_packages": [],
228+
"unresolved_packages": [
229+
OrderedDict(
230+
[
231+
("url", "http://testserver/api/packages/1/"),
232+
("purl", "pkg:deb/debian/librsync@0.9.7-10?distro=jessie"),
233+
]
234+
)
235+
],
236+
"cve_id": "CVE-2014-8242",
237+
"summary": "",
238+
"cvss": None,
239+
},
240+
"RANDOM-CVE": {},
241+
}
242+
response = self.client.post("/api/vulnerabilities/bulk_search/", request_body).data
243+
assert response == expected_response
244+
245+
def test_bulk_packages_api(self):
246+
request_body = {
247+
"packages": [
248+
"pkg:deb/debian/librsync@0.9.7-10?distro=jessie",
249+
"pkg:deb/debian/mimetex@1.50-1.1?distro=jessie",
250+
]
251+
}
252+
response = self.client.post("/api/packages/bulk_search/", request_body).data
253+
expected_response = {
254+
"pkg:deb/debian/librsync@0.9.7-10?distro=jessie": {
255+
"url": "http://testserver/api/packages/1/",
256+
"type": "deb",
257+
"namespace": "debian",
258+
"name": "librsync",
259+
"version": "0.9.7-10",
260+
"qualifiers": {"distro": "jessie"},
261+
"subpath": "",
262+
"purl": "pkg:deb/debian/librsync@0.9.7-10?distro=jessie",
263+
"resolved_vulnerabilities": [],
264+
"unresolved_vulnerabilities": [
265+
OrderedDict(
266+
[
267+
("url", "http://testserver/api/vulnerabilities/1/"),
268+
("vulnerability_id", "CVE-2014-8242"),
269+
]
270+
)
271+
],
272+
},
273+
"pkg:deb/debian/mimetex@1.50-1.1?distro=jessie": {
274+
"url": "http://testserver/api/packages/3/",
275+
"type": "deb",
276+
"namespace": "debian",
277+
"name": "mimetex",
278+
"version": "1.50-1.1",
279+
"qualifiers": {"distro": "jessie"},
280+
"subpath": "",
281+
"purl": "pkg:deb/debian/mimetex@1.50-1.1?distro=jessie",
282+
"resolved_vulnerabilities": [
283+
OrderedDict(
284+
[
285+
("url", "http://testserver/api/vulnerabilities/2/"),
286+
("vulnerability_id", "CVE-2009-1382"),
287+
]
288+
),
289+
OrderedDict(
290+
[
291+
("url", "http://testserver/api/vulnerabilities/3/"),
292+
("vulnerability_id", "CVE-2009-2459"),
293+
]
294+
),
295+
],
296+
"unresolved_vulnerabilities": [],
297+
},
298+
}
299+
300+
assert response == expected_response

0 commit comments

Comments
 (0)