From eb737264780d9360a0eff70dddaff521c5bfcf05 Mon Sep 17 00:00:00 2001 From: Chuya Goto Date: Sun, 19 Sep 2021 14:55:03 +0900 Subject: [PATCH 1/4] feat: Support auto test. --- docker/web/.env.dev.web-example | 2 +- src/management/app/tests.py | 38 ++++++++++++++++++++++++++++++++- src/requirements.txt | 1 + 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/docker/web/.env.dev.web-example b/docker/web/.env.dev.web-example index 36fa363..afa3627 100644 --- a/docker/web/.env.dev.web-example +++ b/docker/web/.env.dev.web-example @@ -1,6 +1,6 @@ DEBUG=1 SECRET_KEY= -ALLOWED_HOSTS=host.docker.internal,localhost,127.0.0.1,[::1] +ALLOWED_HOSTS=host.docker.internal,localhost,127.0.0.1,[::1],testserver # Default account, obviously change for any real use. DJANGO_SUPERUSER_USERNAME=admin diff --git a/src/management/app/tests.py b/src/management/app/tests.py index 7ce503c..0d48b29 100644 --- a/src/management/app/tests.py +++ b/src/management/app/tests.py @@ -1,3 +1,39 @@ from django.test import TestCase +from django.test import Client +from app.models import Package +client = Client() -# Create your tests here. +class ViewApiGetPackageTests(TestCase): + + registered_package_url = "pkg:github/rails/rails" + registered_url = "https://github.com/rails/rails" + def setUp(self): + Package.objects.create(package_url=self.registered_package_url) + + def test_valid_package_url(self): + response = client.get(f"/api/1/get-project?package_url={self.registered_package_url}") + self.assertEqual(response.status_code, 200) + + def test_valid_url(self): + response = client.get(f"/api/1/get-project?url={self.registered_url}") + self.assertEqual(response.status_code, 200) + + def test_not_found(self): + response = client.get("/api/1/get-project?package_url=pkg:github/not_found/not_found") + print(response.content) + self.assertEqual(response.status_code, 404) + + def test_no_parameters(self): + response = client.get("/api/1/get-project") + self.assertEqual(response.status_code, 400) + self.assertEqual(response.content, b"Required, package_url or url.") + + def test_invalid_package_url(self): + response = client.get("/api/1/get-project?package_url=invalid") + self.assertEqual(response.status_code, 400) + self.assertEqual(response.content, b"Invalid Package URL.") + + def test_invalid_url(self): + response = client.get("/api/1/get-project?url=invalid") + self.assertEqual(response.status_code, 400) + self.assertEqual(response.content, b"Invalid URL.") diff --git a/src/requirements.txt b/src/requirements.txt index 5cf166c..3f354a5 100644 --- a/src/requirements.txt +++ b/src/requirements.txt @@ -37,3 +37,4 @@ typing-extensions==3.7.4.3 urllib3==1.26.5 websockets==9.1 yarl==1.6.3 +django-redis==5.0.0 \ No newline at end of file From 95f7171000089c7649cdee1b62f5f60ebdad33d6 Mon Sep 17 00:00:00 2001 From: Chuya Goto Date: Sun, 19 Sep 2021 14:58:22 +0900 Subject: [PATCH 2/4] fix: Add error handling for invalid parameter of package_url. --- src/management/app/views.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/management/app/views.py b/src/management/app/views.py index 3537871..a84c417 100644 --- a/src/management/app/views.py +++ b/src/management/app/views.py @@ -79,18 +79,19 @@ def api_get_package(request: HttpRequest) -> HttpResponse: """ purl = None package_url = request.GET.get("package_url") + url = request.GET.get("url") + if not (package_url or url): + return HttpResponseBadRequest("Required, package_url or url.") + if package_url: - purl = PackageURL.from_string(package_url) - if not purl: + try: + purl = PackageURL.from_string(package_url) + except ValueError: return HttpResponseBadRequest("Invalid Package URL.") - else: - url = request.GET.get("url") - if url: - purl = url2purl(url) - if not purl: - return HttpResponseBadRequest("Invalid URL.") - if not purl: - return HttpResponseBadRequest("Required, package_url or url.") + elif url: + purl = url2purl(url) + if not purl: + return HttpResponseBadRequest("Invalid URL.") package = get_object_or_404(Package, package_url=str(purl)) data = {"package_url": package.package_url} From 4bae7ca1d057098bb3896aa9ffda4a47be548199 Mon Sep 17 00:00:00 2001 From: Chuya Goto Date: Sun, 19 Sep 2021 15:27:30 +0900 Subject: [PATCH 3/4] feat: Use application/json response in case of status 400 or 404. --- src/management/app/tests.py | 9 +++++---- src/management/app/views.py | 31 +++++++++++++++++++++++++------ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/management/app/tests.py b/src/management/app/tests.py index 0d48b29..ac2c8e2 100644 --- a/src/management/app/tests.py +++ b/src/management/app/tests.py @@ -1,3 +1,4 @@ +import json from django.test import TestCase from django.test import Client from app.models import Package @@ -20,20 +21,20 @@ def test_valid_url(self): def test_not_found(self): response = client.get("/api/1/get-project?package_url=pkg:github/not_found/not_found") - print(response.content) self.assertEqual(response.status_code, 404) + self.assertEqual(json.loads(response.content)["message"], "Not Found.") def test_no_parameters(self): response = client.get("/api/1/get-project") self.assertEqual(response.status_code, 400) - self.assertEqual(response.content, b"Required, package_url or url.") + self.assertEqual(json.loads(response.content)["message"], "Required, package_url or url.") def test_invalid_package_url(self): response = client.get("/api/1/get-project?package_url=invalid") self.assertEqual(response.status_code, 400) - self.assertEqual(response.content, b"Invalid Package URL.") + self.assertEqual(json.loads(response.content)["message"], "Invalid Package URL.") def test_invalid_url(self): response = client.get("/api/1/get-project?url=invalid") self.assertEqual(response.status_code, 400) - self.assertEqual(response.content, b"Invalid URL.") + self.assertEqual(json.loads(response.content)["message"], "Invalid URL.") diff --git a/src/management/app/views.py b/src/management/app/views.py index a84c417..2de7c0f 100644 --- a/src/management/app/views.py +++ b/src/management/app/views.py @@ -8,8 +8,9 @@ from django.core.management import call_command, find_commands, get_commands from django.core.paginator import Paginator from django.forms.models import model_to_dict -from django.http import HttpRequest, HttpResponse, JsonResponse +from django.http import HttpRequest, HttpResponse, HttpResponseNotFound, JsonResponse from django.http.response import HttpResponseBadRequest +from django.core.exceptions import ObjectDoesNotExist from django.shortcuts import HttpResponseRedirect, get_object_or_404, render from packageurl import PackageURL from packageurl.contrib.url2purl import url2purl @@ -81,19 +82,25 @@ def api_get_package(request: HttpRequest) -> HttpResponse: package_url = request.GET.get("package_url") url = request.GET.get("url") if not (package_url or url): - return HttpResponseBadRequest("Required, package_url or url.") + return __get_bad_request_with_json("Required, package_url or url.") if package_url: try: purl = PackageURL.from_string(package_url) except ValueError: - return HttpResponseBadRequest("Invalid Package URL.") + return __get_bad_request_with_json("Invalid Package URL.") elif url: purl = url2purl(url) if not purl: - return HttpResponseBadRequest("Invalid URL.") - - package = get_object_or_404(Package, package_url=str(purl)) + return __get_bad_request_with_json("Invalid URL.") + try: + package = Package.objects.get(package_url=str(purl)) + except ObjectDoesNotExist: + return HttpResponseNotFound( + __to_serialized_error_json("Not Found."), + content_type="application/json" + ) + data = {"package_url": package.package_url} metrics = [] @@ -124,3 +131,15 @@ def search_package(request: HttpRequest) -> HttpResponse: def general_about(request: HttpRequest) -> HttpResponse: return render(request, "app/about.html", {}) + +def __get_bad_request_with_json(message: str) -> HttpResponseBadRequest: + return HttpResponseBadRequest( + __to_serialized_error_json(message), + content_type="application/json" + ) + +def __to_serialized_error_json(message: str) -> str: + error_json = { + "message": message + } + return json.dumps(error_json, indent=2) From 48ae0a73b2f86e5cde1af1107150bcc2cdf19221 Mon Sep 17 00:00:00 2001 From: Chuya Goto Date: Sun, 19 Sep 2021 15:40:10 +0900 Subject: [PATCH 4/4] fix: Add test to check response of metric asoosiated package --- src/management/app/tests.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/management/app/tests.py b/src/management/app/tests.py index ac2c8e2..b00cfba 100644 --- a/src/management/app/tests.py +++ b/src/management/app/tests.py @@ -1,19 +1,39 @@ import json from django.test import TestCase from django.test import Client -from app.models import Package +from app.models import Package, Metric client = Client() class ViewApiGetPackageTests(TestCase): registered_package_url = "pkg:github/rails/rails" registered_url = "https://github.com/rails/rails" + metric_key = "openssf.security-review" + metric_value = "test" + metric_properties = "test" + def setUp(self): - Package.objects.create(package_url=self.registered_package_url) + package = Package.objects.create(package_url=self.registered_package_url) + metric = Metric.objects.create( + package=package, key=self.metric_key, value=self.metric_value, properties=self.metric_properties + ) def test_valid_package_url(self): response = client.get(f"/api/1/get-project?package_url={self.registered_package_url}") self.assertEqual(response.status_code, 200) + self.assertEqual( + json.loads(response.content), + { + "package_url": self.registered_package_url, + "metrics": [ + { + "key": self.metric_key, + "value": self.metric_value, + "properties": self.metric_properties + } + ] + } + ) def test_valid_url(self): response = client.get(f"/api/1/get-project?url={self.registered_url}")