public void ProjectViewModel_AutomationName() { // Arrange var projectInfo = new SonarQubeProject("P1", "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; // Assert actualBound.Should().Be(expectedBound, "Unexpected bound SonarQube project description"); // Test case 2: not bound // Act testSubject.IsBound = false; var actualNotBound = testSubject.AutomationName; // Assert actualNotBound.Should().Be(expectedNotBound, "Unexpected unbound SonarQube project description"); }
private void OnBindingFinished(SonarQubeProject 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 <SonarQubeProject>(this.OnBind, this.OnBindStatus)).Command; notifications.ShowNotificationError(Strings.FailedToToBindSolution, NotificationIds.FailedToBindId, rebindCommand); } } }
public void ServerViewModel_SetProjects() { // Arrange var connInfo = new ConnectionInformation(new Uri("https://myawesomeserver:1234/")); var viewModel = new ServerViewModel(connInfo); IEnumerable <SonarQubeProject> projects = new[] { new SonarQubeProject("1", "Project3"), new SonarQubeProject("2", "Project2"), new SonarQubeProject("3", "project1"), }; string[] expectedOrderedProjectNames = projects.Select(p => p.Name).OrderBy(n => n, StringComparer.CurrentCulture).ToArray(); // Act viewModel.SetProjects(projects); // Assert string[] actualProjectNames = viewModel.Projects.Select(p => p.Project.Name).OrderBy(n => n, StringComparer.CurrentCulture).ToArray(); CollectionAssert.AreEqual( expectedOrderedProjectNames, actualProjectNames, message: $"VM projects [{string.Join(", ", actualProjectNames)}] do not match the expected projects [{string.Join(", ", expectedOrderedProjectNames)}]" ); // Act again var newProject = new SonarQubeProject("", ""); viewModel.SetProjects(new[] { newProject }); // Assert that the collection was replaced with the new one viewModel.Projects.SingleOrDefault()?.Project.Should().Be(newProject, "Expected a single project to be present"); }
public void VsSessionHost_ResetBinding_BoundSolutionWithNoActiveSectionScenario() { // Arrange var tracker = new ConfigurableActiveSolutionTracker(); var testSubject = this.CreateTestSubject(tracker); var boundProject = new SonarQubeProject("bla", ""); this.solutionBinding.CurrentBinding = new Persistence.BoundSonarQubeProject(new Uri("http://bound"), boundProject.Key); this.stateManager.SetBoundProject(boundProject); // Sanity this.stateManager.BoundProject.Should().Be(boundProject); this.stepRunner.AbortAllNumberOfCalls.Should().Be(0); // Act (simulate solution opened event) tracker.SimulateActiveSolutionChanged(); // Assert that nothing has changed (should defer all the work to when the section is connected) this.stepRunner.AbortAllNumberOfCalls.Should().Be(1); this.stateManager.BoundProject.Should().Be(boundProject); this.stateManager.BoundProjectKey.Should().BeNull("The key should only be set when there's active section to allow marking it once fetched all the projects"); // Act (set active section) var section = ConfigurableSectionController.CreateDefault(); bool refreshCalled = false; section.RefreshCommand = new RelayCommand(() => refreshCalled = true); testSubject.SetActiveSection(section); // Assert (section has refreshed, no further aborts were required) this.stepRunner.AbortAllNumberOfCalls.Should().Be(1); this.stateManager.BoundProjectKey.Should().Be(boundProject.Key, "Key was not set, will not be able to mark project as bound after refresh"); this.stateManager.BoundProject.Should().Be(boundProject); refreshCalled.Should().BeTrue("Expected the refresh command to be called"); }
public BindingWorkflow(IHost host, ConnectionInformation connectionInformation, SonarQubeProject 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 StateManager_BindCommand_DynamicText() { // Arrange var section = ConfigurableSectionController.CreateDefault(); ConfigurableHost host = new ConfigurableHost(); StateManager testSubject = this.CreateTestSubject(host, section); var connection1 = new ConnectionInformation(new Uri("http://127.0.0.1")); var projects = new SonarQubeProject[] { new SonarQubeProject("", "") }; testSubject.SetProjects(connection1, projects); ProjectViewModel projectVM = testSubject.ManagedState.ConnectedServers.Single().Projects.Single(); host.SetActiveSection(section); testSubject.SyncCommandFromActiveSection(); ContextualCommandViewModel bindCmd = projectVM.Commands.First(x => x.InternalRealCommand.Equals(section.BindCommand)); // Case 1: Bound projectVM.IsBound = true; // Act + Assert bindCmd.DisplayText.Should().Be(Strings.SyncButtonText, "Unexpected disabled context command text"); // Case 2: Not bound projectVM.IsBound = false; // Act + Assert bindCmd.DisplayText.Should().Be(Strings.BindButtonText, "Unexpected context command text"); }
/// <summary> /// Handler which associates source code of Sonar project to a local directory /// </summary> /// <param name="project">SonarQube project to associate</param> /// <returns>Awaitable task which associates a local path and enumerates associated errors</returns> private Task OnFolderSelectAsync(SonarQubeProject project) { string path = null; using (var folderSelectDialog = new FolderSelectDialog()) { if (folderSelectDialog.ShowDialog()) { path = folderSelectDialog.SelectedPath; } } if (!string.IsNullOrEmpty(path)) { _projectPathsManager.Add(project.Key, path); // 'Set Local Path' implies 'View Issues' if the // project has already had its issues loaded if (project.Key == _projectIssuesInView) { return(OnItemSelectAsync(project)); } } return(Task.CompletedTask); }
public void StateManager_SyncCommandFromActiveSection() { // Arrange var section = ConfigurableSectionController.CreateDefault(); ConfigurableHost host = new ConfigurableHost(); StateManager testSubject = this.CreateTestSubject(host, section); var connection1 = new ConnectionInformation(new Uri("http://127.0.0.1")); var projects = new SonarQubeProject[] { new SonarQubeProject("", ""), new SonarQubeProject("", "") }; testSubject.SetProjects(connection1, projects); ServerViewModel serverVM = testSubject.ManagedState.ConnectedServers.Single(); // Case 1: has active section host.SetActiveSection(section); // Act testSubject.SyncCommandFromActiveSection(); VerifySectionCommands(section, serverVM); // Case 2: has no active section host.ClearActiveSection(); // Act testSubject.SyncCommandFromActiveSection(); VerifyNoCommands(serverVM); // Case 3: re-active host.SetActiveSection(section); // Act testSubject.SyncCommandFromActiveSection(); VerifySectionCommands(section, serverVM); }
public void VsSessionHost_ResetBinding_BoundSolutionWithActiveSectionScenario() { // Arrange var tracker = new ConfigurableActiveSolutionTracker(); var testSubject = this.CreateTestSubject(tracker); var boundProject = new SonarQubeProject("bla", ""); this.stateManager.SetBoundProject(boundProject); this.solutionBinding.CurrentBinding = new Persistence.BoundSonarQubeProject(new Uri("http://bound"), boundProject.Key); var section = ConfigurableSectionController.CreateDefault(); bool refreshCalled = false; section.RefreshCommand = new RelayCommand(() => refreshCalled = true); testSubject.SetActiveSection(section); // Sanity this.stateManager.BoundProject.Should().Be(boundProject); this.stepRunner.AbortAllNumberOfCalls.Should().Be(0); // Act (simulate solution opened event) tracker.SimulateActiveSolutionChanged(); // Assert this.stepRunner.AbortAllNumberOfCalls.Should().Be(1); this.stateManager.BoundProjectKey.Should().Be(boundProject.Key, "Key was not set, will not be able to mark project as bound after refresh"); this.stateManager.BoundProject.Should().Be(boundProject); refreshCalled.Should().BeTrue("Expected the refresh command to be called"); }
public void Convert_ValidProjecModel_ReturnsBindingArgs() { // Arrange var expectedUri = new Uri("http://localhost:9000"); var expectedPassword = new SecureString(); expectedPassword.AppendChar('x'); var serverViewModel = new ServerViewModel(new ConnectionInformation(expectedUri, "user1", expectedPassword)); var project = new SonarQubeProject("key1", "name1"); var projectViewModel = new ProjectViewModel(serverViewModel, project); var converter = new ProjectViewModelToBindingArgsConverter(); // Act var convertedObj = converter.Convert(projectViewModel, null, null, null); convertedObj.Should().NotBeNull(); convertedObj.Should().BeOfType <BindCommandArgs>(); var bindCommandArgs = (BindCommandArgs)convertedObj; bindCommandArgs.ProjectKey.Should().Be("key1"); bindCommandArgs.ProjectName.Should().Be("name1"); bindCommandArgs.Connection.Should().NotBeNull(); bindCommandArgs.Connection.ServerUri.Should().BeSameAs(expectedUri); bindCommandArgs.Connection.UserName.Should().Be("user1"); bindCommandArgs.Connection.Password.Length.Should().Be(1); }
public void VsSessionHost_ResetBinding_ErrorInReadingSolutionBinding() { // Arrange var tracker = new ConfigurableActiveSolutionTracker(); var testSubject = this.CreateTestSubject(tracker); var boundProject = new SonarQubeProject("bla", ""); this.stateManager.SetBoundProject(boundProject); this.solutionBinding.CurrentBinding = new BoundSonarQubeProject(new Uri("http://bound"), boundProject.Key); var section = ConfigurableSectionController.CreateDefault(); testSubject.SetActiveSection(section); // Sanity this.stateManager.BoundProject.Should().Be(boundProject); this.stepRunner.AbortAllNumberOfCalls.Should().Be(0); // Introduce an error this.solutionBinding.ReadSolutionBindingAction = () => { throw new Exception("boom"); }; // Act (i.e. simulate loading a different solution) using (new AssertIgnoreScope()) // Ignore exception assert { tracker.SimulateActiveSolutionChanged(); } // Assert this.stateManager.BoundProject.Should().BeNull(); }
private void OnBind(SonarQubeProject projectInformation) { Debug.Assert(this.OnBindStatus(projectInformation)); TelemetryLoggerAccessor.GetLogger(this.host)?.ReportEvent(TelemetryEvent.BindCommandCommandCalled); this.workflow.BindProject(projectInformation); }
public ConnectionInformation GetConnectedServer(SonarQubeProject project) { ConnectionInformation conn; var isFound = this.ProjectServerMap.TryGetValue(project, out conn); isFound.Should().BeTrue("Test setup: project-server mapping is not available for the specified project"); return(conn); }
private BindingWorkflow CreateTestSubject(SonarQubeProject projectInfo = null) { ConnectionInformation connected = new ConnectionInformation(new Uri("http://connected")); this.host.SonarQubeService = this.sonarQubeServiceMock.Object; var useProjectInfo = projectInfo ?? new SonarQubeProject("key", ""); return(new BindingWorkflow(this.host, connected, useProjectInfo)); }
private bool OnBindStatus(SonarQubeProject projectInformation) { return(projectInformation != null && this.host.VisualStateManager.IsConnected && !this.host.VisualStateManager.IsBusy && VsShellUtils.IsSolutionExistsAndFullyLoaded() && VsShellUtils.IsSolutionExistsAndNotBuildingAndNotDebugging() && (this.projectSystemHelper.GetSolutionProjects()?.Any() ?? false)); }
public void SetBoundProject(SonarQubeProject project) { project.Should().NotBeNull(); this.VerifyActiveSection(); this.BoundProject = project; this.BindingStateChanged?.Invoke(this, EventArgs.Empty); }
public void BindingWorkflow_ArgChecks() { var validConnection = new ConnectionInformation(new Uri("http://server")); var validProjectInfo = new SonarQubeProject("", ""); 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(SonarQubeProject project) { this.ClearBindingErrorNotifications(); ProjectViewModel projectViewModel = this.ManagedState.ConnectedServers.SelectMany(s => s.Projects).SingleOrDefault(p => p.Project == 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(); }
void IBindingWorkflowExecutor.BindProject(SonarQubeProject 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 ProjectViewModel(ServerViewModel owner, SonarQubeProject projectInformation) { if (owner == null) { throw new ArgumentNullException(nameof(owner)); } if (projectInformation == null) { throw new ArgumentNullException(nameof(projectInformation)); } this.Owner = owner; this.Project = projectInformation; }
public void ProjectViewModel_Ctor() { // Arrange var projectInfo = new SonarQubeProject("P1", "Project1"); var serverVM = CreateServerViewModel(); // Act var viewModel = new ProjectViewModel(serverVM, projectInfo); // Assert viewModel.IsBound.Should().BeFalse(); viewModel.Key.Should().Be(projectInfo.Key); viewModel.ProjectName.Should().Be(projectInfo.Name); viewModel.Project.Should().Be(projectInfo); viewModel.Owner.Should().Be(serverVM); }
public async Task BindingWorkflow_DownloadQualityProfile_WithNoActiveRules_Fails() { // Arrange const string QualityProfileName = "SQQualityProfileName"; const string ProjectName = "SQProjectName"; var projectInfo = new SonarQubeProject("key", ProjectName); BindingWorkflow testSubject = this.CreateTestSubject(projectInfo); ConfigurableProgressController controller = new ConfigurableProgressController(); var notifications = new ConfigurableProgressStepExecutionEvents(); RuleSet ruleSet = TestRuleSetHelper.CreateTestRuleSetWithRuleIds(new[] { "Key1", "Key2" }); foreach (var rule in ruleSet.Rules) { rule.Action = RuleAction.None; } var expectedRuleSet = new RuleSet(ruleSet) { NonLocalizedDisplayName = string.Format(Strings.SonarQubeRuleSetNameFormat, ProjectName, QualityProfileName), NonLocalizedDescription = "\r\nhttp://connected/profiles/show?key=" }; var nugetPackages = new[] { new PackageName("myPackageId", new SemanticVersion("1.0.0")) }; var additionalFiles = new[] { new AdditionalFileResponse { FileName = "abc.xml", Content = new byte[] { 1, 2, 3 } } }; RoslynExportProfileResponse export = RoslynExportProfileHelper.CreateExport(ruleSet, nugetPackages, additionalFiles); var language = Language.VBNET; SonarQubeQualityProfile profile = this.ConfigureProfileExport(export, language, QualityProfileName); // Act await testSubject.DownloadQualityProfileAsync(controller, notifications, new[] { language }, CancellationToken.None); // Assert testSubject.Rulesets.Should().NotContainKey(Language.VBNET, "Not expecting any rules for this language"); testSubject.Rulesets.Should().NotContainKey(language, "Not expecting any rules"); controller.NumberOfAbortRequests.Should().Be(1); notifications.AssertProgressMessages(Strings.DownloadingQualityProfileProgressMessage); this.outputWindowPane.AssertOutputStrings(1); var expectedOutput = string.Format(Strings.SubTextPaddingFormat, string.Format(Strings.NoSonarAnalyzerActiveRulesForQualityProfile, QualityProfileName, language.Name)); this.outputWindowPane.AssertOutputStrings(expectedOutput); }
public async Task BindingWorkflow_DownloadQualityProfile_Success() { // Arrange const string QualityProfileName = "SQQualityProfileName"; const string ProjectName = "SQProjectName"; var projectInfo = new SonarQubeProject("key", ProjectName); BindingWorkflow testSubject = this.CreateTestSubject(projectInfo); ConfigurableProgressController controller = new ConfigurableProgressController(); var notifications = new ConfigurableProgressStepExecutionEvents(); RuleSet ruleSet = TestRuleSetHelper.CreateTestRuleSetWithRuleIds(new[] { "Key1", "Key2" }); var expectedRuleSet = new RuleSet(ruleSet) { NonLocalizedDisplayName = string.Format(Strings.SonarQubeRuleSetNameFormat, ProjectName, QualityProfileName), NonLocalizedDescription = "\r\nhttp://connected/profiles/show?key=" }; var nugetPackages = new[] { new PackageName("myPackageId", new SemanticVersion("1.0.0")) }; var additionalFiles = new[] { new AdditionalFileResponse { FileName = "abc.xml", Content = new byte[] { 1, 2, 3 } } }; RoslynExportProfileResponse export = RoslynExportProfileHelper.CreateExport(ruleSet, nugetPackages, additionalFiles); var language = Language.VBNET; SonarQubeQualityProfile profile = this.ConfigureProfileExport(export, language, QualityProfileName); // Act await testSubject.DownloadQualityProfileAsync(controller, notifications, new[] { language }, CancellationToken.None); // Assert RuleSetAssert.AreEqual(expectedRuleSet, testSubject.Rulesets[language], "Unexpected rule set"); testSubject.QualityProfiles[language].Should().Be(profile); VerifyNuGetPackgesDownloaded(nugetPackages, testSubject, language); controller.NumberOfAbortRequests.Should().Be(0); 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 ProjectViewModel_ToolTipProjectName_RespectsIsBound() { // Arrange var projectInfo = new SonarQubeProject("P1", "Project1"); var viewModel = new ProjectViewModel(CreateServerViewModel(), projectInfo); // Test Case 1: When project is bound, should show message with 'bound' marker // Act viewModel.IsBound = true; // Assert StringAssert.Contains(viewModel.ToolTipProjectName, viewModel.ProjectName, "ToolTip message should include the project name"); viewModel.ToolTipProjectName.Should().NotBe(viewModel.ProjectName, "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; // Assert viewModel.ToolTipProjectName.Should().Be(viewModel.ProjectName, "ToolTip message should be exactly the same as the project name"); }
/// <summary> /// Handler which enumerates issues for a Sonar project /// </summary> /// <param name="project">SonarQube project to query</param> /// <returns>Awaitable task which enumerates associated errors</returns> private async Task OnItemSelectAsync(SonarQubeProject project) { _projectPathsManager.TryGetValue(project.Key, out string projectLocalPath); IEnumerable <ErrorListItem> errors; try { errors = await _errorListProvider.GetErrorsAsync(project.Key, projectLocalPath); } catch { TeamExplorer.ShowNotification($"Failed to download issues for \"{project.Name}\".", NotificationType.Error, NotificationFlags.None, null, SonarErrorsNotificationId); return; } TeamExplorer.HideNotification(SonarErrorsNotificationId); if (errors.Any()) { if (!Path.IsPathRooted(errors.First().FileName)) { TeamExplorer.ShowNotification("Unable to resolve local file path for issues. Make sure project local path is correctly configured.", NotificationType.Warning, NotificationFlags.None, null, FilePathResolutionNotificationId); } else { TeamExplorer.HideNotification(FilePathResolutionNotificationId); } } ErrorTable.CleanAllErrors(); ErrorTable.AddErrors(project.Name, errors); _projectIssuesInView = project.Key; }
public void SectionController_ToggleShowAllProjectsCommand() { // Arrange var testSubject = this.CreateTestSubject(); var connInfo = new ConnectionInformation(new Uri("http://localhost")); var projectInfo = new SonarQubeProject("p1", "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 + Assert CanExecute testSubject.ToggleShowAllProjectsCommand.CanExecute(server).Should().BeFalse(); // Case 2: Bound project.IsBound = true; // Act + Assert testSubject.ToggleShowAllProjectsCommand.CanExecute(server).Should().BeTrue(); // Assert execution bool original = server.ShowAllProjects; // Act testSubject.ToggleShowAllProjectsCommand.Execute(server); // Assert server.ShowAllProjects.Should().Be(!original); // Act testSubject.ToggleShowAllProjectsCommand.Execute(server); // Assert server.ShowAllProjects.Should().Be(original); }
public void StateManager_GetConnectedServer() { // Arrange const string SharedKey = "Key"; // The key is the same for all projects on purpose ConfigurableHost host = new ConfigurableHost(); StateManager testSubject = this.CreateTestSubject(host); var connection1 = new ConnectionInformation(new Uri("http://conn1")); var project1 = new SonarQubeProject(SharedKey, ""); var connection2 = new ConnectionInformation(new Uri("http://conn2")); var project2 = new SonarQubeProject(SharedKey, ""); testSubject.SetProjects(connection1, new SonarQubeProject[] { project1 }); testSubject.SetProjects(connection2, new SonarQubeProject[] { project2 }); // Case 1: Exists // Act+Verify testSubject.GetConnectedServer(project1).Should().Be(connection1); testSubject.GetConnectedServer(project2).Should().Be(connection2); // Case 2: Doesn't exist // Act+Verify testSubject.GetConnectedServer(new SonarQubeProject(SharedKey, "")).Should().BeNull(); }
public void BindingController_BindCommand_Execution() { // Arrange BindingController testSubject = this.PrepareCommandForExecution(); // Act var projectToBind1 = new SonarQubeProject("1", ""); ProjectViewModel projectVM1 = CreateProjectViewModel(projectToBind1); testSubject.BindCommand.Execute(projectVM1); // Assert this.workflow.BoundProject.Should().Be(projectToBind1); // Act, bind a different project var projectToBind2 = new SonarQubeProject("2", ""); ProjectViewModel projectVM2 = CreateProjectViewModel(projectToBind2); testSubject.BindCommand.Execute(projectVM2); // Assert this.workflow.BoundProject.Should().Be(projectToBind2); }
public void SectionController_BrowseToProjectDashboardCommand() { // Arrange 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 SonarQubeProject("p1", ""); var expectedUrl = new Uri(serverUrl, "/foobar"); this.sonarQubeServiceMock.Setup(x => x.GetProjectDashboardUrl("p1")) .Returns(expectedUrl); // Case 1: Null parameter // Act + Assert CanExecute testSubject.BrowseToProjectDashboardCommand.CanExecute(null).Should().BeFalse(); // Case 2: Project VM is set but SQ server is not connected var serverViewModel = new ServerViewModel(connectionInfo); var projectViewModel = new ProjectViewModel(serverViewModel, projectInfo); this.sonarQubeServiceMock.Setup(x => x.IsConnected).Returns(false); // Act + Assert CanExecute testSubject.BrowseToProjectDashboardCommand.CanExecute(projectViewModel).Should().BeFalse(); // Case 3: Project VM is set and SQ server is connected this.sonarQubeServiceMock.Setup(x => x.IsConnected).Returns(true); // Act + Assert CanExecute testSubject.BrowseToProjectDashboardCommand.CanExecute(projectViewModel).Should().BeTrue(); // Act + Assert Execute testSubject.BrowseToProjectDashboardCommand.Execute(projectViewModel); webBrowser.NavigatedUrls.Should().HaveCount(1); webBrowser.NavigatedUrls.Should().Contain(expectedUrl.ToString()); }
public void VsSessionHost_ResetBinding_NoOpenSolutionScenario() { // Arrange var tracker = new ConfigurableActiveSolutionTracker(); this.CreateTestSubject(tracker); // Previous binding information that should be cleared once there's no solution var boundProject = new SonarQubeProject("bla", ""); this.stateManager.BoundProjectKey = boundProject.Key; this.stateManager.SetBoundProject(boundProject); // Sanity this.stateManager.BoundProject.Should().Be(boundProject); this.stepRunner.AbortAllNumberOfCalls.Should().Be(0); // Act tracker.SimulateActiveSolutionChanged(); // Assert this.stepRunner.AbortAllNumberOfCalls.Should().Be(1); this.stateManager.BoundProject.Should().BeNull(); this.stateManager.BoundProjectKey.Should().BeNull("Expecting the key to be reset to null"); }