public void ConnectionWorkflow_ConnectionStep_SuccessfulConnection()
        {
            // Setup
            var connectionInfo = new ConnectionInformation(new Uri("http://server"));
            var projects = new ProjectInformation[] { new ProjectInformation { Key = "project1" } };
            this.sonarQubeService.ReturnProjectInformation = projects;
            bool projectChangedCallbackCalled = false;
            this.host.TestStateManager.SetProjectsAction = (c, p) =>
            {
                projectChangedCallbackCalled = true;
                Assert.AreSame(connectionInfo, c, "Unexpected connection");
                CollectionAssert.AreEqual(projects, p.ToArray(), "Unexpected projects");
            };
            
            var controller = new ConfigurableProgressController();
            var executionEvents = new ConfigurableProgressStepExecutionEvents();
            string connectionMessage = connectionInfo.ServerUri.ToString();
            var testSubject= new ConnectionWorkflow(this.host, new RelayCommand(AssertIfCalled));

            // Act
            testSubject.ConnectionStep(controller, CancellationToken.None, connectionInfo, executionEvents);

            // Verify
            executionEvents.AssertProgressMessages(connectionMessage, Strings.ConnectionResultSuccess);
            Assert.IsTrue(projectChangedCallbackCalled, "ConnectedProjectsCallaback was not called");
            sonarQubeService.AssertConnectRequests(1);
            Assert.AreEqual(connectionInfo, testSubject.ConnectedServer);
            ((ConfigurableUserNotification)this.host.ActiveSection.UserNotifications).AssertNoShowErrorMessages();
            ((ConfigurableUserNotification)this.host.ActiveSection.UserNotifications).AssertNoNotification(NotificationIds.FailedToConnectId);
        }
        public void ProjectViewModel_ToolTipProjectName_RespectsIsBound()
        {
            // Setup
            var projectInfo = new ProjectInformation
            {
                Key = "P1",
                Name = "Project1"
            };
            var viewModel = new ProjectViewModel(CreateServerViewModel(), projectInfo);

            // Test Case 1: When project is bound, should show message with 'bound' marker
            // Act
            viewModel.IsBound = true;

            // Verify
            StringAssert.Contains(viewModel.ToolTipProjectName, viewModel.ProjectName, "ToolTip message should include the project name");
            Assert.AreNotEqual(viewModel.ProjectName, viewModel.ToolTipProjectName, "ToolTip message should also indicate that the project is 'bound'");

            // Test Case 2: When project is NOT bound, should show project name only
            // Act
            viewModel.IsBound = false;

            // Verify
            Assert.AreEqual(viewModel.ProjectName, viewModel.ToolTipProjectName, "ToolTip message should be exactly the same as the project name");
        }
        public BindingWorkflow(IHost host, ConnectionInformation connectionInformation, ProjectInformation project)
        {
            if (host == null)
            {
                throw new ArgumentNullException(nameof(host));
            }

            if (connectionInformation == null)
            {
                throw new ArgumentNullException(nameof(connectionInformation));
            }

            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }

            this.host = host;
            this.connectionInformation = connectionInformation;
            this.project = project;
            this.projectSystem = this.host.GetService<IProjectSystemHelper>();
            this.projectSystem.AssertLocalServiceIsNotNull();

            this.solutionBindingOperation = new SolutionBindingOperation(
                    this.host,
                    this.connectionInformation,
                    this.project.Key);
        }
        public void ClearBoundProject()
        {
            this.VerifyActiveSection();

            this.boundProject = null;

            this.BindingStateChanged?.Invoke(this, EventArgs.Empty);
        }
        public void BindingWorkflow_ArgChecks()
        {
            var validConnection = new ConnectionInformation(new Uri("http://server"));
            var validProjectInfo = new ProjectInformation();
            var validHost = new ConfigurableHost();

            Exceptions.Expect<ArgumentNullException>(() => new BindingWorkflow(null, validConnection, validProjectInfo));
            Exceptions.Expect<ArgumentNullException>(() => new BindingWorkflow(validHost, null, validProjectInfo));
            Exceptions.Expect<ArgumentNullException>(() => new BindingWorkflow(validHost, validConnection, null));
        }
        public void SetBoundProject(ProjectInformation project)
        {
            Assert.IsNotNull(project);

            this.VerifyActiveSection();

            this.boundProject = project;

            this.BindingStateChanged?.Invoke(this, EventArgs.Empty);
        }
        public void RegisterProjectDashboardUrl(ConnectionInformation connectionInfo, ProjectInformation projectInfo, Uri url)
        {
            var serverUrl = connectionInfo.ServerUri.ToString();
            var projectKey = projectInfo.Key;
            if (!this.projectDashboardUrls.ContainsKey(serverUrl))
            {
                this.projectDashboardUrls[serverUrl] = new Dictionary<string, Uri>();
            }

            this.projectDashboardUrls[serverUrl][projectKey] = url;
        }
        public ProjectViewModel(ServerViewModel owner, ProjectInformation projectInformation)
        {
            if (owner == null)
            {
                throw new ArgumentNullException(nameof(owner));
            }

            if (projectInformation == null)
            {
                throw new ArgumentNullException(nameof(projectInformation));
            }

            this.Owner = owner;
            this.ProjectInformation = projectInformation;
        }
