Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
costin-zaharia-sonarsource committed Nov 18, 2022
1 parent e696256 commit 9b83cf8
Show file tree
Hide file tree
Showing 2 changed files with 129 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,15 @@
*/

using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Moq.Protected;
using SonarScanner.MSBuild.Common;
using TestUtilities;

Expand Down Expand Up @@ -144,6 +150,112 @@ public void MultipleDisposeCallsNotFailing()
testDownloader.IsDisposedCalled.Should().BeTrue();
}

[TestMethod]
public async Task DownloadStream_Success()
{
const string testContent = "test content";
var logger = new TestLogger();
var httpClient = MockHttpClient(new HttpResponseMessage { StatusCode = HttpStatusCode.OK, Content = new StringContent(testContent) });

var sut = new WebClientDownloader("username", "password", logger, httpClient: httpClient);
var stream = await sut.DownloadStream(new Uri("https://test.com"));

var text = await new StreamReader(stream).ReadToEndAsync();
text.Should().Be(testContent);

logger.AssertDebugLogged("Downloading from https://test.com/...");
}

[TestMethod]
public async Task DownloadStream_Fail_ForbiddenResponse_WithLog()
{
const string testContent = "test content";
var logger = new TestLogger();
var httpClient = MockHttpClient(new HttpResponseMessage { StatusCode = HttpStatusCode.Forbidden, Content = new StringContent(testContent) });

var sut = new WebClientDownloader("username", "password", logger, httpClient: httpClient);
await new Func<Task<Stream>>(async () => await sut.DownloadStream(new Uri("https://test.com"), true))
.Should().ThrowAsync<HttpRequestException>();

logger.AssertDebugLogged("Downloading from https://test.com/...");
logger.AssertWarningLogged("To analyze private projects make sure the scanner user has 'Browse' permission.");
}

[TestMethod]
public async Task DownloadStream_Fail_NotForbidden_WithLog()
{
const string testContent = "test content";
var logger = new TestLogger();
var httpClient = MockHttpClient(new HttpResponseMessage { StatusCode = HttpStatusCode.NotFound, Content = new StringContent(testContent) });

var sut = new WebClientDownloader("username", "password", logger, httpClient: httpClient);
var stream = await sut.DownloadStream(new Uri("https://test.com"), true);

stream.Should().BeNull();

logger.AssertDebugLogged("Downloading from https://test.com/...");
logger.AssertNoWarningsLogged();
}

[TestMethod]
public async Task DownloadStream_Fail_NoLog()
{
const string testContent = "test content";
var logger = new TestLogger();
var httpClient = MockHttpClient(new HttpResponseMessage { StatusCode = HttpStatusCode.Forbidden, Content = new StringContent(testContent) });

var sut = new WebClientDownloader("username", "password", logger, httpClient: httpClient);
var stream = await sut.DownloadStream(new Uri("https://test.com"));

stream.Should().BeNull();

logger.AssertDebugLogged("Downloading from https://test.com/...");
logger.AssertNoWarningsLogged();
}

[TestMethod]
public async Task Download_Success()
{
const string testContent = "test content";
var logger = new TestLogger();
var httpClient = MockHttpClient(new HttpResponseMessage { StatusCode = HttpStatusCode.OK, Content = new StringContent(testContent) });

var sut = new WebClientDownloader("username", "password", logger, httpClient: httpClient);
var text = await sut.Download(new Uri("https://test.com"));

text.Should().Be(testContent);

logger.AssertDebugLogged("Downloading from https://test.com/...");
}

[TestMethod]
public async Task Download_Fail_NoLog()
{
const string testContent = "test content";
var logger = new TestLogger();
var httpClient = MockHttpClient(new HttpResponseMessage { StatusCode = HttpStatusCode.Forbidden, Content = new StringContent(testContent) });

var sut = new WebClientDownloader("username", "password", logger, httpClient: httpClient);
var text = await sut.Download(new Uri("https://test.com"));

text.Should().BeNull();

logger.AssertDebugLogged("Downloading from https://test.com/...");
logger.AssertNoWarningsLogged();
}

private static HttpClient MockHttpClient(HttpResponseMessage responseMessage)
{
var httpMessageHandlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);
httpMessageHandlerMock
.Protected()
.Setup<Task<HttpResponseMessage>>("SendAsync", ItExpr.IsAny<HttpRequestMessage>(), ItExpr.IsAny<CancellationToken>())
.ReturnsAsync(responseMessage)
.Verifiable();

return new HttpClient(httpMessageHandlerMock.Object);
}

private sealed class TestDownloader : WebClientDownloader
{
public bool IsDisposedCalled { get; private set; } = false;
Expand Down
29 changes: 17 additions & 12 deletions src/SonarScanner.MSBuild.PreProcessor/WebClientDownloader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,12 @@ public class WebClientDownloader : IDownloader
private readonly ILogger logger;
private readonly HttpClient client;

public WebClientDownloader(string userName, string password, ILogger logger, string clientCertPath = null, string clientCertPassword = null)
public WebClientDownloader(string userName, string password, ILogger logger, string clientCertPath = null, string clientCertPassword = null, HttpClient httpClient = null)
{
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
password = password ?? string.Empty;

if (clientCertPath != null && clientCertPassword != null) // password mandatory, as to use client cert in .jar it cannot be with empty password
{
var clientHandler = new HttpClientHandler { ClientCertificateOptions = ClientCertificateOption.Manual };
clientHandler.ClientCertificates.Add(new X509Certificate2(clientCertPath, clientCertPassword));
client = new HttpClient(clientHandler);
}
else
{
client = new HttpClient();
}

client = httpClient ?? CreateHttpClient(clientCertPath, clientCertPassword);
client.DefaultRequestHeaders.Add(HttpRequestHeader.UserAgent.ToString(), $"ScannerMSBuild/{Utilities.ScannerVersion}");

if (userName != null)
Expand All @@ -70,6 +60,21 @@ public WebClientDownloader(string userName, string password, ILogger logger, str
}
}

private static HttpClient CreateHttpClient(string clientCertPath, string clientCertPassword)
{
// password mandatory, as to use client cert in .jar it cannot be with empty password
if (clientCertPath == null || clientCertPassword == null)
{
return new HttpClient();
}
else
{
var clientHandler = new HttpClientHandler { ClientCertificateOptions = ClientCertificateOption.Manual };
clientHandler.ClientCertificates.Add(new X509Certificate2(clientCertPath, clientCertPassword));
return new HttpClient(clientHandler);
}
}

public string GetHeader(HttpRequestHeader header) =>
client.DefaultRequestHeaders.Contains(header.ToString())
? string.Join(";", client.DefaultRequestHeaders.GetValues(header.ToString()))
Expand Down

0 comments on commit 9b83cf8

Please sign in to comment.