@@ -49,8 +49,9 @@ def test_vulnerability_mixin_get_entry_for_package(self, mock_bulk_search):
4949 mock_bulk_search .return_value = json .loads (response_file .read_text ())
5050
5151 affected_by_vulnerabilities = package1 .get_entry_for_package (vulnerablecode )
52- self .assertEqual (2 , len (affected_by_vulnerabilities ))
52+ self .assertEqual (3 , len (affected_by_vulnerabilities ))
5353 self .assertEqual ("pypa/idna/PYSEC-2024-60" , affected_by_vulnerabilities [0 ]["advisory_uid" ])
54+ self .assertEqual (["pkg:pypi/idna@3.7" ], affected_by_vulnerabilities [0 ]["fixed_by_packages" ])
5455
5556 @mock .patch ("vulnerabilities.models.AffectedByVulnerabilityMixin.get_entry_for_package" )
5657 @mock .patch ("dejacode_toolkit.vulnerablecode.VulnerableCode.is_configured" )
@@ -79,12 +80,19 @@ def test_vulnerability_mixin_fetch_vulnerabilities(self, mock_is_configured, moc
7980 package1 = make_package (self .dataspace , package_url = "pkg:pypi/idna@3.6" )
8081 package1 .fetch_vulnerabilities ()
8182
82- self .assertEqual (2 , Vulnerability .objects .scope (self .dataspace ).count ())
83- self .assertEqual (2 , package1 .affected_by_vulnerabilities .count ())
83+ self .assertEqual (3 , Vulnerability .objects .scope (self .dataspace ).count ())
84+ self .assertEqual (3 , package1 .affected_by_vulnerabilities .count ())
8485 vulnerability = package1 .affected_by_vulnerabilities .filter (
8586 advisory_uid = "pypa/idna/PYSEC-2024-60"
8687 ).get ()
8788 self .assertEqual ("PYSEC-2024-60" , vulnerability .advisory_id )
89+ self .assertEqual (["pkg:pypi/idna@3.7" ], vulnerability .fixed_by_packages )
90+
91+ # This code path (single-package fetch) does not go through
92+ # vulnerabilities.fetch.process_vc_entry, so the purl-level fields are not set.
93+ package1 .refresh_from_db ()
94+ self .assertEqual ("" , package1 .next_non_vulnerable_version )
95+ self .assertEqual ("" , package1 .latest_non_vulnerable_version )
8896
8997 def test_vulnerability_mixin_create_vulnerabilities (self ):
9098 response_file = self .data / "vulnerabilities" / "idna_3.6_response.json"
@@ -96,7 +104,7 @@ def test_vulnerability_mixin_create_vulnerabilities(self):
96104 product1 = make_product (self .dataspace , inventory = [package1 ])
97105 package1 .create_vulnerabilities (vulnerabilities_data )
98106
99- self .assertEqual (3 , Vulnerability .objects .scope (self .dataspace ).count ())
107+ self .assertEqual (4 , Vulnerability .objects .scope (self .dataspace ).count ())
100108 self .assertEqual ("5.0" , str (package1 .risk_score ))
101109 self .assertEqual ("5.0" , str (product1 .productpackages .get ().weighted_risk_score ))
102110
@@ -199,17 +207,17 @@ def test_vulnerability_model_add_affected(self):
199207 self .assertQuerySetEqual (vulnerability2 .affected_packages .all (), [package1 ])
200208 self .assertQuerySetEqual (vulnerability2 .affected_components .all (), [component1 ])
201209
202- def test_vulnerability_model_fixed_packages_count_generated_field (self ):
210+ def test_vulnerability_model_fixed_by_packages_count_generated_field (self ):
203211 vulnerability1 = make_vulnerability (dataspace = self .dataspace )
204- self .assertEqual (0 , vulnerability1 .fixed_packages_count )
212+ self .assertEqual (0 , vulnerability1 .fixed_by_packages_count )
205213
206- vulnerability1 .fixed_packages = [
207- { "purl" : " pkg:pypi/gitpython@3.1.41", "is_vulnerable" : True } ,
208- { "purl" : " pkg:pypi/gitpython@3.2", "is_vulnerable" : False } ,
214+ vulnerability1 .fixed_by_packages = [
215+ " pkg:pypi/gitpython@3.1.41" ,
216+ " pkg:pypi/gitpython@3.2" ,
209217 ]
210218 vulnerability1 .save ()
211219 vulnerability1 .refresh_from_db ()
212- self .assertEqual (2 , vulnerability1 .fixed_packages_count )
220+ self .assertEqual (2 , vulnerability1 .fixed_by_packages_count )
213221
214222 def test_vulnerability_model_create_from_data (self ):
215223 package1 = make_package (self .dataspace )
0 commit comments