From b537989f75c915d79b09e405ff55a9b6c55a798a Mon Sep 17 00:00:00 2001 From: TheCakeIsNaOH Date: Tue, 6 Jun 2023 20:19:49 -0500 Subject: [PATCH] (#3196) Pin add/remove use exact package ID For the pin commands add and remove, find the package to pin/unpin using an exact list, not a normal search, to ensure that only an exact matching package ID is returned, and therefore pinned/unpinned. A test is also added for this, using the mingw and gstreamer-mingw package IDs, which is what was reported causing problems in the issue. --- .../commands/ChocolateyPinCommandSpecs.cs | 76 +++++++++++++++++++ .../commands/ChocolateyPinCommand.cs | 3 + 2 files changed, 79 insertions(+) diff --git a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPinCommandSpecs.cs b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPinCommandSpecs.cs index 1db4187be8..36b71c6c40 100644 --- a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPinCommandSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPinCommandSpecs.cs @@ -48,6 +48,8 @@ public abstract class ChocolateyPinCommandSpecsBase : TinySpec protected ChocolateyConfiguration configuration = new ChocolateyConfiguration(); protected Mock package = new Mock(); protected Mock pinnedPackage = new Mock(); + protected Mock mingwPackage = new Mock(); + protected Mock gstreamerMingwPackage = new Mock(); public override void Context() { @@ -72,6 +74,23 @@ public override void Context() { IsPinned = true }); + + mingwPackage = new Mock(); + mingwPackage.Setup(p => p.Id).Returns("mingw"); + mingwPackage.Setup(p => p.Version).Returns(new NuGetVersion("1.0.0")); + packageInfoService.Setup(s => s.Get(mingwPackage.Object)).Returns( + new ChocolateyPackageInformation(mingwPackage.Object) + { + IsPinned = true + }); + gstreamerMingwPackage = new Mock(); + gstreamerMingwPackage.Setup(p => p.Id).Returns("gstreamer-mingw"); + gstreamerMingwPackage.Setup(p => p.Version).Returns(new NuGetVersion("1.0.0")); + packageInfoService.Setup(s => s.Get(gstreamerMingwPackage.Object)).Returns( + new ChocolateyPackageInformation(gstreamerMingwPackage.Object) + { + IsPinned = true + }); } public void Reset() @@ -461,5 +480,62 @@ public void Should_remove_pin_when_command_is_remove() } } + public class When_run_is_called_with_similarly_named_package_installed : ChocolateyPinCommandSpecsBase + { + public override void Context() + { + base.Context(); + configuration.Sources = ApplicationParameters.PackagesLocation; + configuration.ListCommand.LocalOnly = true; + configuration.AllVersions = true; + + var packageResults = new[] + { + new PackageResult(mingwPackage.Object, null), + new PackageResult(gstreamerMingwPackage.Object, null) + }; + nugetService.Setup(n => n.List(It.IsAny())).Returns(packageResults); + } + + public new void Reset() + { + Context(); + base.Reset(); + } + + public override void AfterEachSpec() + { + base.AfterEachSpec(); + MockLogger.Messages.Clear(); + } + + public override void Because() + { + } + + [Fact] + public void Should_call_nuget_service_list_run_when_command_is_list() + { + Reset(); + configuration.PinCommand.Command = PinCommandType.List; + command.Run(configuration); + + nugetService.Verify(n => n.List(It.IsAny()), Times.Once); + } + + [Fact] + public void Should_remove_pin_from_correct_package() + { + Reset(); + configuration.PinCommand.Name = "mingw"; + configuration.PinCommand.Command = PinCommandType.Remove; + + command.SetPin(configuration); + + packageInfoService.Verify(s => + s.Save(It.Is(n => + n.Package.Id.Equals("mingw"))), Times.Once); + } + } } } diff --git a/src/chocolatey/infrastructure.app/commands/ChocolateyPinCommand.cs b/src/chocolatey/infrastructure.app/commands/ChocolateyPinCommand.cs index 38bf19321a..ef4ebe3d36 100644 --- a/src/chocolatey/infrastructure.app/commands/ChocolateyPinCommand.cs +++ b/src/chocolatey/infrastructure.app/commands/ChocolateyPinCommand.cs @@ -190,9 +190,12 @@ public virtual void SetPin(ChocolateyConfiguration config) config.Input = config.PinCommand.Name; config.Version = semanticVersion.ToFullStringChecked(); config.ListCommand.ByIdOnly = true; + var exact = config.ListCommand.Exact; + config.ListCommand.Exact = true; var quiet = config.QuietOutput; config.QuietOutput = true; var installedPackage = _nugetService.List(config).FirstOrDefault(); + config.ListCommand.Exact = exact; config.QuietOutput = quiet; config.Input = input;