示例#9
0
        public bool TryGetQualityProfile(ConnectionInformation serverConnection, ProjectInformation project, Language language, CancellationToken token, out QualityProfile profile)
        {
            if (serverConnection == null)
            {
                throw new ArgumentNullException(nameof(serverConnection));
            }

            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }

            if (language == null)
            {
                throw new ArgumentNullException(nameof(language));
            }

            if (!language.IsSupported)
            {
                throw new ArgumentOutOfRangeException(nameof(language));
            }

            profile = this.SafeUseHttpClient <QualityProfile>(serverConnection,
                                                              async client =>
            {
                QualityProfile qp = await DownloadQualityProfile(client, project, language, token);
                if (qp == null)
                {
                    return(null);
                }

                QualityProfileChangeLog changeLog = await DownloadQualityProfileChangeLog(client, qp, token);
                if (changeLog != null)
                {
                    qp.QualityProfileTimestamp = changeLog.Events.SingleOrDefault()?.Date;
                }

                return(qp);
            });

            return(profile != null);
        }
        public void ProjectViewModel_Ctor()
        {
            // Setup
            var projectInfo = new ProjectInformation
            {
                Key = "P1",
                Name = "Project1"
            };
            var serverVM = CreateServerViewModel();

            // Act
            var viewModel = new ProjectViewModel(serverVM, projectInfo);

            // Verify
            Assert.IsFalse(viewModel.IsBound);
            Assert.AreEqual(projectInfo.Key, viewModel.Key);
            Assert.AreEqual(projectInfo.Name, viewModel.ProjectName);
            Assert.AreSame(projectInfo, viewModel.ProjectInformation);
            Assert.AreSame(serverVM, viewModel.Owner);
        }
        public void ProjectViewModel_AutomationName()
        {
            // Setup
            var projectInfo = new ProjectInformation
            {
                Key = "P1",
                Name = "Project1"
            };
            var testSubject = new ProjectViewModel(CreateServerViewModel(), projectInfo);

            var expectedNotBound = projectInfo.Name;
            var expectedBound = string.Format(CultureInfo.CurrentCulture, Strings.AutomationProjectBoundDescription, projectInfo.Name);

            // Test case 1: bound
            // Act
            testSubject.IsBound = true;
            var actualBound = testSubject.AutomationName;

            // Verify
            Assert.AreEqual(expectedBound, actualBound, "Unexpected bound SonarQube project description");


            // Test case 2: not bound
            // Act
            testSubject.IsBound = false;
            var actualNotBound = testSubject.AutomationName;

            // Verify
            Assert.AreEqual(expectedNotBound, actualNotBound, "Unexpected unbound SonarQube project description");
        }
        public ConnectionInformation GetConnectedServer(ProjectInformation project)
        {
            ConnectionInformation conn;
            if (!this.ProjectServerMap.TryGetValue(project, out conn))
            {
                Assert.Inconclusive("Test setup: project-server mapping is not available for the specified project");
            }

            return conn;
        }
