Skip to content

Commit 5c93af3

Browse files
fix: tests and injection
1 parent b6bd2c2 commit 5c93af3

File tree

9 files changed

+98
-61
lines changed

9 files changed

+98
-61
lines changed

Snyk.Common/Service/SnykApiService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public async Task<HttpResponseMessage> SendSastSettingsRequestAsync()
8181

8282
using (var httpRequest = new HttpRequestMessage(HttpMethod.Get, builder.Uri))
8383
{
84-
httpRequest.Headers.Add("x-snyk-ide", $"{this.options.IntegrationName}-{SnykExtension.Version}");
84+
httpRequest.Headers.Add("x-snyk-ide", $"{SnykExtension.IntegrationName}-{SnykExtension.Version}");
8585

8686
return await HttpClient.SendAsync(httpRequest);
8787
}

Snyk.VisualStudio.Extension.Shared/CLI/ICli.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,6 @@ public interface ICli
4747
void Authenticate();
4848

4949
string RunCommand(string basePath);
50-
void ReportAnalytics(string data);
50+
Task ReportAnalyticsAsync(string data);
5151
}
5252
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace Snyk.VisualStudio.Extension.Shared.CLI
2+
{
3+
public interface ICliProvider
4+
{
5+
public ICli Cli { get; }
6+
}
7+
}

Snyk.VisualStudio.Extension.Shared/CLI/SnykCli.cs

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,14 @@ public string RunCommand(string arguments)
200200
return consoleResult;
201201
}
202202

203-
public void ReportAnalytics(string data)
203+
public async Task ReportAnalyticsAsync(string data)
204204
{
205-
ConsoleRunner.CreateProcess(GetCliPath(), "reportAnalytics -i " + data,
205+
List<string> args = new ();
206+
args.Add("reportAnalytics");
207+
args.Add("-i");
208+
args.Add("data");
209+
await AddGeneralArgsFromConfigAsync(args);
210+
ConsoleRunner.CreateProcess(GetCliPath(), string.Join(" ", args),
206211
BuildScanEnvironmentVariables());
207212

208213
ConsoleRunner.Execute();
@@ -258,17 +263,7 @@ public async Task<string> BuildScanArgumentsAsync()
258263
arguments.Add("--insecure");
259264
}
260265

261-
if (!string.IsNullOrEmpty(this.Options.Organization))
262-
{
263-
arguments.Add($"--org={this.Options.Organization}");
264-
}
265-
266-
var additionalOptions = await this.Options.GetAdditionalOptionsAsync();
267-
268-
if (!string.IsNullOrEmpty(additionalOptions))
269-
{
270-
arguments.Add($"{additionalOptions}");
271-
}
266+
await AddGeneralArgsFromConfigAsync(arguments);
272267

273268
var isScanAllProjects = await this.Options.IsScanAllProjectsAsync();
274269

@@ -285,6 +280,21 @@ public async Task<string> BuildScanArgumentsAsync()
285280
return cliOptions;
286281
}
287282

283+
private async Task AddGeneralArgsFromConfigAsync(ICollection<string> arguments)
284+
{
285+
if (!string.IsNullOrEmpty(this.Options.Organization))
286+
{
287+
arguments.Add($"--org={this.Options.Organization}");
288+
}
289+
290+
var additionalOptions = await this.Options.GetAdditionalOptionsAsync();
291+
292+
if (!string.IsNullOrEmpty(additionalOptions))
293+
{
294+
arguments.Add($"{additionalOptions}");
295+
}
296+
}
297+
288298
/// <summary>
289299
/// Convert raw json string to <see cref="CliResult"/> object.
290300
/// Check is json object is array. If it's array of cli vulnerability objects it will create <see cref="CliVulnerabilities"/> list.

Snyk.VisualStudio.Extension.Shared/Service/SnykService.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
/// <summary>
2727
/// Main logic for Snyk extension.
2828
/// </summary>
29-
public class SnykService : ISnykServiceProvider, ISnykService
29+
public class SnykService : ISnykServiceProvider, ISnykService, ICliProvider
3030
{
3131
private static readonly ILogger Logger = LogManager.ForContext<SnykService>();
3232

@@ -119,7 +119,7 @@ public SnykIdeAnalyticsService SnykIdeAnalyticsService
119119
if (ideAnalyticsService == null)
120120
{
121121
ideAnalyticsService =
122-
new SnykIdeAnalyticsService(Package, new SnykCli(Options, vsVersion), TasksService);
122+
new SnykIdeAnalyticsService(Package, this, TasksService);
123123
}
124124

125125
return ideAnalyticsService;
@@ -327,5 +327,7 @@ private void InitializeAnalyticsService()
327327
this.analyticsService = SnykAnalyticsService.Instance;
328328
Logger.Information("Analytics service initialized");
329329
}
330+
331+
public ICli Cli => NewCli();
330332
}
331333
}

