public async Task WithNoExistingVulnerability_Withdrawn_DoesNotAdd() { // Arrange var id = "theId"; var versionRange = new VersionRange(NuGetVersion.Parse("1.0.0")).ToNormalizedString(); var vulnerability = new PackageVulnerability(); var range = new VulnerablePackageVersionRange { Vulnerability = vulnerability, PackageId = id, PackageVersionRange = versionRange }; vulnerability.AffectedRanges.Add(range); // Act await Service.UpdateVulnerabilityAsync(vulnerability, true); // Assert Assert.False(Context.Vulnerabilities.AnySafe()); Assert.False(Context.VulnerableRanges.AnySafe()); UpdateServiceMock.Verify( x => x.UpdatePackagesAsync(It.IsAny <IReadOnlyList <Package> >(), It.IsAny <bool>()), Times.Never); VerifyTransaction(); }
public async Task WithExistingVulnerability_Withdrawn_RemovesAndUnmarks(bool hasExistingVulnerablePackages) { // Arrange var key = 1; var vulnerability = new PackageVulnerability { GitHubDatabaseKey = key }; var existingVulnerability = new PackageVulnerability { GitHubDatabaseKey = key, Severity = PackageVulnerabilitySeverity.Moderate }; Context.Vulnerabilities.Add(existingVulnerability); var id = "theId"; var versionRange = new VersionRange(NuGetVersion.Parse("1.0.0")).ToNormalizedString(); var range = new VulnerablePackageVersionRange { Vulnerability = vulnerability, PackageId = id, PackageVersionRange = versionRange }; vulnerability.AffectedRanges.Add(range); if (hasExistingVulnerablePackages) { var existingVulnerablePackage = new Package(); var existingRange = new VulnerablePackageVersionRange { Vulnerability = existingVulnerability }; Context.VulnerableRanges.Add(existingRange); existingVulnerability.AffectedRanges.Add(existingRange); existingRange.Packages.Add(existingVulnerablePackage); vulnerability.AffectedRanges.Add(existingRange); UpdateServiceMock .Setup(x => x.UpdatePackagesAsync(new[] { existingVulnerablePackage }, true)) .Returns(Task.CompletedTask) .Verifiable(); } var service = GetService <PackageVulnerabilitiesManagementService>(); // Act await service.UpdateVulnerabilityAsync(vulnerability, true); // Assert Assert.False(Context.Vulnerabilities.AnySafe()); Assert.DoesNotContain(range, Context.VulnerableRanges); UpdateServiceMock.Verify(); VerifyTransaction(); }
public async Task WithNoExistingVulnerability_WithRanges_Adds() { // Arrange var id = "theId"; var versionRange = new VersionRange(NuGetVersion.Parse("1.0.0")).ToNormalizedString(); var vulnerability = new PackageVulnerability(); var range = new VulnerablePackageVersionRange { Vulnerability = vulnerability, PackageId = id, PackageVersionRange = versionRange }; vulnerability.AffectedRanges.Add(range); var registration = new PackageRegistration { Id = id }; Context.PackageRegistrations.Add(registration); var vulnerablePackage = new Package { PackageRegistration = registration, NormalizedVersion = "1.0.1" }; registration.Packages.Add(vulnerablePackage); var notVulnerablePackage = new Package { PackageRegistration = registration, NormalizedVersion = "0.0.0" }; registration.Packages.Add(notVulnerablePackage); UpdateServiceMock .Setup(x => x.UpdatePackagesAsync(new[] { vulnerablePackage }, true)) .Returns(Task.CompletedTask) .Verifiable(); // Act await Service.UpdateVulnerabilityAsync(vulnerability, false); // Assert Assert.Single(Context.Vulnerabilities, vulnerability); Assert.Single(Context.VulnerableRanges, range); UpdateServiceMock.Verify(); VerifyTransaction(); }
public async Task WithNoExistingVulnerability_NoRanges_DoesNotAdd() { // Arrange var vulnerability = new PackageVulnerability(); // Act await Service.UpdateVulnerabilityAsync(vulnerability, true); // Assert Assert.False(Context.Vulnerabilities.AnySafe()); Assert.False(Context.VulnerableRanges.AnySafe()); UpdateServiceMock.Verify( x => x.UpdatePackagesAsync(It.IsAny <IReadOnlyList <Package> >(), It.IsAny <bool>()), Times.Never); VerifyTransaction(); }
public async Task WithExistingVulnerability_NotWithdrawn_NoRanges_RemovesAndUnmarks(bool hasExistingVulnerablePackages) { // Arrange var key = 1; var vulnerability = new PackageVulnerability { GitHubDatabaseKey = key }; var existingVulnerability = new PackageVulnerability { GitHubDatabaseKey = key, Severity = PackageVulnerabilitySeverity.Moderate }; Context.Vulnerabilities.Add(existingVulnerability); if (hasExistingVulnerablePackages) { var existingVulnerablePackage = new Package(); var existingRange = new VulnerablePackageVersionRange { Vulnerability = existingVulnerability }; Context.VulnerableRanges.Add(existingRange); existingVulnerability.AffectedRanges.Add(existingRange); existingRange.Packages.Add(existingVulnerablePackage); UpdateServiceMock .Setup(x => x.UpdatePackagesAsync(new[] { existingVulnerablePackage }, true)) .Returns(Task.CompletedTask) .Verifiable(); } var service = GetService <PackageVulnerabilityService>(); // Act await service.UpdateVulnerabilityAsync(vulnerability, false); // Assert Assert.False(Context.Vulnerabilities.AnySafe()); Assert.False(Context.VulnerableRanges.AnySafe()); UpdateServiceMock.Verify(); VerifyTransaction(); }
public async Task WithExistingVulnerability_NotWithdrawn_UpdatesPackages( bool hasExistingVulnerablePackages, bool wasUpdated) { // Arrange var key = 1; var severity = PackageVulnerabilitySeverity.Low; var newSeverity = PackageVulnerabilitySeverity.Critical; var url = "http://hi"; var newUrl = "https://howdy"; var vulnerability = new PackageVulnerability { GitHubDatabaseKey = key, Severity = wasUpdated ? newSeverity : severity, AdvisoryUrl = wasUpdated ? newUrl : url }; var existingVulnerability = new PackageVulnerability { GitHubDatabaseKey = key, Severity = severity, AdvisoryUrl = url }; Context.Vulnerabilities.Add(existingVulnerability); var id = "theId"; var versionRange = new VersionRange(NuGetVersion.Parse("1.0.0")).ToNormalizedString(); var range = new VulnerablePackageVersionRange { Vulnerability = vulnerability, PackageId = id, PackageVersionRange = versionRange }; vulnerability.AffectedRanges.Add(range); var registration = new PackageRegistration { Id = id }; var expectedPackagesToUpdate = new List <Package>(); var expectedVulnerablePackages = new List <Package>(); if (hasExistingVulnerablePackages) { // Any packages that are already vulnerable to this vulnerability but not associated with this package vulnerability should be updated if the vulnerability is updated. var existingVulnerablePackage = new Package { PackageRegistration = registration, NormalizedVersion = "0.0.5" }; var existingVulnerablePackageVersion = NuGetVersion.Parse(existingVulnerablePackage.NormalizedVersion); var existingRange = new VulnerablePackageVersionRange { Vulnerability = existingVulnerability, PackageId = id, PackageVersionRange = new VersionRange(existingVulnerablePackageVersion, true, existingVulnerablePackageVersion, true).ToNormalizedString() }; Context.VulnerableRanges.Add(existingRange); existingRange.Packages.Add(existingVulnerablePackage); existingVulnerability.AffectedRanges.Add(existingRange); vulnerability.AffectedRanges.Add(existingRange); expectedVulnerablePackages.Add(existingVulnerablePackage); if (wasUpdated) { expectedPackagesToUpdate.Add(existingVulnerablePackage); } // If an existing vulnerable range is updated, its packages should be updated. var existingVulnerablePackageWithUpdatedRange = new Package { PackageRegistration = registration, NormalizedVersion = "0.0.9" }; var existingVulnerablePackageVersionWithUpdatedRange = NuGetVersion.Parse(existingVulnerablePackageWithUpdatedRange.NormalizedVersion); var existingRangeWithUpdatedRange = new VulnerablePackageVersionRange { Vulnerability = existingVulnerability, PackageId = id, PackageVersionRange = new VersionRange(existingVulnerablePackageVersionWithUpdatedRange, true, existingVulnerablePackageVersionWithUpdatedRange, true).ToNormalizedString() }; Context.VulnerableRanges.Add(existingRangeWithUpdatedRange); existingRangeWithUpdatedRange.Packages.Add(existingVulnerablePackageWithUpdatedRange); existingVulnerability.AffectedRanges.Add(existingRangeWithUpdatedRange); var updatedExistingRange = new VulnerablePackageVersionRange { Vulnerability = existingRangeWithUpdatedRange.Vulnerability, PackageId = existingRangeWithUpdatedRange.PackageId, PackageVersionRange = existingRangeWithUpdatedRange.PackageVersionRange, FirstPatchedPackageVersion = "1.0.0" }; vulnerability.AffectedRanges.Add(updatedExistingRange); expectedVulnerablePackages.Add(existingVulnerablePackageWithUpdatedRange); expectedPackagesToUpdate.Add(existingVulnerablePackageWithUpdatedRange); // If a package vulnerability is missing from the new vulnerability, it should be removed. var existingMissingVulnerablePackage = new Package { PackageRegistration = registration, NormalizedVersion = "0.0.6" }; var existingMissingVulnerablePackageVersion = NuGetVersion.Parse(existingMissingVulnerablePackage.NormalizedVersion); var existingMissingRange = new VulnerablePackageVersionRange { Vulnerability = existingVulnerability, PackageId = id, PackageVersionRange = new VersionRange(existingMissingVulnerablePackageVersion, true, existingMissingVulnerablePackageVersion, true).ToNormalizedString() }; Context.VulnerableRanges.Add(existingMissingRange); existingMissingRange.Packages.Add(existingMissingVulnerablePackage); existingVulnerability.AffectedRanges.Add(existingMissingRange); expectedPackagesToUpdate.Add(existingMissingVulnerablePackage); } Context.PackageRegistrations.Add(registration); // A package that fits in the version range but is not vulnerable yet should be vulnerable and updated. var newlyVulnerablePackage = new Package { PackageRegistration = registration, NormalizedVersion = "1.0.2" }; registration.Packages.Add(newlyVulnerablePackage); expectedVulnerablePackages.Add(newlyVulnerablePackage); expectedPackagesToUpdate.Add(newlyVulnerablePackage); // A package that is not vulnerable and does not fit in the version range should not be touched. var neverVulnerablePackage = new Package { PackageRegistration = registration, NormalizedVersion = "0.0.1" }; registration.Packages.Add(neverVulnerablePackage); if (expectedPackagesToUpdate.Any()) { UpdateServiceMock .Setup(x => x.UpdatePackagesAsync( It.Is <IReadOnlyList <Package> >( p => p .OrderBy(v => v.NormalizedVersion) .SequenceEqual( expectedPackagesToUpdate.OrderBy(v => v.NormalizedVersion))), true)) .Returns(Task.CompletedTask) .Verifiable(); } var service = GetService <PackageVulnerabilitiesManagementService>(); // Act await service.UpdateVulnerabilityAsync(vulnerability, false); // Assert Assert.Contains(existingVulnerability, Context.Vulnerabilities); Assert.Contains(range, Context.VulnerableRanges); Assert.Equal(existingVulnerability, range.Vulnerability); Assert.Equal(wasUpdated ? newSeverity : severity, existingVulnerability.Severity); Assert.Equal(wasUpdated ? newUrl : url, existingVulnerability.AdvisoryUrl); Assert.Equal( expectedVulnerablePackages.OrderBy(p => p.NormalizedVersion), Context.VulnerableRanges.SelectMany(pv => pv.Packages).OrderBy(p => p.NormalizedVersion)); UpdateServiceMock.Verify(); VerifyTransaction(); }