示例#13
0
        internal /*for testing purposes*/ static string CreateQualityProfileUrl(Language language, ProjectInformation project = null)
        {
            string projectKey = project?.Key;

            return(string.IsNullOrWhiteSpace(projectKey)
                ? AppendQueryString(QualityProfileListAPI, "?defaults=true")
                : AppendQueryString(QualityProfileListAPI, "?projectKey={0}", projectKey));
        }
 private BindingWorkflow CreateTestSubject(ProjectInformation projectInfo = null)
 {
     var host = new ConfigurableHost(this.serviceProvider, Dispatcher.CurrentDispatcher);
     ConnectionInformation connected = new ConnectionInformation(new Uri("http://connected"));
     host.SonarQubeService = this.sonarQubeService;
     var useProjectInfo = projectInfo ?? new ProjectInformation { Key = "key" };
     return new BindingWorkflow(host, connected, useProjectInfo);
 }
 void IBindingWorkflowExecutor.BindProject(ProjectInformation project)
 {
     this.BoundProject = project;
 }
        bool ISonarQubeServiceWrapper.TryGetQualityProfile(ConnectionInformation serverConnection, ProjectInformation project, Language language, CancellationToken token, out QualityProfile profile)
        {
            profile = null;

            if (this.AllowConnections && !token.IsCancellationRequested)
            {
                this.AssertExpectedConnection(serverConnection);

                this.AssertExpectedProjectInformation(project);

                this.ReturnProfile.TryGetValue(language, out profile);
            }

            return profile != null;
        }
        Uri ISonarQubeServiceWrapper.CreateProjectDashboardUrl(ConnectionInformation serverConnection, ProjectInformation project)
        {
            this.AssertExpectedConnection(serverConnection);

            Uri url;
            IDictionary<string, Uri> projects;
            if (this.projectDashboardUrls.TryGetValue(serverConnection.ServerUri.ToString(), out projects)
                && projects.TryGetValue(project.Key, out url))
            {
                return url;
            }
            return null;
        }
        bool ISonarQubeServiceWrapper.TryGetProjects(ConnectionInformation serverConnection, CancellationToken token, out ProjectInformation[] serverProjects)
        {
            this.AssertExpectedConnection(serverConnection);
            this.connectRequestsCount++;

            if (this.AllowConnections && !token.IsCancellationRequested)
            {
                serverProjects = this.ReturnProjectInformation;
                return true;
            }
            else
            {
                serverProjects = null;
                return false;
            }
        }
        private void AssertExpectedProjectInformation(ProjectInformation projectInformation)
        {
            Assert.IsNotNull(projectInformation, "The API requires project information");

            if (this.ExpectedProjectKey != null)
            {
                Assert.AreEqual(this.ExpectedProjectKey, projectInformation.Key, "Unexpected project key");
            }
        }
        public void SectionController_ToggleShowAllProjectsCommand()
        {
            // Setup
            var testSubject = this.CreateTestSubject();
            var connInfo = new ConnectionInformation(new Uri("http://localhost"));
            var projectInfo = new ProjectInformation { Key = "p1", Name = "proj1" };
            var server = new ServerViewModel(connInfo);
            var project = new ProjectViewModel(server, projectInfo);
            server.Projects.Add(project);

            // Case 1: No bound projects
            project.IsBound = false;

            // Act + Verify CanExecute
            Assert.IsFalse(testSubject.ToggleShowAllProjectsCommand.CanExecute(server));

            // Case 2: Bound
            project.IsBound = true;

            // Act + Verify
            Assert.IsTrue(testSubject.ToggleShowAllProjectsCommand.CanExecute(server));

            // Verify execution
            bool original = server.ShowAllProjects;

            // Act
            testSubject.ToggleShowAllProjectsCommand.Execute(server);

            // Verify
            Assert.AreEqual(!original, server.ShowAllProjects);

            // Act
            testSubject.ToggleShowAllProjectsCommand.Execute(server);

            // Verify
            Assert.AreEqual(original, server.ShowAllProjects);
        }