Snyk.VisualStudio.Extension.Shared/Snyk.VisualStudio.Extension.Shared.projitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
2020
</Compile>
2121
<Compile Include="$(MSBuildThisFileDirectory)CLI\ICli.cs" />
22+
<Compile Include="$(MSBuildThisFileDirectory)CLI\ICliProvider.cs" />
2223
<Compile Include="$(MSBuildThisFileDirectory)CLI\InvalidTokenException.cs" />
2324
<Compile Include="$(MSBuildThisFileDirectory)Commands\AbstractTaskCommand.cs" />
2425
<Compile Include="$(MSBuildThisFileDirectory)Microsoft\HtmlParser\CssStylesheet.cs" />
Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1+
using System;
2+
using System.Diagnostics.CodeAnalysis;
3+
using System.Globalization;
4+
using System.Text.Json.Serialization;
5+
using Snyk.Common.Settings;
6+
17
namespace Snyk.VisualStudio.Extension.Shared.CLI
28
{
3-
using System;
4-
using System.Diagnostics.CodeAnalysis;
5-
using Snyk.Common.Settings;
6-
79
public class UniqueIssueCount
810
{
911
public int Critical { get; set; }
@@ -15,30 +17,34 @@ public class UniqueIssueCount
1517
[SuppressMessage("ReSharper", "UnusedMember.Global")]
1618
public class Attributes
1719
{
18-
public ISnykOptions Options { get; set; }
19-
2020
public Attributes(ISnykOptions options)
2121
{
22-
this.Options = options;
22+
DeviceId = options.AnonymousId;
23+
Application = options.Application;
24+
ApplicationVersion = options.ApplicationVersion;
25+
IntegrationName = options.IntegrationName;
26+
IntegrationVersion = options.IntegrationVersion;
27+
IntegrationEnvironment = options.IntegrationEnvironment;
28+
IntegrationEnvironmentVersion = options.IntegrationEnvironmentVersion;
2329
}
2430

25-
public string DeviceId => Options.AnonymousId;
26-
public string Application => Options.Application;
27-
public string ApplicationVersion => Options.ApplicationVersion;
31+
public string DeviceId { get; }
32+
public string Application { get; }
33+
public string ApplicationVersion { get; }
2834
public string Os => "windows";
2935
public string Arch => "X86_64";
30-
public string IntegrationName => Options.IntegrationName;
31-
public string IntegrationVersion => Options.IntegrationVersion;
32-
public string IntegrationEnvironment => Options.IntegrationEnvironment;
33-
public string IntegrationEnvironmentVersion => Options.IntegrationEnvironmentVersion;
36+
public string IntegrationName { get; }
37+
public string IntegrationVersion { get; }
38+
public string IntegrationEnvironment { get; }
39+
public string IntegrationEnvironmentVersion { get; }
3440
public string EventType => "Scan done";
3541
public string Status => "Succeeded";
3642
public string ScanType { get; set; }
3743
public UniqueIssueCount UniqueIssueCount { get; set; }
3844
public string DurationMs { get; set; }
39-
45+
4046
public string TimestampFinished { get; } = DateTime.Now.ToUniversalTime()
41-
.ToString(DateTimeFormat, System.Globalization.CultureInfo.InvariantCulture);
47+
.ToString(DateTimeFormat, CultureInfo.InvariantCulture);
4248

4349
private const string DateTimeFormat = "yyyy-MM-ddTHH:mm:ss.fffZ";
4450
}
@@ -53,4 +59,4 @@ public class ScanDoneEvent
5359
{
5460
public Data Data { get; set; }
5561
}
56-
};
62+
}

