From 55bbfa966af533de33b0181834e794f97cf72277 Mon Sep 17 00:00:00 2001
From: Gabriela Trutan <gabriela.trutan@sonarsource.com>
Date: Wed, 25 Sep 2024 16:14:30 +0200
Subject: [PATCH 1/4] SLVS-1465 Remove duplicate resources

---
 src/ConnectedMode/UI/Resources/UiResources.Designer.cs | 1 +
 src/ConnectedMode/UI/Resources/UiResources.resx        | 6 ------
 2 files changed, 1 insertion(+), 6 deletions(-)

diff --git a/src/ConnectedMode/UI/Resources/UiResources.Designer.cs b/src/ConnectedMode/UI/Resources/UiResources.Designer.cs
index 292a12eb66..1ba27be414 100644
--- a/src/ConnectedMode/UI/Resources/UiResources.Designer.cs
+++ b/src/ConnectedMode/UI/Resources/UiResources.Designer.cs
@@ -1,6 +1,7 @@
 //------------------------------------------------------------------------------
 // <auto-generated>
 //     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
 //
 //     Changes to this file may cause incorrect behavior and will be lost if
 //     the code is regenerated.
diff --git a/src/ConnectedMode/UI/Resources/UiResources.resx b/src/ConnectedMode/UI/Resources/UiResources.resx
index c9e8eb8307..db2d81c65b 100644
--- a/src/ConnectedMode/UI/Resources/UiResources.resx
+++ b/src/ConnectedMode/UI/Resources/UiResources.resx
@@ -403,10 +403,4 @@ Please manually add the connection through "Manage Connections" and then try aga
   <data name="CalculatingConnectionReferencesText" xml:space="preserve">
     <value>Calculating connection references...</value>
   </data>
-  <data name="CalculatingConnectionReferencesFailedText" xml:space="preserve">
-    <value>Calculating the connection references failed</value>
-  </data>
-  <data name="CalculatingConnectionReferencesText" xml:space="preserve">
-    <value>Calculating connection references...</value>
-  </data>
 </root>
\ No newline at end of file

From bc4bb4ee2045c698ce105283876112a517bbda1e Mon Sep 17 00:00:00 2001
From: Gabriela Trutan <gabriela.trutan@sonarsource.com>
Date: Wed, 25 Sep 2024 16:38:31 +0200
Subject: [PATCH 2/4] SLVS-1465 Show message box when the credentials for an
 existing connection do not exist

---
 .../ManageBindingViewModelTests.cs            | 39 +++++++++++++++++++
 src/ConnectedMode/Resources.Designer.cs       | 10 +++++
 src/ConnectedMode/Resources.resx              |  3 ++
 .../ManageBinding/ManageBindingViewModel.cs   |  6 +++
 .../UI/Resources/UiResources.Designer.cs      | 19 +++++++++
 .../UI/Resources/UiResources.resx             |  7 ++++
 6 files changed, 84 insertions(+)

diff --git a/src/ConnectedMode.UnitTests/UI/ManageBinding/ManageBindingViewModelTests.cs b/src/ConnectedMode.UnitTests/UI/ManageBinding/ManageBindingViewModelTests.cs
index 2447a2a7ce..5efc3af96d 100644
--- a/src/ConnectedMode.UnitTests/UI/ManageBinding/ManageBindingViewModelTests.cs
+++ b/src/ConnectedMode.UnitTests/UI/ManageBinding/ManageBindingViewModelTests.cs
@@ -852,6 +852,43 @@ await bindingController.DidNotReceive()
                 proj.ServerProjectKey == testSubject.SharedBindingConfigModel.ProjectKey), Arg.Any<CancellationToken>());
     }
 
