Skip to content

Commit

Permalink
User profile page does not show SemVer 2.0.0 packages #3911 (#3933)
Browse files Browse the repository at this point in the history
  • Loading branch information
xavierdecoster committed May 18, 2017
1 parent a5a1f14 commit 56dd0f0
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 40 deletions.
107 changes: 72 additions & 35 deletions src/NuGetGallery/Services/PackageService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,9 +160,9 @@ public virtual PackageRegistration FindPackageRegistrationById(string id)
}

public virtual Package FindPackageByIdAndVersion(
string id,
string version,
int? semVerLevelKey = null,
string id,
string version,
int? semVerLevelKey = null,
bool allowPrerelease = true)
{
if (string.IsNullOrWhiteSpace(id))
Expand Down Expand Up @@ -210,7 +210,7 @@ public virtual Package FindPackageByIdAndVersion(
// If SemVer-level is not defined,
// or SemVer-level = 2.0.0 and no package was marked as SemVer2-latest,
// then check for packages marked as non-SemVer2 latest.
if (semVerLevelKey == SemVerLevelKey.Unknown
if (semVerLevelKey == SemVerLevelKey.Unknown
|| (semVerLevelKey == SemVerLevelKey.SemVer2 && package == null))
{
package = packageVersions.FirstOrDefault(p => p.IsLatestStable);
Expand All @@ -228,7 +228,7 @@ public virtual Package FindPackageByIdAndVersion(
package = packageVersions.OrderByDescending(p => p.Version).FirstOrDefault();
}
}

return package;
}

Expand Down Expand Up @@ -282,49 +282,86 @@ public IEnumerable<Package> FindPackagesByOwner(User user, bool includeUnlisted)
// Like DisplayPackage we should prefer to show you information from the latest stable version,
// but show you the latest version (potentially latest UNLISTED version) otherwise.

var mergedResults = new Dictionary<string, Package>(StringComparer.OrdinalIgnoreCase);

MergeLatestPackagesByOwner(user, includeUnlisted, mergedResults);
MergeLatestStablePackagesByOwner(user, includeUnlisted, mergedResults);

return mergedResults.Values;
}

private void MergeLatestStablePackagesByOwner(User user, bool includeUnlisted, Dictionary<string, Package> mergedResults)
{
IQueryable<Package> latestStablePackageVersions = _packageRepository.GetAll()
.Where(p =>
p.PackageRegistration.Owners.Any(owner => owner.Key == user.Key)
&& p.IsLatestStable)
.Include(p => p.PackageRegistration)
.Include(p => p.PackageRegistration.Owners);

var latestPackageVersions = _packageRepository.GetAll()
.Where(p =>
p.PackageRegistration.Owners.Any(owner => owner.Key == user.Key)
&& p.IsLatest)
.Include(p => p.PackageRegistration)
.Include(p => p.PackageRegistration.Owners);
.Where(p =>
p.PackageRegistration.Owners.Any(owner => owner.Key == user.Key)
&& (p.IsLatestStable || p.IsLatestStableSemVer2))
.Include(p => p.PackageRegistration)
.Include(p => p.PackageRegistration.Owners);

foreach (var latestStablePackagesById in latestStablePackageVersions.ToList().GroupBy(p => p.PackageRegistration.Id))
{
Package latestStablePackage;
if (includeUnlisted)
{
latestStablePackage = latestStablePackagesById.Single();
}
else
{
latestStablePackage =
latestStablePackagesById.SingleOrDefault(p => p.IsLatestStableSemVer2)
?? latestStablePackagesById.SingleOrDefault(p => p.IsLatestStable);
}

mergedResults[latestStablePackage.PackageRegistration.Id] = latestStablePackage;
}
}

private void MergeLatestPackagesByOwner(User user, bool includeUnlisted, Dictionary<string, Package> mergedResults)
{
IQueryable<Package> latestPackageVersions;
if (includeUnlisted)
{
latestPackageVersions = _packageRegistrationRepository.GetAll()
.Where(pr => pr.Owners.Where(owner => owner.Username == user.Username).Any())
.Select(pr => pr.Packages.OrderByDescending(p => p.Version).FirstOrDefault())
.Include(p => p.PackageRegistration)
.Include(p => p.PackageRegistration.Owners);
.Where(pr => pr.Owners.Where(owner => owner.Username == user.Username).Any())
.Select(pr => pr.Packages.OrderByDescending(p => p.Version).First())
.Include(p => p.PackageRegistration)
.Include(p => p.PackageRegistration.Owners);
}
else
{
latestPackageVersions = _packageRepository.GetAll()
.Where(p =>
p.PackageRegistration.Owners.Any(owner => owner.Key == user.Key)
&& (p.IsLatest || p.IsLatestSemVer2))
.Include(p => p.PackageRegistration)
.Include(p => p.PackageRegistration.Owners);
}

var mergedResults = new Dictionary<string, Package>(StringComparer.OrdinalIgnoreCase);
foreach (var package in latestPackageVersions.Where(p => p != null))
foreach (var latestPackagesById in latestPackageVersions.ToList().GroupBy(p => p.PackageRegistration.Id))
{
if (mergedResults.ContainsKey(package.PackageRegistration.Id)
&& mergedResults[package.PackageRegistration.Id].Created < package.Created)
Package latestPackage;
if (includeUnlisted)
{
mergedResults[package.PackageRegistration.Id] = package;
latestPackage = latestPackagesById.Single();
}
else
{
mergedResults.Add(package.PackageRegistration.Id, package);
latestPackage =
latestPackagesById.SingleOrDefault(p => p.IsLatestSemVer2)
?? latestPackagesById.Single(p => p.IsLatest);
}
}

foreach (var package in latestStablePackageVersions.Where(p => p != null))
{
mergedResults[package.PackageRegistration.Id] = package;
if (mergedResults.ContainsKey(latestPackage.PackageRegistration.Id)
&& mergedResults[latestPackage.PackageRegistration.Id].Created < latestPackage.Created)
{
mergedResults[latestPackage.PackageRegistration.Id] = latestPackage;
}
else
{
mergedResults.Add(latestPackage.PackageRegistration.Id, latestPackage);
}
}

return mergedResults.Values;
}

public IEnumerable<PackageRegistration> FindPackageRegistrationsByOwner(User user)
Expand Down Expand Up @@ -804,11 +841,11 @@ public async Task UpdateIsLatestAsync(PackageRegistration packageRegistration, b

// If the last listed package was just unlisted, then we won't find another one
var latestPackage = FindPackage(
packageRegistration.Packages,
packageRegistration.Packages,
p => !p.Deleted && p.Listed && p.SemVerLevelKey == SemVerLevelKey.Unknown);

var latestSemVer2Package = FindPackage(
packageRegistration.Packages,
packageRegistration.Packages,
p => !p.Deleted && p.Listed && (p.SemVerLevelKey == SemVerLevelKey.SemVer2 || p.SemVerLevelKey == SemVerLevelKey.Unknown));

if (latestPackage != null)
Expand Down
2 changes: 1 addition & 1 deletion src/NuGetGallery/Views/Users/Profiles.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ else if (Model.ShowAllPackages)
</a>
</div>
<div class="main">
<h1><a href="@Url.Package(package.Id)">@package.Title</a> <small>Latest version: @package.Version</small></h1>
<h1><a href="@Url.Package(package.Id)">@package.Title</a> <small>Latest version: @package.FullVersion</small></h1>

<p>
@if (String.IsNullOrEmpty(package.Description) || package.Description.Length < 350)
Expand Down
31 changes: 27 additions & 4 deletions tests/NuGetGallery.Facts/Services/PackageServiceFacts.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1501,7 +1501,7 @@ public void ReturnsAListedPackage()
{
var owner = new User { Username = "someone" };
var packageRegistration = new PackageRegistration { Id = "theId", Owners = { owner } };
var package = new Package { Version = "1.0", PackageRegistration = packageRegistration, Listed = true, IsLatest = true, IsLatestStable = true };
var package = new Package { Version = "1.0", PackageRegistration = packageRegistration, Listed = true, IsLatestSemVer2 = true, IsLatestStableSemVer2 = true };
packageRegistration.Packages.Add(package);

var context = GetFakeContext();
Expand Down Expand Up @@ -1556,8 +1556,8 @@ public void ReturnsAPackageForEachPackageRegistration()
var owner = new User { Username = "someone" };
var packageRegistrationA = new PackageRegistration { Id = "idA", Owners = { owner } };
var packageRegistrationB = new PackageRegistration { Id = "idB", Owners = { owner } };
var packageA = new Package { Version = "1.0", PackageRegistration = packageRegistrationA, Listed = true, IsLatest = true, IsLatestStable = true };
var packageB = new Package { Version = "1.0", PackageRegistration = packageRegistrationB, Listed = true, IsLatest = true, IsLatestStable = true };
var packageA = new Package { Version = "1.0", PackageRegistration = packageRegistrationA, Listed = true, IsLatestSemVer2 = true, IsLatestStableSemVer2 = true };
var packageB = new Package { Version = "1.0", PackageRegistration = packageRegistrationB, Listed = true, IsLatestSemVer2 = true, IsLatestStableSemVer2 = true };
packageRegistrationA.Packages.Add(packageA);
packageRegistrationB.Packages.Add(packageB);

Expand All @@ -1576,7 +1576,30 @@ public void ReturnsAPackageForEachPackageRegistration()
}

[Fact]
public void ReturnsOnlyLatestStablePackageIfBothExist()
public void ReturnsOnlyLatestStableSemVer2PackageIfBothExist()
{
var owner = new User { Username = "someone" };
var packageRegistration = new PackageRegistration { Id = "theId", Owners = { owner } };
var latestPackage = new Package { Version = "2.0.0-alpha", PackageRegistration = packageRegistration, Listed = true, IsLatest = true };
var latestSemVer2Package = new Package { Version = "2.0.0-alpha.1", PackageRegistration = packageRegistration, Listed = true, IsLatestSemVer2 = true };
var latestStablePackage = new Package { Version = "1.0", PackageRegistration = packageRegistration, Listed = true, IsLatestStableSemVer2 = true };
packageRegistration.Packages.Add(latestPackage);
packageRegistration.Packages.Add(latestStablePackage);

var context = GetFakeContext();
context.Users.Add(owner);
context.PackageRegistrations.Add(packageRegistration);
context.Packages.Add(latestPackage);
context.Packages.Add(latestStablePackage);
var service = Get<PackageService>();

var packages = service.FindPackagesByOwner(owner, includeUnlisted: false).ToList();
Assert.Equal(1, packages.Count);
Assert.Contains(latestStablePackage, packages);
}

[Fact]
public void ReturnsOnlyLatestStablePackageIfNoLatestStableSemVer2Exist()
{
var owner = new User { Username = "someone" };
var packageRegistration = new PackageRegistration { Id = "theId", Owners = { owner } };
Expand Down

0 comments on commit 56dd0f0

Please sign in to comment.