From 5a354c6a175286f70fb6d39194e84ad4457fd390 Mon Sep 17 00:00:00 2001 From: Patrick Sadowski Date: Mon, 26 Feb 2018 17:57:28 +0100 Subject: [PATCH] Use includeDelisted query parameter (#56) * Use includeDelisted query parameter * Rename parameter to share the same paradigm with NuGetGallery. * Simplify tests --- .../IServerPackageRepository.cs | 8 ++ .../Infrastructure/ServerPackageRepository.cs | 17 ++- .../ServerPackageRepositoryExtensions.cs | 17 +++ .../Controllers/NuGetODataController.cs | 19 ++-- .../ServerPackageRepositoryTest.cs | 100 +++++++++++++++++- 5 files changed, 145 insertions(+), 16 deletions(-) diff --git a/src/NuGet.Server.Core/Infrastructure/IServerPackageRepository.cs b/src/NuGet.Server.Core/Infrastructure/IServerPackageRepository.cs index b584a047..9c0c4ceb 100644 --- a/src/NuGet.Server.Core/Infrastructure/IServerPackageRepository.cs +++ b/src/NuGet.Server.Core/Infrastructure/IServerPackageRepository.cs @@ -22,6 +22,14 @@ Task> SearchAsync( ClientCompatibility compatibility, CancellationToken token); + Task> SearchAsync( + string searchTerm, + IEnumerable targetFrameworks, + bool allowPrereleaseVersions, + bool allowUnlistedVersions, + ClientCompatibility compatibility, + CancellationToken token); + Task ClearCacheAsync(CancellationToken token); Task RemovePackageAsync(string packageId, SemanticVersion version, CancellationToken token); diff --git a/src/NuGet.Server.Core/Infrastructure/ServerPackageRepository.cs b/src/NuGet.Server.Core/Infrastructure/ServerPackageRepository.cs index 7b8533b4..940a8a40 100644 --- a/src/NuGet.Server.Core/Infrastructure/ServerPackageRepository.cs +++ b/src/NuGet.Server.Core/Infrastructure/ServerPackageRepository.cs @@ -214,6 +214,17 @@ public async Task> SearchAsync( bool allowPrereleaseVersions, ClientCompatibility compatibility, CancellationToken token) + { + return await SearchAsync(searchTerm, targetFrameworks, allowPrereleaseVersions, false, compatibility, token); + } + + public async Task> SearchAsync( + string searchTerm, + IEnumerable targetFrameworks, + bool allowPrereleaseVersions, + bool allowUnlistedVersions, + ClientCompatibility compatibility, + CancellationToken token) { var cache = await GetPackagesAsync(compatibility, token); @@ -221,7 +232,7 @@ public async Task> SearchAsync( .Find(searchTerm) .FilterByPrerelease(allowPrereleaseVersions); - if (EnableDelisting) + if (EnableDelisting && !allowUnlistedVersions) { packages = packages.Where(p => p.Listed); } @@ -496,7 +507,7 @@ private async Task> ReadPackagesFromDiskWithoutLockingAsy throw; } } - + /// /// Sets the current cache to null so it will be regenerated next time. /// @@ -605,7 +616,7 @@ private async void FileSystemChangedAsync(object sender, FileSystemEventArgs e) return; } - changedDirectory = Path.GetFullPath(changedDirectory); + changedDirectory = Path.GetFullPath(changedDirectory); // 1) If a .nupkg is dropped in the root, add it as a package if (string.Equals(changedDirectory, _watchDirectory, StringComparison.OrdinalIgnoreCase) diff --git a/src/NuGet.Server.Core/Infrastructure/ServerPackageRepositoryExtensions.cs b/src/NuGet.Server.Core/Infrastructure/ServerPackageRepositoryExtensions.cs index 2d9acf20..e5d782fc 100644 --- a/src/NuGet.Server.Core/Infrastructure/ServerPackageRepositoryExtensions.cs +++ b/src/NuGet.Server.Core/Infrastructure/ServerPackageRepositoryExtensions.cs @@ -38,6 +38,23 @@ public static async Task> SearchAsync( token); } + public static async Task> SearchAsync( + this IServerPackageRepository repository, + string searchTerm, + bool allowPrereleaseVersions, + bool allowUnlistedVersions, + ClientCompatibility compatibility, + CancellationToken token) + { + return await repository.SearchAsync( + searchTerm, + Enumerable.Empty(), + allowPrereleaseVersions, + allowUnlistedVersions, + compatibility, + token); + } + public static async Task FindPackageAsync( this IServerPackageRepository repository, string id, diff --git a/src/NuGet.Server.V2/Controllers/NuGetODataController.cs b/src/NuGet.Server.V2/Controllers/NuGetODataController.cs index 03c7d745..a678f97c 100644 --- a/src/NuGet.Server.V2/Controllers/NuGetODataController.cs +++ b/src/NuGet.Server.V2/Controllers/NuGetODataController.cs @@ -44,7 +44,7 @@ protected NuGetODataController( _serverRepository = repository ?? throw new ArgumentNullException(nameof(repository)); _authenticationService = authenticationService; } - + // GET /Packages [HttpGet] public virtual async Task Get( @@ -129,8 +129,8 @@ public virtual IHttpActionResult GetPropertyFromPackages(string propertyName, st [HttpPost] public virtual async Task Search( ODataQueryOptions options, - [FromODataUri] string searchTerm = "", - [FromODataUri] string targetFramework = "", + [FromODataUri] string searchTerm = "", + [FromODataUri] string targetFramework = "", [FromODataUri] bool includePrerelease = false, [FromODataUri] bool includeDelisted = false, [FromUri] string semVerLevel = "", @@ -144,6 +144,7 @@ public virtual async Task Search( searchTerm, targetFrameworks, includePrerelease, + includeDelisted, clientCompatibility, token); @@ -203,8 +204,8 @@ public virtual async Task GetUpdates( var idValues = packageIds.Trim().Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); var versionValues = versions.Trim().Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries); - var targetFrameworkValues = String.IsNullOrEmpty(targetFrameworks) - ? null + var targetFrameworkValues = String.IsNullOrEmpty(targetFrameworks) + ? null : targetFrameworks.Split('|').Select(VersionUtility.ParseFrameworkName).ToList(); var versionConstraintValues = (String.IsNullOrEmpty(versionConstraints) ? new string[idValues.Length] @@ -219,7 +220,7 @@ public virtual async Task GetUpdates( var packagesToUpdate = new List(); for (var i = 0; i < idValues.Length; i++) { - if(SemanticVersion.TryParse(versionValues[i], out var semVersion)) + if (SemanticVersion.TryParse(versionValues[i], out var semVersion)) { packagesToUpdate.Add(new PackageBuilder { Id = idValues[i], Version = semVersion }); } @@ -365,7 +366,7 @@ public virtual async Task DeletePackage( } else { - return CreateStringResponse(HttpStatusCode.Forbidden, string.Format("Access denied for package '{0}', version '{1}'.", requestedPackage.Id,version)); + return CreateStringResponse(HttpStatusCode.Forbidden, string.Format("Access denied for package '{0}', version '{1}'.", requestedPackage.Id, version)); } } @@ -416,7 +417,7 @@ public virtual async Task UploadPackage(CancellationToken t File.Delete(temporaryFile); } catch (Exception) - { + { retValue = CreateStringResponse(HttpStatusCode.InternalServerError, "Could not remove temporary upload file."); } @@ -436,7 +437,7 @@ private string GetApiKeyFromHeader() { apiKey = values.FirstOrDefault(); } - + return apiKey; } diff --git a/test/NuGet.Server.Core.Tests/ServerPackageRepositoryTest.cs b/test/NuGet.Server.Core.Tests/ServerPackageRepositoryTest.cs index b813d942..e5391646 100644 --- a/test/NuGet.Server.Core.Tests/ServerPackageRepositoryTest.cs +++ b/test/NuGet.Server.Core.Tests/ServerPackageRepositoryTest.cs @@ -106,11 +106,11 @@ public async Task ServerPackageRepositoryAddsPackagesFromDropFolderOnStart(bool foreach (var packageToAddToDropFolder in packagesToAddToDropFolder) { var package = packages.FirstOrDefault( - p => p.Id == packageToAddToDropFolder.Value.Id + p => p.Id == packageToAddToDropFolder.Value.Id && p.Version == packageToAddToDropFolder.Value.Version); // check the package from drop folder has been added - Assert.NotNull(package); + Assert.NotNull(package); // check the package in the drop folder has been removed Assert.False(File.Exists(Path.Combine(temporaryDirectory.Path, packageToAddToDropFolder.Key))); @@ -356,6 +356,98 @@ public async Task ServerPackageRepositorySearchUnlisted() } } + [Fact] + public async Task ServerPackageRepositorySearchUnlistingDisabledAndExclude() + { + await ServerPackageRepositorySearchUnlistedWithOptions( + enableUnlisting: false, + allowUnlistedVersions: false, + searchable: false, + gettable: false); + } + + [Fact] + public async Task ServerPackageRepositorySearchUnlistingDisabledAndInclude() + { + await ServerPackageRepositorySearchUnlistedWithOptions( + enableUnlisting: false, + allowUnlistedVersions: true, + searchable: false, + gettable: false); + } + + [Fact] + public async Task ServerPackageRepositorySearchUnlistingEnabledAndExclude() + { + await ServerPackageRepositorySearchUnlistedWithOptions( + enableUnlisting: true, + allowUnlistedVersions: false, + searchable: false, + gettable: true); + } + + [Fact] + public async Task ServerPackageRepositorySearchUnlistingEnabledAndInclude() + { + await ServerPackageRepositorySearchUnlistedWithOptions( + enableUnlisting: true, + allowUnlistedVersions: true, + searchable: true, + gettable: true); + } + + private async Task ServerPackageRepositorySearchUnlistedWithOptions( + bool enableUnlisting, bool allowUnlistedVersions, bool searchable, bool gettable) + { + using (var temporaryDirectory = new TemporaryDirectory()) + { + // Arrange + var getSetting = enableUnlisting ? EnableDelisting : (Func)null; + var serverRepository = await CreateServerPackageRepositoryAsync(temporaryDirectory.Path, repository => + { + repository.AddPackage(CreatePackage("test1", "1.0")); + }, getSetting); + + // Remove the package + await serverRepository.RemovePackageAsync("test1", new SemanticVersion("1.0"), Token); + + // Verify that the package is not returned by search + var packages = (await serverRepository.SearchAsync( + "test1", + allowPrereleaseVersions: true, + allowUnlistedVersions: allowUnlistedVersions, + compatibility: ClientCompatibility.Max, + token: Token)).ToList(); + if (searchable) + { + Assert.Equal(1, packages.Count); + Assert.Equal("test1", packages[0].Id); + Assert.Equal("1.0", packages[0].Version.ToString()); + Assert.False(packages[0].Listed); + } + else + { + Assert.Equal(0, packages.Count); + } + + // Act: search with includeDelisted=true + packages = (await serverRepository.GetPackagesAsync(ClientCompatibility.Max, Token)).ToList(); + + // Assert + if (gettable) + { + Assert.Equal(1, packages.Count); + Assert.Equal("test1", packages[0].Id); + Assert.Equal("1.0", packages[0].Version.ToString()); + Assert.False(packages[0].Listed); + } + else + { + Assert.Equal(0, packages.Count); + } + } + } + [Fact] public async Task ServerPackageRepositoryFindPackageById() { @@ -463,7 +555,7 @@ public async Task ServerPackageRepositoryFindPackage() new SemanticVersion("1.0.0-alpha"), Token); var invalidPreRel = await serverRepository.FindPackageAsync( - "test3", + "test3", new SemanticVersion("1.0.0"), Token); var invalid = await serverRepository.FindPackageAsync("bad", new SemanticVersion("1.0"), Token); @@ -586,7 +678,7 @@ public async Task ServerPackageRepositoryIsLatestOnlyPreRel() repository.AddPackage(CreatePackage("test", "2.1-alpha")); repository.AddPackage(CreatePackage("test", "2.2-beta+tagged")); }); - + // Act var packages = await serverRepository.GetPackagesAsync(ClientCompatibility.Max, Token);