Skip to content

Commit

Permalink
Vaas tests
Browse files Browse the repository at this point in the history
  • Loading branch information
ata-no-one authored and pstadermann committed Oct 23, 2023
1 parent 972931a commit b147cdb
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 28 deletions.
9 changes: 9 additions & 0 deletions dotnet/Vaas/src/Vaas/Messages/VerdictResponse.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
using System.Diagnostics.CodeAnalysis;
using System.Text.Json.Serialization;
using CommunityToolkit.Diagnostics;

namespace Vaas.Messages;

public class VerdictResponse
{
public VerdictResponse(string sha256, Verdict verdict)
{
Guard.IsNotNull(sha256);
Guard.IsNotNull(verdict);
Sha256 = sha256;
Verdict = verdict;
}

[JsonPropertyName("kind")]
public string Kind { get; init; } = "VerdictResponse";

Expand Down
26 changes: 12 additions & 14 deletions dotnet/Vaas/src/Vaas/Vaas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using CommunityToolkit.Diagnostics;
using Vaas.Messages;
using Websocket.Client;
using Websocket.Client.Exceptions;
Expand Down Expand Up @@ -47,7 +48,7 @@ public class Vaas : IDisposable, IVaas
private WebsocketClient? _client;
private WebsocketClient AuthenticatedClient => GetAuthenticatedWebSocket();

private readonly HttpClient _httpClient = new();
private readonly HttpClient _httpClient;

private string? SessionId { get; set; }
private bool AuthenticatedErrorOccured { get; set; }
Expand All @@ -59,13 +60,15 @@ public class Vaas : IDisposable, IVaas

private readonly VaasOptions _options;

public Vaas(VaasOptions? options = null)
public Vaas(HttpClient httpClient, VaasOptions? options = null)
{
Guard.IsNotNullOrWhiteSpace(options?.Url.Host ?? VaasOptions.Defaults.Url.Host);
_httpClient = httpClient;
_options = options ?? VaasOptions.Defaults;
_httpClient.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(ProductName, ProductVersion));
}

private const string ProductName = "VaaS C# SDK";
private const string ProductName = "VaaS_C#_SDK";
private static string ProductVersion => Assembly.GetAssembly(typeof(Vaas))?.GetName().Version?.ToString() ?? "0.0.0";

public async Task Connect(string token)
Expand Down Expand Up @@ -164,8 +167,7 @@ public async Task<VaasVerdict> ForSha256Async(ChecksumSha256 sha256, Cancellatio
var url = _options.Url;
var authority = _options.Url.Authority.Replace("gateway", "upload");
var scheme = url.Scheme == "wss" ? "https" : "http";
//TODO: Replace hash in url path with sha256
url = new Uri($"{scheme}://{authority}/verdicts/hash/{sha256}");
url = new Uri($"{scheme}://{authority}/verdicts/sha256/{sha256}");

var responseMessage = await GetAsync(url, cancellationToken);

Expand All @@ -181,14 +183,10 @@ private Task<HttpResponseMessage> GetAsync(Uri url, CancellationToken cancellati
{
return _httpClient.GetAsync(url, cancellationToken);
}
catch (InvalidOperationException e)
{
throw new VaasClientException("TODO", e);
}
catch (HttpRequestException e)
{
// TODO: Parse ProblemDetails once implemented in server
throw new VaasServerException("TODO", e);
throw new VaasServerException("Server-side error", e);
}
}

Expand All @@ -199,9 +197,9 @@ private static void EnsureSuccess(HttpResponseMessage responseMessage)
switch (status)
{
case >= 400 and < 500:
throw new VaasClientException("TODO");
throw new VaasClientException("Client-side error");
case >= 500 and < 600:
throw new VaasServerException("TODO");
throw new VaasServerException("Server-side error");
}
}

Expand All @@ -213,9 +211,9 @@ private static async Task<T> DeserializeResponse<T>(HttpResponseMessage response
return JsonSerializer.Deserialize<T>(contentStream) ?? throw
new VaasServerException("Server returned 'null'");
}
catch (JsonException e)
catch (Exception e) when (e is JsonException or ArgumentException)
{
throw new VaasServerException("TODO", e);
throw new VaasServerException("Server-side error", e);
}
}

Expand Down
7 changes: 4 additions & 3 deletions dotnet/Vaas/test/Vaas.Test/IntegrationTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Xunit;
Expand Down Expand Up @@ -33,7 +34,7 @@ public async void ConnectWithWrongCredentialsThrowsVaasAuthenticationException()
const string clientSecret = "foobar2";
var authenticator = new ClientCredentialsGrantAuthenticator(clientId, clientSecret, TokenUrl);

var vaas = new Vaas(new VaasOptions {Url = VaasUrl});
var vaas = new Vaas(new HttpClient(), new VaasOptions {Url = VaasUrl});
await Assert.ThrowsAsync<VaasAuthenticationException>(async () =>
await vaas.Connect(await authenticator.GetToken()));
}
Expand Down Expand Up @@ -167,7 +168,7 @@ private static async Task<Vaas> AuthenticateWithCredentials()
{
var authenticator = new ClientCredentialsGrantAuthenticator(ClientId, ClientSecret, TokenUrl);

var vaas = new Vaas(new VaasOptions { Url = VaasUrl });
var vaas = new Vaas(new HttpClient(),new VaasOptions { Url = VaasUrl });

await vaas.Connect(await authenticator.GetToken());
return vaas;
Expand All @@ -188,7 +189,7 @@ public async Task Connect_WithResourceOwnerPasswordGrantAuthenticator()
{
var authenticator = new ResourceOwnerPasswordGrantAuthenticator(ClientIdForResourceOwnerPasswordGrant, UserName, Password, TokenUrl);

var vaas = new Vaas(new VaasOptions { Url = VaasUrl });
var vaas = new Vaas(new HttpClient(), new VaasOptions { Url = VaasUrl });
await vaas.Connect(await authenticator.GetToken());
}
}
1 change: 1 addition & 0 deletions dotnet/Vaas/test/Vaas.Test/Vaas.Test.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<ItemGroup>
<PackageReference Include="DotNetEnv" Version="2.5.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
<PackageReference Include="Moq.Contrib.HttpClient" Version="1.4.0" />
<PackageReference Include="Snapshooter.Xunit" Version="0.13.0" />
<PackageReference Include="xunit" Version="2.5.3" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3">
Expand Down
81 changes: 70 additions & 11 deletions dotnet/Vaas/test/Vaas.Test/VaasTest.cs
Original file line number Diff line number Diff line change
@@ -1,44 +1,103 @@
using System;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Moq;
using Moq.Contrib.HttpClient;
using Vaas.Messages;
using Xunit;

