Skip to content

Commit

Permalink
Low level part of fixing #403.
Browse files Browse the repository at this point in the history
Make the LATEST STABLE package version the one returned by default when version == null.
Make the LATEST version the one returned if no STABLE version exists and allowPrerelease == true.
  • Loading branch information
Tim Lovell-Smith committed Oct 3, 2013
1 parent 077b46f commit fd20ca4
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 60 deletions.
14 changes: 7 additions & 7 deletions src/NuGetGallery/Services/PackageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,27 +106,27 @@ public virtual Package FindPackageByIdAndVersion(string id, string version, bool
.Include(p => p.LicenseReports)
.Include(p => p.PackageRegistration)
.Where(p => (p.PackageRegistration.Id == id));

if (String.IsNullOrEmpty(version) && !allowPrerelease)
{
// If there's a specific version given, don't bother filtering by prerelease. You could be asking for a prerelease package.
packagesQuery = packagesQuery.Where(p => !p.IsPrerelease);
}

var packageVersions = packagesQuery.ToList();

Package package;
if (version == null)
if (String.IsNullOrEmpty(version))
{
if (allowPrerelease)
package = packageVersions.FirstOrDefault(p => p.IsLatestStable);

if (package == null && allowPrerelease)
{
package = packageVersions.FirstOrDefault(p => p.IsLatest);
}
else
{
package = packageVersions.FirstOrDefault(p => p.IsLatestStable);
}

// If we couldn't find a package marked as latest, then
// return the most recent one.
// return the most recent one (prerelease ones were already filtered out if appropriate...)
if (package == null)
{
package = packageVersions.OrderByDescending(p => p.Version).FirstOrDefault();
Expand Down
115 changes: 62 additions & 53 deletions tests/NuGetGallery.Facts/Services/PackageServiceFacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using NuGet;
using NuGetGallery.Packaging;
using Xunit;
using Xunit.Extensions;

namespace NuGetGallery
{
Expand Down Expand Up @@ -1046,108 +1047,116 @@ public void WillThrowIfThePackageDoesNotExist()
public class TheFindPackageByIdAndVersionMethod
{
[Fact]
public void WillGetTheLatestVersionWhenTheVersionArgumentIsNull()
{
var packageRegistration = new PackageRegistration { Id = "theId" };
var packages = new[]
{
new Package { Version = "1.0", PackageRegistration = packageRegistration },
new Package
{ Version = "2.0", PackageRegistration = packageRegistration, IsLatestStable = true, IsLatest = true }
}.AsQueryable();
var packageRepository = new Mock<IEntityRepository<Package>>();
packageRepository.Setup(r => r.GetAll()).Returns(packages);
var service = CreateService(packageRepository: packageRepository);

var package = service.FindPackageByIdAndVersion("theId", null);

Assert.Equal("2.0", package.Version);
}

[Fact]
public void WillGetSpecifiedVersionWhenTheVersionArgumentIsNotNull()
public void ReturnsTheRequestedPackageVersion()
{
var service = CreateService(setup:
mockPackageService =>
{
mockPackageService.Setup(x => x.FindPackageRegistrationById(It.IsAny<string>())).Throws(
new Exception("This should not be called when the version is specified."));
});
mockPackageService =>
{
mockPackageService.Setup(x => x.FindPackageRegistrationById(It.IsAny<string>())).Throws(
new Exception("This should not be called when the version is specified."));
});

Assert.DoesNotThrow(() => service.FindPackageByIdAndVersion("theId", "1.0.42"));

// Nothing to assert because it's too damn complicated to test the actual LINQ expression.
// What we're testing via the throw above is that it didn't load the registration and get the latest version.
}

[Fact]
public void WillThrowIfIdIsNull()
[Theory]
[InlineData(null)]
[InlineData("")]
public void WillThrowIfIdIsNull(string id)
{
var service = CreateService();
var ex = Assert.Throws<ArgumentNullException>(() => service.FindPackageByIdAndVersion(id, "1.0.42"));
Assert.Equal("id", ex.ParamName);
}

var ex = Assert.Throws<ArgumentNullException>(() => service.FindPackageByIdAndVersion(null, "1.0.42"));
[Fact]
public void ReturnsTheLatestStableVersionIfAvailable()
{
// Arrange
var repository = new Mock<IEntityRepository<Package>>(MockBehavior.Strict);
var packageRegistration = new PackageRegistration { Id = "theId" };
var package1 = new Package { Version = "1.0", PackageRegistration = packageRegistration, Listed = true, IsLatestStable = true };
var package2 = new Package { Version = "1.0.0a", PackageRegistration = packageRegistration, IsPrerelease = true, Listed = true, IsLatest = true };

Assert.Equal("id", ex.ParamName);
repository
.Setup(repo => repo.GetAll())
.Returns(new[] { package1, package2 }.AsQueryable());
var service = CreateService(packageRepository: repository);

// Act
var result = service.FindPackageByIdAndVersion("theId", version: null);

// Assert
Assert.NotNull(result);
Assert.Equal("1.0", result.Version);
}

[Fact]
public void FindPackageReturnsTheLatestVersionIfAvailable()
public void ReturnsTheLatestVersionIfNoLatestStableVersionIsAvailable()
{
// Arrange
var repository = new Mock<IEntityRepository<Package>>(MockBehavior.Strict);
var package = CreatePackage("Foo", "1.0.0");
package.IsLatest = true;
package.IsLatestStable = true;
var packageA = CreatePackage("Foo", "1.0.0a");
var packageRegistration = new PackageRegistration { Id = "theId" };
var package1 = new Package { Version = "1.0.0b", PackageRegistration = packageRegistration, IsPrerelease = true, Listed = true, IsLatest = true };
var package2 = new Package { Version = "1.0.0a", PackageRegistration = packageRegistration, IsPrerelease = true, Listed = true };

repository.Setup(repo => repo.GetAll())
.Returns(new[] { package, packageA }.AsQueryable());
repository
.Setup(repo => repo.GetAll())
.Returns(new[] { package1, package2 }.AsQueryable());
var service = CreateService(packageRepository: repository);

// Act
var result = service.FindPackageByIdAndVersion("Foo", version: null);
var result = service.FindPackageByIdAndVersion("theId", version: null);

// Assert
Assert.Equal(package, result);
Assert.NotNull(result);
Assert.Equal("1.0.0b", result.Version);
}

[Fact]
public void FindPackageReturnsTheLatestVersionIfNoLatestStableVersionIsAvailable()
public void ReturnsNullIfNoLatestStableVersionIsAvailableAndPrereleaseIsDisallowed()
{
// Arrange
var repository = new Mock<IEntityRepository<Package>>(MockBehavior.Strict);
var package = CreatePackage("Foo", "1.0.0b");
package.IsLatest = true;
var packageA = CreatePackage("Foo", "1.0.0a");
var packageRegistration = new PackageRegistration { Id = "theId" };
var package1 = new Package { Version = "1.0.0b", PackageRegistration = packageRegistration, IsPrerelease = true, Listed = true, IsLatest = true };
var package2 = new Package { Version = "1.0.0a", PackageRegistration = packageRegistration, IsPrerelease = true, Listed = true };

repository.Setup(repo => repo.GetAll())
.Returns(new[] { package, packageA }.AsQueryable());
repository
.Setup(repo => repo.GetAll())
.Returns(new[] { package1, package2 }.AsQueryable());
var service = CreateService(packageRepository: repository);

// Act
var result = service.FindPackageByIdAndVersion("Foo", null);
var result = service.FindPackageByIdAndVersion("theId", version: null, allowPrerelease: false);

// Assert
Assert.Equal(package, result);
Assert.Null(result);
}

[Fact]
public void FindPackageReturnsTheLatestVersionIfNoLatestVersionIsAvailable()
public void ReturnsTheMostRecentVersionIfNoLatestVersionIsAvailable()
{
// Arrange
var repository = new Mock<IEntityRepository<Package>>(MockBehavior.Strict);
var package = CreatePackage("Foo", "1.0.0b");
var packageA = CreatePackage("Foo", "1.0.0a");
var packageRegistration = new PackageRegistration { Id = "theId" };
var package1 = new Package { Version = "1.0.0b", PackageRegistration = packageRegistration, IsPrerelease = true, Listed = false };
var package2 = new Package { Version = "1.0.0a", PackageRegistration = packageRegistration, IsPrerelease = true, Listed = false };

repository.Setup(repo => repo.GetAll())
.Returns(new[] { package, packageA }.AsQueryable());
repository
.Setup(repo => repo.GetAll())
.Returns(new[] { package1, package2 }.AsQueryable());
var service = CreateService(packageRepository: repository);

// Act
var result = service.FindPackageByIdAndVersion("Foo", null);
var result = service.FindPackageByIdAndVersion("theId", null);

// Assert
Assert.Equal(package, result);
Assert.NotNull(result);
Assert.Equal("1.0.0b", result.Version);
}
}

Expand Down

0 comments on commit fd20ca4

Please sign in to comment.