Snyk.VisualStudio.Extension.Shared/analytics/SnykIdeAnalyticsService.cs

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Diagnostics.CodeAnalysis;
23
using Serilog;
34
using Snyk.Code.Library.Domain.Analysis;
45
using Snyk.Common;
@@ -11,21 +12,21 @@ public class SnykIdeAnalyticsService
1112
{
1213
private static readonly ILogger Logger = LogManager.ForContext<SnykIdeAnalyticsService>();
1314
private readonly ISnykOptionsProvider optionsProvider;
15+
private readonly ICliProvider cliProvider;
1416
private readonly ISnykScanTopicProvider scanTopicProvider;
15-
private readonly ICli cli;
1617

1718
private DateTime codeScanningStarted;
1819
private DateTime ossScanningStarted;
1920

2021
public SnykIdeAnalyticsService(
2122
ISnykOptionsProvider optionsProvider,
22-
ICli cli,
23+
ICliProvider cliProvider,
2324
ISnykScanTopicProvider scanTopicProvider
2425
)
2526
{
2627
this.optionsProvider = optionsProvider;
28+
this.cliProvider = cliProvider;
2729
this.scanTopicProvider = scanTopicProvider;
28-
this.cli = cli;
2930
}
3031

3132
public void Initialize()
@@ -42,17 +43,24 @@ public string GetAnalyticsPayload(string product, int durationMs, int critical,
4243
{
4344
ScanDoneEvent e = new()
4445
{
45-
Data = new()
46+
Data = new Data
47+
{
48+
Attributes = new Attributes(optionsProvider.Options)
49+
{
50+
DurationMs = durationMs.ToString(),
51+
ScanType = product,
52+
UniqueIssueCount = new UniqueIssueCount
53+
{
54+
Critical = critical,
55+
High = high,
56+
Medium = medium,
57+
Low = low
58+
}
59+
}
60+
}
4661
};
4762

48-
e.Data.Attributes = new(optionsProvider.Options);
49-
e.Data.Attributes.DurationMs = durationMs.ToString();
50-
e.Data.Attributes.ScanType = product;
51-
e.Data.Attributes.UniqueIssueCount = new();
52-
e.Data.Attributes.UniqueIssueCount.Critical = critical;
53-
e.Data.Attributes.UniqueIssueCount.High = high;
54-
e.Data.Attributes.UniqueIssueCount.Medium = medium;
55-
e.Data.Attributes.UniqueIssueCount.Low = low;
63+
// remove options before serialization
5664
return Json.Serialize(e);
5765
}
5866

@@ -61,6 +69,7 @@ public void OnCliScanningStarted(object sender, SnykCliScanEventArgs e)
6169
ossScanningStarted = DateTime.UtcNow;
6270
}
6371

72+
[SuppressMessage("Usage", "VSTHRD110:Observe result of async calls")]
6473
public void OnOssScanningUpdate(object sender, SnykCliScanEventArgs e)
6574
{
6675
try
@@ -78,7 +87,7 @@ public void OnOssScanningUpdate(object sender, SnykCliScanEventArgs e)
7887
}
7988

8089
var payload = GetAnalyticsPayload("Snyk Open Source", durationMs, critical, high, medium, low);
81-
cli.ReportAnalytics(payload);
90+
cliProvider.Cli.ReportAnalyticsAsync(payload);
8291
}
8392
catch (Exception exception)
8493
{
@@ -96,6 +105,7 @@ public void OnSnykCodeScanningStarted(object sender, SnykCodeScanEventArgs e)
96105
codeScanningStarted = DateTime.UtcNow;
97106
}
98107

108+
[SuppressMessage("Usage", "VSTHRD110:Observe result of async calls")]
99109
public void OnSnykCodeScanningUpdate(object sender, SnykCodeScanEventArgs e)
100110
{
101111
try
@@ -129,7 +139,7 @@ public void OnSnykCodeScanningUpdate(object sender, SnykCodeScanEventArgs e)
129139
}
130140

