Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions src/IssueViz.Security.UnitTests/Hotspots/LocalHotspotTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using SonarLint.VisualStudio.Core.Analysis;
using SonarLint.VisualStudio.IssueVisualization.Models;
using SonarLint.VisualStudio.IssueVisualization.Security.Hotspots;

namespace SonarLint.VisualStudio.IssueVisualization.Security.UnitTests.Hotspots;
Expand All @@ -32,4 +34,55 @@ public void Ctor_VisualizationIsNull_Throws()

test.Should().Throw<ArgumentNullException>().WithMessage("*visualization*");
}

[TestMethod]
[DataRow(HotspotStatus.ToReview)]
[DataRow(HotspotStatus.Acknowledged)]
[DataRow(HotspotStatus.Fixed)]
[DataRow(HotspotStatus.Safe)]
public void ToLocalHotspot_WithHotspotStatus_CreatesLocalHotspot(HotspotStatus hotspotStatus)
{
var analysisIssueVisualization = CreateMockedHotspot(hotspotStatus);

var result = LocalHotspot.ToLocalHotspot(analysisIssueVisualization);

result.Visualization.Should().Be(analysisIssueVisualization);
result.HotspotStatus.Should().Be(hotspotStatus);
}

[TestMethod]
[DataRow(HotspotPriority.High)]
[DataRow(HotspotPriority.Low)]
[DataRow(HotspotPriority.Medium)]
public void ToLocalHotspot_WithHotspotPriority_CreatesLocalHotspot(HotspotPriority hotspotPriority)
{
var analysisIssueVisualization = CreateMockedHotspot(hotspotStatus: default, hotspotPriority);

var result = LocalHotspot.ToLocalHotspot(analysisIssueVisualization);

result.Visualization.Should().Be(analysisIssueVisualization);
result.Priority.Should().Be(hotspotPriority);
}

[TestMethod]
public void ToLocalHotspot_NoHotspotPriority_ReturnsHighPriority()
{
var analysisIssueVisualization = CreateMockedHotspot(hotspotStatus: default, hotspotPriority: null);

var result = LocalHotspot.ToLocalHotspot(analysisIssueVisualization);

result.Visualization.Should().Be(analysisIssueVisualization);
result.Priority.Should().Be(HotspotPriority.High);
}

