public async Task DownloadQualityProfile_WhenBindingConfigIsNull_Fails()
        {
            // Arrange
            const string QualityProfileName = "SQQualityProfileName";
            const string ProjectName        = "SQProjectName";

            Mock <INuGetBindingOperation> nuGetOpMock = new Mock <INuGetBindingOperation>();

            var notifications   = new ConfigurableProgressStepExecutionEvents();
            var progressAdapter = new FixedStepsProgressAdapter(notifications);

            var language = Language.VBNET;
            SonarQubeQualityProfile profile = this.ConfigureQualityProfile(language, QualityProfileName);

            var configProviderMock = new Mock <IBindingConfigProvider>();
            var testSubject        = this.CreateTestSubject("key", ProjectName, nuGetOpMock.Object, configProviderMock.Object);

            ConfigureSupportedBindingProject(testSubject.InternalState, language);

            // Act
            var result = await testSubject.DownloadQualityProfileAsync(progressAdapter, CancellationToken.None);

            // Assert
            result.Should().BeFalse();
            testSubject.InternalState.QualityProfiles[language].Should().Be(profile);

            notifications.AssertProgress(0.0);
            notifications.AssertProgressMessages(Strings.DownloadingQualityProfileProgressMessage);

            this.outputWindowPane.AssertOutputStrings(1);
            var expectedOutput = string.Format(Strings.SubTextPaddingFormat,
                                               string.Format(Strings.FailedToCreateBindingConfigForLanguage, language.Name));

            this.outputWindowPane.AssertOutputStrings(expectedOutput);
        }
        public async Task DownloadQualityProfile_WhenQualityProfileIsNotAvailable_Fails()
        {
            // Arrange
            var testSubject     = this.CreateTestSubject();
            var notifications   = new ConfigurableProgressStepExecutionEvents();
            var progressAdapter = new FixedStepsProgressAdapter(notifications);

            var language = Language.CSharp;

            ConfigureSupportedBindingProject(testSubject.InternalState, language);
            this.ConfigureQualityProfile(Language.VBNET, "");

            // Act
            var result = await testSubject.DownloadQualityProfileAsync(progressAdapter, CancellationToken.None);

            // Assert
            result.Should().BeFalse();
            testSubject.InternalState.BindingConfigs.Should().NotContainKey(Language.VBNET, "Not expecting any rules for this language");
            testSubject.InternalState.BindingConfigs.Should().NotContainKey(language, "Not expecting any rules");

            notifications.AssertProgressMessages(Strings.DownloadingQualityProfileProgressMessage);

            this.outputWindowPane.AssertOutputStrings(1);
            var expectedOutput = string.Format(Strings.SubTextPaddingFormat,
                                               string.Format(Strings.CannotDownloadQualityProfileForLanguage, language.Name));

            this.outputWindowPane.AssertOutputStrings(expectedOutput);
        }
        public void Progress_MultipleValidSteps()
        {
            // Arrange
            var listener    = new ConfigurableProgressStepExecutionEvents();
            var testSubject = new FixedStepsProgressAdapter(listener);

            // Act
            Report(testSubject, "Starting...", 0, 4);
            Report(testSubject, "Step1", 1, 4);
            Report(testSubject, "Step1 again", 1, 4);
            Report(testSubject, null, 2, 4);
            Report(testSubject, "", 3, 4);
            Report(testSubject, "Ending...", 4, 4);

            listener.AssertProgressMessages("Starting...",
                                            "Step1",
                                            "Step1 again",
                                            null,
                                            "",
                                            "Ending...");

            listener.AssertProgress(
                0 / 4d,
                1 / 4d,
                1 / 4d,
                2 / 4d,
                3 / 4d,
                1.0);
        }
        private static void Report(FixedStepsProgressAdapter testSubject, string message, int currentStep, int totalSteps)
        {
            var testSubjectAsIProgress = (IProgress <FixedStepsProgress>)testSubject;
            var progressData           = new FixedStepsProgress(message, currentStep, totalSteps);

            testSubjectAsIProgress.Report(progressData);
        }
        public void InstallPackages_FailureOnOneProject_Continues()
        {
            // Arrange
            const string failureMessage = "Failure for project1";
            const string project1Name   = "project1";
            const string project2Name   = "project2";

            var testSubject     = this.CreateTestSubject();
            var progressEvents  = new ConfigurableProgressStepExecutionEvents();
            var progressAdapter = new FixedStepsProgressAdapter(progressEvents);
            var cts             = new CancellationTokenSource();

            ProjectMock project1 = new ProjectMock(project1Name)
            {
                ProjectKind = ProjectSystemHelper.CSharpProjectKind
            };
            ProjectMock project2 = new ProjectMock(project2Name)
            {
                ProjectKind = ProjectSystemHelper.CSharpProjectKind
            };
            var projectsToBind = new HashSet <Project> {
                project1, project2
            };

            var nugetPackage  = new PackageName("mypackage", new SemanticVersion("1.1.0"));
            var packages      = new[] { nugetPackage };
            var nugetPackages = new Dictionary <Language, IEnumerable <PackageName> >();

            nugetPackages.Add(Language.CSharp, packages);

            ConfigurablePackageInstaller packageInstaller = this.PrepareInstallPackagesTest(testSubject, nugetPackages);

            packageInstaller.InstallPackageAction = (p) =>
            {
                packageInstaller.InstallPackageAction = null;
                throw new Exception(failureMessage);
            };

            // Act
            testSubject.InstallPackages(projectsToBind, progressAdapter, cts.Token);

            // Assert
            packageInstaller.AssertNoInstalledPackages(project1);
            packageInstaller.AssertInstalledPackages(project2, packages);
            this.logger.AssertOutputStrings(4);
            this.logger.AssertOutputStrings(
                string.Format(Strings.SubTextPaddingFormat, string.Format(Strings.EnsuringNugetPackagesProgressMessage, nugetPackage.Id, project1Name)),
                string.Format(Strings.SubTextPaddingFormat, string.Format(Strings.FailedDuringNuGetPackageInstall, nugetPackage.Id, project1Name, failureMessage)),
                string.Format(Strings.SubTextPaddingFormat, string.Format(Strings.EnsuringNugetPackagesProgressMessage, nugetPackage.Id, project2Name)),
                string.Format(Strings.SubTextPaddingFormat, string.Format(Strings.SuccessfullyInstalledNugetPackageForProject, nugetPackage.Id, project2Name))
                );

            progressEvents.AssertProgress(.5, 1.0);
        }
        public async Task DownloadQualityProfile_Success()
        {
            var configPersister = new ConfigurableConfigurationProvider();

            this.serviceProvider.RegisterService(typeof(IConfigurationPersister), configPersister);

            // Arrange
            const string QualityProfileName = "SQQualityProfileName";
            const string ProjectName        = "SQProjectName";

            Mock <INuGetBindingOperation> nuGetOpMock = new Mock <INuGetBindingOperation>();

            var notifications   = new ConfigurableProgressStepExecutionEvents();
            var progressAdapter = new FixedStepsProgressAdapter(notifications);

            var bindingConfig = new Mock <IBindingConfig>().Object;

            var language = Language.VBNET;
            SonarQubeQualityProfile profile = this.ConfigureQualityProfile(language, QualityProfileName);

            var configProviderMock = new Mock <IBindingConfigProvider>();

            configProviderMock.Setup(x => x.GetConfigurationAsync(profile, language, BindingConfiguration.Standalone, CancellationToken.None))
            .ReturnsAsync(bindingConfig);

            var bindingArgs = new BindCommandArgs("key", ProjectName, new ConnectionInformation(new Uri("http://connected")));
            var testSubject = this.CreateTestSubject(bindingArgs, nuGetOpMock.Object, configProviderMock.Object);

            ConfigureSupportedBindingProject(testSubject.InternalState, language);

            // Act
            var result = await testSubject.DownloadQualityProfileAsync(progressAdapter, CancellationToken.None);

            // Assert
            result.Should().BeTrue();
            testSubject.InternalState.BindingConfigs.Should().ContainKey(language);
            testSubject.InternalState.BindingConfigs[language].Should().Be(bindingConfig);
            testSubject.InternalState.BindingConfigs.Count().Should().Be(1);

            testSubject.InternalState.QualityProfiles[language].Should().Be(profile);

            notifications.AssertProgress(0.0, 1.0);
            notifications.AssertProgressMessages(Strings.DownloadingQualityProfileProgressMessage, string.Empty);

            this.outputWindowPane.AssertOutputStrings(1);
            var expectedOutput = string.Format(Strings.SubTextPaddingFormat,
                                               string.Format(Strings.QualityProfileDownloadSuccessfulMessageFormat, QualityProfileName, string.Empty, language.Name));

            this.outputWindowPane.AssertOutputStrings(expectedOutput);
        }
        public void Progress_ReduceCurrentStep_Fails()
        {
            // Arrange
            var listener    = new ConfigurableProgressStepExecutionEvents();
            var testSubject = new FixedStepsProgressAdapter(listener);

            // 1. Report first event
            Report(testSubject, null, 2, 3);

            // 2. Report second event, reporting a lower current step
            Action act = () => Report(testSubject, null, 1, 3);

            act.Should().ThrowExactly <ArgumentOutOfRangeException>().And.ParamName.Should().Be("CurrentStep");
        }
        public void Progress_ChangeTotalSteps_Fails()
        {
            // Arrange
            var listener    = new ConfigurableProgressStepExecutionEvents();
            var testSubject = new FixedStepsProgressAdapter(listener);

            // 1. Report first event
            Report(testSubject, "Starting...", 0, 3);

            // 2. Report second event, reporting a changed total step count
            Action act = () => Report(testSubject, null, 1, 4);

            act.Should().ThrowExactly <ArgumentOutOfRangeException>().And.ParamName.Should().Be("TotalSteps");
        }
        public async Task DownloadQualityProfile_Success()
        {
            // Arrange
            const string QualityProfileName = "SQQualityProfileName";
            const string ProjectName        = "SQProjectName";

            Mock <INuGetBindingOperation> nuGetOpMock = new Mock <INuGetBindingOperation>();

            var notifications   = new ConfigurableProgressStepExecutionEvents();
            var progressAdapter = new FixedStepsProgressAdapter(notifications);

            RuleSet expectedRuleSet = TestRuleSetHelper.CreateTestRuleSetWithRuleIds(new[] { "Key1", "Key2" });
            var     configFile      = new Mock <IBindingConfigFile>().Object;

            var language = Language.VBNET;
            SonarQubeQualityProfile profile = this.ConfigureQualityProfile(language, QualityProfileName);

            var configProviderMock = new Mock <IBindingConfigProvider>();

            configProviderMock.Setup(x => x.GetConfigurationAsync(profile, null, language, CancellationToken.None))
            .ReturnsAsync(configFile);

            var testSubject = this.CreateTestSubject("key", ProjectName, nuGetOpMock.Object, configProviderMock.Object);

            ConfigureSupportedBindingProject(testSubject.InternalState, language);

            // Act
            var result = await testSubject.DownloadQualityProfileAsync(progressAdapter, CancellationToken.None);

            // Assert
            result.Should().BeTrue();
            testSubject.InternalState.BindingConfigFiles.Should().ContainKey(language);
            testSubject.InternalState.BindingConfigFiles[language].Should().Be(configFile);
            testSubject.InternalState.BindingConfigFiles.Count().Should().Be(1);

            testSubject.InternalState.QualityProfiles[language].Should().Be(profile);

            notifications.AssertProgress(0.0, 1.0);
            notifications.AssertProgressMessages(Strings.DownloadingQualityProfileProgressMessage, string.Empty);

            this.outputWindowPane.AssertOutputStrings(1);
            var expectedOutput = string.Format(Strings.SubTextPaddingFormat,
                                               string.Format(Strings.QualityProfileDownloadSuccessfulMessageFormat, QualityProfileName, string.Empty, language.Name));

            this.outputWindowPane.AssertOutputStrings(expectedOutput);
        }
        public async Task DownloadQualityProfile_SavesConfiguration()
        {
            var configPersister = new ConfigurableConfigurationProvider();

            this.serviceProvider.RegisterService(typeof(IConfigurationPersister), configPersister);

            // Arrange
            const string QualityProfileName = "SQQualityProfileName";
            const string ProjectName        = "SQProjectName";

            Mock <INuGetBindingOperation> nuGetOpMock = new Mock <INuGetBindingOperation>();

            var notifications   = new ConfigurableProgressStepExecutionEvents();
            var progressAdapter = new FixedStepsProgressAdapter(notifications);

            var bindingConfig = new Mock <IBindingConfig>().Object;

            var language = Language.VBNET;
            SonarQubeQualityProfile profile = this.ConfigureQualityProfile(language, QualityProfileName);

            var configProviderMock = new Mock <IBindingConfigProvider>();

            configProviderMock.Setup(x => x.GetConfigurationAsync(profile, language, It.IsAny <BindingConfiguration>(), CancellationToken.None))
            .ReturnsAsync(bindingConfig);

            var bindingArgs = new BindCommandArgs("key", ProjectName, new ConnectionInformation(new Uri("http://connected")));
            var testSubject = this.CreateTestSubject(bindingArgs, nuGetOpMock.Object, configProviderMock.Object);

            ConfigureSupportedBindingProject(testSubject.InternalState, language);

            // Act
            await testSubject.DownloadQualityProfileAsync(progressAdapter, CancellationToken.None);

            // Assert
            configPersister.SavedProject.Should().NotBeNull();
            configPersister.SavedMode.Should().Be(SonarLintMode.Connected);

            var savedProject = configPersister.SavedProject;

            savedProject.ServerUri.Should().Be(bindingArgs.Connection.ServerUri);
            savedProject.Profiles.Should().HaveCount(1);
            savedProject.Profiles[Language.VBNET].ProfileKey.Should().Be(profile.Key);
            savedProject.Profiles[Language.VBNET].ProfileTimestamp.Should().Be(profile.TimeStamp);
        }
        public void InstallPackages_Cancellation()
        {
            // Arrange
            var testSubject     = this.CreateTestSubject();
            var progressEvents  = new ConfigurableProgressStepExecutionEvents();
            var progressAdapter = new FixedStepsProgressAdapter(progressEvents);
            var cts             = new CancellationTokenSource();

            var project1 = new ProjectMock("project1")
            {
                ProjectKind = ProjectSystemHelper.CSharpProjectKind
            };
            var project2 = new ProjectMock("project2")
            {
                ProjectKind = ProjectSystemHelper.CSharpProjectKind
            };
            var projectsToBind = new HashSet <Project> {
                project1, project2
            };

            var nugetPackage            = new PackageName("mypackage", new SemanticVersion("1.1.0"));
            var packages                = new[] { nugetPackage };
            var nugetPackagesByLanguage = new Dictionary <Language, IEnumerable <PackageName> >();

            nugetPackagesByLanguage.Add(Language.CSharp, packages);

            ConfigurablePackageInstaller packageInstaller = this.PrepareInstallPackagesTest(testSubject, nugetPackagesByLanguage);

            packageInstaller.InstallPackageAction = (p) =>
            {
                cts.Cancel(); // Cancel the next one (should complete the first one)
            };

            // Acts
            testSubject.InstallPackages(projectsToBind, progressAdapter, cts.Token);

            // Assert
            packageInstaller.AssertInstalledPackages(project1, packages);
            packageInstaller.AssertNoInstalledPackages(project2);

            progressEvents.AssertProgress(.5);
        }
        private void InstallPackages_Succeed(string projectKind, Language language)
        {
            // Arrange
            var testSubject     = this.CreateTestSubject();
            var progressEvents  = new ConfigurableProgressStepExecutionEvents();
            var progressAdapter = new FixedStepsProgressAdapter(progressEvents);

            ProjectMock project1 = new ProjectMock("project1")
            {
                ProjectKind = projectKind
            };
            ProjectMock project2 = new ProjectMock("project2")
            {
                ProjectKind = projectKind
            };
            var projectsToBind = new HashSet <Project> {
                project1, project2
            };

            var nugetPackage = new PackageName("mypackage", new SemanticVersion("1.1.0"));
            var packages     = new Dictionary <Language, IEnumerable <PackageName> >();

            packages.Add(language, new[] { nugetPackage });

            ConfigurablePackageInstaller packageInstaller = this.PrepareInstallPackagesTest(testSubject, packages);

            // Act
            testSubject.InstallPackages(projectsToBind, progressAdapter, CancellationToken.None);

            // Assert
            packageInstaller.AssertInstalledPackages(project1, new[] { nugetPackage });
            packageInstaller.AssertInstalledPackages(project2, new[] { nugetPackage });
            this.logger.AssertOutputStrings(4);
            this.logger.AssertOutputStrings(
                string.Format(Strings.SubTextPaddingFormat, string.Format(Strings.EnsuringNugetPackagesProgressMessage, nugetPackage.Id, ((Project)project1).Name)),
                string.Format(Strings.SubTextPaddingFormat, string.Format(Strings.SuccessfullyInstalledNugetPackageForProject, nugetPackage.Id, ((Project)project1).Name)),
                string.Format(Strings.SubTextPaddingFormat, string.Format(Strings.EnsuringNugetPackagesProgressMessage, nugetPackage.Id, ((Project)project2).Name)),
                string.Format(Strings.SubTextPaddingFormat, string.Format(Strings.SuccessfullyInstalledNugetPackageForProject, nugetPackage.Id, ((Project)project2).Name))
                );
            progressEvents.AssertProgress(.5, 1.0);
        }
        public void InstallPackages_WhenProjectLanguageDoesNotExist_PrintMessageAndContinue()
        {
            // Arrange
            const string project1Name = "project1";
            const string project2Name = "project2";

            var testSubject     = this.CreateTestSubject();
            var progressEvents  = new ConfigurableProgressStepExecutionEvents();
            var progressAdapter = new FixedStepsProgressAdapter(progressEvents);

            ProjectMock project1 = new ProjectMock(project1Name); // No project kind so no nuget package will be installed
            ProjectMock project2 = new ProjectMock(project2Name)
            {
                ProjectKind = ProjectSystemHelper.CSharpProjectKind
            };
            var projectsToBind = new HashSet <Project> {
                project1, project2
            };

            var nugetPackage  = new PackageName("mypackage", new SemanticVersion("1.1.0"));
            var packages      = new[] { nugetPackage };
            var nugetPackages = new Dictionary <Language, IEnumerable <PackageName> >();

            nugetPackages.Add(Language.CSharp, packages);

            ConfigurablePackageInstaller packageInstaller = this.PrepareInstallPackagesTest(testSubject, nugetPackages);

            // Act
            testSubject.InstallPackages(projectsToBind, progressAdapter, CancellationToken.None);

            // Assert
            packageInstaller.AssertNoInstalledPackages(project1);
            packageInstaller.AssertInstalledPackages(project2, packages);
            this.logger.AssertOutputStrings(3);
            this.logger.AssertOutputStrings(
                string.Format(Strings.SubTextPaddingFormat, string.Format(Strings.BindingProjectLanguageNotMatchingAnyQualityProfileLanguage, project1Name)),
                string.Format(Strings.SubTextPaddingFormat, string.Format(Strings.EnsuringNugetPackagesProgressMessage, nugetPackage.Id, project2Name)),
                string.Format(Strings.SubTextPaddingFormat, string.Format(Strings.SuccessfullyInstalledNugetPackageForProject, nugetPackage.Id, project2Name))
                );
        }
        public void InstallPackages_Succeeds_SuccessPropertyIsFalse()
        {
            // Arrange
            var bindingArgs = new BindCommandArgs("projectKey", "projectName", new ConnectionInformation(new Uri("http://connected")));

            var slnBindOpMock = new Mock <ISolutionBindingOperation>();
            var nugetMock     = new Mock <INuGetBindingOperation>();

            nugetMock.Setup(x => x.InstallPackages(It.IsAny <ISet <Project> >(),
                                                   It.IsAny <IProgress <FixedStepsProgress> >(),
                                                   It.IsAny <CancellationToken>())).Returns(false);
            var finder         = new ConfigurableUnboundProjectFinder();
            var configProvider = new Mock <IBindingConfigProvider>();

            var testSubject = new BindingProcessImpl(this.host, bindingArgs, slnBindOpMock.Object, nugetMock.Object, finder, configProvider.Object, SonarLintMode.Connected);

            ProjectMock project1 = new ProjectMock("project1")
            {
                ProjectKind = ProjectSystemHelper.CSharpProjectKind
            };

            testSubject.InternalState.BindingProjects.Clear();
            testSubject.InternalState.BindingProjects.Add(project1);

            var progressEvents  = new ConfigurableProgressStepExecutionEvents();
            var progressAdapter = new FixedStepsProgressAdapter(progressEvents);
            var cts             = new CancellationTokenSource();

            testSubject.InternalState.BindingOperationSucceeded = true;

            // Act
            testSubject.InstallPackages(progressAdapter, cts.Token);

            // Assert
            testSubject.InternalState.BindingOperationSucceeded.Should().BeFalse();
        }