Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SLVS-1457 Open ManageBindingDialog from SharedBindingGoldBar #5699

Merged
merged 7 commits into from
Sep 24, 2024
13 changes: 10 additions & 3 deletions src/ConnectedMode/UI/ManageBinding/ManageBindingDialog.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,24 @@
using System.Windows;
using System.Windows.Navigation;
using Microsoft.VisualStudio.Threading;
using SonarLint.VisualStudio.ConnectedMode.Binding;
using SonarLint.VisualStudio.ConnectedMode.UI.ManageConnections;
using SonarLint.VisualStudio.ConnectedMode.UI.ProjectSelection;
using SonarLint.VisualStudio.Core;

namespace SonarLint.VisualStudio.ConnectedMode.UI.ManageBinding;

[ExcludeFromCodeCoverage] // UI, not really unit-testable
public partial class ManageBindingDialog : Window
{
private readonly IConnectedModeServices connectedModeServices;
private readonly bool useSharedBindingOnInitialization;

public ManageBindingDialog(IConnectedModeServices connectedModeServices, IConnectedModeBindingServices connectedModeBindingServices)
public ManageBindingDialog(
IConnectedModeServices connectedModeServices,
IConnectedModeBindingServices connectedModeBindingServices,
bool useSharedBindingOnInitialization = false)
{
this.connectedModeServices = connectedModeServices;
this.useSharedBindingOnInitialization = useSharedBindingOnInitialization;
ViewModel = new ManageBindingViewModel(connectedModeServices, connectedModeBindingServices, new ProgressReporterViewModel());
InitializeComponent();
}
Expand Down Expand Up @@ -66,6 +69,10 @@ private void SelectProject_OnClick(object sender, RoutedEventArgs e)
private async void ManageBindingDialog_OnInitialized(object sender, EventArgs e)
{
await ViewModel.InitializeDataAsync();
if (useSharedBindingOnInitialization)
{
await ViewModel.UseSharedBindingWithProgressAsync();
vnaskos-sonar marked this conversation as resolved.
Show resolved Hide resolved
}
}

private void Unbind_OnClick(object sender, RoutedEventArgs e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SonarLint.VisualStudio.ConnectedMode.Binding;
using SonarLint.VisualStudio.ConnectedMode.Shared;
using SonarLint.VisualStudio.Integration.Binding;
using SonarLint.VisualStudio.Integration.TeamExplorer;
using SonarLint.VisualStudio.Integration.WPF;
Expand Down Expand Up @@ -70,7 +72,9 @@ public void MefCtor_CheckIsExported()
MefTestHelpers.CreateExport<SVsServiceProvider>(),
MefTestHelpers.CreateExport<IHost>(new ConfigurableHost()),
MefTestHelpers.CreateExport<IWebBrowser>(),
MefTestHelpers.CreateExport<IAutoBindTrigger>());
MefTestHelpers.CreateExport<IAutoBindTrigger>(),
MefTestHelpers.CreateExport<ISharedBindingConfigProvider>(),
MefTestHelpers.CreateExport<ICredentialStoreService>());
}

[TestMethod]
Expand Down Expand Up @@ -475,7 +479,7 @@ public int QueryStatusReturnsResult

private SectionController CreateTestSubject(IWebBrowser webBrowser = null)
{
var controller = new SectionController(serviceProvider, host, webBrowser ?? new ConfigurableWebBrowser(), Mock.Of<IAutoBindTrigger>());
var controller = new SectionController(serviceProvider, host, webBrowser ?? new ConfigurableWebBrowser(), Mock.Of<IAutoBindTrigger>(), Mock.Of<ISharedBindingConfigProvider>(), Mock.Of<ICredentialStoreService>());
controller.Initialize(null, new SectionInitializeEventArgs(new ServiceContainer(), null));
return controller;
}
Expand Down
11 changes: 9 additions & 2 deletions src/Integration.TeamExplorer/SectionController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
using Microsoft.TeamFoundation.Controls.WPF.TeamExplorer;
using Microsoft.VisualStudio.Shell;
using SonarLint.VisualStudio.ConnectedMode.Binding;
using SonarLint.VisualStudio.ConnectedMode.Shared;
using SonarLint.VisualStudio.Integration.Binding;
using SonarLint.VisualStudio.Integration.Connection;
using SonarLint.VisualStudio.Integration.Progress;
Expand Down Expand Up @@ -55,18 +56,24 @@ internal class SectionController : TeamExplorerSectionBase, ISectionController
private readonly IServiceProvider serviceProvider;
private readonly IWebBrowser webBrowser;
private readonly IAutoBindTrigger autoBindTrigger;
private readonly ISharedBindingConfigProvider sharedBindingConfigProvider;
private readonly ICredentialStoreService credentialStoreService;

