diff --git a/src/chocolatey.tests/TinySpec.cs b/src/chocolatey.tests/TinySpec.cs index fe0f02604..02a8f1679 100644 --- a/src/chocolatey.tests/TinySpec.cs +++ b/src/chocolatey.tests/TinySpec.cs @@ -67,6 +67,14 @@ public void Setup() { MockLogger.Reset(); } + + // Chocolatey CLI by default will exit with Code 0, when everything work as expected, even if it doesn't + // set this explicitly. + // However, in some tests, we are testing for the setting of an explicit exit code, and when we do this, + // it can have an impact on other tests, since it may not have been reset. Let's explicitly set it to + // 0 before running each test, so that everything starts off at the right place. + Environment.ExitCode = default; + //Log.InitializeWith(MockLogger); NugetCommon.ClearRepositoriesCache(); Context(); diff --git a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPinCommandSpecs.cs b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPinCommandSpecs.cs index ece60dea8..37208c8c8 100644 --- a/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPinCommandSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/commands/ChocolateyPinCommandSpecs.cs @@ -33,6 +33,7 @@ using NUnit.Framework; using FluentAssertions; +using FluentAssertions.Execution; namespace chocolatey.tests.infrastructure.app.commands { @@ -537,5 +538,139 @@ public void Should_remove_pin_from_correct_package() n.Package.Id.Equals("mingw"))), Times.Once); } } + + public class When_adding_a_pin_on_an_already_pinned_package : ChocolateyPinCommandSpecsBase + { + public override void Context() + { + base.Context(); + Configuration.Sources = ApplicationParameters.PackagesLocation; + Configuration.ListCommand.LocalOnly = true; + Configuration.AllVersions = true; + + var packageResults = new[] + { + new PackageResult(PinnedPackage.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_Return_0_ExitCode_When_Pinning_An_Already_Pinned_Package() + { + Reset(); + Configuration.Features.UseEnhancedExitCodes = false; + Configuration.PinCommand.Name = "pinned"; + Configuration.PinCommand.Command = PinCommandType.Add; + + Command.SetPin(Configuration); + + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Pin already set or removed."); + Environment.ExitCode.Should().Be(0); + } + } + + [Fact] + public void Should_Return_2_ExitCode_When_Pinning_An_Already_Pinned_Package_With_UseEnhancedExitCodes_Enabled() + { + Reset(); + Configuration.Features.UseEnhancedExitCodes = true; + Configuration.PinCommand.Name = "pinned"; + Configuration.PinCommand.Command = PinCommandType.Add; + + Command.SetPin(Configuration); + + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Pin already set or removed."); + Environment.ExitCode.Should().Be(2); + } + } + } + + public class When_removing_a_pin_on_a_package_with_no_pin : ChocolateyPinCommandSpecsBase + { + public override void Context() + { + base.Context(); + Configuration.Sources = ApplicationParameters.PackagesLocation; + Configuration.ListCommand.LocalOnly = true; + Configuration.AllVersions = true; + + var packageResults = new[] + { + new PackageResult(Package.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_Return_0_ExitCode_When_Pinning_An_Already_Pinned_Package() + { + Reset(); + Configuration.Features.UseEnhancedExitCodes = false; + Configuration.PinCommand.Name = "regular"; + Configuration.PinCommand.Command = PinCommandType.Remove; + + Command.SetPin(Configuration); + + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Pin already set or removed."); + Environment.ExitCode.Should().Be(0); + } + } + + [Fact] + public void Should_Return_2_ExitCode_When_Pinning_An_Already_Pinned_Package_With_UseEnhancedExitCodes_Enabled() + { + Reset(); + Configuration.Features.UseEnhancedExitCodes = true; + Configuration.PinCommand.Name = "regular"; + Configuration.PinCommand.Command = PinCommandType.Remove; + + Command.SetPin(Configuration); + + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Pin already set or removed."); + Environment.ExitCode.Should().Be(2); + } + } + } } } diff --git a/src/chocolatey.tests/infrastructure.app/services/ChocolateyConfigSettingsServiceSpecs.cs b/src/chocolatey.tests/infrastructure.app/services/ChocolateyConfigSettingsServiceSpecs.cs index f1c3a973b..1efa97e54 100644 --- a/src/chocolatey.tests/infrastructure.app/services/ChocolateyConfigSettingsServiceSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/services/ChocolateyConfigSettingsServiceSpecs.cs @@ -3,10 +3,12 @@ using System.Linq; using chocolatey.infrastructure.app; using chocolatey.infrastructure.app.configuration; +using chocolatey.infrastructure.app.nuget; using chocolatey.infrastructure.app.services; using chocolatey.infrastructure.services; -using Moq; using FluentAssertions; +using FluentAssertions.Execution; +using Moq; namespace chocolatey.tests.integration.infrastructure.app.services { @@ -572,5 +574,903 @@ public void Should_return_feature_status() infoMessages[0].Should().Contain("Enabled"); } } + + public class When_ChocolateyConfigSettingsService_AddSource_When_Source_Already_Exists : ChocolateyConfigSettingsServiceSpecsBase + { + public override void Because() + { + var config = new ChocolateyConfiguration() + { + RegularOutput = true, + Sources = "https://test.org/api/v2", + SourceCommand = new SourcesCommandConfiguration() + { + Name = "testSource", + Command = chocolatey.infrastructure.app.domain.SourceCommandType.Add + }, + Features = new FeaturesConfiguration() + { + UseEnhancedExitCodes = false + } + }; + + Service.AddSource(config); + } + + public override void Context() + { + base.Context(); + + XmlService.Setup(x => x.Deserialize(ApplicationParameters.GlobalConfigFileLocation)) + .Returns(new ConfigFileSettings + { + Sources = new HashSet + { + new ConfigFileSourceSetting() + { + Id = "testSource", + Value = "https://test.org/api/v2" + } + } + }); + + Service = new ChocolateyConfigSettingsService(XmlService.Object); + } + + [Fact] + public void Should_return_exit_code_0() + { + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Config already set."); + Environment.ExitCode.Should().Be(0); + } + } + } + + public class When_ChocolateyConfigSettingsService_AddSource_When_Source_Already_Exists_With_Enhanced_Exit_Codes : ChocolateyConfigSettingsServiceSpecsBase + { + public override void Because() + { + var config = new ChocolateyConfiguration() + { + RegularOutput = true, + Sources = "https://test.org/api/v2", + SourceCommand = new SourcesCommandConfiguration() + { + Name = "testSource", + Command = chocolatey.infrastructure.app.domain.SourceCommandType.Add + }, + Features = new FeaturesConfiguration() + { + UseEnhancedExitCodes = true + } + }; + + Service.AddSource(config); + } + + public override void Context() + { + base.Context(); + + XmlService.Setup(x => x.Deserialize(ApplicationParameters.GlobalConfigFileLocation)) + .Returns(new ConfigFileSettings + { + Sources = new HashSet + { + new ConfigFileSourceSetting() + { + Id = "testSource", + Value = "https://test.org/api/v2" + } + } + }); + + Service = new ChocolateyConfigSettingsService(XmlService.Object); + } + + [Fact] + public void Should_return_exit_code_2() + { + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Config already set."); + Environment.ExitCode.Should().Be(2); + } + } + } + + public class When_ChocolateyConfigSettingsService_RemoveSource_When_Source_Doesnt_Exist : ChocolateyConfigSettingsServiceSpecsBase + { + public override void Because() + { + var config = new ChocolateyConfiguration() + { + RegularOutput = true, + Sources = "https://test.org/api/v2", + SourceCommand = new SourcesCommandConfiguration() + { + Name = "testSource", + Command = chocolatey.infrastructure.app.domain.SourceCommandType.Remove + }, + Features = new FeaturesConfiguration() + { + UseEnhancedExitCodes = false + } + }; + + Service.RemoveSource(config); + } + + public override void Context() + { + base.Context(); + + XmlService.Setup(x => x.Deserialize(ApplicationParameters.GlobalConfigFileLocation)) + .Returns(new ConfigFileSettings + { + Sources = new HashSet() + }); + + Service = new ChocolateyConfigSettingsService(XmlService.Object); + } + + [Fact] + public void Should_return_exit_code_0() + { + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Config already set."); + Environment.ExitCode.Should().Be(0); + } + } + } + + public class When_ChocolateyConfigSettingsService_RemoveSource_When_Source_Doesnt_Exist_With_Enhanced_Exit_Codes : ChocolateyConfigSettingsServiceSpecsBase + { + public override void Because() + { + var config = new ChocolateyConfiguration() + { + RegularOutput = true, + Sources = "https://test.org/api/v2", + SourceCommand = new SourcesCommandConfiguration() + { + Name = "testSource", + Command = chocolatey.infrastructure.app.domain.SourceCommandType.Remove + }, + Features = new FeaturesConfiguration() + { + UseEnhancedExitCodes = true + } + }; + + Service.RemoveSource(config); + } + + public override void Context() + { + base.Context(); + + XmlService.Setup(x => x.Deserialize(ApplicationParameters.GlobalConfigFileLocation)) + .Returns(new ConfigFileSettings + { + Sources = new HashSet() + }); + + Service = new ChocolateyConfigSettingsService(XmlService.Object); + } + + [Fact] + public void Should_return_exit_code_2() + { + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Config already set."); + Environment.ExitCode.Should().Be(2); + } + } + } + + public class When_ChocolateyConfigSettingsService_DisableSource_When_Source_Doesnt_Exist : ChocolateyConfigSettingsServiceSpecsBase + { + public override void Because() + { + var config = new ChocolateyConfiguration() + { + RegularOutput = true, + Sources = "https://test.org/api/v2", + SourceCommand = new SourcesCommandConfiguration() + { + Name = "testSource", + Command = chocolatey.infrastructure.app.domain.SourceCommandType.Disable + }, + Features = new FeaturesConfiguration() + { + UseEnhancedExitCodes = false + } + }; + + Service.DisableSource(config); + } + + public override void Context() + { + base.Context(); + + XmlService.Setup(x => x.Deserialize(ApplicationParameters.GlobalConfigFileLocation)) + .Returns(new ConfigFileSettings + { + Sources = new HashSet() + }); + + Service = new ChocolateyConfigSettingsService(XmlService.Object); + } + + [Fact] + public void Should_return_exit_code_0() + { + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Config already set."); + Environment.ExitCode.Should().Be(0); + } + } + } + + public class When_ChocolateyConfigSettingsService_DisableSource_When_Source_Doesnt_Exist_With_Enhanced_Exit_Codes : ChocolateyConfigSettingsServiceSpecsBase + { + public override void Because() + { + var config = new ChocolateyConfiguration() + { + RegularOutput = true, + Sources = "https://test.org/api/v2", + SourceCommand = new SourcesCommandConfiguration() + { + Name = "testSource", + Command = chocolatey.infrastructure.app.domain.SourceCommandType.Disable + }, + Features = new FeaturesConfiguration() + { + UseEnhancedExitCodes = true + } + }; + + Service.DisableSource(config); + } + + public override void Context() + { + base.Context(); + + XmlService.Setup(x => x.Deserialize(ApplicationParameters.GlobalConfigFileLocation)) + .Returns(new ConfigFileSettings + { + Sources = new HashSet() + }); + + Service = new ChocolateyConfigSettingsService(XmlService.Object); + } + + [Fact] + public void Should_return_exit_code_2() + { + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Config already set."); + Environment.ExitCode.Should().Be(2); + } + } + } + + public class When_ChocolateyConfigSettingsService_EnableSource_When_Source_Doesnt_Exist : ChocolateyConfigSettingsServiceSpecsBase + { + public override void Because() + { + var config = new ChocolateyConfiguration() + { + RegularOutput = true, + Sources = "https://test.org/api/v2", + SourceCommand = new SourcesCommandConfiguration() + { + Name = "testSource", + Command = chocolatey.infrastructure.app.domain.SourceCommandType.Enable + }, + Features = new FeaturesConfiguration() + { + UseEnhancedExitCodes = false + } + }; + + Service.EnableSource(config); + } + + public override void Context() + { + base.Context(); + + XmlService.Setup(x => x.Deserialize(ApplicationParameters.GlobalConfigFileLocation)) + .Returns(new ConfigFileSettings + { + Sources = new HashSet() + }); + + Service = new ChocolateyConfigSettingsService(XmlService.Object); + } + + [Fact] + public void Should_return_exit_code_0() + { + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Config already set."); + Environment.ExitCode.Should().Be(0); + } + } + } + + public class When_ChocolateyConfigSettingsService_EnableSource_When_Source_Doesnt_Exist_With_Enhanced_Exit_Codes : ChocolateyConfigSettingsServiceSpecsBase + { + public override void Because() + { + var config = new ChocolateyConfiguration() + { + RegularOutput = true, + Sources = "https://test.org/api/v2", + SourceCommand = new SourcesCommandConfiguration() + { + Name = "testSource", + Command = chocolatey.infrastructure.app.domain.SourceCommandType.Enable + }, + Features = new FeaturesConfiguration() + { + UseEnhancedExitCodes = true + } + }; + + Service.EnableSource(config); + } + + public override void Context() + { + base.Context(); + + XmlService.Setup(x => x.Deserialize(ApplicationParameters.GlobalConfigFileLocation)) + .Returns(new ConfigFileSettings + { + Sources = new HashSet() + }); + + Service = new ChocolateyConfigSettingsService(XmlService.Object); + } + + [Fact] + public void Should_return_exit_code_2() + { + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Config already set."); + Environment.ExitCode.Should().Be(2); + } + } + } + + public class When_ChocolateyConfigSettingsService_DisableFeature_When_Feature_Already_Disabled : ChocolateyConfigSettingsServiceSpecsBase + { + public override void Because() + { + var config = new ChocolateyConfiguration() + { + RegularOutput = true, + FeatureCommand = new FeatureCommandConfiguration() + { + Name = ApplicationParameters.Features.ChecksumFiles, + Command = chocolatey.infrastructure.app.domain.FeatureCommandType.Disable + }, + Features = new FeaturesConfiguration() + { + UseEnhancedExitCodes = false + } + }; + + Service.DisableFeature(config); + } + + public override void Context() + { + base.Context(); + + XmlService.Setup(x => x.Deserialize(ApplicationParameters.GlobalConfigFileLocation)) + .Returns(new ConfigFileSettings + { + Features = new HashSet + { + new ConfigFileFeatureSetting + { + Name = ApplicationParameters.Features.ChecksumFiles, + Enabled = false, + SetExplicitly = true + } + } + }); + + Service = new ChocolateyConfigSettingsService(XmlService.Object); + } + + [Fact] + public void Should_return_exit_code_0() + { + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Config already set."); + Environment.ExitCode.Should().Be(0); + } + } + } + + public class When_ChocolateyConfigSettingsService_DisableFeature_When_Feature_Already_Disabled_With_Enhanced_Exit_Codes : ChocolateyConfigSettingsServiceSpecsBase + { + public override void Because() + { + var config = new ChocolateyConfiguration() + { + RegularOutput = true, + FeatureCommand = new FeatureCommandConfiguration() + { + Name = ApplicationParameters.Features.ChecksumFiles, + Command = chocolatey.infrastructure.app.domain.FeatureCommandType.Disable + }, + Features = new FeaturesConfiguration() + { + UseEnhancedExitCodes = true + } + }; + + Service.DisableFeature(config); + } + + public override void Context() + { + base.Context(); + + XmlService.Setup(x => x.Deserialize(ApplicationParameters.GlobalConfigFileLocation)) + .Returns(new ConfigFileSettings + { + Features = new HashSet + { + new ConfigFileFeatureSetting + { + Name = ApplicationParameters.Features.ChecksumFiles, + Enabled = false, + SetExplicitly = true + } + } + }); + + Service = new ChocolateyConfigSettingsService(XmlService.Object); + } + + [Fact] + public void Should_return_exit_code_2() + { + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Config already set."); + Environment.ExitCode.Should().Be(2); + } + } + } + + public class When_ChocolateyConfigSettingsService_EnableFeature_When_Feature_Already_Enabled: ChocolateyConfigSettingsServiceSpecsBase + { + public override void Because() + { + var config = new ChocolateyConfiguration() + { + RegularOutput = true, + FeatureCommand = new FeatureCommandConfiguration() + { + Name = ApplicationParameters.Features.ChecksumFiles, + Command = chocolatey.infrastructure.app.domain.FeatureCommandType.Enable + }, + Features = new FeaturesConfiguration() + { + UseEnhancedExitCodes = false + } + }; + + Service.EnableFeature(config); + } + + public override void Context() + { + base.Context(); + + XmlService.Setup(x => x.Deserialize(ApplicationParameters.GlobalConfigFileLocation)) + .Returns(new ConfigFileSettings + { + Features = new HashSet + { + new ConfigFileFeatureSetting + { + Name = ApplicationParameters.Features.ChecksumFiles, + Enabled = true, + SetExplicitly = true + } + } + }); + + Service = new ChocolateyConfigSettingsService(XmlService.Object); + } + + [Fact] + public void Should_return_exit_code_0() + { + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Config already set."); + Environment.ExitCode.Should().Be(0); + } + } + } + + public class When_ChocolateyConfigSettingsService_EnableFeature_When_Feature_Already_Enabled_With_Enhanced_Exit_Codes : ChocolateyConfigSettingsServiceSpecsBase + { + public override void Because() + { + var config = new ChocolateyConfiguration() + { + RegularOutput = true, + FeatureCommand = new FeatureCommandConfiguration() + { + Name = ApplicationParameters.Features.ChecksumFiles, + Command = chocolatey.infrastructure.app.domain.FeatureCommandType.Enable + }, + Features = new FeaturesConfiguration() + { + UseEnhancedExitCodes = true + } + }; + + Service.EnableFeature(config); + } + + public override void Context() + { + base.Context(); + + XmlService.Setup(x => x.Deserialize(ApplicationParameters.GlobalConfigFileLocation)) + .Returns(new ConfigFileSettings + { + Features = new HashSet + { + new ConfigFileFeatureSetting + { + Name = ApplicationParameters.Features.ChecksumFiles, + Enabled = true, + SetExplicitly = true + } + } + }); + + Service = new ChocolateyConfigSettingsService(XmlService.Object); + } + + [Fact] + public void Should_return_exit_code_2() + { + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Config already set."); + Environment.ExitCode.Should().Be(2); + } + } + } + + public class When_ChocolateyConfigSettingsService_SetApiKey_When_ApiKey_Already_Exists : ChocolateyConfigSettingsServiceSpecsBase + { + public override void Because() + { + var config = new ChocolateyConfiguration() + { + RegularOutput = true, + Sources = "https://test.org/api/v2", + ApiKeyCommand = new ApiKeyCommandConfiguration() + { + Key = "bob", + Command = chocolatey.infrastructure.app.domain.ApiKeyCommandType.Add + }, + Features = new FeaturesConfiguration() + { + UseEnhancedExitCodes = false + } + }; + + Service.SetApiKey(config); + } + + public override void Context() + { + base.Context(); + + XmlService.Setup(x => x.Deserialize(ApplicationParameters.GlobalConfigFileLocation)) + .Returns(new ConfigFileSettings + { + ApiKeys = new HashSet + { + new ConfigFileApiKeySetting + { + Key = NugetEncryptionUtility.EncryptString("bob"), + Source = "https://test.org/api/v2" + } + } + }); + + Service = new ChocolateyConfigSettingsService(XmlService.Object); + } + + [Fact] + public void Should_return_exit_code_0() + { + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Config already set."); + Environment.ExitCode.Should().Be(0); + } + } + } + + public class When_ChocolateyConfigSettingsService_SetApiKey_When_ApiKey_Already_Exists_With_Enhanced_Exit_Codes : ChocolateyConfigSettingsServiceSpecsBase + { + public override void Because() + { + var config = new ChocolateyConfiguration() + { + RegularOutput = true, + Sources = "https://test.org/api/v2", + ApiKeyCommand = new ApiKeyCommandConfiguration() + { + Key = "bob", + Command = chocolatey.infrastructure.app.domain.ApiKeyCommandType.Add + }, + Features = new FeaturesConfiguration() + { + UseEnhancedExitCodes = true + } + }; + + Service.SetApiKey(config); + } + + public override void Context() + { + base.Context(); + + XmlService.Setup(x => x.Deserialize(ApplicationParameters.GlobalConfigFileLocation)) + .Returns(new ConfigFileSettings + { + ApiKeys = new HashSet + { + new ConfigFileApiKeySetting + { + Key = NugetEncryptionUtility.EncryptString("bob"), + Source = "https://test.org/api/v2" + } + } + }); + + Service = new ChocolateyConfigSettingsService(XmlService.Object); + } + + [Fact] + public void Should_return_exit_code_2() + { + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Config already set."); + Environment.ExitCode.Should().Be(2); + } + } + } + + public class When_ChocolateyConfigSettingsService_SetConfig_When_Config_Already_Set : ChocolateyConfigSettingsServiceSpecsBase + { + public override void Because() + { + var config = new ChocolateyConfiguration() + { + RegularOutput = true, + ConfigCommand = new ConfigCommandConfiguration() + { + Name = ApplicationParameters.ConfigSettings.CacheLocation, + Command = chocolatey.infrastructure.app.domain.ConfigCommandType.Set, + ConfigValue = @"C:\temp" + }, + Features = new FeaturesConfiguration() + { + UseEnhancedExitCodes = false + } + }; + + Service.SetConfig(config); + } + + public override void Context() + { + base.Context(); + + XmlService.Setup(x => x.Deserialize(ApplicationParameters.GlobalConfigFileLocation)) + .Returns(new ConfigFileSettings + { + ConfigSettings = new HashSet() + { + new ConfigFileConfigSetting() + { + Key = ApplicationParameters.ConfigSettings.CacheLocation, + Value = @"C:\temp" + } + } + }); + + Service = new ChocolateyConfigSettingsService(XmlService.Object); + } + + [Fact] + public void Should_return_exit_code_0() + { + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Config already set."); + Environment.ExitCode.Should().Be(0); + } + } + } + + public class When_ChocolateyConfigSettingsService_SetConfig_When_Config_Already_Set_Enhanced_Exit_Codes : ChocolateyConfigSettingsServiceSpecsBase + { + public override void Because() + { + var config = new ChocolateyConfiguration() + { + RegularOutput = true, + ConfigCommand = new ConfigCommandConfiguration() + { + Name = ApplicationParameters.ConfigSettings.CacheLocation, + Command = chocolatey.infrastructure.app.domain.ConfigCommandType.Set, + ConfigValue = @"C:\temp" + + }, + Features = new FeaturesConfiguration() + { + UseEnhancedExitCodes = true + } + }; + + Service.SetConfig(config); + } + + public override void Context() + { + base.Context(); + + XmlService.Setup(x => x.Deserialize(ApplicationParameters.GlobalConfigFileLocation)) + .Returns(new ConfigFileSettings + { + ConfigSettings = new HashSet() + { + new ConfigFileConfigSetting() + { + Key = ApplicationParameters.ConfigSettings.CacheLocation, + Value = @"C:\temp" + } + } + }); + + Service = new ChocolateyConfigSettingsService(XmlService.Object); + } + + [Fact] + public void Should_return_exit_code_2() + { + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Config already set."); + Environment.ExitCode.Should().Be(2); + } + } + } + + public class When_ChocolateyConfigSettingsService_UnSetConfig_When_Config_Already_UnSet : ChocolateyConfigSettingsServiceSpecsBase + { + public override void Because() + { + var config = new ChocolateyConfiguration() + { + RegularOutput = true, + ConfigCommand = new ConfigCommandConfiguration() + { + Name = ApplicationParameters.ConfigSettings.CacheLocation, + Command = chocolatey.infrastructure.app.domain.ConfigCommandType.Unset + }, + Features = new FeaturesConfiguration() + { + UseEnhancedExitCodes = false + } + }; + + Service.UnsetConfig(config); + } + + public override void Context() + { + base.Context(); + + XmlService.Setup(x => x.Deserialize(ApplicationParameters.GlobalConfigFileLocation)) + .Returns(new ConfigFileSettings + { + ConfigSettings = new HashSet() + }); + + Service = new ChocolateyConfigSettingsService(XmlService.Object); + } + + [Fact] + public void Should_return_exit_code_0() + { + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Config already set."); + Environment.ExitCode.Should().Be(0); + } + } + } + + public class When_ChocolateyConfigSettingsService_UnSetConfig_When_Config_Already_UnSet_Enhanced_Exit_Codes : ChocolateyConfigSettingsServiceSpecsBase + { + public override void Because() + { + var config = new ChocolateyConfiguration() + { + RegularOutput = true, + ConfigCommand = new ConfigCommandConfiguration() + { + Name = ApplicationParameters.ConfigSettings.CacheLocation, + Command = chocolatey.infrastructure.app.domain.ConfigCommandType.Unset + + }, + Features = new FeaturesConfiguration() + { + UseEnhancedExitCodes = true + } + }; + + Service.UnsetConfig(config); + } + + public override void Context() + { + base.Context(); + + XmlService.Setup(x => x.Deserialize(ApplicationParameters.GlobalConfigFileLocation)) + .Returns(new ConfigFileSettings + { + ConfigSettings = new HashSet() + }); + + Service = new ChocolateyConfigSettingsService(XmlService.Object); + } + + [Fact] + public void Should_return_exit_code_2() + { + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain("Nothing to change. Config already set."); + Environment.ExitCode.Should().Be(2); + } + } + } } } diff --git a/src/chocolatey.tests/infrastructure.app/services/ChocolateyPackageServiceSpecs.cs b/src/chocolatey.tests/infrastructure.app/services/ChocolateyPackageServiceSpecs.cs index d972ea0b3..3adeedf94 100644 --- a/src/chocolatey.tests/infrastructure.app/services/ChocolateyPackageServiceSpecs.cs +++ b/src/chocolatey.tests/infrastructure.app/services/ChocolateyPackageServiceSpecs.cs @@ -17,10 +17,12 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using chocolatey.infrastructure.app.configuration; using chocolatey.infrastructure.app.domain; +using chocolatey.infrastructure.app.registration; using chocolatey.infrastructure.app.services; using chocolatey.infrastructure.filesystem; using chocolatey.infrastructure.results; @@ -28,9 +30,8 @@ using Moq; using NUnit.Framework; using FluentAssertions; +using FluentAssertions.Execution; using IFileSystem = chocolatey.infrastructure.filesystem.IFileSystem; -using System.IO; -using chocolatey.infrastructure.app.registration; using NuGet.Packaging; namespace chocolatey.tests.infrastructure.app.services @@ -395,7 +396,7 @@ public override void Context() Action = () => Service.Upgrade(Configuration); Configuration.CommandName = "upgrade"; } - } + } public class When_ChocolateyPackageService_tries_to_upgrade_noop_nupkg_file : When_ChocolateyPackageService_tries_to_install_nupkg_file { @@ -406,5 +407,81 @@ public override void Context() Configuration.CommandName = "upgrade"; } } + + public class When_ChocolateyPackageService_tries_to_upgrade_a_package_that_doesnt_need_upgraded : ChocolateyPackageServiceSpecsBase + { + private ConcurrentDictionary _result; + + public override void Context() + { + base.Context(); + Configuration.PackageNames = "alreadyupgraded"; + Configuration.Sources = @"c:\packages"; + Configuration.Features.UseEnhancedExitCodes = false; + + var package = new Mock(); + var expectedResult = new ConcurrentDictionary(); + var packageResult = new PackageResult(package.Object, @"c:\programdata\chocolatey\lib\alreadyupgraded", null); + var logMessage = "alreadyupgraded v1.2.3 is the latest version available based on your source(s)."; + packageResult.Messages.Add(new ResultMessage(ResultType.Inconclusive, logMessage)); + expectedResult.TryAdd("alreadyupgraded", packageResult); + + NugetService.Setup(n => n.Upgrade(It.IsAny(), It.IsAny>(), It.IsAny>())) + .Returns(expectedResult); + } + + public override void Because() + { + _result = Service.Upgrade(Configuration); + } + + [Fact] + public void Should_Return_0_Exit_Code() + { + using(new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain(m => m.Contains("Chocolatey upgraded 0/1 packages.")); + Environment.ExitCode.Should().Be(0); + } + } + } + + public class When_ChocolateyPackageService_tries_to_upgrade_a_package_that_doesnt_need_upgraded_using_enhanced_exitcodes : ChocolateyPackageServiceSpecsBase + { + private ConcurrentDictionary _result; + + public override void Context() + { + base.Context(); + Configuration.PackageNames = "alreadyupgraded"; + Configuration.Sources = @"c:\packages"; + Configuration.Features.UseEnhancedExitCodes = true; + + var package = new Mock(); + var expectedResult = new ConcurrentDictionary(); + var packageResult = new PackageResult(package.Object, @"c:\programdata\chocolatey\lib\alreadyupgraded", null); + var logMessage = "alreadyupgraded v1.2.3 is the latest version available based on your source(s)."; + packageResult.Messages.Add(new ResultMessage(ResultType.Inconclusive, logMessage)); + expectedResult.TryAdd("alreadyupgraded", packageResult); + + NugetService.Setup(n => n.Upgrade(It.IsAny(), It.IsAny>(), It.IsAny>())) + .Returns(expectedResult); + } + + public override void Because() + { + _result = Service.Upgrade(Configuration); + } + + [Fact] + public void Should_Return_0_Exit_Code() + { + using (new AssertionScope()) + { + MockLogger.Messages.Should().ContainKey("Warn").WhoseValue.Should().ContainSingle().And.Contain(m => m.Contains("Chocolatey upgraded 0/1 packages.")); + Environment.ExitCode.Should().Be(2); + } + } + } } }