+    [TestMethod]
+    public async Task UseSharedBindingAsync_SharedBindingSonarCloudConnectionWithMissingCredentials_ReturnsFalseAndLogsAndInformsUser()
+    {
+        testSubject.SharedBindingConfigModel = sonarCloudSharedBindingConfigModel;
+        var expectedServerConnection = new ServerConnection.SonarCloud(testSubject.SharedBindingConfigModel.Organization);
+        SetupBoundProject(expectedServerConnection);
+        expectedServerConnection.Credentials = null;
+
+        var response = await testSubject.UseSharedBindingAsync();
+
+        response.Success.Should().BeFalse();
+        logger.WriteLine(Resources.UseSharedBinding_CredentiasNotFound, testSubject.SharedBindingConfigModel.Organization);
+        messageBox.Received(1).Show(UiResources.NotFoundCredentialsForSharedBindingMessageBoxText, UiResources.NotFoundCredentialsForSharedBindingMessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Warning);
+        await bindingController.DidNotReceive()
+            .BindAsync(Arg.Is<BoundServerProject>(proj =>
+                proj.ServerProjectKey == testSubject.SharedBindingConfigModel.ProjectKey), Arg.Any<CancellationToken>());
+    }
+
+
+    [TestMethod]
+    public async Task UseSharedBindingAsync_SharedBindingSonarQubeConnectionWithMissingCredentials_ReturnsFalseAndLogsAndInformsUser()
+    {
+        testSubject.SharedBindingConfigModel = sonarQubeSharedBindingConfigModel;
+        var expectedServerConnection = new ServerConnection.SonarQube(testSubject.SharedBindingConfigModel.Uri);
+        SetupBoundProject(expectedServerConnection);
+        expectedServerConnection.Credentials = null;
+
+        var response = await testSubject.UseSharedBindingAsync();
+
+        response.Success.Should().BeFalse();
+        logger.WriteLine(Resources.UseSharedBinding_CredentiasNotFound, testSubject.SharedBindingConfigModel.Uri);
+        messageBox.Received(1).Show(UiResources.NotFoundCredentialsForSharedBindingMessageBoxText, UiResources.NotFoundCredentialsForSharedBindingMessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Warning);
+        await bindingController.DidNotReceive()
+            .BindAsync(Arg.Is<BoundServerProject>(proj =>
+                proj.ServerProjectKey == testSubject.SharedBindingConfigModel.ProjectKey), Arg.Any<CancellationToken>());
+    }
+
     [TestMethod]
     public async Task UseSharedBindingAsync_BindingFails_ReturnsFalse()
     {
@@ -866,6 +903,7 @@ public async Task UseSharedBindingAsync_BindingFails_ReturnsFalse()
         response.Success.Should().BeFalse();
     }
 
