@@ -15,33 +15,25 @@ namespace NuGetGallery.Services
1515{
1616 public class PackageVulnerabilitiesCacheServiceFacts
1717 {
18+ private Mock < IServiceScope > _serviceScopeMock ;
19+ private Mock < ITelemetryService > _telemetryServiceMock ;
20+ private PackageVulnerabilitiesCacheService _cacheService ;
21+
1822 [ Fact ]
1923 public void RefreshesVulnerabilitiesCache ( )
2024 {
2125 // Arrange
22- var entitiesContext = new Mock < IEntitiesContext > ( ) ;
23- entitiesContext . Setup ( x => x . Set < VulnerablePackageVersionRange > ( ) ) . Returns ( GetVulnerableRanges ( ) ) ;
24- var serviceProvider = new Mock < IServiceProvider > ( ) ;
25- serviceProvider . Setup ( x => x . GetService ( typeof ( IEntitiesContext ) ) ) . Returns ( entitiesContext . Object ) ;
26- var serviceScope = new Mock < IServiceScope > ( ) ;
27- serviceScope . Setup ( x => x . ServiceProvider ) . Returns ( serviceProvider . Object ) ;
28- serviceScope . Setup ( x => x . Dispose ( ) ) . Verifiable ( ) ;
29- var serviceScopeFactory = new Mock < IServiceScopeFactory > ( ) ;
30- serviceScopeFactory . Setup ( x => x . CreateScope ( ) ) . Returns ( serviceScope . Object ) ;
31- var telemetryService = new Mock < ITelemetryService > ( ) ;
32- telemetryService . Setup ( x => x . TrackVulnerabilitiesCacheRefreshDuration ( It . IsAny < TimeSpan > ( ) ) ) . Verifiable ( ) ;
33- var cacheService = new PackageVulnerabilitiesCacheService ( telemetryService . Object ) ;
34- cacheService . RefreshCache ( serviceScopeFactory . Object ) ;
26+ Setup ( ) ;
3527
3628 // Act
37- var vulnerabilitiesFoo = cacheService . GetVulnerabilitiesById ( "Foo" ) ;
38- var vulnerabilitiesBar = cacheService . GetVulnerabilitiesById ( "Bar" ) ;
29+ var vulnerabilitiesFoo = _cacheService . GetVulnerabilitiesById ( "Foo" ) ;
30+ var vulnerabilitiesBar = _cacheService . GetVulnerabilitiesById ( "Bar" ) ;
3931
4032 // Assert
4133 // - ensure telemetry is sent
42- telemetryService . Verify ( x => x . TrackVulnerabilitiesCacheRefreshDuration ( It . IsAny < TimeSpan > ( ) ) , Times . Once ) ;
34+ _telemetryServiceMock . Verify ( x => x . TrackVulnerabilitiesCacheRefreshDuration ( It . IsAny < TimeSpan > ( ) ) , Times . Once ) ;
4335 // - ensure scope is disposed
44- serviceScope . Verify ( x => x . Dispose ( ) , Times . AtLeastOnce ) ;
36+ _serviceScopeMock . Verify ( x => x . Dispose ( ) , Times . AtLeastOnce ) ;
4537 // - ensure contants of cache are correct
4638 Assert . Equal ( 4 , vulnerabilitiesFoo . Count ) ;
4739 Assert . Equal ( 1 , vulnerabilitiesFoo [ 0 ] . Count ) ;
@@ -56,10 +48,57 @@ public void RefreshesVulnerabilitiesCache()
5648 Assert . Equal ( 1 , vulnerabilitiesBar [ 6 ] . Count ) ;
5749 }
5850
59- DbSet < VulnerablePackageVersionRange > GetVulnerableRanges ( )
51+ [ Theory ]
52+ [ InlineData ( "Foo" , 4 ) ]
53+ [ InlineData ( "Bar" , 2 ) ]
54+ [ InlineData ( "FOo" , 4 ) ]
55+ [ InlineData ( "FoO" , 4 ) ]
56+ [ InlineData ( "Bär" , 2 ) ]
57+ [ InlineData ( "BÄr" , 2 ) ]
58+ [ InlineData ( "ÇCombinedWithCedilla" , 1 ) ] // first char here is C combined with cedilla diacritic: /u00C7 ** actual match
59+ [ InlineData ( "çCombinedWithCedilla" , 1 ) ] // first char here is c combined with cedilla diacritic: /u00E7
60+ [ InlineData ( "çCombinedWithCedilla" , 1 ) ] // first char here c followed by combining cedilla diacritic: /u0063 /u0327
61+ [ InlineData ( "cCombinedWithCedilla" , 0 ) ] // first char here c only (not a match with a c-cedilla): /u0063
62+ [ InlineData ( "ÇFollowedByCedilla" , 1 ) ] // first char here is C combined with cedilla diacritic: /u00C7
63+ [ InlineData ( "çFollowedByCedilla" , 1 ) ] // first char here is c combined with cedilla diacritic: /u00E7
64+ [ InlineData ( "çFollowedByCedilla" , 1 ) ] // first char here c followed by combining cedilla diacritic: /u0063 /u0327 ** actual match
65+ [ InlineData ( "cFollowedByCedilla" , 0 ) ] // first char here c only (not a match with a c-cedilla): /u0063
66+ public void CacheSupportsCaseInsensitiveLookups ( string packageLookupId , int expectedVulnerabilitiesCount )
67+ {
68+ // Arrange
69+ Setup ( ) ;
70+
71+ // Act
72+ var vulnerabilitiesFoo = _cacheService . GetVulnerabilitiesById ( packageLookupId ) ;
73+
74+ // Assert
75+ Assert . Equal ( expectedVulnerabilitiesCount , vulnerabilitiesFoo ? . Count ?? 0 ) ;
76+ }
77+
78+ private void Setup ( )
79+ {
80+ var entitiesContext = new Mock < IEntitiesContext > ( ) ;
81+ entitiesContext . Setup ( x => x . Set < VulnerablePackageVersionRange > ( ) ) . Returns ( GetVulnerableRanges ( ) ) ;
82+ var serviceProvider = new Mock < IServiceProvider > ( ) ;
83+ serviceProvider . Setup ( x => x . GetService ( typeof ( IEntitiesContext ) ) ) . Returns ( entitiesContext . Object ) ;
84+ _serviceScopeMock = new Mock < IServiceScope > ( ) ;
85+ _serviceScopeMock . Setup ( x => x . ServiceProvider ) . Returns ( serviceProvider . Object ) ;
86+ _serviceScopeMock . Setup ( x => x . Dispose ( ) ) . Verifiable ( ) ;
87+ var serviceScopeFactory = new Mock < IServiceScopeFactory > ( ) ;
88+ serviceScopeFactory . Setup ( x => x . CreateScope ( ) ) . Returns ( _serviceScopeMock . Object ) ;
89+ _telemetryServiceMock = new Mock < ITelemetryService > ( ) ;
90+ _telemetryServiceMock . Setup ( x => x . TrackVulnerabilitiesCacheRefreshDuration ( It . IsAny < TimeSpan > ( ) ) ) . Verifiable ( ) ;
91+ _cacheService = new PackageVulnerabilitiesCacheService ( _telemetryServiceMock . Object ) ;
92+ _cacheService . RefreshCache ( serviceScopeFactory . Object ) ;
93+ }
94+
95+ private static DbSet < VulnerablePackageVersionRange > GetVulnerableRanges ( )
6096 {
6197 var registrationFoo = new PackageRegistration { Id = "Foo" } ;
6298 var registrationBar = new PackageRegistration { Id = "Bar" } ;
99+ var registrationBarNonLatin = new PackageRegistration { Id = "Bär" } ;
100+ var registrationCedillaNonLatin = new PackageRegistration { Id = "ÇCombinedWithCedilla" } ; // Ç is /u00C7
101+ var registrationCedillaNonLatin2 = new PackageRegistration { Id = "çFollowedByCedilla" } ; // ç is /u0063 /u0327
63102
64103 var vulnerabilityCriticalFoo = new PackageVulnerability
65104 {
@@ -79,6 +118,24 @@ DbSet<VulnerablePackageVersionRange> GetVulnerableRanges()
79118 GitHubDatabaseKey = 9012 ,
80119 Severity = PackageVulnerabilitySeverity . Critical
81120 } ;
121+ var vulnerabilityCriticalBarNonLatin = new PackageVulnerability
122+ {
123+ AdvisoryUrl = "http://theurl/2109" ,
124+ GitHubDatabaseKey = 2109 ,
125+ Severity = PackageVulnerabilitySeverity . Critical
126+ } ;
127+ var vulnerabilityCriticalCedillaNonLatin = new PackageVulnerability
128+ {
129+ AdvisoryUrl = "http://theurl/2901" ,
130+ GitHubDatabaseKey = 2901 ,
131+ Severity = PackageVulnerabilitySeverity . Critical
132+ } ;
133+ var vulnerabilityCriticalCedillaNonLatin2 = new PackageVulnerability
134+ {
135+ AdvisoryUrl = "http://theurl/29012" ,
136+ GitHubDatabaseKey = 29012 ,
137+ Severity = PackageVulnerabilitySeverity . Critical
138+ } ;
82139
83140 var versionRangeCriticalFoo = new VulnerablePackageVersionRange
84141 {
@@ -101,6 +158,27 @@ DbSet<VulnerablePackageVersionRange> GetVulnerableRanges()
101158 PackageVersionRange = "<=1.1.0" ,
102159 FirstPatchedPackageVersion = "1.1.1"
103160 } ;
161+ var versionRangeCriticalBarNonLatin = new VulnerablePackageVersionRange
162+ {
163+ Vulnerability = vulnerabilityCriticalBarNonLatin ,
164+ PackageId = "Bär" ,
165+ PackageVersionRange = "<=1.1.0" ,
166+ FirstPatchedPackageVersion = "1.1.1"
167+ } ;
168+ var versionRangeCriticalCedillaNonLatin = new VulnerablePackageVersionRange
169+ {
170+ Vulnerability = vulnerabilityCriticalCedillaNonLatin ,
171+ PackageId = "ÇCombinedWithCedilla" ,
172+ PackageVersionRange = "<=1.0.0" ,
173+ FirstPatchedPackageVersion = "1.1.1"
174+ } ;
175+ var versionRangeCriticalCedillaNonLatin2 = new VulnerablePackageVersionRange
176+ {
177+ Vulnerability = vulnerabilityCriticalCedillaNonLatin2 ,
178+ PackageId = "çFollowedByCedilla" ,
179+ PackageVersionRange = "<=1.0.0" ,
180+ FirstPatchedPackageVersion = "1.1.1"
181+ } ;
104182
105183 var packageFoo100 = new Package
106184 {
@@ -163,12 +241,57 @@ DbSet<VulnerablePackageVersionRange> GetVulnerableRanges()
163241 versionRangeCriticalBar
164242 }
165243 } ;
244+ var packageBarNonLatin100 = new Package
245+ {
246+ Key = 5 ,
247+ Version = "1.0.0" ,
248+ PackageRegistration = registrationBarNonLatin ,
249+ VulnerablePackageRanges = new List < VulnerablePackageVersionRange >
250+ {
251+ versionRangeCriticalBarNonLatin
252+ }
253+ } ;
254+ var packageBarNonLatin110 = new Package
255+ {
256+ Key = 6 ,
257+ PackageRegistration = registrationBarNonLatin ,
258+ Version = "1.1.0" ,
259+ VulnerablePackageRanges = new List < VulnerablePackageVersionRange >
260+ {
261+ versionRangeCriticalBarNonLatin
262+ }
263+ } ;
264+ var packageCedillaNonLatin100 = new Package
265+ {
266+ Key = 5 ,
267+ Version = "1.0.0" ,
268+ PackageRegistration = registrationCedillaNonLatin ,
269+ VulnerablePackageRanges = new List < VulnerablePackageVersionRange >
270+ {
271+ versionRangeCriticalCedillaNonLatin
272+ }
273+ } ;
274+ var packageCedillaNonLatin2_100 = new Package
275+ {
276+ Key = 5 ,
277+ Version = "1.0.0" ,
278+ PackageRegistration = registrationCedillaNonLatin2 ,
279+ VulnerablePackageRanges = new List < VulnerablePackageVersionRange >
280+ {
281+ versionRangeCriticalCedillaNonLatin2
282+ }
283+ } ;
166284
167285 versionRangeCriticalFoo . Packages = new List < Package > { packageFoo111 } ;
168286 versionRangeModerateFoo . Packages = new List < Package > { packageFoo100 , packageFoo110 , packageFoo111 , packageFoo112 } ;
169287 versionRangeCriticalBar . Packages = new List < Package > { packageBar100 , packageBar110 } ;
288+ versionRangeCriticalBarNonLatin . Packages = new List < Package > { packageBarNonLatin100 , packageBarNonLatin110 } ;
289+ versionRangeCriticalCedillaNonLatin . Packages = new List < Package > { packageCedillaNonLatin100 } ;
290+ versionRangeCriticalCedillaNonLatin2 . Packages = new List < Package > { packageCedillaNonLatin2_100 } ;
170291
171- var vulnerableRangeList = new List < VulnerablePackageVersionRange > { versionRangeCriticalFoo , versionRangeModerateFoo , versionRangeCriticalBar } . AsQueryable ( ) ;
292+ var vulnerableRangeList = new List < VulnerablePackageVersionRange > { versionRangeCriticalFoo , versionRangeModerateFoo , versionRangeCriticalBar ,
293+ versionRangeCriticalBarNonLatin , versionRangeCriticalCedillaNonLatin , versionRangeCriticalCedillaNonLatin2 }
294+ . AsQueryable ( ) ;
172295 var vulnerableRangeDbSet = new Mock < DbSet < VulnerablePackageVersionRange > > ( ) ;
173296
174297 // boilerplate mock DbSet redirects:
0 commit comments