示例#21
0
        internal /*for testing purposes*/ static async Task <QualityProfile> DownloadQualityProfile(HttpClient client, ProjectInformation project, Language language, CancellationToken token)
        {
            string apiUrl = CreateQualityProfileUrl(language, project);
            HttpResponseMessage response = await InvokeGetRequest(client, apiUrl, token, ensureSuccess : false);

            if (response.StatusCode == HttpStatusCode.NotFound)
            {
                // Special handling for the case when a project was not analyzed yet, in which case a 404 is returned
                // Request the profile without the project
                bool ensureSuccess = true;
                apiUrl   = CreateQualityProfileUrl(language);
                response = await InvokeGetRequest(client, apiUrl, token, ensureSuccess);
            }

            response.EnsureSuccessStatusCode(); // Bubble up the rest of the errors

            var profiles = await ProcessJsonResponse <QualityProfiles>(response, token);

            var serverLanguage            = GetServerLanguageKey(language);
            var profilesWithGivenLanguage = profiles.Profiles.Where(x => x.Language == serverLanguage).ToList();

            return(profilesWithGivenLanguage.Count > 1
                ? profilesWithGivenLanguage.Single(x => x.IsDefault)
                : profilesWithGivenLanguage.Single());
        }
        public void BindingController_BindCommand_Execution()
        {
            // Setup
            BindingController testSubject = this.PrepareCommandForExecution();

            // Act
            var projectToBind1 = new ProjectInformation { Key = "1" };
            ProjectViewModel projectVM1 = CreateProjectViewModel(projectToBind1);
            testSubject.BindCommand.Execute(projectVM1);

            // Verify
            this.workflow.AssertBoundProject(projectToBind1);

            // Act, bind a different project
            var projectToBind2 = new ProjectInformation { Key = "2" };
            ProjectViewModel projectVM2 = CreateProjectViewModel(projectToBind2);
            testSubject.BindCommand.Execute(projectVM2);

            // Verify
            this.workflow.AssertBoundProject(projectToBind2);
        }
 private static ProjectViewModel CreateProjectViewModel(ProjectInformation projectInfo = null)
 {
     return new ProjectViewModel(CreateServerViewModel(), projectInfo ?? new ProjectInformation());
 }
        internal /*for testing purposes*/ void SetBindingInProgress(IProgressEvents progressEvents, ProjectInformation projectInformation)
        {
            this.OnBindingStarted();

            ProgressNotificationListener progressListener = new ProgressNotificationListener(this.ServiceProvider, progressEvents);
            progressListener.MessageFormat = Strings.BindingSolutionPrefixMessageFormat;

            progressEvents.RunOnFinished(result =>
            {
                progressListener.Dispose();

                this.OnBindingFinished(projectInformation, result == ProgressControllerResult.Succeeded);
            });
        }
 public void AssertBoundProject(ProjectInformation expected)
 {
     Assert.AreSame(expected, this.BoundProject, "Unexpected project binding");
 }
        private void OnBind(ProjectInformation projectInformation)
        {
            Debug.Assert(this.OnBindStatus(projectInformation));

            TelemetryLoggerAccessor.GetLogger(this.host)?.ReportEvent(TelemetryEvent.BindCommandCommandCalled);

            this.workflow.BindProject(projectInformation);
        }
 private bool OnBindStatus(ProjectInformation projectInformation)
 {
     return projectInformation != null
         && this.host.VisualStateManager.IsConnected
         && !this.host.VisualStateManager.IsBusy
         && VsShellUtils.IsSolutionExistsAndFullyLoaded()
         && VsShellUtils.IsSolutionExistsAndNotBuildingAndNotDebugging()
         && (this.projectSystemHelper.GetSolutionProjects()?.Any() ?? false);
 }
