From 445d076e6e36bcfbad33cf8089222b75593fdae3 Mon Sep 17 00:00:00 2001 From: Martin Ruiz Date: Mon, 3 Jul 2023 16:56:45 -0700 Subject: [PATCH 1/4] Fix display package license in PM UI --- .../PackageLicenseUtilities.cs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/NuGet.Clients/NuGet.PackageManagement.UI/PackageLicenseUtilities.cs b/src/NuGet.Clients/NuGet.PackageManagement.UI/PackageLicenseUtilities.cs index e81d269dbe1..f23bb9d69fe 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.UI/PackageLicenseUtilities.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.UI/PackageLicenseUtilities.cs @@ -9,6 +9,7 @@ using System.Threading.Tasks; using System.Windows.Documents; using Microsoft.ServiceHub.Framework; +using NuGet.PackageManagement.VisualStudio; using NuGet.Packaging; using NuGet.Packaging.Core; using NuGet.Packaging.Licenses; @@ -109,6 +110,9 @@ internal static IReadOnlyList GenerateLicenseLinks(LicenseMetadata metada break; case LicenseType.File: + NuGetPackageFileService.AddLicenseToCache( + packageIdentity, + CreateEmbeddedLicenseUri(packagePath, metadata)); list.Add(new LicenseFileText(Resources.Text_ViewLicense, licenseFileHeader, packagePath, metadata.License, packageIdentity)); break; @@ -119,6 +123,33 @@ internal static IReadOnlyList GenerateLicenseLinks(LicenseMetadata metada return list; } + private static Uri CreateEmbeddedLicenseUri(string packagePath, LicenseMetadata licenseMetadata) + { + Uri baseUri = Convert(packagePath); + + var builder = new UriBuilder(baseUri) + { + Fragment = licenseMetadata.License + }; + + return builder.Uri; + } + + /// + /// Convert a string to a URI safely. This will return null if there are errors. + /// + private static Uri Convert(string uri) + { + Uri fullUri = null; + + if (!string.IsNullOrEmpty(uri)) + { + Uri.TryCreate(uri, UriKind.Absolute, out fullUri); + } + + return fullUri; + } + private static void PopulateLicenseIdentifiers(NuGetLicenseExpression expression, IList identifiers) { switch (expression.Type) From acf0051033fb5d0ede4e86995090d21bdc3612ea Mon Sep 17 00:00:00 2001 From: Martin Ruiz Date: Wed, 5 Jul 2023 11:50:46 -0700 Subject: [PATCH 2/4] added tests --- .../PackageLicenseUtilitiesTests.cs | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/test/NuGet.Clients.Tests/NuGet.PackageManagement.UI.Test/PackageLicenseUtilitiesTests.cs b/test/NuGet.Clients.Tests/NuGet.PackageManagement.UI.Test/PackageLicenseUtilitiesTests.cs index 76715686ece..92b98e28eee 100644 --- a/test/NuGet.Clients.Tests/NuGet.PackageManagement.UI.Test/PackageLicenseUtilitiesTests.cs +++ b/test/NuGet.Clients.Tests/NuGet.PackageManagement.UI.Test/PackageLicenseUtilitiesTests.cs @@ -3,10 +3,22 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; using System.Windows.Documents; +using Microsoft.ServiceHub.Framework; +using Microsoft.ServiceHub.Framework.Services; +using Moq; +using NuGet.PackageManagement.VisualStudio; using NuGet.Packaging; +using NuGet.Packaging.Core; using NuGet.Packaging.Licenses; +using NuGet.Test.Utility; +using NuGet.Versioning; +using NuGet.VisualStudio.Telemetry; using Xunit; namespace NuGet.PackageManagement.UI.Test @@ -163,6 +175,49 @@ public void PackageLicenseUtility_GeneratesLinkForFiles() Assert.Equal(Resources.LicenseFile_Loading, ((Run)((Paragraph)licenseFileText.LicenseText.Blocks.AsEnumerable().First()).Inlines.First()).Text); } + private Mock _telemetryProvider = new Mock(MockBehavior.Strict); + + [Fact] + public async Task PackageLicenseUtility_GeneratesLinkForFiles_And_CacheIsUpdated() + { + using (TestDirectory testDir = TestDirectory.Create()) + { + // Setup + // Create decoy nuget package + var zipPath = Path.Combine(testDir.Path, "file.nupkg"); + CreateDummyPackage(zipPath: zipPath, licenseFile: "License.txt", licenseFileTargetElement: ""); + + var packageFileService = new NuGetPackageFileService( + default(ServiceActivationOptions), + Mock.Of(), + new AuthorizationServiceClient(Mock.Of()), + _telemetryProvider.Object); + + var licenseFileLocation = "License.txt"; + var licenseFileHeader = "header"; + var licenseData = new LicenseMetadata(LicenseType.File, licenseFileLocation, null, null, LicenseMetadata.CurrentVersion); + + var packageIdentity = new PackageIdentity("AddLicenseToCache", NuGetVersion.Parse("1.0.0")); + + // Act + var links = PackageLicenseUtilities.GenerateLicenseLinks( + licenseData, + licenseFileHeader, + zipPath, + packageIdentity); + + Assert.Equal(1, links.Count); + Assert.True(links[0] is LicenseFileText); + var licenseFileText = links[0] as LicenseFileText; + Assert.Equal(Resources.Text_ViewLicense, licenseFileText.Text); + Assert.Equal(Resources.LicenseFile_Loading, ((Run)((Paragraph)licenseFileText.LicenseText.Blocks.AsEnumerable().First()).Inlines.First()).Text); + + Stream licenseStream = await packageFileService.GetEmbeddedLicenseAsync(packageIdentity, CancellationToken.None); + Assert.NotNull(licenseStream); + Assert.Equal(StreamLicenseContents.Length, licenseStream.Length); + } + } + [Fact] public void PackageLicenseUtility_GenerateCorrectLink() { @@ -181,5 +236,43 @@ public void PackageLicenseUtility_GenerateCorrectLink() Assert.Equal(license, licenseText.Text); Assert.Equal("https://licenses.nuget.org/MIT", licenseText.Link.AbsoluteUri); } + + private static void CreateDummyPackage( + string zipPath, + string licenseFile = "License.txt", + string licenseFileTargetElement = "") + { + var dir = Path.GetDirectoryName(zipPath); + var holdDir = "pkg"; + var folderPath = Path.Combine(dir, holdDir); + + // base dir + Directory.CreateDirectory(folderPath); + + // create nuspec + var nuspec = NuspecBuilder.Create() + .WithFile(licenseFile, licenseFileTargetElement); + + // create license file + var licensePath = Path.Combine(folderPath, licenseFile); + var licenseDir = Path.GetDirectoryName(licensePath); + Directory.CreateDirectory(licenseDir); + + File.WriteAllText(licensePath, StreamLicenseContents); + + // Create nuget package + using (var nuspecStream = new MemoryStream()) + using (FileStream nupkgStream = File.Create(zipPath)) + using (var writer = new StreamWriter(nuspecStream)) + { + nuspec.Write(writer); + writer.Flush(); + nuspecStream.Position = 0; + var pkgBuilder = new PackageBuilder(stream: nuspecStream, basePath: folderPath); + pkgBuilder.Save(nupkgStream); + } + } + + private static string StreamLicenseContents = "I am license"; } } From 1efc497c29d63d0d926611110f4a8ac916a25ae6 Mon Sep 17 00:00:00 2001 From: Martin Ruiz Date: Tue, 11 Jul 2023 13:13:50 -0700 Subject: [PATCH 3/4] fix test --- .../PackageLicenseUtilitiesTests.cs | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/test/NuGet.Clients.Tests/NuGet.PackageManagement.UI.Test/PackageLicenseUtilitiesTests.cs b/test/NuGet.Clients.Tests/NuGet.PackageManagement.UI.Test/PackageLicenseUtilitiesTests.cs index 92b98e28eee..6886aa7376a 100644 --- a/test/NuGet.Clients.Tests/NuGet.PackageManagement.UI.Test/PackageLicenseUtilitiesTests.cs +++ b/test/NuGet.Clients.Tests/NuGet.PackageManagement.UI.Test/PackageLicenseUtilitiesTests.cs @@ -156,23 +156,32 @@ public void PackageLicenseUtility_BadUnlicensedGeneratesNoLinksAndAWarning() [Fact] public void PackageLicenseUtility_GeneratesLinkForFiles() { - // Setup - var licenseFileLocation = "License.txt"; - var licenseFileHeader = "header"; - var licenseData = new LicenseMetadata(LicenseType.File, licenseFileLocation, null, null, LicenseMetadata.CurrentVersion); + using (TestDirectory testDir = TestDirectory.Create()) + { + // Setup + // Create decoy nuget package + var zipPath = Path.Combine(testDir.Path, "file.nupkg"); + CreateDummyPackage(zipPath: zipPath, licenseFile: "License.txt", licenseFileTargetElement: ""); - // Act - var links = PackageLicenseUtilities.GenerateLicenseLinks( - licenseData, - licenseFileHeader, - licenseFileLocation, - packageIdentity: null); + var licenseFileLocation = "License.txt"; + var licenseFileHeader = "header"; + var licenseData = new LicenseMetadata(LicenseType.File, licenseFileLocation, null, null, LicenseMetadata.CurrentVersion); - Assert.Equal(1, links.Count); - Assert.True(links[0] is LicenseFileText); - var licenseFileText = links[0] as LicenseFileText; - Assert.Equal(Resources.Text_ViewLicense, licenseFileText.Text); - Assert.Equal(Resources.LicenseFile_Loading, ((Run)((Paragraph)licenseFileText.LicenseText.Blocks.AsEnumerable().First()).Inlines.First()).Text); + var packageIdentity = new PackageIdentity("AddLicenseToCache", NuGetVersion.Parse("1.0.0")); + + // Act + var links = PackageLicenseUtilities.GenerateLicenseLinks( + licenseData, + licenseFileHeader, + zipPath, + packageIdentity: packageIdentity); + + Assert.Equal(1, links.Count); + Assert.True(links[0] is LicenseFileText); + var licenseFileText = links[0] as LicenseFileText; + Assert.Equal(Resources.Text_ViewLicense, licenseFileText.Text); + Assert.Equal(Resources.LicenseFile_Loading, ((Run)((Paragraph)licenseFileText.LicenseText.Blocks.AsEnumerable().First()).Inlines.First()).Text); + } } private Mock _telemetryProvider = new Mock(MockBehavior.Strict); From 28d8626bde2a0c0dfba528db99cdeee40d7787c6 Mon Sep 17 00:00:00 2001 From: Martin Ruiz Date: Mon, 17 Jul 2023 11:09:26 -0700 Subject: [PATCH 4/4] deleted unnecesary function and better tests --- .../PackageLicenseUtilities.cs | 17 +--- .../PackageLicenseUtilitiesTests.cs | 87 ++++++------------- 2 files changed, 27 insertions(+), 77 deletions(-) diff --git a/src/NuGet.Clients/NuGet.PackageManagement.UI/PackageLicenseUtilities.cs b/src/NuGet.Clients/NuGet.PackageManagement.UI/PackageLicenseUtilities.cs index f23bb9d69fe..3ec7744866f 100644 --- a/src/NuGet.Clients/NuGet.PackageManagement.UI/PackageLicenseUtilities.cs +++ b/src/NuGet.Clients/NuGet.PackageManagement.UI/PackageLicenseUtilities.cs @@ -125,7 +125,7 @@ internal static IReadOnlyList GenerateLicenseLinks(LicenseMetadata metada private static Uri CreateEmbeddedLicenseUri(string packagePath, LicenseMetadata licenseMetadata) { - Uri baseUri = Convert(packagePath); + Uri baseUri = new Uri(packagePath, UriKind.Absolute); var builder = new UriBuilder(baseUri) { @@ -135,21 +135,6 @@ private static Uri CreateEmbeddedLicenseUri(string packagePath, LicenseMetadata return builder.Uri; } - /// - /// Convert a string to a URI safely. This will return null if there are errors. - /// - private static Uri Convert(string uri) - { - Uri fullUri = null; - - if (!string.IsNullOrEmpty(uri)) - { - Uri.TryCreate(uri, UriKind.Absolute, out fullUri); - } - - return fullUri; - } - private static void PopulateLicenseIdentifiers(NuGetLicenseExpression expression, IList identifiers) { switch (expression.Type) diff --git a/test/NuGet.Clients.Tests/NuGet.PackageManagement.UI.Test/PackageLicenseUtilitiesTests.cs b/test/NuGet.Clients.Tests/NuGet.PackageManagement.UI.Test/PackageLicenseUtilitiesTests.cs index 6886aa7376a..d4837520785 100644 --- a/test/NuGet.Clients.Tests/NuGet.PackageManagement.UI.Test/PackageLicenseUtilitiesTests.cs +++ b/test/NuGet.Clients.Tests/NuGet.PackageManagement.UI.Test/PackageLicenseUtilitiesTests.cs @@ -156,29 +156,27 @@ public void PackageLicenseUtility_BadUnlicensedGeneratesNoLinksAndAWarning() [Fact] public void PackageLicenseUtility_GeneratesLinkForFiles() { - using (TestDirectory testDir = TestDirectory.Create()) + using (var pathContext = new SimpleTestPathContext()) { // Setup - // Create decoy nuget package - var zipPath = Path.Combine(testDir.Path, "file.nupkg"); - CreateDummyPackage(zipPath: zipPath, licenseFile: "License.txt", licenseFileTargetElement: ""); + var packageA1 = new SimpleTestPackageContext("AddLicenseToCache", "1.0.0"); + string licenseFileLocation = "License.txt"; + string licenseFileHeader = "header"; + LicenseMetadata licenseData = new LicenseMetadata(LicenseType.File, licenseFileLocation, null, null, LicenseMetadata.CurrentVersion); + packageA1.AddFile(licenseFileLocation, StreamLicenseContents); - var licenseFileLocation = "License.txt"; - var licenseFileHeader = "header"; - var licenseData = new LicenseMetadata(LicenseType.File, licenseFileLocation, null, null, LicenseMetadata.CurrentVersion); - - var packageIdentity = new PackageIdentity("AddLicenseToCache", NuGetVersion.Parse("1.0.0")); + PackageIdentity packageIdentity = new PackageIdentity("AddLicenseToCache", NuGetVersion.Parse("1.0.0")); // Act - var links = PackageLicenseUtilities.GenerateLicenseLinks( + IReadOnlyList links = PackageLicenseUtilities.GenerateLicenseLinks( licenseData, licenseFileHeader, - zipPath, + pathContext.SolutionRoot, packageIdentity: packageIdentity); Assert.Equal(1, links.Count); Assert.True(links[0] is LicenseFileText); - var licenseFileText = links[0] as LicenseFileText; + LicenseFileText licenseFileText = links[0] as LicenseFileText; Assert.Equal(Resources.Text_ViewLicense, licenseFileText.Text); Assert.Equal(Resources.LicenseFile_Loading, ((Run)((Paragraph)licenseFileText.LicenseText.Blocks.AsEnumerable().First()).Inlines.First()).Text); } @@ -189,35 +187,38 @@ public void PackageLicenseUtility_GeneratesLinkForFiles() [Fact] public async Task PackageLicenseUtility_GeneratesLinkForFiles_And_CacheIsUpdated() { - using (TestDirectory testDir = TestDirectory.Create()) + using (var pathContext = new SimpleTestPathContext()) { // Setup - // Create decoy nuget package - var zipPath = Path.Combine(testDir.Path, "file.nupkg"); - CreateDummyPackage(zipPath: zipPath, licenseFile: "License.txt", licenseFileTargetElement: ""); + var package = new SimpleTestPackageContext("AddLicenseToCache", "1.0.0"); + string licenseFileLocation = "License.txt"; + string licenseFileHeader = "header"; + LicenseMetadata licenseData = new LicenseMetadata(LicenseType.File, licenseFileLocation, null, null, LicenseMetadata.CurrentVersion); + package.AddFile(licenseFileLocation, StreamLicenseContents); - var packageFileService = new NuGetPackageFileService( + NuGetPackageFileService packageFileService = new NuGetPackageFileService( default(ServiceActivationOptions), Mock.Of(), new AuthorizationServiceClient(Mock.Of()), _telemetryProvider.Object); - var licenseFileLocation = "License.txt"; - var licenseFileHeader = "header"; - var licenseData = new LicenseMetadata(LicenseType.File, licenseFileLocation, null, null, LicenseMetadata.CurrentVersion); + await SimpleTestPackageUtility.CreateFolderFeedV3Async( + pathContext.PackageSource, + PackageSaveMode.Defaultv3, + package); - var packageIdentity = new PackageIdentity("AddLicenseToCache", NuGetVersion.Parse("1.0.0")); + PackageIdentity packageIdentity = new PackageIdentity("AddLicenseToCache", NuGetVersion.Parse("1.0.0")); // Act - var links = PackageLicenseUtilities.GenerateLicenseLinks( + IReadOnlyList links = PackageLicenseUtilities.GenerateLicenseLinks( licenseData, licenseFileHeader, - zipPath, + Path.Combine(pathContext.PackageSource, packageIdentity.Id, packageIdentity.Version.ToString(), package.PackageName), packageIdentity); Assert.Equal(1, links.Count); Assert.True(links[0] is LicenseFileText); - var licenseFileText = links[0] as LicenseFileText; + LicenseFileText licenseFileText = links[0] as LicenseFileText; Assert.Equal(Resources.Text_ViewLicense, licenseFileText.Text); Assert.Equal(Resources.LicenseFile_Loading, ((Run)((Paragraph)licenseFileText.LicenseText.Blocks.AsEnumerable().First()).Inlines.First()).Text); @@ -246,42 +247,6 @@ public void PackageLicenseUtility_GenerateCorrectLink() Assert.Equal("https://licenses.nuget.org/MIT", licenseText.Link.AbsoluteUri); } - private static void CreateDummyPackage( - string zipPath, - string licenseFile = "License.txt", - string licenseFileTargetElement = "") - { - var dir = Path.GetDirectoryName(zipPath); - var holdDir = "pkg"; - var folderPath = Path.Combine(dir, holdDir); - - // base dir - Directory.CreateDirectory(folderPath); - - // create nuspec - var nuspec = NuspecBuilder.Create() - .WithFile(licenseFile, licenseFileTargetElement); - - // create license file - var licensePath = Path.Combine(folderPath, licenseFile); - var licenseDir = Path.GetDirectoryName(licensePath); - Directory.CreateDirectory(licenseDir); - - File.WriteAllText(licensePath, StreamLicenseContents); - - // Create nuget package - using (var nuspecStream = new MemoryStream()) - using (FileStream nupkgStream = File.Create(zipPath)) - using (var writer = new StreamWriter(nuspecStream)) - { - nuspec.Write(writer); - writer.Flush(); - nuspecStream.Position = 0; - var pkgBuilder = new PackageBuilder(stream: nuspecStream, basePath: folderPath); - pkgBuilder.Save(nupkgStream); - } - } - - private static string StreamLicenseContents = "I am license"; + private const string StreamLicenseContents = "I am a license"; } }