Skip to content

Commit 3b6f543

Browse files
SLVS-1448 Prevent deleting connection when in use (#5701)
1 parent ca5fbca commit 3b6f543

15 files changed

+519
-47
lines changed

src/ConnectedMode.UnitTests/SlCoreConnectionAdapterTests.cs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ namespace SonarLint.VisualStudio.ConnectedMode.UnitTests;
3939
public class SlCoreConnectionAdapterTests
4040
{
4141
private static readonly BasicAuthCredentials ValidToken = new ("I_AM_JUST_A_TOKEN", new SecureString());
42-
private static readonly ServerConnection.SonarQube SonarQubeConnection = new(new Uri("http://localhost:9000/"), new ServerConnectionSettings(true), ValidToken);
43-
private static readonly ServerConnection.SonarCloud SonarCloudConnection = new("myOrg", new ServerConnectionSettings(true), ValidToken);
42+
private readonly ServerConnection.SonarQube sonarQubeConnection = new(new Uri("http://localhost:9000/"), new ServerConnectionSettings(true), ValidToken);
43+
private readonly ServerConnection.SonarCloud sonarCloudConnection = new("myOrg", new ServerConnectionSettings(true), ValidToken);
4444

4545
private SlCoreConnectionAdapter testSubject;
4646
private ISLCoreServiceProvider slCoreServiceProvider;
@@ -258,7 +258,7 @@ public async Task GetAllProjectsAsync_SwitchesToBackgroundThread()
258258
var threadHandlingMock = Substitute.For<IThreadHandling>();
259259
var slCoreConnectionAdapter = new SlCoreConnectionAdapter(slCoreServiceProvider, threadHandlingMock, logger);
260260

261-
await slCoreConnectionAdapter.GetAllProjectsAsync(SonarQubeConnection);
261+
await slCoreConnectionAdapter.GetAllProjectsAsync(sonarQubeConnection);
262262

263263
await threadHandlingMock.Received(1).RunOnBackgroundThread(Arg.Any<Func<Task<AdapterResponseWithData<List<ServerProject>>>>>());
264264
}
@@ -268,7 +268,7 @@ public async Task GetAllProjectsAsync_GettingConnectionConfigurationSLCoreServic
268268
{
269269
slCoreServiceProvider.TryGetTransientService(out IConnectionConfigurationSLCoreService _).Returns(false);
270270

271-
var response = await testSubject.GetAllProjectsAsync(SonarQubeConnection);
271+
var response = await testSubject.GetAllProjectsAsync(sonarQubeConnection);
272272

273273
logger.Received(1).LogVerbose($"[{nameof(IConnectionConfigurationSLCoreService)}] {SLCoreStrings.ServiceProviderNotInitialized}");
274274
response.Success.Should().BeFalse();
@@ -277,7 +277,7 @@ public async Task GetAllProjectsAsync_GettingConnectionConfigurationSLCoreServic
277277
[TestMethod]
278278
public async Task GetAllProjectsAsync_ConnectionToSonarQubeWithToken_CallsGetAllProjectsAsyncWithCorrectParams()
279279
{
280-
await testSubject.GetAllProjectsAsync(SonarQubeConnection);
280+
await testSubject.GetAllProjectsAsync(sonarQubeConnection);
281281

282282
await connectionConfigurationSlCoreService.Received(1)
283283
.GetAllProjectsAsync(Arg.Is<GetAllProjectsParams>(x => IsExpectedSonarQubeConnectionParams(x.transientConnection, ValidToken.UserName)));
@@ -288,9 +288,9 @@ public async Task GetAllProjectsAsync_ConnectionToSonarQubeWithCredentials_Calls
288288
{
289289
const string username = "username";
290290
const string password = "password";
291-
SonarQubeConnection.Credentials = new BasicAuthCredentials(username, password.CreateSecureString());
291+
sonarQubeConnection.Credentials = new BasicAuthCredentials(username, password.CreateSecureString());
292292

293-
await testSubject.GetAllProjectsAsync(SonarQubeConnection);
293+
await testSubject.GetAllProjectsAsync(sonarQubeConnection);
294294

295295
await connectionConfigurationSlCoreService.Received(1)
296296
.GetAllProjectsAsync(Arg.Is<GetAllProjectsParams>(x => IsExpectedSonarQubeConnectionParams(x.transientConnection, username, password)));
@@ -299,7 +299,7 @@ await connectionConfigurationSlCoreService.Received(1)
299299
[TestMethod]
300300
public async Task GetAllProjectsAsync_ConnectionToSonarCloudWithToken_CallsGetAllProjectsAsyncWithCorrectParams()
301301
{
302-
await testSubject.GetAllProjectsAsync(SonarCloudConnection);
302+
await testSubject.GetAllProjectsAsync(sonarCloudConnection);
303303

304304
await connectionConfigurationSlCoreService.Received(1)
305305
.GetAllProjectsAsync(Arg.Is<GetAllProjectsParams>(x => IsExpectedSonarCloudConnectionParams(x.transientConnection, ValidToken.UserName)));
@@ -310,9 +310,9 @@ public async Task GetAllProjectsAsync_ConnectionToSonarCloudWithCredentials_Call
310310
{
311311
const string username = "username";
312312
const string password = "password";
313-
SonarCloudConnection.Credentials = new BasicAuthCredentials(username, password.CreateSecureString());
313+
sonarCloudConnection.Credentials = new BasicAuthCredentials(username, password.CreateSecureString());
314314

315-
await testSubject.GetAllProjectsAsync(SonarCloudConnection);
315+
await testSubject.GetAllProjectsAsync(sonarCloudConnection);
316316

317317
await connectionConfigurationSlCoreService.Received(1)
318318
.GetAllProjectsAsync(Arg.Is<GetAllProjectsParams>(x => IsExpectedSonarCloudConnectionParams(x.transientConnection, username, password)));
@@ -324,7 +324,7 @@ public async Task GetAllProjectsAsync_ReturnsResponseFromSlCore()
324324
List<SonarProjectDto> expectedServerProjects = [CreateSonarProjectDto("projKey1", "projName1"), CreateSonarProjectDto("projKey2", "projName2")];
325325
connectionConfigurationSlCoreService.GetAllProjectsAsync(Arg.Any<GetAllProjectsParams>()).Returns(new GetAllProjectsResponse(expectedServerProjects));
326326

327-
var response = await testSubject.GetAllProjectsAsync(SonarCloudConnection);
327+
var response = await testSubject.GetAllProjectsAsync(sonarCloudConnection);
328328

329329
response.Success.Should().BeTrue();
330330
response.ResponseData.Count.Should().Be(expectedServerProjects.Count);
@@ -340,7 +340,7 @@ public async Task GetServerProjectByKeyAsync_SwitchesToBackgroundThread()
340340
var threadHandlingMock = Substitute.For<IThreadHandling>();
341341
var slCoreConnectionAdapter = new SlCoreConnectionAdapter(slCoreServiceProvider, threadHandlingMock, logger);
342342

343-
await slCoreConnectionAdapter.GetServerProjectByKeyAsync(SonarCloudConnection, "server-project-key");
343+
await slCoreConnectionAdapter.GetServerProjectByKeyAsync(sonarCloudConnection, "server-project-key");
344344

345345
await threadHandlingMock.Received(1).RunOnBackgroundThread(Arg.Any<Func<Task<AdapterResponseWithData<ServerProject>>>>());
346346
}
@@ -350,7 +350,7 @@ public async Task GetServerProjectByKeyAsync_GettingConnectionConfigurationSLCor
350350
{
351351
slCoreServiceProvider.TryGetTransientService(out IConnectionConfigurationSLCoreService _).Returns(false);
352352

353-
var response = await testSubject.GetServerProjectByKeyAsync(SonarCloudConnection, "server-project-key");
353+
var response = await testSubject.GetServerProjectByKeyAsync(sonarCloudConnection, "server-project-key");
354354

355355
logger.Received(1).LogVerbose($"[{nameof(IConnectionConfigurationSLCoreService)}] {SLCoreStrings.ServiceProviderNotInitialized}");
356356
response.Success.Should().BeFalse();
@@ -364,7 +364,7 @@ public async Task GetServerProjectByKeyAsync_SlCoreThrowsException_ReturnsFailed
364364
connectionConfigurationSlCoreService.When(x => x.GetProjectNamesByKeyAsync(Arg.Any<GetProjectNamesByKeyParams>()))
365365
.Do(_ => throw new Exception(exceptionMessage));
366366

367-
var response = await testSubject.GetServerProjectByKeyAsync(SonarCloudConnection, "server-project-key");
367+
var response = await testSubject.GetServerProjectByKeyAsync(sonarCloudConnection, "server-project-key");
368368

369369
logger.Received(1).LogVerbose($"{Resources.GetServerProjectByKey_Fails}: {exceptionMessage}");
370370
response.Success.Should().BeFalse();
@@ -378,7 +378,7 @@ public async Task GetServerProjectByKeyAsync_ProjectNotFound_ReturnsFailedRespon
378378
connectionConfigurationSlCoreService.GetProjectNamesByKeyAsync(Arg.Any<GetProjectNamesByKeyParams>())
379379
.Returns(new GetProjectNamesByKeyResponse(slCoreResponse));
380380

381-
var response = await testSubject.GetServerProjectByKeyAsync(SonarCloudConnection, "project-key");
381+
var response = await testSubject.GetServerProjectByKeyAsync(sonarCloudConnection, "project-key");
382382

383383
response.Success.Should().BeFalse();
384384
response.ResponseData.Should().BeNull();
@@ -393,7 +393,7 @@ public async Task GetServerProjectByKeyAsync_ProjectFound_ReturnsSuccessResponse
393393
};
394394
connectionConfigurationSlCoreService.GetProjectNamesByKeyAsync(Arg.Any<GetProjectNamesByKeyParams>())
395395
.Returns(new GetProjectNamesByKeyResponse(slCoreResponse));
396-
var response = await testSubject.GetServerProjectByKeyAsync(SonarQubeConnection, "project-key");
396+
var response = await testSubject.GetServerProjectByKeyAsync(sonarQubeConnection, "project-key");
397397

398398
response.Success.Should().BeTrue();
399399
response.ResponseData.Should().BeEquivalentTo(new ServerProject("project-key", "project-name"));
@@ -407,7 +407,7 @@ public async Task GetAllProjectsAsync_SlCoreValidationThrowsException_ReturnsUns
407407
connectionConfigurationSlCoreService.When(x => x.GetAllProjectsAsync(Arg.Any<GetAllProjectsParams>()))
408408
.Do(_ => throw new Exception(exceptionMessage));
409409

410-
var response = await testSubject.GetAllProjectsAsync(SonarCloudConnection);
410+
var response = await testSubject.GetAllProjectsAsync(sonarCloudConnection);
411411

412412
logger.Received(1).LogVerbose($"{Resources.GetAllProjects_Fails}: {exceptionMessage}");
413413
response.Success.Should().BeFalse();

src/ConnectedMode.UnitTests/UI/ConnectedModeBindingServicesTests.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
using SonarLint.VisualStudio.ConnectedMode.UI;
2424
using SonarLint.VisualStudio.ConnectedMode.Shared;
2525
using SonarLint.VisualStudio.ConnectedMode.Binding;
26+
using SonarLint.VisualStudio.Core.Binding;
2627

2728
namespace SonarLint.VisualStudio.ConnectedMode.UnitTests.UI;
2829

@@ -35,6 +36,7 @@ public void MefCtor_CheckIsExported()
3536
MefTestHelpers.CheckTypeCanBeImported<ConnectedModeBindingServices, IConnectedModeBindingServices>(
3637
MefTestHelpers.CreateExport<IBindingController>(),
3738
MefTestHelpers.CreateExport<ISolutionInfoProvider>(),
38-
MefTestHelpers.CreateExport<ISharedBindingConfigProvider>());
39+
MefTestHelpers.CreateExport<ISharedBindingConfigProvider>(),
40+
MefTestHelpers.CreateExport<ISolutionBindingRepository>());
3941
}
4042
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* SonarLint for Visual Studio
3+
* Copyright (C) 2016-2024 SonarSource SA
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
21+
using SonarLint.VisualStudio.ConnectedMode.UI.DeleteConnection;
22+
23+
namespace SonarLint.VisualStudio.ConnectedMode.UnitTests.UI.DeleteConnection;
24+
25+
[TestClass]
26+
public class PreventDeleteConnectionViewModelTests
27+
{
28+
[TestMethod]
29+
public void Ctor_SetsProperties()
30+
{
31+
var projectsToUnbind = Substitute.For<IReadOnlyList<string>>();
32+
var connectionInfo = new ConnectionInfo(default, default);
33+
34+
var testSubject = new PreventDeleteConnectionViewModel(projectsToUnbind, connectionInfo);
35+
36+
testSubject.ConnectionInfo.Should().BeSameAs(connectionInfo);
37+
testSubject.ProjectsToUnbind.Should().BeSameAs(projectsToUnbind);
38+
}
39+
40+
[DataTestMethod]
41+
public void DisplayProjectList_MultipleProjectsToUnbind_ReturnsTrue()
42+
{
43+
var projects = new[] { "binding1", "binding2"};
44+
45+
var testSubject = new PreventDeleteConnectionViewModel(projects, new ConnectionInfo(default, default));
46+
47+
testSubject.DisplayProjectList.Should().BeTrue();
48+
}
49+
50+
[DataTestMethod]
51+
public void DisplayProjectList_ProjectsIsNull_ReturnsFalse()
52+
{
53+
var testSubject = new PreventDeleteConnectionViewModel(null, new ConnectionInfo(default, default));
54+
55+
testSubject.DisplayProjectList.Should().BeFalse();
56+
}
57+
58+
[DataTestMethod]
59+
public void DisplayProjectList_NoProjectsToUnbind_ReturnsFalse()
60+
{
61+
var testSubject = new PreventDeleteConnectionViewModel([], new ConnectionInfo(default, default));
62+
63+
testSubject.DisplayProjectList.Should().BeFalse();
64+
}
65+
}

0 commit comments

Comments
 (0)