示例#28
0
        public Uri CreateProjectDashboardUrl(ConnectionInformation connectionInformation, ProjectInformation project)
        {
            if (connectionInformation == null)
            {
                throw new ArgumentNullException(nameof(connectionInformation));
            }

            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }

            return(new Uri(connectionInformation.ServerUri, string.Format(ProjectDashboardRelativeUrl, project.Key)));
        }
        void IBindingWorkflowExecutor.BindProject(ProjectInformation projectInformation)
        {
            ConnectionInformation connection = this.host.VisualStateManager.GetConnectedServer(projectInformation);
            Debug.Assert(connection != null, "Could not find a connected server for project: " + projectInformation?.Key);

            BindingWorkflow workflowExecutor = new BindingWorkflow(this.host, connection, projectInformation);
            IProgressEvents progressEvents = workflowExecutor.Run();
            Debug.Assert(progressEvents != null, "BindingWorkflow.Run returned null");
            this.SetBindingInProgress(progressEvents, projectInformation);
        }
        public void SectionController_BrowseToProjectDashboardCommand()
        {
            // Setup
            var webBrowser = new ConfigurableWebBrowser();
            var testSubject = this.CreateTestSubject(webBrowser);
            var serverUrl = new Uri("http://my-sonar-server:5555");
            var connectionInfo = new ConnectionInformation(serverUrl);
            var projectInfo = new ProjectInformation { Key = "p1" };

            Uri expectedUrl = new Uri(serverUrl, string.Format(SonarQubeServiceWrapper.ProjectDashboardRelativeUrl, projectInfo.Key));
            this.sonarQubeService.RegisterProjectDashboardUrl(connectionInfo, projectInfo, expectedUrl);

            // Case 1: Null parameter
            // Act + Verify CanExecute
            Assert.IsFalse(testSubject.BrowseToProjectDashboardCommand.CanExecute(null));

            // Case 2: Project VM
            var serverViewModel = new ServerViewModel(connectionInfo);
            var projectViewModel = new ProjectViewModel(serverViewModel, projectInfo);

            // Act + Verify CanExecute
            Assert.IsTrue(testSubject.BrowseToProjectDashboardCommand.CanExecute(projectViewModel));

            // Act + Verify Execute
            testSubject.BrowseToProjectDashboardCommand.Execute(projectViewModel);
            webBrowser.AssertNavigateToCalls(1);
            webBrowser.AssertRequestToNavigateTo(expectedUrl.ToString());
        }
        private void OnBindingFinished(ProjectInformation projectInformation, bool isFinishedSuccessfully)
        {
            this.IsBindingInProgress = false;
            this.host.VisualStateManager.ClearBoundProject();

            if (isFinishedSuccessfully)
            {
                this.host.VisualStateManager.SetBoundProject(projectInformation);

                var conflictsController = this.host.GetService<IRuleSetConflictsController>();
                conflictsController.AssertLocalServiceIsNotNull();

                if (conflictsController.CheckForConflicts())
                {
                    // In some cases we will end up navigating to the solution explorer, this will make sure that
                    // we're back in team explorer to view the conflicts
                    this.ServiceProvider.GetMefService<ITeamExplorerController>()?.ShowSonarQubePage();
                }
                else
                {
                    VsShellUtils.ActivateSolutionExplorer(this.ServiceProvider);
                }
            }
            else
            {
                IUserNotification notifications = this.host.ActiveSection?.UserNotifications;
                if (notifications != null)
                {
                    // Create a command with a fixed argument with the help of ContextualCommandViewModel that creates proxy command for the contextual (fixed) instance and the passed in ICommand that expects it
                    ICommand rebindCommand = new ContextualCommandViewModel(projectInformation, new RelayCommand<ProjectInformation>(this.OnBind, this.OnBindStatus)).Command;
                    notifications.ShowNotificationError(Strings.FailedToToBindSolution, NotificationIds.FailedToBindId, rebindCommand);
                }
            }
        }
        public void SetBoundProject(ProjectInformation project)
        {
            this.ClearBindingErrorNotifications();
            ProjectViewModel projectViewModel = this.ManagedState.ConnectedServers.SelectMany(s => s.Projects).SingleOrDefault(p => p.ProjectInformation == project);
            Debug.Assert(projectViewModel != null, "Expecting a single project mapped to project information");
            this.ManagedState.SetBoundProject(projectViewModel);
            Debug.Assert(this.HasBoundProject, "Expected to have a bound project");

            this.OnBindingStateChanged();
        }
 private void OnProjectsChanged(ConnectionInformation connection, ProjectInformation[] projects)
 {
     this.host.VisualStateManager.SetProjects(connection, projects);
 }
 public ConnectionInformation GetConnectedServer(ProjectInformation project)
 {
     return this.ManagedState.ConnectedServers
         .SingleOrDefault(s => s.Projects.Any(p => p.ProjectInformation == project))?.ConnectionInformation;
 }