[ImportingConstructor]
public SectionController(
[Import(typeof(SVsServiceProvider))] IServiceProvider serviceProvider,
IHost host,
IWebBrowser webBrowser,
IAutoBindTrigger autoBindTrigger)
IAutoBindTrigger autoBindTrigger,
ISharedBindingConfigProvider sharedBindingConfigProvider,
ICredentialStoreService credentialStoreService)
{
this.serviceProvider = serviceProvider;
this.Host = host;
this.webBrowser = webBrowser;
this.autoBindTrigger = autoBindTrigger;
this.sharedBindingConfigProvider = sharedBindingConfigProvider;
this.credentialStoreService = credentialStoreService;
}

internal /*for testing purposes*/ List<IVSOleCommandTarget> CommandTargets
Expand Down Expand Up @@ -238,7 +245,7 @@ private void InitializeControllerCommands()
{
// Due to complexity of connect and bind we "outsource" the controlling part
// to separate controllers which just expose commands
var connectionController = new Connection.ConnectionController(serviceProvider, Host, autoBindTrigger);
var connectionController = new Connection.ConnectionController(serviceProvider, Host, autoBindTrigger, sharedBindingConfigProvider, credentialStoreService);
var bindingController = new Binding.BindingController(serviceProvider, Host);

this.CommandTargets.Add(connectionController);
Expand Down
48 changes: 28 additions & 20 deletions src/Integration.UnitTests/Connection/ConnectControllerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using SonarLint.VisualStudio.ConnectedMode.Binding;
using SonarLint.VisualStudio.ConnectedMode.Shared;
using SonarLint.VisualStudio.Core;
using SonarLint.VisualStudio.Integration.Binding;
Expand All @@ -48,6 +49,8 @@ public class ConnectControllerTests
private ConfigurableSonarLintSettings settings;
private Mock<ISolutionInfoProvider> solutionInfoProvider;
private TestLogger logger;
private Mock<ISharedBindingConfigProvider> sharedBindingConfigProvider;
private Mock<ICredentialStoreService> credentialsStore;

[TestInitialize]
public void TestInit()
Expand All @@ -66,6 +69,8 @@ public void TestInit()
SonarQubeService = this.sonarQubeServiceMock.Object,
Logger = logger
};
this.sharedBindingConfigProvider = new Mock<ISharedBindingConfigProvider>();
this.credentialsStore = new Mock<ICredentialStoreService>();

IComponentModel componentModel = ConfigurableComponentModel.CreateWithExports(
new []
Expand All @@ -81,9 +86,9 @@ public void TestInit()
[TestMethod]
public void ConnectionController_Ctor_ArgumentChecks()
{
Exceptions.Expect<ArgumentNullException>(() => new ConnectionController(null, Mock.Of<IHost>(), Mock.Of<IAutoBindTrigger>()));
Exceptions.Expect<ArgumentNullException>(() => new ConnectionController(Mock.Of<IServiceProvider>(), null, Mock.Of<IAutoBindTrigger>()));
Exceptions.Expect<ArgumentNullException>(() => new ConnectionController(Mock.Of<IServiceProvider>(), Mock.Of<IHost>(), null));
Exceptions.Expect<ArgumentNullException>(() => new ConnectionController(null, Mock.Of<IHost>(), Mock.Of<IAutoBindTrigger>(), sharedBindingConfigProvider.Object, credentialsStore.Object));
Exceptions.Expect<ArgumentNullException>(() => new ConnectionController(Mock.Of<IServiceProvider>(), null, Mock.Of<IAutoBindTrigger>(), sharedBindingConfigProvider.Object, credentialsStore.Object));
Exceptions.Expect<ArgumentNullException>(() => new ConnectionController(Mock.Of<IServiceProvider>(), Mock.Of<IHost>(), null, sharedBindingConfigProvider.Object, credentialsStore.Object));
}

[TestMethod]
Expand Down Expand Up @@ -184,7 +189,7 @@ public void ConnectionController_ConnectCommand_Execution()
var connectionWorkflowMock = CreateWorkflow();
connectionWorkflowMock.Setup(x => x.EstablishConnection(It.IsAny<ConnectionInformation>(), It.IsAny<string>()));
ConnectionController testSubject = new ConnectionController(this.serviceProvider, this.host, null,
this.connectionProvider, connectionWorkflowMock.Object);
this.connectionProvider, connectionWorkflowMock.Object, sharedBindingConfigProvider.Object, credentialsStore.Object);
this.solutionInfoProvider.Setup(x => x.IsSolutionFullyOpened()).Returns(true);

