Skip to content

Commit

Permalink
Refine the delete event on m2m #95
Browse files Browse the repository at this point in the history
Signed-off-by: tdruez <tdruez@nexb.com>
  • Loading branch information
tdruez committed Sep 4, 2024
1 parent c2e7e62 commit fdf4cd0
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 28 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 5.0.6 on 2024-09-04 08:17
# Generated by Django 5.0.6 on 2024-09-04 09:15

import django.db.models.deletion
import uuid
Expand All @@ -21,7 +21,7 @@ class Migration(migrations.Migration):
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, verbose_name='UUID')),
('component', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='component_catalog.component')),
('dataspace', models.ForeignKey(editable=False, help_text='A Dataspace is an independent, exclusive set of DejaCode data, which can be either nexB master reference data or installation-specific data.', on_delete=django.db.models.deletion.PROTECT, to='dje.dataspace')),
('vulnerability', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='vulnerabilities.vulnerability')),
('vulnerability', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vulnerabilities.vulnerability')),
],
options={
'unique_together': {('component', 'vulnerability'), ('dataspace', 'uuid')},
Expand All @@ -39,7 +39,7 @@ class Migration(migrations.Migration):
('uuid', models.UUIDField(default=uuid.uuid4, editable=False, verbose_name='UUID')),
('dataspace', models.ForeignKey(editable=False, help_text='A Dataspace is an independent, exclusive set of DejaCode data, which can be either nexB master reference data or installation-specific data.', on_delete=django.db.models.deletion.PROTECT, to='dje.dataspace')),
('package', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='component_catalog.package')),
('vulnerability', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='vulnerabilities.vulnerability')),
('vulnerability', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='vulnerabilities.vulnerability')),
],
options={
'unique_together': {('dataspace', 'uuid'), ('package', 'vulnerability')},
Expand Down
7 changes: 1 addition & 6 deletions vulnerabilities/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,20 +256,15 @@ def as_cyclonedx(self, affected_instances):
)


# TODO: Review cascade
class AffectedByVulnerabilityRelationship(DataspacedModel):
vulnerability = models.ForeignKey(
to="vulnerabilities.Vulnerability",
on_delete=models.PROTECT,
on_delete=models.CASCADE,
)

class Meta:
abstract = True

def save(self, *args, **kwargs):
self.dataspace = self.vulnerability.dataspace
super().save(*args, **kwargs)


class AffectedByVulnerabilityMixin(models.Model):
"""Add the `vulnerability` many to many field."""
Expand Down
52 changes: 33 additions & 19 deletions vulnerabilities/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from django.test import TestCase

from component_catalog.tests import make_component
from component_catalog.models import Package
from component_catalog.tests import make_package
from dejacode_toolkit.vulnerablecode import VulnerableCode
from dje.models import Dataspace
Expand Down Expand Up @@ -85,35 +86,48 @@ def test_vulnerability_mixin_create_vulnerabilities(self):

def test_vulnerability_model_affected_packages_m2m(self):
package1 = make_package(self.dataspace)
vulnerablity1 = make_vulnerability(dataspace=self.dataspace, affecting=package1)
self.assertEqual(package1, vulnerablity1.affected_packages.get())
self.assertEqual(vulnerablity1, package1.affected_by_vulnerabilities.get())
vulnerability1 = make_vulnerability(dataspace=self.dataspace, affecting=package1)
self.assertEqual(package1, vulnerability1.affected_packages.get())
self.assertEqual(vulnerability1, package1.affected_by_vulnerabilities.get())

def test_vulnerability_model_affected_by_vulnerability_relationship_delete(self):
package1 = make_package(self.dataspace)
vulnerability1 = make_vulnerability(dataspace=self.dataspace, affecting=package1)
package1.delete()
self.assertEqual(vulnerability1, Vulnerability.objects.get())
self.assertEqual(0, Package.objects.count())

package1 = make_package(self.dataspace)
vulnerability1.add_affected(package1)
vulnerability1.delete()
self.assertEqual(package1, Package.objects.get())
self.assertEqual(0, Vulnerability.objects.count())

def test_vulnerability_model_add_affected(self):
vulnerablity1 = make_vulnerability(dataspace=self.dataspace)
vulnerability1 = make_vulnerability(dataspace=self.dataspace)
package1 = make_package(self.dataspace)
package2 = make_package(self.dataspace)
vulnerablity1.add_affected(package1)
vulnerablity1.add_affected([package2])
self.assertEqual(2, vulnerablity1.affected_packages.count())
vulnerability1.add_affected(package1)
vulnerability1.add_affected([package2])
self.assertEqual(2, vulnerability1.affected_packages.count())

vulnerablity2 = make_vulnerability(dataspace=self.dataspace)
vulnerability2 = make_vulnerability(dataspace=self.dataspace)
component1 = make_component(self.dataspace)
vulnerablity2.add_affected([component1, package1])
self.assertQuerySetEqual(vulnerablity2.affected_packages.all(), [package1])
self.assertQuerySetEqual(vulnerablity2.affected_components.all(), [component1])
vulnerability2.add_affected([component1, package1])
self.assertQuerySetEqual(vulnerability2.affected_packages.all(), [package1])
self.assertQuerySetEqual(vulnerability2.affected_components.all(), [component1])

def test_vulnerability_model_fixed_packages_count_generated_field(self):
vulnerablity1 = make_vulnerability(dataspace=self.dataspace)
self.assertEqual(0, vulnerablity1.fixed_packages_count)
vulnerability1 = make_vulnerability(dataspace=self.dataspace)
self.assertEqual(0, vulnerability1.fixed_packages_count)

vulnerablity1.fixed_packages = [
vulnerability1.fixed_packages = [
{"purl": "pkg:pypi/gitpython@3.1.41", "is_vulnerable": True},
{"purl": "pkg:pypi/gitpython@3.2", "is_vulnerable": False},
]
vulnerablity1.save()
vulnerablity1.refresh_from_db()
self.assertEqual(2, vulnerablity1.fixed_packages_count)
vulnerability1.save()
vulnerability1.refresh_from_db()
self.assertEqual(2, vulnerability1.fixed_packages_count)

def test_vulnerability_model_create_from_data(self):
package1 = make_package(self.dataspace)
Expand Down Expand Up @@ -164,8 +178,8 @@ def test_vulnerability_model_create_from_data_computed_scores(self):
def test_vulnerability_model_queryset_count_methods(self):
package1 = make_package(self.dataspace)
package2 = make_package(self.dataspace)
vulnerablity1 = make_vulnerability(dataspace=self.dataspace)
vulnerablity1.add_affected([package1, package2])
vulnerability1 = make_vulnerability(dataspace=self.dataspace)
vulnerability1.add_affected([package1, package2])
make_product(self.dataspace, inventory=[package1, package2])

qs = (
Expand Down

0 comments on commit fdf4cd0

Please sign in to comment.