|
6 | 6 | # See https://github.com/aboutcode-org/vulnerablecode for support or download. |
7 | 7 | # See https://aboutcode.org for more information about nexB OSS projects. |
8 | 8 | # |
| 9 | +from datetime import datetime |
9 | 10 |
|
10 | 11 | from django.apps import apps |
| 12 | +from django.db import IntegrityError |
11 | 13 | from django.db import connection |
12 | 14 | from django.db.migrations.executor import MigrationExecutor |
13 | 15 | from django.test import TestCase |
@@ -951,3 +953,82 @@ def test_fix_alpine_purl(self): |
951 | 953 |
|
952 | 954 | assert package.filter(type="alpine").count() == 0 |
953 | 955 | assert package.filter(type="apk").count() == 1 |
| 956 | + |
| 957 | + |
| 958 | +class TestCodeCommitMigration(TestMigrations): |
| 959 | + """ |
| 960 | + Tests the migration that introduces the CodeCommit model |
| 961 | + and adds new ManyToMany fields to ImpactedPackage ( affecting_commits, fixed_by_commits ). |
| 962 | + """ |
| 963 | + |
| 964 | + app_name = "vulnerabilities" |
| 965 | + migrate_from = "0102_alter_impactedpackage_affecting_vers_and_more" |
| 966 | + migrate_to = "0103_codecommit_impactedpackage_affecting_commits_and_more" |
| 967 | + |
| 968 | + def setUpBeforeMigration(self, apps): |
| 969 | + """ |
| 970 | + Prepare old data before migration — this should be destroyed afterward. |
| 971 | + """ |
| 972 | + ImpactedPackage = apps.get_model("vulnerabilities", "ImpactedPackage") |
| 973 | + AdvisoryV2 = apps.get_model("vulnerabilities", "AdvisoryV2") |
| 974 | + |
| 975 | + date = datetime.now() |
| 976 | + adv = AdvisoryV2.objects.create( |
| 977 | + unique_content_id="old_adv", |
| 978 | + url="https://old.example.com", |
| 979 | + summary="Old advisory", |
| 980 | + date_imported=date, |
| 981 | + date_collected=date, |
| 982 | + advisory_id="old_adv", |
| 983 | + avid="test_pipeline/old_adv", |
| 984 | + datasource_id="test_pipeline", |
| 985 | + ) |
| 986 | + ImpactedPackage.objects.create(advisory=adv, base_purl="pkg:pypi/oldpkg") |
| 987 | + |
| 988 | + def test_unique_constraint_on_commit_hash_and_vcs_url(self): |
| 989 | + """Ensure the (commit_hash, vcs_url) uniqueness constraint works.""" |
| 990 | + CodeCommit = self.apps.get_model("vulnerabilities", "CodeCommit") |
| 991 | + |
| 992 | + CodeCommit.objects.create( |
| 993 | + commit_hash="abc123", |
| 994 | + vcs_url="https://github.com/example/repo.git", |
| 995 | + commit_rank="0", |
| 996 | + commit_author="tester", |
| 997 | + commit_message="message 1", |
| 998 | + commit_date=datetime.now(), |
| 999 | + ) |
| 1000 | + |
| 1001 | + with self.assertRaises(IntegrityError): |
| 1002 | + CodeCommit.objects.create( |
| 1003 | + commit_hash="abc123", |
| 1004 | + vcs_url="https://github.com/example/repo.git", |
| 1005 | + ) |
| 1006 | + |
| 1007 | + def test_m2m_relationships_work(self): |
| 1008 | + """Ensure that the new M2M relationships can store data.""" |
| 1009 | + ImpactedPackage = self.apps.get_model("vulnerabilities", "ImpactedPackage") |
| 1010 | + AdvisoryV2 = self.apps.get_model("vulnerabilities", "AdvisoryV2") |
| 1011 | + CodeCommit = self.apps.get_model("vulnerabilities", "CodeCommit") |
| 1012 | + |
| 1013 | + adv = AdvisoryV2.objects.get( |
| 1014 | + unique_content_id="old_adv", |
| 1015 | + advisory_id="old_adv", |
| 1016 | + avid="test_pipeline/old_adv", |
| 1017 | + datasource_id="test_pipeline", |
| 1018 | + ) |
| 1019 | + |
| 1020 | + impacted = ImpactedPackage.objects.get(advisory=adv, base_purl="pkg:pypi/oldpkg") |
| 1021 | + commit1 = CodeCommit.objects.create( |
| 1022 | + commit_hash="def456", |
| 1023 | + vcs_url="https://example.com/repo.git", |
| 1024 | + ) |
| 1025 | + commit2 = CodeCommit.objects.create( |
| 1026 | + commit_hash="eef456", |
| 1027 | + vcs_url="https://example.com/repo.git", |
| 1028 | + ) |
| 1029 | + |
| 1030 | + impacted.affecting_commits.add(commit1) |
| 1031 | + impacted.fixed_by_commits.add(commit2) |
| 1032 | + |
| 1033 | + self.assertIn(commit1, impacted.affecting_commits.all()) |
| 1034 | + self.assertIn(commit2, impacted.fixed_by_commits.all()) |
0 commit comments