Skip to content

Commit

Permalink
SLVS-1399 Implement IServerConnectionRepository (#5663)
Browse files Browse the repository at this point in the history
  • Loading branch information
gabriela-trutan-sonarsource authored and vnaskos-sonar committed Sep 19, 2024
1 parent 98de897 commit 3a7d4d8
Show file tree
Hide file tree
Showing 9 changed files with 983 additions and 112 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using SonarLint.VisualStudio.Core;
using SonarLint.VisualStudio.Core.Binding;
using SonarLint.VisualStudio.TestInfrastructure;
using static SonarLint.VisualStudio.Core.Binding.ServerConnection;
Expand All @@ -43,75 +42,101 @@ public void MefCtor_CheckIsExported()
=> MefTestHelpers.CheckTypeCanBeImported<ServerConnectionsRepositoryAdapter, IServerConnectionsRepositoryAdapter>(MefTestHelpers.CreateExport<IServerConnectionsRepository>());

[TestMethod]
public void GetAllConnections_CallServerConnectionsRepository()
public void TryGetAllConnections_CallServerConnectionsRepository()
{
serverConnectionsRepository.GetAll().Returns([]);
MockServerConnections([]);

var connections = testSubject.GetAllConnections();
testSubject.TryGetAllConnections(out var connections);

serverConnectionsRepository.Received(1).GetAll();
serverConnectionsRepository.Received(1).TryGetAll(out Arg.Any<IReadOnlyList<ServerConnection>>());
connections.Should().BeEmpty();
}

[TestMethod]
[DataRow(true)]
[DataRow(false)]
public void GetAllConnections_HasOneSonarCloudConnection_ReturnsOneMappedConnection(bool isSmartNotificationsEnabled)
public void TryGetAllConnections_HasOneSonarCloudConnection_ReturnsOneMappedConnection(bool isSmartNotificationsEnabled)
{
var sonarCloud = CreateSonarCloudServerConnection(isSmartNotificationsEnabled);
serverConnectionsRepository.GetAll().Returns([sonarCloud]);
MockServerConnections([sonarCloud]);

var connections = testSubject.GetAllConnections();
testSubject.TryGetAllConnections(out var connections);

connections.Should().BeEquivalentTo([new Connection(new ConnectionInfo(sonarCloud.Id, ConnectionServerType.SonarCloud), isSmartNotificationsEnabled)]);
}

[TestMethod]
[DataRow(true)]
[DataRow(false)]
public void GetAllConnections_HasOneSonarQubeConnection_ReturnsOneMappedConnection(bool isSmartNotificationsEnabled)
public void TryGetAllConnections_HasOneSonarQubeConnection_ReturnsOneMappedConnection(bool isSmartNotificationsEnabled)
{
var sonarQube = CreateSonarQubeServerConnection(isSmartNotificationsEnabled);
serverConnectionsRepository.GetAll().Returns([sonarQube]);
MockServerConnections([sonarQube]);

var connections = testSubject.GetAllConnections();
testSubject.TryGetAllConnections(out var connections);

connections.Should().BeEquivalentTo([new Connection(new ConnectionInfo(sonarQube.Id, ConnectionServerType.SonarQube), isSmartNotificationsEnabled)]);
}

[TestMethod]
public void GetAllConnectionsInfo_CallServerConnectionsRepository()
[DataRow(true)]
[DataRow(false)]
public void TryGetAllConnections_ReturnsStatusFromSlCore(bool expectedStatus)
{
serverConnectionsRepository.GetAll().Returns([]);
var sonarCloud = CreateSonarCloudServerConnection();
MockServerConnections([sonarCloud], succeeded:expectedStatus);

var connections = testSubject.GetAllConnectionsInfo();
var succeeded = testSubject.TryGetAllConnections(out _);

serverConnectionsRepository.Received(1).GetAll();
succeeded.Should().Be(expectedStatus);
}

[TestMethod]
public void TryGetAllConnectionsInfo_CallServerConnectionsRepository()
{
MockServerConnections([]);

testSubject.TryGetAllConnectionsInfo(out var connections);

serverConnectionsRepository.Received(1).TryGetAll(out Arg.Any<IReadOnlyList<ServerConnection>>());
connections.Should().BeEmpty();
}

[TestMethod]
public void GetAllConnectionsInfo_HasOneSonarCloudConnection_ReturnsOneMappedConnection()
public void TryGetAllConnectionsInfo_HasOneSonarCloudConnection_ReturnsOneMappedConnection()
{
var sonarCloud = CreateSonarCloudServerConnection();
serverConnectionsRepository.GetAll().Returns([sonarCloud]);
MockServerConnections([sonarCloud]);

var connections = testSubject.GetAllConnectionsInfo();
testSubject.TryGetAllConnectionsInfo(out var connections);

connections.Should().BeEquivalentTo([new ConnectionInfo(sonarCloud.Id, ConnectionServerType.SonarCloud)]);
}

[TestMethod]
public void GetAllConnectionsInfo_HasOneSonarQubeConnection_ReturnsOneMappedConnection()
public void TryGetAllConnectionsInfo_HasOneSonarQubeConnection_ReturnsOneMappedConnection()
{
var sonarQube = CreateSonarQubeServerConnection();
serverConnectionsRepository.GetAll().Returns([sonarQube]);
MockServerConnections([sonarQube]);

var connections = testSubject.GetAllConnectionsInfo();
testSubject.TryGetAllConnectionsInfo(out var connections);

connections.Should().BeEquivalentTo([new ConnectionInfo(sonarQube.Id, ConnectionServerType.SonarQube)]);
}

[TestMethod]
[DataRow(true)]
[DataRow(false)]
public void TryGetAllConnectionsInfo_ReturnsStatusFromSlCore(bool expectedStatus)
{
var sonarQube = CreateSonarQubeServerConnection();
MockServerConnections([sonarQube], succeeded: expectedStatus);

var succeeded = testSubject.TryGetAllConnectionsInfo(out _);

succeeded.Should().Be(expectedStatus);
}

private static SonarCloud CreateSonarCloudServerConnection(bool isSmartNotificationsEnabled = true)
{
return new SonarCloud("myOrg", new ServerConnectionSettings(isSmartNotificationsEnabled), Substitute.For<ICredentials>());
Expand All @@ -122,4 +147,13 @@ private static ServerConnection.SonarQube CreateSonarQubeServerConnection(bool i
var sonarQube = new ServerConnection.SonarQube(new Uri("http://localhost"), new ServerConnectionSettings(isSmartNotificationsEnabled), Substitute.For<ICredentials>());
return sonarQube;
}

private void MockServerConnections(List<ServerConnection> connections, bool succeeded = true)
{
serverConnectionsRepository.TryGetAll(out Arg.Any<IReadOnlyList<ServerConnection>>()).Returns(callInfo =>
{
callInfo[0] = connections;
return succeeded;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ public void IsConnectionSelectionEnabled_ProjectIsNotBoundAndBindingIsNotInProgr
{
testSubject.BoundProject = null;
progressReporterViewModel.IsOperationInProgress.Returns(false);
connectedModeServices.ServerConnectionsRepositoryAdapter.GetAllConnectionsInfo().Returns([sonarCloudConnectionInfo]);
MockTryGetAllConnectionsInfo([sonarCloudConnectionInfo]);
testSubject.LoadConnections();

testSubject.IsConnectionSelectionEnabled.Should().BeTrue();
Expand Down Expand Up @@ -434,7 +434,7 @@ public void IsExportButtonEnabled_ProjectIsBoundAndBindingIsNotInProgress_Return
public void LoadConnections_FillsConnections()
{
List<ConnectionInfo> existingConnections = [sonarQubeConnectionInfo, sonarCloudConnectionInfo];
serverConnectionsRepositoryAdapter.GetAllConnectionsInfo().Returns(existingConnections);
MockTryGetAllConnectionsInfo(existingConnections);

testSubject.LoadConnections();

Expand All @@ -444,7 +444,7 @@ public void LoadConnections_FillsConnections()
[TestMethod]
public void LoadConnections_ClearsPreviousConnections()
{
serverConnectionsRepositoryAdapter.GetAllConnectionsInfo().Returns([sonarQubeConnectionInfo]);
MockTryGetAllConnectionsInfo([sonarQubeConnectionInfo]);
testSubject.Connections.Add(sonarCloudConnectionInfo);

testSubject.LoadConnections();
Expand All @@ -467,6 +467,18 @@ public void LoadConnections_RaisesEvents()
Arg.Is<PropertyChangedEventArgs>(x => x.PropertyName == nameof(testSubject.ConnectionSelectionCaptionText)));
}

[TestMethod]
[DataRow(true)]
[DataRow(false)]
public void LoadConnectionsAsync_ReturnsResponseFromAdapter(bool expectedStatus)
{
serverConnectionsRepositoryAdapter.TryGetAllConnectionsInfo(out Arg.Any<List<ConnectionInfo>>()).Returns(expectedStatus);

var succeeded = testSubject.LoadConnections();

succeeded.Should().Be(expectedStatus);
}

[TestMethod]
public async Task InitializeDataAsync_InitializesDataAndReportsProgress()
{
Expand All @@ -482,19 +494,11 @@ await progressReporterViewModel.Received(1)
}

[TestMethod]
public async Task LoadDataAsync_LoadsConnections()
public async Task LoadDataAsync_LoadsConnectionsOnUIThread()
{
await testSubject.LoadDataAsync();

await threadHandling.Received(1).RunOnUIThreadAsync(Arg.Is<Action>(op => op == testSubject.LoadConnections));
}

[TestMethod]
public async Task LoadDataAsync_ConnectionsLoadedSuccessfully_ReturnsTrue()
{
var adapterResponse = await testSubject.LoadDataAsync();

adapterResponse.Success.Should().BeTrue();
await threadHandling.Received(1).RunOnUIThreadAsync(Arg.Any<Action>());
}

[TestMethod]
Expand Down Expand Up @@ -537,6 +541,15 @@ private void MockServices()
connectedModeServices.ThreadHandling.Returns(threadHandling);
connectedModeServices.Logger.Returns(logger);

serverConnectionsRepositoryAdapter.GetAllConnectionsInfo().Returns([]);
MockTryGetAllConnectionsInfo([]);
}

private void MockTryGetAllConnectionsInfo(List<ConnectionInfo> connectionInfos)
{
connectedModeServices.ServerConnectionsRepositoryAdapter.TryGetAllConnectionsInfo(out _).Returns(callInfo =>
{
callInfo[0] = connectionInfos;
return true;
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace SonarLint.VisualStudio.ConnectedMode.UnitTests.UI.ManageConnections;
public class ManageConnectionsViewModelTest
{
private ManageConnectionsViewModel testSubject;
private List<Connection> connections;
private List<Connection> twoConnections;
private IProgressReporterViewModel progressReporterViewModel;
private IConnectedModeServices connectedModeServices;
private IServerConnectionsRepositoryAdapter serverConnectionsRepositoryAdapter;
Expand All @@ -40,7 +40,7 @@ public class ManageConnectionsViewModelTest
[TestInitialize]
public void TestInitialize()
{
connections =
twoConnections =
[
new Connection(new ConnectionInfo("http://localhost:9000", ConnectionServerType.SonarQube), true),
new Connection(new ConnectionInfo("https://sonarcloud.io/myOrg", ConnectionServerType.SonarCloud), false)
Expand All @@ -63,11 +63,11 @@ public void ConnectionViewModels_NoInitialization_HasEmptyList()
[TestMethod]
public void InitializeConnections_InitializesConnectionsCorrectly()
{
serverConnectionsRepositoryAdapter.GetAllConnections().Returns(connections);
MockTryGetConnections(twoConnections);

testSubject.InitializeConnections();

HasExpectedConnections(connections);
HasExpectedConnections(twoConnections);
}

[TestMethod]
Expand All @@ -78,7 +78,7 @@ public void RemoveConnection_RemovesProvidedConnection()

testSubject.RemoveConnection(connectionToRemove);

testSubject.ConnectionViewModels.Count.Should().Be(connections.Count() - 1);
testSubject.ConnectionViewModels.Count.Should().Be(twoConnections.Count - 1);
testSubject.ConnectionViewModels.Should().NotContain(connectionToRemove);
}

Expand Down Expand Up @@ -119,6 +119,8 @@ public void AddConnection_RaisesEvents()
[TestMethod]
public void NoConnectionExists_NoConnections_ReturnsTrue()
{
MockTryGetConnections([]);

testSubject.InitializeConnections();

testSubject.NoConnectionExists.Should().BeTrue();
Expand Down Expand Up @@ -146,19 +148,11 @@ await progressReporterViewModel.Received(1)
}

[TestMethod]
public async Task LoadConnectionsAsync_LoadsConnections()
public async Task LoadConnectionsAsync_LoadsConnectionsOnUIThread()
{
await testSubject.LoadConnectionsAsync();

await threadHandling.Received(1).RunOnUIThreadAsync(Arg.Is<Action>(op => op == testSubject.InitializeConnections));
}

[TestMethod]
public async Task LoadConnectionsAsync_ConnectionsLoadedSuccessfully_ReturnsTrue()
{
var adapterResponse = await testSubject.LoadConnectionsAsync();

adapterResponse.Success.Should().BeTrue();
await threadHandling.Received(1).RunOnUIThreadAsync(Arg.Any<Action>());
}

[TestMethod]
Expand All @@ -175,10 +169,22 @@ public async Task LoadConnectionsAsync_LoadingConnectionsThrows_ReturnsFalse()
logger.Received(1).WriteLine(exceptionMsg);
}

[TestMethod]
[DataRow(true)]
[DataRow(false)]
public void InitializeConnections_ReturnsResponseFromAdapter(bool expectedStatus)
{
serverConnectionsRepositoryAdapter.TryGetAllConnections(out _).Returns(expectedStatus);

var adapterResponse = testSubject.InitializeConnections();

adapterResponse.Should().Be(expectedStatus);
}

private void HasExpectedConnections(IEnumerable<Connection> expectedConnections)
{
testSubject.ConnectionViewModels.Should().NotBeNull();
testSubject.ConnectionViewModels.Count.Should().Be(connections.Count());
testSubject.ConnectionViewModels.Count.Should().Be(twoConnections.Count);
foreach (var connection in expectedConnections)
{
var connectionViewModel = testSubject.ConnectionViewModels.SingleOrDefault(c => c.Name == connection.Info.Id);
Expand All @@ -190,7 +196,11 @@ private void HasExpectedConnections(IEnumerable<Connection> expectedConnections)

private void InitializeTwoConnections()
{
serverConnectionsRepositoryAdapter.GetAllConnections().Returns(connections);
serverConnectionsRepositoryAdapter.TryGetAllConnections(out _).Returns(callInfo =>
{
callInfo[0] = twoConnections;
return true;
});
testSubject.InitializeConnections();
}

Expand All @@ -203,6 +213,15 @@ private void MockServices()
connectedModeServices.ServerConnectionsRepositoryAdapter.Returns(serverConnectionsRepositoryAdapter);
connectedModeServices.ThreadHandling.Returns(threadHandling);
connectedModeServices.Logger.Returns(logger);
serverConnectionsRepositoryAdapter.GetAllConnections().Returns([]);
MockTryGetConnections(twoConnections);
}

private void MockTryGetConnections(List<Connection> connections)
{
serverConnectionsRepositoryAdapter.TryGetAllConnections(out _).Returns(callInfo =>
{
callInfo[0] = connections;
return true;
});
}
}
Loading

0 comments on commit 3a7d4d8

Please sign in to comment.