private IAnalysisIssueVisualization CreateMockedHotspot(HotspotStatus hotspotStatus, HotspotPriority? hotspotPriority = null)
{
var analysisIssueVisualization = Substitute.For<IAnalysisIssueVisualization>();
var analysisHotspotIssue = Substitute.For<IAnalysisHotspotIssue>();
analysisHotspotIssue.HotspotStatus.Returns(hotspotStatus);
analysisHotspotIssue.HotspotPriority.Returns(hotspotPriority);
analysisIssueVisualization.Issue.Returns(analysisHotspotIssue);

return analysisIssueVisualization;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* SonarLint for Visual Studio
* Copyright (C) 2016-2025 SonarSource SA
* mailto:info AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

using SonarLint.VisualStudio.Core.Analysis;
using SonarLint.VisualStudio.IssueVisualization.Models;
using SonarLint.VisualStudio.IssueVisualization.Security.ReportView;

namespace SonarLint.VisualStudio.IssueVisualization.Security.UnitTests.ReportView;

[TestClass]
public class AnalysisIssueViewModelBaseTest
{
[TestMethod]
public void Ctor_InitializesPropertiesAsExpected()
{
var analysisIssueVisualization = CreateMockedIssue("csharp:101",
Guid.NewGuid(),
1,
66,
"remove todo comment",
"myClass.cs");

var testSubject = new AnalysisIssueViewModelBase(analysisIssueVisualization);

testSubject.Issue.Should().Be(analysisIssueVisualization);
testSubject.RuleInfo.RuleKey.Should().Be(analysisIssueVisualization.RuleId);
testSubject.RuleInfo.IssueId.Should().Be(analysisIssueVisualization.IssueId);
testSubject.Line.Should().Be(analysisIssueVisualization.Issue.PrimaryLocation.TextRange.StartLine);
testSubject.Column.Should().Be(analysisIssueVisualization.Issue.PrimaryLocation.TextRange.StartLineOffset);
testSubject.Title.Should().Be(analysisIssueVisualization.Issue.PrimaryLocation.Message);
testSubject.FilePath.Should().Be(analysisIssueVisualization.Issue.PrimaryLocation.FilePath);
testSubject.Issue.Should().Be(analysisIssueVisualization);
}

[TestMethod]
[DataRow("931CF6A0-A479-4566-929B-FC6D3AB3D3EA", "serverKey")]
[DataRow(null, "serverKey")]
[DataRow(null, null)]
public void IsSameAnalysisIssue_SameIdAndServerKey_ReturnsTrue(string issueId, string serverKey)
{
var analysisIssueVisualization1 = CreateMockedIssue(GetGuid(issueId), serverKey);
var analysisIssueVisualization2 = CreateMockedIssue(analysisIssueVisualization1.Issue.Id, analysisIssueVisualization1.Issue.IssueServerKey);

new AnalysisIssueViewModelBase(analysisIssueVisualization1).IsSameAnalysisIssue(analysisIssueVisualization2).Should().BeTrue();
}

[TestMethod]
public void IsSameAnalysisIssue_SameReference_ReturnsTrue()
{
var analysisIssueVisualization1 = CreateMockedIssue(Guid.NewGuid(), "E2670BAB-4B1E-49C2-8641-7B77CE2A6DBF");

new AnalysisIssueViewModelBase(analysisIssueVisualization1).IsSameAnalysisIssue(analysisIssueVisualization1).Should().BeTrue();
}

[TestMethod]
[DataRow("931CF6A0-A479-4566-929B-FC6D3AB3D3EA", "E2670BAB-4B1E-49C2-8641-7B77CE2A6DBF")]
[DataRow(null, "931CF6A0-A479-4566-929B-FC6D3AB3D3EA")]
public void IsSameAnalysisIssue_DifferentId_ReturnsFalse(string issueId1, string issueId2)
{
var serverKey = Guid.NewGuid().ToString();
var analysisIssueVisualization1 = CreateMockedIssue(GetGuid(issueId1), serverKey);
var analysisIssueVisualization2 = CreateMockedIssue(GetGuid(issueId2), serverKey);

new AnalysisIssueViewModelBase(analysisIssueVisualization1).IsSameAnalysisIssue(analysisIssueVisualization2).Should().BeFalse();
}

[TestMethod]
[DataRow("931CF6A0-A479-4566-929B-FC6D3AB3D3EA", "E2670BAB-4B1E-49C2-8641-7B77CE2A6DBF")]
[DataRow(null, "931CF6A0-A479-4566-929B-FC6D3AB3D3EA")]
public void IsSameAnalysisIssue_DifferentServerKey_ReturnsFalse(string serverKey1, string serverKey2)
{
var issueId = Guid.NewGuid();
var analysisIssueVisualization1 = CreateMockedIssue(issueId, serverKey1);
var analysisIssueVisualization2 = CreateMockedIssue(issueId, serverKey2);

new AnalysisIssueViewModelBase(analysisIssueVisualization1).IsSameAnalysisIssue(analysisIssueVisualization2).Should().BeFalse();
}

private static IAnalysisIssueVisualization CreateMockedIssue(
string ruleId,
Guid issueId,
int startLine,
int startLineOffset,
string message,
string filePath)
{
var analysisIssueVisualization = Substitute.For<IAnalysisIssueVisualization>();
analysisIssueVisualization.RuleId.Returns(ruleId);
analysisIssueVisualization.IssueId.Returns(issueId);

var analysisIssueBase = Substitute.For<IAnalysisIssueBase>();
analysisIssueBase.PrimaryLocation.TextRange.StartLine.Returns(startLine);
analysisIssueBase.PrimaryLocation.TextRange.StartLineOffset.Returns(startLineOffset);
analysisIssueBase.PrimaryLocation.Message.Returns(message);
analysisIssueBase.PrimaryLocation.FilePath.Returns(filePath);
analysisIssueVisualization.Issue.Returns(analysisIssueBase);

return analysisIssueVisualization;
}

private static IAnalysisIssueVisualization CreateMockedIssue(
Guid? issueId,
string serverKey)
{
var analysisIssueVisualization = Substitute.For<IAnalysisIssueVisualization>();
var analysisIssueBase = Substitute.For<IAnalysisIssueBase>();
analysisIssueBase.IssueServerKey.Returns(serverKey);
analysisIssueBase.Id.Returns(issueId);
analysisIssueVisualization.Issue.Returns(analysisIssueBase);

return analysisIssueVisualization;
}

private static Guid? GetGuid(string issueId) => issueId == null ? null : Guid.Parse(issueId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,26 @@
*/

using System.Collections.ObjectModel;
using SonarLint.VisualStudio.Core;
using SonarLint.VisualStudio.IssueVisualization.Security.ReportView;

namespace SonarLint.VisualStudio.IssueVisualization.Security.UnitTests.ReportView;

[TestClass]
public class GroupFileViewModelTest
{
private IThreadHandling threadHandling;

[TestInitialize]
public void TestInitialize() => threadHandling = Substitute.For<IThreadHandling>();

[TestMethod]
public void Ctor_InitializesPropertiesAsExpected()
{
var issues = new ObservableCollection<IIssueViewModel> { Substitute.For<IIssueViewModel>() };
var filePath = "c:\\myDir\\myFile.cs";

var testSubject = new GroupFileViewModel(filePath, issues);
var testSubject = new GroupFileViewModel(filePath, issues, threadHandling);

testSubject.Title.Should().Be("myFile.cs");
testSubject.FilePath.Should().Be(filePath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ public class HotspotsReportViewModelTest
private IReviewHotspotsService reviewHotspotsService;
private ITelemetryManager telemetryManager;
private HotspotsReportViewModel testSubject;
private IThreadHandling threadHandling;

[TestInitialize]
public void TestInitialize()
Expand All @@ -50,7 +51,8 @@ public void TestInitialize()
reviewHotspotsService = Substitute.For<IReviewHotspotsService>();
messageBox = Substitute.For<IMessageBox>();
telemetryManager = Substitute.For<ITelemetryManager>();
testSubject = new HotspotsReportViewModel(localHotspotsStore, reviewHotspotsService, messageBox, telemetryManager);
threadHandling = Substitute.For<IThreadHandling>();
testSubject = new HotspotsReportViewModel(localHotspotsStore, reviewHotspotsService, messageBox, telemetryManager, threadHandling);
}

[TestMethod]
Expand All @@ -59,7 +61,8 @@ public void MefCtor_CheckIsExported() =>
MefTestHelpers.CreateExport<ILocalHotspotsStore>(),
MefTestHelpers.CreateExport<IReviewHotspotsService>(),
MefTestHelpers.CreateExport<IMessageBox>(),
MefTestHelpers.CreateExport<ITelemetryManager>()
MefTestHelpers.CreateExport<ITelemetryManager>(),
MefTestHelpers.CreateExport<IThreadHandling>()
);

[TestMethod]
Expand Down Expand Up @@ -123,7 +126,7 @@ public void GetHotspotsGroupViewModels_TwoHotspotsInDifferentFiles_CreatesTwoGro
public void HotspotsChanged_RaisedOnStoreIssuesChanged()
{
var raised = false;
testSubject.HotspotsChanged += (_, _) => raised = true;
testSubject.IssuesChanged += (_, _) => raised = true;

localHotspotsStore.IssuesChanged += Raise.Event<EventHandler<IssuesChangedEventArgs>>(null, null);

Expand Down
Loading