+
     private void MockServices()
     {
         serverConnectionsRepositoryAdapter = Substitute.For<IServerConnectionsRepositoryAdapter>();
@@ -908,6 +946,7 @@ private void SetupBoundProject(ServerConnection serverConnection, ServerProject
     {
         expectedServerProject ??= serverProject;
         
+        serverConnection.Credentials = validCredentials;
         var boundServerProject = new BoundServerProject(ALocalProjectKey, expectedServerProject.Key, serverConnection);
         var configurationProvider = Substitute.For<IConfigurationProvider>();
         configurationProvider.GetConfiguration().Returns(new BindingConfiguration(boundServerProject, SonarLintMode.Connected, "binding-dir"));
diff --git a/src/ConnectedMode/Resources.Designer.cs b/src/ConnectedMode/Resources.Designer.cs
index 6c345152a3..897fc6f430 100644
--- a/src/ConnectedMode/Resources.Designer.cs
+++ b/src/ConnectedMode/Resources.Designer.cs
@@ -1,6 +1,7 @@
 //------------------------------------------------------------------------------
 // <auto-generated>
 //     This code was generated by a tool.
+//     Runtime Version:4.0.30319.42000
 //
 //     Changes to this file may cause incorrect behavior and will be lost if
 //     the code is regenerated.
@@ -653,6 +654,15 @@ internal static string UseSharedBinding_ConnectionNotFound {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to [ConnectedMode/UseSharedBinding] The credentials for the connection {0} could not be found.
+        /// </summary>
+        internal static string UseSharedBinding_CredentiasNotFound {
+            get {
+                return ResourceManager.GetString("UseSharedBinding_CredentiasNotFound", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to [ConnectedMode] Validating credentials failed.
         /// </summary>
diff --git a/src/ConnectedMode/Resources.resx b/src/ConnectedMode/Resources.resx
index cddfd4dd1c..93a17b553e 100644
--- a/src/ConnectedMode/Resources.resx
+++ b/src/ConnectedMode/Resources.resx
@@ -325,4 +325,7 @@
   <data name="UnexpectedConnectionType" xml:space="preserve">
     <value>Unexpected server connection type</value>
   </data>
+  <data name="UseSharedBinding_CredentiasNotFound" xml:space="preserve">
+    <value>[ConnectedMode/UseSharedBinding] The credentials for the connection {0} could not be found</value>
+  </data>
 </root>
\ No newline at end of file
diff --git a/src/ConnectedMode/UI/ManageBinding/ManageBindingViewModel.cs b/src/ConnectedMode/UI/ManageBinding/ManageBindingViewModel.cs
index 712e9b2907..a1f829aa3d 100644
--- a/src/ConnectedMode/UI/ManageBinding/ManageBindingViewModel.cs
+++ b/src/ConnectedMode/UI/ManageBinding/ManageBindingViewModel.cs
@@ -185,6 +185,12 @@ internal async Task<AdapterResponse> UseSharedBindingAsync()
             connectedModeServices.MessageBox.Show(UiResources.NotFoundConnectionForSharedBindingMessageBoxText, UiResources.NotFoundConnectionForSharedBindingMessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Warning);
             return new AdapterResponse(false);
         }
+        if (serverConnection.Credentials == null)
+        {
+            connectedModeServices.Logger.WriteLine(ConnectedMode.Resources.UseSharedBinding_CredentiasNotFound, connection.Id);
+            connectedModeServices.MessageBox.Show(UiResources.NotFoundCredentialsForSharedBindingMessageBoxText, UiResources.NotFoundCredentialsForSharedBindingMessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Warning);
+            return new AdapterResponse(false);
+        }
 
         var response = await BindAsync(serverConnection, SharedBindingConfigModel.ProjectKey);
         return new AdapterResponse(response.Success);
diff --git a/src/ConnectedMode/UI/Resources/UiResources.Designer.cs b/src/ConnectedMode/UI/Resources/UiResources.Designer.cs
index 1ba27be414..06244008cb 100644
--- a/src/ConnectedMode/UI/Resources/UiResources.Designer.cs
+++ b/src/ConnectedMode/UI/Resources/UiResources.Designer.cs
@@ -655,6 +655,25 @@ public static string NotFoundConnectionForSharedBindingMessageBoxText {
             }
         }
         
+        /// <summary>
+        ///   Looks up a localized string similar to Credentials not found.
+        /// </summary>
+        public static string NotFoundCredentialsForSharedBindingMessageBoxCaption {
+            get {
+                return ResourceManager.GetString("NotFoundCredentialsForSharedBindingMessageBoxCaption", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The shared binding could not be executed, because the credentials for the connection to the server could not be found. 
+        ///Please manually add the credentials for the connection and then try again..
+        /// </summary>
+        public static string NotFoundCredentialsForSharedBindingMessageBoxText {
+            get {
+                return ResourceManager.GetString("NotFoundCredentialsForSharedBindingMessageBoxText", resourceCulture);
+            }
+        }
+        
         /// <summary>
         ///   Looks up a localized string similar to OK.
         /// </summary>
diff --git a/src/ConnectedMode/UI/Resources/UiResources.resx b/src/ConnectedMode/UI/Resources/UiResources.resx
index db2d81c65b..6ff22f749d 100644
--- a/src/ConnectedMode/UI/Resources/UiResources.resx
+++ b/src/ConnectedMode/UI/Resources/UiResources.resx
@@ -403,4 +403,11 @@ Please manually add the connection through "Manage Connections" and then try aga
   <data name="CalculatingConnectionReferencesText" xml:space="preserve">
     <value>Calculating connection references...</value>
   </data>
+  <data name="NotFoundCredentialsForSharedBindingMessageBoxCaption" xml:space="preserve">
+    <value>Credentials not found</value>
+  </data>
+  <data name="NotFoundCredentialsForSharedBindingMessageBoxText" xml:space="preserve">
+    <value>The shared binding could not be executed, because the credentials for the connection to the server could not be found. 
+Please manually add the credentials for the connection and then try again.</value>
+  </data>
 </root>
\ No newline at end of file

From faa408818e215b850426b0881c860711e08a2361 Mon Sep 17 00:00:00 2001
From: Gabriela Trutan <gabriela.trutan@sonarsource.com>
Date: Wed, 25 Sep 2024 16:55:51 +0200
Subject: [PATCH 3/4] SLVS-1465 Refactor code: - extract credentials and
 connection validation logic into methods - move public/internal methods into
 the correct position in file

---
 .../ManageBinding/ManageBindingViewModel.cs   | 55 +++++++++++++------
 1 file changed, 38 insertions(+), 17 deletions(-)

diff --git a/src/ConnectedMode/UI/ManageBinding/ManageBindingViewModel.cs b/src/ConnectedMode/UI/ManageBinding/ManageBindingViewModel.cs
index a1f829aa3d..aa23f51401 100644
--- a/src/ConnectedMode/UI/ManageBinding/ManageBindingViewModel.cs
+++ b/src/ConnectedMode/UI/ManageBinding/ManageBindingViewModel.cs
@@ -174,21 +174,25 @@ public async Task ExportBindingConfigurationAsync()
         }
     }
 
-    internal async Task<AdapterResponse> UseSharedBindingAsync()
+    public void Dispose()
     {
-        var connection = SharedBindingConfigModel.IsSonarCloud()
-            ? new ConnectionInfo(SharedBindingConfigModel.Organization, ConnectionServerType.SonarCloud)
-            : new ConnectionInfo(SharedBindingConfigModel.Uri.ToString(), ConnectionServerType.SonarQube);
-        if (!connectedModeServices.ServerConnectionsRepositoryAdapter.TryGet(connection, out var serverConnection))
+        cancellationTokenSource?.Dispose();
+    }
+    
+    internal void DetectSharedBinding()
+    {
+        if (IsCurrentProjectBound)
         {
-            connectedModeServices.Logger.WriteLine(ConnectedMode.Resources.UseSharedBinding_ConnectionNotFound, connection.Id);
-            connectedModeServices.MessageBox.Show(UiResources.NotFoundConnectionForSharedBindingMessageBoxText, UiResources.NotFoundConnectionForSharedBindingMessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Warning);
-            return new AdapterResponse(false);
+            return;
         }
-        if (serverConnection.Credentials == null)
+        SharedBindingConfigModel = connectedModeBindingServices.SharedBindingConfigProvider.GetSharedBinding();
+    }
+
+    internal async Task<AdapterResponse> UseSharedBindingAsync()
+    {
+        var connectionInfo = CreteConnectionInfoFromSharedBinding();
+        if (!ConnectionExists(connectionInfo, out var serverConnection) || !CredentialsExists(connectionInfo, serverConnection))
         {
-            connectedModeServices.Logger.WriteLine(ConnectedMode.Resources.UseSharedBinding_CredentiasNotFound, connection.Id);
-            connectedModeServices.MessageBox.Show(UiResources.NotFoundCredentialsForSharedBindingMessageBoxText, UiResources.NotFoundCredentialsForSharedBindingMessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Warning);
             return new AdapterResponse(false);
         }
 
@@ -292,17 +296,34 @@ private async Task<AdapterResponse> BindAsync(ServerConnection serverConnection,
         }
     }
 
-    internal void DetectSharedBinding()
+    private bool ConnectionExists(ConnectionInfo connectionInfo, out ServerConnection serverConnection)
     {
-        if (IsCurrentProjectBound)
+        if (connectedModeServices.ServerConnectionsRepositoryAdapter.TryGet(connectionInfo, out serverConnection))
         {
-            return;
+            return true;
         }
-        SharedBindingConfigModel = connectedModeBindingServices.SharedBindingConfigProvider.GetSharedBinding();
+
+        connectedModeServices.Logger.WriteLine(ConnectedMode.Resources.UseSharedBinding_ConnectionNotFound, connectionInfo.Id);
+        connectedModeServices.MessageBox.Show(UiResources.NotFoundConnectionForSharedBindingMessageBoxText, UiResources.NotFoundConnectionForSharedBindingMessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Warning);
+        return false;
     }
 
-    public void Dispose()
+    private bool CredentialsExists(ConnectionInfo connectionInfo, ServerConnection serverConnection)
     {
-        cancellationTokenSource?.Dispose();
+        if (serverConnection.Credentials != null)
+        {
+            return true;
+        }
+        connectedModeServices.Logger.WriteLine(ConnectedMode.Resources.UseSharedBinding_CredentiasNotFound, connectionInfo.Id);
+        connectedModeServices.MessageBox.Show(UiResources.NotFoundCredentialsForSharedBindingMessageBoxText, UiResources.NotFoundCredentialsForSharedBindingMessageBoxCaption, MessageBoxButton.OK, MessageBoxImage.Warning);
+        return false;
+
+    }
+
+    private ConnectionInfo CreteConnectionInfoFromSharedBinding()
+    {
+        return SharedBindingConfigModel.IsSonarCloud()
+            ? new ConnectionInfo(SharedBindingConfigModel.Organization, ConnectionServerType.SonarCloud)
+            : new ConnectionInfo(SharedBindingConfigModel.Uri.ToString(), ConnectionServerType.SonarQube);
     }
 }

From 07ce551a9d39e79c0651af1a9f499a3b66045d72 Mon Sep 17 00:00:00 2001
From: Gabriela Trutan <gabriela.trutan@sonarsource.com>
Date: Thu, 26 Sep 2024 13:17:12 +0200
Subject: [PATCH 4/4] SLVS-1465 Fix tooltip not shown anymore due to
 referencing prop that was renamed

---
 src/ConnectedMode/UI/ManageBinding/ManageBindingDialog.xaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/ConnectedMode/UI/ManageBinding/ManageBindingDialog.xaml b/src/ConnectedMode/UI/ManageBinding/ManageBindingDialog.xaml
index 5c6292a947..0ef9905a2b 100644
--- a/src/ConnectedMode/UI/ManageBinding/ManageBindingDialog.xaml
+++ b/src/ConnectedMode/UI/ManageBinding/ManageBindingDialog.xaml
@@ -64,7 +64,7 @@
                 <Button.Style>
                     <Style TargetType="Button">
                         <Style.Triggers>
-                            <DataTrigger Binding="{Binding Path=IsSharedBindingConfigurationDetected}" Value="False">
+                            <DataTrigger Binding="{Binding Path=IsUseSharedBindingButtonVisible}" Value="False">
                                 <Setter Property="ToolTip" Value="{x:Static res:UiResources.SharedBindingConfigurationTooltip}"/>
                             </DataTrigger>
                         </Style.Triggers>