// Case 1: connection provider return null connection
Expand Down Expand Up @@ -232,9 +237,11 @@ public void ConnectionController_ConnectCommand_SharedConfigAndCredentialsPresen
SetUpOpenSolution();
var connectionProviderMock = new Mock<IConnectionInformationProvider>();
var testSubject = new ConnectionController(this.serviceProvider, this.host, null, connectionProviderMock.Object,
connectionWorkflowMock.Object);
host.SharedBindingConfig = new SharedBindingConfigModel { ProjectKey = "projectKey", Uri = new Uri("https://sonarcloudi.io"), Organization = "Org"};
host.CredentialsForSharedConfig = new Credential("user", "pwd");
connectionWorkflowMock.Object, sharedBindingConfigProvider.Object, credentialsStore.Object);
var sharedBindingConfig = new SharedBindingConfigModel { ProjectKey = "projectKey", Uri = new Uri("https://sonarcloudi.io"), Organization = "Org" };
vnaskos-sonar marked this conversation as resolved.
Show resolved Hide resolved
sharedBindingConfigProvider.Setup(mock => mock.GetSharedBinding()).Returns(sharedBindingConfig);
credentialsStore.Setup(mock => mock.ReadCredentials(It.IsAny<TargetUri>())).Returns(new Credential("user", "pwd"));


testSubject.ConnectCommand.Execute(new ConnectConfiguration(){UseSharedBinding = true});

Expand All @@ -253,12 +260,13 @@ public void ConnectionController_ConnectCommand_SharedConfig_AsksForCredentialsP
SetUpOpenSolution();
var connectionProviderMock = new Mock<IConnectionInformationProvider>();
var testSubject = new ConnectionController(this.serviceProvider, this.host, null, connectionProviderMock.Object,
connectionWorkflowMock.Object);
host.SharedBindingConfig = new SharedBindingConfigModel { ProjectKey = "projectKey", Uri = new Uri("https://sonarcloudi.io"), Organization = "Org"};
connectionWorkflowMock.Object, sharedBindingConfigProvider.Object, credentialsStore.Object);
var sharedBindingConfig = new SharedBindingConfigModel { ProjectKey = "projectKey", Uri = new Uri("https://sonarcloudi.io"), Organization = "Org" };
vnaskos-sonar marked this conversation as resolved.
Show resolved Hide resolved
sharedBindingConfigProvider.Setup(mock => mock.GetSharedBinding()).Returns(sharedBindingConfig);
var connectionInformation =
new ConnectionInformation(host.SharedBindingConfig.Uri, "user", "pwd".ToSecureString())
new ConnectionInformation(sharedBindingConfig.Uri, "user", "pwd".ToSecureString())
{
Organization = new SonarQubeOrganization(host.SharedBindingConfig.Organization, string.Empty)
Organization = new SonarQubeOrganization(sharedBindingConfig.Organization, string.Empty)
};
SetupConnectionProvider(connectionProviderMock, connectionInformation);