131141
var payload = GetAnalyticsPayload("Snyk Code", durationMs, critical, high, medium, low);
132-
cli.ReportAnalytics(payload);
142+
cliProvider.Cli.ReportAnalyticsAsync(payload);
133143
}
134144
catch (Exception ex)
135145
{

Snyk.VisualStudio.Extension.Tests/analytics/SnykIDEAnalyticsServiceTest.cs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
1-
using System;
21
using System.Collections.Generic;
3-
using Microsoft;
4-
using Microsoft.VisualStudio.Package;
5-
using Microsoft.VisualStudio.Text.Editor;
62
using Moq;
73
using Snyk.Code.Library.Api.Dto.Analysis;
84
using Snyk.Code.Library.Domain.Analysis;
9-
using Snyk.Common;
105
using Snyk.Common.Settings;
116
using Snyk.VisualStudio.Extension.Shared;
127
using Snyk.VisualStudio.Extension.Shared.CLI;
@@ -39,8 +34,8 @@ public void SnykIdeAnalyticsServiceTest_shouldCreateTheCorrectPayloadString()
3934
var optionsProviderMock = new Mock<ISnykOptionsProvider>();
4035
var optionsMock = new Mock<ISnykOptions>();
4136
var scanTopicMock = new Mock<ISnykScanTopicProvider>();
42-
var cliMock = new Mock<ICli>();
43-
var service = new SnykIdeAnalyticsService(optionsProviderMock.Object, cliMock.Object, scanTopicMock.Object);
37+
var cliProviderMock = new Mock<ICliProvider>();
38+
var service = new SnykIdeAnalyticsService(optionsProviderMock.Object, cliProviderMock.Object, scanTopicMock.Object);
4439
SetupOptionsMock(optionsProviderMock, optionsMock);
4540

4641
var payload = service.GetAnalyticsPayload("product", 100, 1, 2, 3, 4);
@@ -69,8 +64,10 @@ public void SnykIdeAnalyticsServiceTest_shouldReportAnalyticsOnSnykCodeScanningU
6964
var optionsProviderMock = new Mock<ISnykOptionsProvider>();
7065
var optionsMock = new Mock<ISnykOptions>();
7166
var scanTopicMock = new Mock<ISnykScanTopicProvider>();
67+
var cliProviderMock = new Mock<ICliProvider>();
7268
var cliMock = new Mock<ICli>();
73-
var service = new SnykIdeAnalyticsService(optionsProviderMock.Object, cliMock.Object, scanTopicMock.Object);
69+
cliProviderMock.SetupGet(cli => cli.Cli).Returns(cliMock.Object);
70+
var service = new SnykIdeAnalyticsService(optionsProviderMock.Object, cliProviderMock.Object, scanTopicMock.Object);
7471
SetupOptionsMock(optionsProviderMock, optionsMock);
7572
var analysisResult = SetupAnalysisResult();
7673
var e = new SnykCodeScanEventArgs(analysisResult);
@@ -79,7 +76,8 @@ public void SnykIdeAnalyticsServiceTest_shouldReportAnalyticsOnSnykCodeScanningU
7976

8077
// assert payload is generated (anonymousID called) and cli reportAnalytics is called
8178
optionsMock.VerifyGet(options => options.AnonymousId, Times.Once);
82-
cliMock.Verify(cli => cli.ReportAnalytics(It.IsAny<string>()), Times.Once);
79+
cliProviderMock.Verify(cli => cli.Cli, Times.Once);
80+
cliMock.Verify( c => c.ReportAnalyticsAsync(It.IsAny<string>()), Times.Once);
8381
}
8482

8583
[Fact]
@@ -88,8 +86,10 @@ public void SnykIdeAnalyticsServiceTest_shouldReportAnalyticsOnOssScanningUpdate
8886
var optionsProviderMock = new Mock<ISnykOptionsProvider>();
8987
var optionsMock = new Mock<ISnykOptions>();
9088
var scanTopicMock = new Mock<ISnykScanTopicProvider>();
89+
var cliProviderMock = new Mock<ICliProvider>();
9190
var cliMock = new Mock<ICli>();
92-
var service = new SnykIdeAnalyticsService(optionsProviderMock.Object, cliMock.Object, scanTopicMock.Object);
91+
cliProviderMock.SetupGet(cli => cli.Cli).Returns(cliMock.Object);
92+
var service = new SnykIdeAnalyticsService(optionsProviderMock.Object, cliProviderMock.Object, scanTopicMock.Object);
9393
SetupOptionsMock(optionsProviderMock, optionsMock);
9494
var cliResult = SetupCliResult();
9595

@@ -98,7 +98,8 @@ public void SnykIdeAnalyticsServiceTest_shouldReportAnalyticsOnOssScanningUpdate
9898

9999
// assert payload is generated (anonymousID called) and cli reportAnalytics is called
100100
optionsMock.VerifyGet(options => options.AnonymousId, Times.Once);
101-
cliMock.Verify(cli => cli.ReportAnalytics(It.IsAny<string>()), Times.Once);
101+
cliProviderMock.Verify(cli => cli.Cli, Times.Once);
102+
cliMock.Verify( c => c.ReportAnalyticsAsync(It.IsAny<string>()), Times.Once);
102103
}
103104

104105
private static CliResult SetupCliResult()
@@ -136,8 +137,8 @@ private static AnalysisResult SetupAnalysisResult()
136137
};
137138
var fileDto = new FileDto
138139
{
139-
Rows = new int[] { 1, 2 },
140-
Cols = new int[] { 1, 2 },
140+
Rows = new[] { 1, 2 },
141+
Cols = new[] { 1, 2 },
141142
Markers = new List<MarkerDto>()
142143
};
143144
var suggestion = new Suggestion("fileName", suggestionDto, fileDto);

0 commit comments

Comments
 (0)