|
23 | 23 | from vulnerabilities.models import Alias |
24 | 24 | from vulnerabilities.models import ApiUser |
25 | 25 | from vulnerabilities.models import CodeFixV2 |
| 26 | +from vulnerabilities.models import ImpactedPackage |
26 | 27 | from vulnerabilities.models import Package |
| 28 | +from vulnerabilities.models import PackageCommitPatch |
27 | 29 | from vulnerabilities.models import PackageV2 |
| 30 | +from vulnerabilities.models import Patch |
28 | 31 | from vulnerabilities.models import PipelineRun |
29 | 32 | from vulnerabilities.models import PipelineSchedule |
30 | 33 | from vulnerabilities.models import Vulnerability |
@@ -834,3 +837,142 @@ def test_filter_codefix_by_advisory_id_not_found(self): |
834 | 837 | response = self.client.get(self.url, {"advisory_id": "nonexistent/ADVISORY-ID"}) |
835 | 838 | assert response.status_code == status.HTTP_200_OK |
836 | 839 | assert response.data["count"] == 0 |
| 840 | + |
| 841 | + |
| 842 | +class PackageCommitPatchList(APITestCase): |
| 843 | + def setUp(self): |
| 844 | + self.advisory = AdvisoryV2.objects.create( |
| 845 | + datasource_id="test_source", |
| 846 | + advisory_id="TEST-2025-001", |
| 847 | + avid="test_source/TEST-2025-001", |
| 848 | + unique_content_id="a" * 64, |
| 849 | + url="https://example.com/advisory", |
| 850 | + date_collected="2025-07-01T00:00:00Z", |
| 851 | + ) |
| 852 | + |
| 853 | + self.affected_package = PackageV2.objects.from_purl(purl="pkg:github/torvalds/linux@1.0.0") |
| 854 | + self.fixed_package = PackageV2.objects.from_purl(purl="pkg:github/torvalds/linux@1.0.1") |
| 855 | + |
| 856 | + self.pkg_commit_patch1 = PackageCommitPatch.objects.create( |
| 857 | + commit_hash="2e1c42391ff2556387b3cb6308b24f6f65619feb", |
| 858 | + vcs_url="https://github.com/torvalds/linux", |
| 859 | + patch_text="From 2e1c42391ff2556387b3cb6308b24f6f65619feb Mon Sep 17 00:00:00 2001...", |
| 860 | + ) |
| 861 | + |
| 862 | + self.pkg_commit_patch2 = PackageCommitPatch.objects.create( |
| 863 | + commit_hash="99253eb750fda6a644d5188fb26c43bad8d5a745", |
| 864 | + vcs_url="https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git", |
| 865 | + patch_text="From 99253eb750fda6a644d5188fb26c43bad8d5a745 Mon Sep 17 00:00:00 2001...", |
| 866 | + ) |
| 867 | + |
| 868 | + self.pkg_commit_patch3 = PackageCommitPatch.objects.create( |
| 869 | + commit_hash="f043bfc98c193c284e2cd768fefabe18ac2fed9b", |
| 870 | + vcs_url="https://github.com/torvalds/linux", |
| 871 | + patch_text="From f043bfc98c193c284e2cd768fefabe18ac2fed9b Mon Sep 17 00:00:00 2001...", |
| 872 | + ) |
| 873 | + |
| 874 | + self.impacted_package1 = ImpactedPackage.objects.create( |
| 875 | + base_purl="pkg:github/torvalds/linux", |
| 876 | + advisory=self.advisory, |
| 877 | + ) |
| 878 | + |
| 879 | + self.impacted_package2 = ImpactedPackage.objects.create( |
| 880 | + base_purl="pkg:generic/git.kernel.org/pub/scm/linux/kernel", |
| 881 | + advisory=self.advisory, |
| 882 | + ) |
| 883 | + |
| 884 | + self.impacted_package1.fixed_by_package_commit_patches.add(self.pkg_commit_patch1) |
| 885 | + self.impacted_package1.introduced_by_package_commit_patches.add(self.pkg_commit_patch3) |
| 886 | + self.impacted_package2.fixed_by_package_commit_patches.add(self.pkg_commit_patch2) |
| 887 | + |
| 888 | + self.user = ApiUser.objects.create_api_user(username="e@mail.com") |
| 889 | + self.auth = f"Token {self.user.auth_token.key}" |
| 890 | + self.client = APIClient(enforce_csrf_checks=True) |
| 891 | + self.client.credentials(HTTP_AUTHORIZATION=self.auth) |
| 892 | + self.url = reverse("package-commit-patch-list") |
| 893 | + |
| 894 | + def test_package_commit_patches_list(self): |
| 895 | + response = self.client.get(self.url) |
| 896 | + assert response.status_code == 200 |
| 897 | + results = response.json().get("results", response.json()) |
| 898 | + assert len(results) == 3 |
| 899 | + patch_data = results[0] |
| 900 | + assert patch_data["vcs_url"] == self.pkg_commit_patch1.vcs_url |
| 901 | + assert patch_data["commit_hash"] == self.pkg_commit_patch1.commit_hash |
| 902 | + assert patch_data["fixed_in_advisories"] == [ |
| 903 | + {"avid": self.advisory.avid, "purl": self.impacted_package1.base_purl} |
| 904 | + ] |
| 905 | + assert patch_data["introduced_in_advisories"] == [] |
| 906 | + |
| 907 | + def test_filter_by_commit_hash(self): |
| 908 | + response = self.client.get(f"{self.url}?commit_hash={self.pkg_commit_patch1.commit_hash}") |
| 909 | + results = response.json().get("results", response.json()) |
| 910 | + assert len(results) == 1 |
| 911 | + |
| 912 | + response = self.client.get(f"{self.url}?commit_hash=test") |
| 913 | + results = response.json().get("results", response.json()) |
| 914 | + assert len(results) == 0 |
| 915 | + |
| 916 | + def test_filter_by_vcs_url(self): |
| 917 | + response = self.client.get(f"{self.url}?vcs_url={self.pkg_commit_patch1.vcs_url}") |
| 918 | + results = response.json().get("results", response.json()) |
| 919 | + assert len(results) == 2 |
| 920 | + |
| 921 | + response = self.client.get(f"{self.url}?vcs_url=test") |
| 922 | + results = response.json().get("results", response.json()) |
| 923 | + assert len(results) == 0 |
| 924 | + |
| 925 | + def test_filter_by_advisory_avid(self): |
| 926 | + response = self.client.get(f"{self.url}?advisory_avid={self.advisory.avid}") |
| 927 | + results = response.json().get("results", response.json()) |
| 928 | + assert len(results) == 3 |
| 929 | + |
| 930 | + response = self.client.get(f"{self.url}?advisory_avid=test_source/DOES-NOT-EXIST") |
| 931 | + results = response.json().get("results", response.json()) |
| 932 | + assert len(results) == 0 |
| 933 | + |
| 934 | + def test_filter_by_purl(self): |
| 935 | + response = self.client.get(f"{self.url}?purl=pkg:github/torvalds/linux") |
| 936 | + results = response.json().get("results", response.json()) |
| 937 | + assert len(results) == 2 |
| 938 | + |
| 939 | + response = self.client.get(f"{self.url}?purl=pkg:github/aboutcode-org") |
| 940 | + results = response.json().get("results", response.json()) |
| 941 | + assert len(results) == 0 |
| 942 | + |
| 943 | + |
| 944 | +class PatchList(APITestCase): |
| 945 | + def setUp(self): |
| 946 | + self.advisory = AdvisoryV2.objects.create( |
| 947 | + datasource_id="test_source", |
| 948 | + advisory_id="TEST-2025-001", |
| 949 | + avid="test_source/TEST-2025-001", |
| 950 | + unique_content_id="a" * 64, |
| 951 | + url="https://example.com/advisory", |
| 952 | + date_collected="2025-07-01T00:00:00Z", |
| 953 | + ) |
| 954 | + |
| 955 | + self.patch = Patch.objects.create( |
| 956 | + patch_url="https://lore.kernel.org/patchwork/patch/1086060/", patch_text="some text" |
| 957 | + ) |
| 958 | + |
| 959 | + self.advisory.patches.add(self.patch) |
| 960 | + |
| 961 | + self.user = ApiUser.objects.create_api_user(username="e@mail.com") |
| 962 | + self.auth = f"Token {self.user.auth_token.key}" |
| 963 | + self.client = APIClient(enforce_csrf_checks=True) |
| 964 | + self.client.credentials(HTTP_AUTHORIZATION=self.auth) |
| 965 | + self.url = reverse("patches-list") |
| 966 | + |
| 967 | + def test_patch_list(self): |
| 968 | + response = self.client.get(self.url) |
| 969 | + assert response.status_code == 200 |
| 970 | + results = response.json().get("results", response.json()) |
| 971 | + assert len(results) == 1 |
| 972 | + assert results[0]["patch_url"] == self.patch.patch_url |
| 973 | + assert results == [ |
| 974 | + { |
| 975 | + "patch_url": "https://lore.kernel.org/patchwork/patch/1086060/", |
| 976 | + "in_advisories": ["test_source/TEST-2025-001"], |
| 977 | + } |
| 978 | + ] |
0 commit comments