namespace Vaas.Test;

public class VaasTest
{
[Fact]
public Task ForSha256Async_SendsUserAgent()
private readonly ChecksumSha256 _maliciousChecksum256 = new("000005c43196142f01d615a67b7da8a53cb0172f8e9317a2ec9a0a39a1da6fe8");
private readonly HttpClient _httpClient;
private readonly Mock<HttpMessageHandler> _handler;
private readonly Vaas _vaas;

public VaasTest()
{
throw new NotImplementedException();
_handler = new Mock<HttpMessageHandler>();
_httpClient = _handler.CreateClient();
_vaas = new Vaas(_httpClient);
}

[Fact]
public Task ForSha256Async_IfRelativeUrl_ThrowsVaasClientException()
public async Task ForSha256Async_SendsUserAgent()
{
throw new NotImplementedException();
const string productName = "VaaS_C#_SDK";
var productVersion = Assembly.GetAssembly(typeof(Vaas))?.GetName().Version?.ToString() ?? "0.0.0";
_handler.SetupRequest(r => r.Headers.UserAgent.ToString() == $"{productName}/{productVersion}")
.ReturnsResponse(JsonSerializer.Serialize(new VerdictResponse(_maliciousChecksum256, Verdict.Malicious)));

var verdict = await _vaas.ForSha256Async(_maliciousChecksum256, CancellationToken.None);

Assert.Equal(Verdict.Malicious, verdict.Verdict);
}

[Fact]
public void Constructor_IfRelativeUrl_ThrowsVaasClientException()
{
var e = Assert.Throws<ArgumentException>(() => new Vaas(_httpClient, new VaasOptions() { Url = new Uri("/relative") }));
Assert.Equal("Parameter \"options?.Url.Host ?? VaasOptions.Defaults.Url.Host\" (string) must not be null or whitespace, was whitespace. (Parameter 'options?.Url.Host ?? VaasOptions.Defaults.Url.Host')", e.Message);
}

[Theory]
[InlineData(HttpStatusCode.BadRequest)]
[InlineData(HttpStatusCode.NotFound)]
public Task ForSha256Async_OnClientError_ThrowsVaasClientException(HttpStatusCode statusCode)
public async Task ForSha256Async_OnClientError_ThrowsVaasClientException(HttpStatusCode statusCode)
{
throw new NotImplementedException();
_handler.SetupAnyRequest()
.ReturnsResponse(statusCode);

var e = await Assert.ThrowsAsync<VaasClientException>(() => _vaas.ForSha256Async(_maliciousChecksum256, CancellationToken.None));
Assert.Equal("Client-side error", e.Message);
}

[Theory]
[InlineData(HttpStatusCode.InternalServerError)]
[InlineData(HttpStatusCode.BadGateway)]
[InlineData(HttpStatusCode.GatewayTimeout)]
public Task ForSha256Async_OnServerError_ThrowsVaasServerError(HttpStatusCode statusCode)
public async Task ForSha256Async_OnServerError_ThrowsVaasServerError(HttpStatusCode statusCode)
{
_handler.SetupAnyRequest()
.ReturnsResponse(statusCode);

var e = await Assert.ThrowsAsync<VaasServerException>(() => _vaas.ForSha256Async(_maliciousChecksum256, CancellationToken.None));
Assert.Equal("Server-side error", e.Message);
}

[Fact]
public async Task ForSha256Async_IfNullIsReturned_ThrowsVaasServerError()
{
_handler.SetupAnyRequest()
.ReturnsResponse("null");

var e = await Assert.ThrowsAsync<VaasServerException>(() => _vaas.ForSha256Async(_maliciousChecksum256, CancellationToken.None));
Assert.Equal("Server returned 'null'", e.Message);
}

[Fact]
public async Task ForSha256Async_OnJsonException_ThrowsVaasServerException()
{
throw new NotImplementedException();
_handler.SetupAnyRequest()
.ReturnsResponse("{");

var e = await Assert.ThrowsAsync<VaasServerException>(() => _vaas.ForSha256Async(_maliciousChecksum256, CancellationToken.None));
Assert.Equal("Server-side error", e.Message);
}

[Fact]
public Task ForSha256Async_IfNullIsReturned_ThrowsVaasServerError()
public async Task ForSha256Async_OnSha256Null_ThrowsVaasServerException()
{
throw new NotImplementedException();
_handler.SetupAnyRequest()
.ReturnsResponse("{}");

var e = await Assert.ThrowsAsync<VaasServerException>(() => _vaas.ForSha256Async(_maliciousChecksum256, CancellationToken.None));
Assert.Equal("Server-side error", e.Message);
}
}

0 comments on commit b147cdb

Please sign in to comment.