Expand All @@ -269,7 +277,7 @@ public void ConnectionController_ConnectCommand_SharedConfig_AsksForCredentialsP
Times.Once);
connectionProviderMock.Verify(x =>
x.GetConnectionInformation(It.Is<ConnectionInformation>(c =>
c.ServerUri == host.SharedBindingConfig.Uri && c.Organization.Key == host.SharedBindingConfig.Organization)),
c.ServerUri == sharedBindingConfig.Uri && c.Organization.Key == sharedBindingConfig.Organization)),
Times.Once);
}

Expand All @@ -291,14 +299,14 @@ private void TestDisabledSharedConfig(ConnectConfiguration config)
SetupConnectionWorkflow(connectionWorkflowMock);
SetUpOpenSolution();
var connectionProviderMock = new Mock<IConnectionInformationProvider>();
host.SharedBindingConfig = new SharedBindingConfigModel
{ ProjectKey = "projectKey", Uri = new Uri("https://sonarcloudi.io"), Organization = "Org" };
host.CredentialsForSharedConfig = new Credential("user", "pwd");
var sharedBindingConfig = new SharedBindingConfigModel { ProjectKey = "projectKey", Uri = new Uri("https://sonarcloudi.io"), Organization = "Org" };
sharedBindingConfigProvider.Setup(mock => mock.GetSharedBinding()).Returns(sharedBindingConfig);
credentialsStore.Setup(mock => mock.ReadCredentials(It.IsAny<TargetUri>())).Returns(new Credential("user", "pwd"));
var expectedConnection = new ConnectionInformation(new Uri("https://127.0.0.0"));
SetupConnectionProvider(connectionProviderMock, expectedConnection);

var testSubject = new ConnectionController(this.serviceProvider, this.host, null,
connectionProviderMock.Object, connectionWorkflowMock.Object);
connectionProviderMock.Object, connectionWorkflowMock.Object, sharedBindingConfigProvider.Object, credentialsStore.Object);

testSubject.ConnectCommand.Execute(config);

Expand All @@ -321,7 +329,7 @@ public void ConnectionController_ConnectCommand_SharedConfigNotPresentDoesNotAut
SetupConnectionProvider(connectionProviderMock, expectedConnection);

var testSubject = new ConnectionController(this.serviceProvider, this.host, null,
connectionProviderMock.Object, connectionWorkflowMock.Object);
connectionProviderMock.Object, connectionWorkflowMock.Object, sharedBindingConfigProvider.Object, credentialsStore.Object);

testSubject.ConnectCommand.Execute(new ConnectConfiguration() { UseSharedBinding = true });

Expand Down Expand Up @@ -381,7 +389,7 @@ public void ConnectionController_RefreshCommand_Execution()
// Arrange
var connectionWorkflowMock = CreateWorkflow();
ConnectionController testSubject = new ConnectionController(serviceProvider, host, null, connectionProvider,
connectionWorkflowMock.Object);
connectionWorkflowMock.Object, sharedBindingConfigProvider.Object, credentialsStore.Object);
this.connectionProvider.ConnectionInformationToReturn = new ConnectionInformation(new Uri("http://notExpected"));
var connection = new ConnectionInformation(new Uri("http://Expected"));
// Sanity
Expand All @@ -405,7 +413,7 @@ public void ConnectionController_SetConnectionInProgress()
// Arrange
var connectionWorkflowMock = CreateWorkflow();
ConnectionController testSubject = new ConnectionController(serviceProvider, host, null, connectionProvider,
connectionWorkflowMock.Object);
connectionWorkflowMock.Object, sharedBindingConfigProvider.Object, credentialsStore.Object);
this.solutionInfoProvider.Setup(x => x.IsSolutionFullyOpened()).Returns(true);
this.connectionProvider.ConnectionInformationToReturn = null;
var progressEvents = new ConfigurableProgressEvents();
Expand Down Expand Up @@ -463,6 +471,6 @@ private static void SetupConnectionProvider(Mock<IConnectionInformationProvider>
}

private ConnectionController CreateTestSubject() =>
new ConnectionController(serviceProvider, host, Mock.Of<IAutoBindTrigger>());
new ConnectionController(serviceProvider, host, Mock.Of<IAutoBindTrigger>(), sharedBindingConfigProvider.Object, credentialsStore.Object);
}
}
Loading