From 6c083cc512c21478c5dced128bd04b6c80b2e394 Mon Sep 17 00:00:00 2001 From: Gabriela Trutan Date: Wed, 18 Dec 2024 11:15:27 +0100 Subject: [PATCH] SLVS-1718 CaYC: refactor, reformat and cleanup code in touched classes --- .../ManageBindingViewModelTests.cs | 116 +++++++++--------- .../ManageBinding/ManageBindingViewModel.cs | 54 ++++---- 2 files changed, 85 insertions(+), 85 deletions(-) diff --git a/src/ConnectedMode.UnitTests/UI/ManageBinding/ManageBindingViewModelTests.cs b/src/ConnectedMode.UnitTests/UI/ManageBinding/ManageBindingViewModelTests.cs index 0466bb8b6..65c42e376 100644 --- a/src/ConnectedMode.UnitTests/UI/ManageBinding/ManageBindingViewModelTests.cs +++ b/src/ConnectedMode.UnitTests/UI/ManageBinding/ManageBindingViewModelTests.cs @@ -40,11 +40,11 @@ namespace SonarLint.VisualStudio.ConnectedMode.UnitTests.UI.ManageBinding; public class ManageBindingViewModelTests { private const string ALocalProjectKey = "local-project-key"; - - private readonly ServerProject serverProject = new ("a-project", "A Project"); - private readonly ConnectionInfo sonarQubeConnectionInfo = new ("http://localhost:9000", ConnectionServerType.SonarQube); - private readonly ConnectionInfo sonarCloudConnectionInfo = new ("organization", ConnectionServerType.SonarCloud); - private readonly BasicAuthCredentials validCredentials = new ("TOKEN", new SecureString()); + + private readonly ServerProject serverProject = new("a-project", "A Project"); + private readonly ConnectionInfo sonarQubeConnectionInfo = new("http://localhost:9000", ConnectionServerType.SonarQube); + private readonly ConnectionInfo sonarCloudConnectionInfo = new("organization", ConnectionServerType.SonarCloud); + private readonly BasicAuthCredentials validCredentials = new("TOKEN", new SecureString()); private readonly SharedBindingConfigModel sonarQubeSharedBindingConfigModel = new() { Uri = new Uri("http://localhost:9000"), ProjectKey = "myProj" }; private readonly SharedBindingConfigModel sonarCloudSharedBindingConfigModel = new() { Organization = "myOrg", ProjectKey = "myProj" }; @@ -552,7 +552,7 @@ await progressReporterViewModel.Received(1) x.WarningText == UiResources.LoadingConnectionsFailedText && x.AfterProgressUpdated == testSubject.OnProgressUpdated)); } - + [TestMethod] public async Task InitializeDataAsync_DisplaysBindStatusAndReportsProgress() { @@ -566,12 +566,12 @@ await progressReporterViewModel.Received(1) x.WarningText == UiResources.FetchingBindingStatusFailedText && x.AfterProgressUpdated == testSubject.OnProgressUpdated)); } - + [TestMethod] public async Task InitializeDataAsync_WhenStandalone_ChecksForSharedBindingAndReportsProgress() { SetupUnboundProject(); - + await testSubject.InitializeDataAsync(); await progressReporterViewModel.Received(1) @@ -582,12 +582,12 @@ await progressReporterViewModel.Received(1) x.WarningText == UiResources.CheckingForSharedBindingFailedText && x.AfterProgressUpdated == testSubject.OnProgressUpdated)); } - + [TestMethod] public async Task InitializeDataAsync_WhenBound_DoesNotChecksForSharedBindingAndReportsProgress() { testSubject.BoundProject = serverProject; - + await testSubject.InitializeDataAsync(); await progressReporterViewModel.DidNotReceive() @@ -603,20 +603,20 @@ await progressReporterViewModel.DidNotReceive() public async Task DisplayBindStatusAsync_WhenProjectIsNotBound_Succeeds() { SetupUnboundProject(); - + var response = await testSubject.DisplayBindStatusAsync(); - + response.Should().BeEquivalentTo(new AdapterResponse(true)); } - + [TestMethod] public async Task DisplayBindStatusAsync_WhenProjectIsBoundAndBindingStatusIsFetched_Succeeds() { var sonarCloudConnection = new ServerConnection.SonarCloud("organization", credentials: validCredentials); SetupBoundProject(sonarCloudConnection, serverProject); - + var response = await testSubject.DisplayBindStatusAsync(); - + testSubject.BoundProject.Should().NotBeNull(); response.Should().BeEquivalentTo(new AdapterResponse(true)); } @@ -626,9 +626,9 @@ public async Task DisplayBindStatusAsync_WhenProjectIsBoundButBindingStatusIsNot { var sonarCloudConnection = new ServerConnection.SonarCloud("organization", credentials: validCredentials); SetupBoundProjectThatDoesNotExistOnServer(sonarCloudConnection); - + var response = await testSubject.DisplayBindStatusAsync(); - + testSubject.BoundProject.Should().BeNull(); response.Should().BeEquivalentTo(new AdapterResponse(false)); } @@ -638,23 +638,23 @@ public async Task DisplayBindStatusAsync_WhenSolutionIsOpen_FetchesSolutionInfo( { solutionInfoProvider.GetSolutionNameAsync().Returns("Local solution name"); solutionInfoProvider.IsFolderWorkspaceAsync().Returns(false); - + await testSubject.DisplayBindStatusAsync(); - + testSubject.SolutionInfo.Should().BeEquivalentTo(new SolutionInfoModel("Local solution name", SolutionType.Solution)); } - + [TestMethod] public async Task DisplayBindStatusAsync_WhenFolderIsOpen_FetchesSolutionInfo() { solutionInfoProvider.GetSolutionNameAsync().Returns("Local folder name"); solutionInfoProvider.IsFolderWorkspaceAsync().Returns(true); - + await testSubject.DisplayBindStatusAsync(); - + testSubject.SolutionInfo.Should().BeEquivalentTo(new SolutionInfoModel("Local folder name", SolutionType.Folder)); } - + [TestMethod] public async Task DisplayBindStatusAsync_WhenProjectIsBoundToSonarCloud_SelectsBoundSonarCloudConnection() { @@ -662,7 +662,7 @@ public async Task DisplayBindStatusAsync_WhenProjectIsBoundToSonarCloud_SelectsB SetupBoundProject(sonarCloudConnection); await testSubject.DisplayBindStatusAsync(); - + testSubject.SelectedConnectionInfo.Should().BeEquivalentTo(new ConnectionInfo("organization", ConnectionServerType.SonarCloud)); } @@ -671,17 +671,17 @@ public async Task DisplayBindStatusAsync_WhenProjectIsBoundToSonarQube_SelectsBo { var sonarQubeConnection = new ServerConnection.SonarQube(new Uri("http://localhost:9000/"), credentials: validCredentials); SetupBoundProject(sonarQubeConnection); - + await testSubject.DisplayBindStatusAsync(); - + testSubject.SelectedConnectionInfo.Should().BeEquivalentTo(new ConnectionInfo("http://localhost:9000/", ConnectionServerType.SonarQube)); } - + [TestMethod] public async Task DisplayBindStatusAsync_WhenProjectIsNotBound_SelectedConnectionShouldBeEmpty() { SetupUnboundProject(); - + await testSubject.DisplayBindStatusAsync(); testSubject.SelectedConnectionInfo.Should().BeNull(); @@ -693,9 +693,9 @@ public async Task DisplayBindStatusAsync_WhenProjectIsBound_SelectsServerProject var expectedServerProject = new ServerProject("server-project-key", "server-project-name"); var sonarCloudConnection = new ServerConnection.SonarCloud("organization", credentials: validCredentials); SetupBoundProject(sonarCloudConnection, expectedServerProject); - + await testSubject.DisplayBindStatusAsync(); - + testSubject.SelectedProject.Should().BeEquivalentTo(expectedServerProject); testSubject.BoundProject.Should().BeEquivalentTo(testSubject.SelectedProject); } @@ -705,9 +705,9 @@ public async Task DisplayBindStatusAsync_WhenProjectIsBoundButProjectNotFoundOnS { var sonarCloudConnection = new ServerConnection.SonarCloud("organization", credentials: validCredentials); SetupBoundProjectThatDoesNotExistOnServer(sonarCloudConnection); - + await testSubject.DisplayBindStatusAsync(); - + testSubject.SelectedProject.Should().BeNull(); testSubject.BoundProject.Should().BeNull(); } @@ -787,21 +787,21 @@ public async Task BindAsync_WhenConnectionNotFound_Fails() callInfo[1] = null; return false; }); - + var response = await testSubject.BindAsync(); - + response.Success.Should().BeFalse(); } - + [TestMethod] public async Task BindAsync_WhenBindingFailsUnexpectedly_FailsAndLogs() { var sonarCloudConnection = new ServerConnection.SonarCloud("organization", credentials: validCredentials); SetupConnectionAndProjectToBind(sonarCloudConnection, serverProject); bindingController.BindAsync(Arg.Any(), Arg.Any()).ThrowsAsync(new Exception("Failed unexpectedly")); - + var response = await testSubject.BindAsync(); - + response.Success.Should().BeFalse(); logger.Received(1).WriteLine(Resources.Binding_Fails, "Failed unexpectedly"); } @@ -813,7 +813,7 @@ public async Task BindAsync_WhenBindingCompletesSuccessfully_Succeeds() SetupConnectionAndProjectToBind(sonarCloudConnection, serverProject); var response = await testSubject.BindAsync(); - + response.Success.Should().BeTrue(); } @@ -822,9 +822,9 @@ public async Task BindAsync_WhenBindingCompletesSuccessfully_SetsBoundProjectToS { var sonarCloudConnection = new ServerConnection.SonarCloud("organization", credentials: validCredentials); SetupConnectionAndProjectToBind(sonarCloudConnection, serverProject); - + await testSubject.BindAsync(); - + testSubject.BoundProject.Should().BeEquivalentTo(serverProject); } @@ -839,7 +839,7 @@ public async Task CheckForSharedBindingAsync_WhenSharedBindingExists_SetsSharedB sharedBindingConfigProvider.Received(1).GetSharedBinding(); testSubject.SharedBindingConfigModel.Should().Be(sharedBindingModel); } - + [TestMethod] public async Task CheckForSharedBindingAsync_WhenSharedBindingDoesNotExist_SetsNullSharedBindingConfigModel() { @@ -879,7 +879,7 @@ public async Task UseSharedBindingAsync_SharedBindingForSonarQubeConnection_Bind response.Success.Should().BeTrue(); await bindingController.Received(1) .BindAsync(Arg.Is(proj => - proj.ServerProjectKey == testSubject.SharedBindingConfigModel.ProjectKey), Arg.Any()); + proj.ServerProjectKey == testSubject.SharedBindingConfigModel.ProjectKey), Arg.Any()); } [TestMethod] @@ -918,7 +918,7 @@ public async Task UseSharedBindingAsync_SharedBindingForExistingSonarCloudConnec { testSubject.SelectedProject = serverProject; // this is to make sure the SelectedProject is ignored and the shared config is used instead testSubject.SharedBindingConfigModel = sonarCloudSharedBindingConfigModel; - var expectedServerConnection = new ServerConnection.SonarCloud(testSubject.SharedBindingConfigModel.Organization); + var expectedServerConnection = new ServerConnection.SonarCloud(testSubject.SharedBindingConfigModel.Organization); SetupBoundProject(expectedServerConnection); var response = await testSubject.UseSharedBindingAsync(); @@ -938,7 +938,8 @@ public async Task UseSharedBindingAsync_SharedBindingForNonExistingSonarQubeConn var response = await testSubject.UseSharedBindingAsync(); response.Success.Should().BeFalse(); - messageBox.Received(1).Show(UiResources.NotFoundConnectionForSharedBindingMessageBoxText, UiResources.NotFoundConnectionForSharedBindingMessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Warning); + messageBox.Received(1).Show(UiResources.NotFoundConnectionForSharedBindingMessageBoxText, UiResources.NotFoundConnectionForSharedBindingMessageBoxCaption, MessageBoxButton.OK, + MessageBoxImage.Warning); logger.WriteLine(Resources.UseSharedBinding_ConnectionNotFound, testSubject.SharedBindingConfigModel.Uri); await bindingController.DidNotReceive() .BindAsync(Arg.Is(proj => @@ -955,7 +956,8 @@ public async Task UseSharedBindingAsync_SharedBindingForNonExistingSonarCloudCon response.Success.Should().BeFalse(); logger.WriteLine(Resources.UseSharedBinding_ConnectionNotFound, testSubject.SharedBindingConfigModel.Organization); - messageBox.Received(1).Show(UiResources.NotFoundConnectionForSharedBindingMessageBoxText, UiResources.NotFoundConnectionForSharedBindingMessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Warning); + messageBox.Received(1).Show(UiResources.NotFoundConnectionForSharedBindingMessageBoxText, UiResources.NotFoundConnectionForSharedBindingMessageBoxCaption, MessageBoxButton.OK, + MessageBoxImage.Warning); await bindingController.DidNotReceive() .BindAsync(Arg.Is(proj => proj.ServerProjectKey == testSubject.SharedBindingConfigModel.ProjectKey), Arg.Any()); @@ -973,13 +975,13 @@ public async Task UseSharedBindingAsync_SharedBindingSonarCloudConnectionWithMis response.Success.Should().BeFalse(); logger.WriteLine(Resources.UseSharedBinding_CredentiasNotFound, testSubject.SharedBindingConfigModel.Organization); - messageBox.Received(1).Show(UiResources.NotFoundCredentialsForSharedBindingMessageBoxText, UiResources.NotFoundCredentialsForSharedBindingMessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Warning); + messageBox.Received(1).Show(UiResources.NotFoundCredentialsForSharedBindingMessageBoxText, UiResources.NotFoundCredentialsForSharedBindingMessageBoxCaption, MessageBoxButton.OK, + MessageBoxImage.Warning); await bindingController.DidNotReceive() .BindAsync(Arg.Is(proj => proj.ServerProjectKey == testSubject.SharedBindingConfigModel.ProjectKey), Arg.Any()); } - [TestMethod] public async Task UseSharedBindingAsync_SharedBindingSonarQubeConnectionWithMissingCredentials_ReturnsFalseAndLogsAndInformsUser() { @@ -992,7 +994,8 @@ public async Task UseSharedBindingAsync_SharedBindingSonarQubeConnectionWithMiss response.Success.Should().BeFalse(); logger.WriteLine(Resources.UseSharedBinding_CredentiasNotFound, testSubject.SharedBindingConfigModel.Uri); - messageBox.Received(1).Show(UiResources.NotFoundCredentialsForSharedBindingMessageBoxText, UiResources.NotFoundCredentialsForSharedBindingMessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Warning); + messageBox.Received(1).Show(UiResources.NotFoundCredentialsForSharedBindingMessageBoxText, UiResources.NotFoundCredentialsForSharedBindingMessageBoxCaption, MessageBoxButton.OK, + MessageBoxImage.Warning); await bindingController.DidNotReceive() .BindAsync(Arg.Is(proj => proj.ServerProjectKey == testSubject.SharedBindingConfigModel.ProjectKey), Arg.Any()); @@ -1012,7 +1015,6 @@ public async Task UseSharedBindingAsync_BindingFails_ReturnsFalse() response.Success.Should().BeFalse(); } - private void MockServices() { serverConnectionsRepositoryAdapter = Substitute.For(); @@ -1043,18 +1045,18 @@ private void MockTryGetAllConnectionsInfo(List connectionInfos) return true; }); } - + private void SetupConnectionAndProjectToBind(ServerConnection selectedServerConnection, ServerProject selectedServerProject) { SetupBoundProject(selectedServerConnection, selectedServerProject); testSubject.SelectedConnectionInfo = sonarCloudConnectionInfo; testSubject.SelectedProject = selectedServerProject; } - + private void SetupBoundProject(ServerConnection serverConnection, ServerProject expectedServerProject = null) { expectedServerProject ??= serverProject; - + serverConnection.Credentials = validCredentials; var boundServerProject = new BoundServerProject(ALocalProjectKey, expectedServerProject.Key, serverConnection); var configurationProvider = Substitute.For(); @@ -1062,7 +1064,7 @@ private void SetupBoundProject(ServerConnection serverConnection, ServerProject connectedModeServices.ConfigurationProvider.Returns(configurationProvider); MockTryGetServerConnection(serverConnection); solutionInfoProvider.GetSolutionNameAsync().Returns(ALocalProjectKey); - + MockGetServerProjectByKey(true, expectedServerProject); } @@ -1080,24 +1082,24 @@ private void SetupUnboundProject() var configurationProvider = Substitute.For(); configurationProvider.GetConfiguration().Returns(new BindingConfiguration(null, SonarLintMode.Standalone, null)); connectedModeServices.ConfigurationProvider.Returns(configurationProvider); - + MockGetServerProjectByKey(false, null); } - + private void SetupBoundProjectThatDoesNotExistOnServer(ServerConnection serverConnection) { var boundServerProject = new BoundServerProject(ALocalProjectKey, "a-server-project", serverConnection); var configurationProvider = Substitute.For(); configurationProvider.GetConfiguration().Returns(new BindingConfiguration(boundServerProject, SonarLintMode.Connected, "binding-dir")); connectedModeServices.ConfigurationProvider.Returns(configurationProvider); - + MockGetServerProjectByKey(false, null); } private void MockGetServerProjectByKey(bool success, ServerProject responseData) { var slCoreConnectionAdapter = Substitute.For(); - slCoreConnectionAdapter.GetServerProjectByKeyAsync(Arg.Any(),Arg.Any()) + slCoreConnectionAdapter.GetServerProjectByKeyAsync(Arg.Any(), Arg.Any()) .Returns(Task.FromResult(new AdapterResponseWithData(success, responseData))); connectedModeServices.SlCoreConnectionAdapter.Returns(slCoreConnectionAdapter); } diff --git a/src/ConnectedMode/UI/ManageBinding/ManageBindingViewModel.cs b/src/ConnectedMode/UI/ManageBinding/ManageBindingViewModel.cs index 565311156..5e910edf2 100644 --- a/src/ConnectedMode/UI/ManageBinding/ManageBindingViewModel.cs +++ b/src/ConnectedMode/UI/ManageBinding/ManageBindingViewModel.cs @@ -21,7 +21,6 @@ using System.Collections.ObjectModel; using System.Windows; using SonarLint.VisualStudio.ConnectedMode.Shared; -using SonarLint.VisualStudio.ConnectedMode.UI.ManageConnections; using SonarLint.VisualStudio.ConnectedMode.UI.ProjectSelection; using SonarLint.VisualStudio.ConnectedMode.UI.Resources; using SonarLint.VisualStudio.Core.Binding; @@ -31,14 +30,14 @@ namespace SonarLint.VisualStudio.ConnectedMode.UI.ManageBinding; public sealed class ManageBindingViewModel : ViewModelBase, IDisposable { - private SolutionInfoModel solutionInfo; + private readonly CancellationTokenSource cancellationTokenSource = new(); + private readonly IConnectedModeBindingServices connectedModeBindingServices; + private readonly IConnectedModeServices connectedModeServices; private ServerProject boundProject; private ConnectionInfo selectedConnectionInfo; private ServerProject selectedProject; private SharedBindingConfigModel sharedBindingConfigModel; - private readonly IConnectedModeServices connectedModeServices; - private readonly IConnectedModeBindingServices connectedModeBindingServices; - private readonly CancellationTokenSource cancellationTokenSource = new(); + private SolutionInfoModel solutionInfo; public SolutionInfoModel SolutionInfo { @@ -131,6 +130,8 @@ public ManageBindingViewModel( ProgressReporter = progressReporterViewModel; } + public void Dispose() => cancellationTokenSource?.Dispose(); + public async Task InitializeDataAsync() { var loadData = new TaskToPerformParams(LoadDataAsync, UiResources.LoadingConnectionsText, @@ -165,8 +166,7 @@ public async Task UnbindWithProgressAsync() { var bind = new TaskToPerformParams(UnbindAsync, UiResources.UnbindingInProgressText, UiResources.UnbindingFailedText) { - AfterSuccess = AfterUnbind, - AfterProgressUpdated = OnProgressUpdated + AfterSuccess = AfterUnbind, AfterProgressUpdated = OnProgressUpdated }; await ProgressReporter.ExecuteTaskWithProgressAsync(bind); } @@ -185,11 +185,6 @@ public async Task ExportBindingConfigurationAsync() } } - public void Dispose() - { - cancellationTokenSource?.Dispose(); - } - internal Task CheckForSharedBindingAsync() { SharedBindingConfigModel = connectedModeBindingServices.SharedBindingConfigProvider.GetSharedBinding(); @@ -254,9 +249,7 @@ internal bool LoadConnections() internal /* for testing */ async Task DisplayBindStatusAsync() { - var solutionName = await connectedModeBindingServices.SolutionInfoProvider.GetSolutionNameAsync(); - var isFolderWorkspace = await connectedModeBindingServices.SolutionInfoProvider.IsFolderWorkspaceAsync(); - SolutionInfo = new SolutionInfoModel(solutionName, isFolderWorkspace ? SolutionType.Folder : SolutionType.Solution); + SolutionInfo = await GetSolutionInfoModelAsync(); var bindingConfiguration = connectedModeServices.ConfigurationProvider.GetConfiguration(); if (bindingConfiguration == null || bindingConfiguration.Mode == SonarLintMode.Standalone) @@ -266,7 +259,7 @@ internal bool LoadConnections() return successResponse; } - var boundServerProject = connectedModeServices.ConfigurationProvider.GetConfiguration()?.Project; + var boundServerProject = bindingConfiguration.Project; var serverConnection = boundServerProject?.ServerConnection; if (serverConnection == null) { @@ -274,10 +267,8 @@ internal bool LoadConnections() } var response = await connectedModeServices.SlCoreConnectionAdapter.GetServerProjectByKeyAsync(serverConnection, boundServerProject.ServerProjectKey); + UpdateBoundProjectProperties(serverConnection, response.ResponseData); - SelectedConnectionInfo = ConnectionInfo.From(serverConnection); - SelectedProject = response.ResponseData; - BoundProject = SelectedProject; return new AdapterResponse(BoundProject != null); } @@ -306,12 +297,7 @@ internal async Task UnbindAsync() return new AdapterResponse(succeeded); } - internal void AfterUnbind(AdapterResponse obj) - { - BoundProject = null; - SelectedConnectionInfo = null; - SelectedProject = null; - } + internal void AfterUnbind(AdapterResponse obj) => UpdateBoundProjectProperties(null, null); private async Task BindAsync(ServerConnection serverConnection, string serverProjectKey) { @@ -354,10 +340,22 @@ private bool CredentialsExists(ConnectionInfo connectionInfo, ServerConnection s return false; } - private ConnectionInfo CreateConnectionInfoFromSharedBinding() - { - return SharedBindingConfigModel.IsSonarCloud() + private ConnectionInfo CreateConnectionInfoFromSharedBinding() => + SharedBindingConfigModel.IsSonarCloud() ? new ConnectionInfo(SharedBindingConfigModel.Organization, ConnectionServerType.SonarCloud) : new ConnectionInfo(SharedBindingConfigModel.Uri.ToString(), ConnectionServerType.SonarQube); + + private void UpdateBoundProjectProperties(ServerConnection serverConnection, ServerProject serverProject) + { + SelectedConnectionInfo = serverConnection == null ? null : ConnectionInfo.From(serverConnection); + SelectedProject = serverProject; + BoundProject = SelectedProject; + } + + private async Task GetSolutionInfoModelAsync() + { + var solutionName = await connectedModeBindingServices.SolutionInfoProvider.GetSolutionNameAsync(); + var isFolderWorkspace = await connectedModeBindingServices.SolutionInfoProvider.IsFolderWorkspaceAsync(); + return new SolutionInfoModel(solutionName, isFolderWorkspace ? SolutionType.Folder : SolutionType.Solution); } }