RestClient tests with mocking
This commit is contained in:
parent
b0b78fa272
commit
ec482b9233
@ -14,14 +14,16 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="coverlet.collector" Version="6.0.0"/>
|
<PackageReference Include="coverlet.collector" Version="6.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0"/>
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
|
||||||
<PackageReference Include="xunit" Version="2.5.3"/>
|
<PackageReference Include="Moq" Version="4.20.70" />
|
||||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3"/>
|
<PackageReference Include="RichardSzalay.MockHttp" Version="7.0.0" />
|
||||||
|
<PackageReference Include="xunit" Version="2.5.3" />
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.3" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Using Include="Xunit"/>
|
<Using Include="Xunit" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
51
Discord.API.Tests/Rest/RestClientTests.cs
Normal file
51
Discord.API.Tests/Rest/RestClientTests.cs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
using System.Net;
|
||||||
|
using Discord.API.Rest;
|
||||||
|
using RichardSzalay.MockHttp;
|
||||||
|
|
||||||
|
namespace Discord.API.Tests;
|
||||||
|
|
||||||
|
public class RestClientTests{
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async void GetGatewayTest(){
|
||||||
|
// Arrange
|
||||||
|
var mock = new MockHttpMessageHandler();
|
||||||
|
mock.Expect(HttpMethod.Get, "https://localhost/gateway").Respond(HttpStatusCode.OK,"application/json", """
|
||||||
|
{"url":"wss://test.gateway.api/"}
|
||||||
|
""");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var rest_client = new RestClient("https://localhost/", "api_key", mock);
|
||||||
|
var res = await rest_client.GetGateway();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsType<RestSuccessResponse<GetGatewayResponse>>(res);
|
||||||
|
Assert.True(res.Success);
|
||||||
|
Assert.Equal("wss://test.gateway.api/", res.Value.Url);
|
||||||
|
mock.VerifyNoOutstandingExpectation();
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async void GetGatewayErrorTest(){
|
||||||
|
// Arrange
|
||||||
|
var mock = new MockHttpMessageHandler();
|
||||||
|
mock.Expect(HttpMethod.Get, "https://localhost/gateway").Respond(HttpStatusCode.TooManyRequests,"application/json", """
|
||||||
|
{
|
||||||
|
"message": "You are being rate limited.",
|
||||||
|
"retry_after": 64.57,
|
||||||
|
"global": false
|
||||||
|
}
|
||||||
|
""");
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var rest_client = new RestClient("https://localhost/", "api_key", mock);
|
||||||
|
var res = await rest_client.GetGateway();
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.IsType<RestErrorResponse<GetGatewayResponse>>(res);
|
||||||
|
Assert.False(res.Success);
|
||||||
|
Assert.Equal("You are being rate limited.", res.Error.Message);
|
||||||
|
mock.VerifyNoOutstandingExpectation();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,5 +1,4 @@
|
|||||||
using Discord.API.Rest;
|
using Discord.API.Rest;
|
||||||
using Discord.API.Rest.HttpClientWrapper;
|
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace Discord.API;
|
namespace Discord.API;
|
||||||
@ -20,10 +19,10 @@ public class DiscordClient
|
|||||||
Task.Run(ConnectGateway);
|
Task.Run(ConnectGateway);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal DiscordClient(string api_key, TimeProvider time_provider, IHttpClientWrapper http_client){
|
internal DiscordClient(string api_key, TimeProvider time_provider, HttpMessageHandler msg_handler){
|
||||||
this.TimeProvider=time_provider;
|
this.TimeProvider=time_provider;
|
||||||
this.ApiKey=api_key;
|
this.ApiKey=api_key;
|
||||||
Rest = new RestClient(ApiKey, http_client);
|
Rest = new RestClient(ApiBaseUrl, ApiKey, msg_handler);
|
||||||
Task.Run(ConnectGateway);
|
Task.Run(ConnectGateway);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,45 +0,0 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Net.Http.Headers;
|
|
||||||
using System.Runtime.Versioning;
|
|
||||||
|
|
||||||
namespace Discord.API.Rest.HttpClientWrapper;
|
|
||||||
|
|
||||||
public class HttpClientWrapper : HttpClient, IHttpClientWrapper{
|
|
||||||
//
|
|
||||||
// Summary:
|
|
||||||
// Initializes a new instance of the System.Net.Http.HttpClient class using a System.Net.Http.HttpClientHandler
|
|
||||||
// that is disposed when this instance is disposed.
|
|
||||||
public HttpClientWrapper() : base() { }
|
|
||||||
//
|
|
||||||
// Summary:
|
|
||||||
// Initializes a new instance of the System.Net.Http.HttpClient class with the specified
|
|
||||||
// handler. The handler is disposed when this instance is disposed.
|
|
||||||
//
|
|
||||||
// Parameters:
|
|
||||||
// handler:
|
|
||||||
// The HTTP handler stack to use for sending requests.
|
|
||||||
//
|
|
||||||
// Exceptions:
|
|
||||||
// T:System.ArgumentNullException:
|
|
||||||
// The handler is null.
|
|
||||||
public HttpClientWrapper(HttpMessageHandler handler) : base(handler) { }
|
|
||||||
//
|
|
||||||
// Summary:
|
|
||||||
// Initializes a new instance of the System.Net.Http.HttpClient class with the provided
|
|
||||||
// handler, and specifies whether that handler should be disposed when this instance
|
|
||||||
// is disposed.
|
|
||||||
//
|
|
||||||
// Parameters:
|
|
||||||
// handler:
|
|
||||||
// The System.Net.Http.HttpMessageHandler responsible for processing the HTTP response
|
|
||||||
// messages.
|
|
||||||
//
|
|
||||||
// disposeHandler:
|
|
||||||
// true if the inner handler should be disposed of by HttpClient.Dispose; false
|
|
||||||
// if you intend to reuse the inner handler.
|
|
||||||
//
|
|
||||||
// Exceptions:
|
|
||||||
// T:System.ArgumentNullException:
|
|
||||||
// The handler is null.
|
|
||||||
public HttpClientWrapper(HttpMessageHandler handler, bool disposeHandler) : base(handler, disposeHandler) { }
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@ -1,20 +1,27 @@
|
|||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using Discord.API.Rest.HttpClientWrapper;
|
|
||||||
using Serilog;
|
using Serilog;
|
||||||
|
|
||||||
namespace Discord.API.Rest;
|
namespace Discord.API.Rest;
|
||||||
|
|
||||||
internal class RestClient{
|
internal class RestClient{
|
||||||
|
|
||||||
private IHttpClientWrapper httpClient;
|
private HttpClient httpClient;
|
||||||
|
|
||||||
public RestClient(string base_url, string api_key)
|
public RestClient(string base_url, string api_key)
|
||||||
: this(api_key, new HttpClientWrapper.HttpClientWrapper() {BaseAddress = new Uri(base_url)})
|
{
|
||||||
{ }
|
Log.Debug("REST: Creating new rest client. Base url: {base_url}", base_url);
|
||||||
|
httpClient = new HttpClient(){
|
||||||
|
BaseAddress=new Uri(base_url)
|
||||||
|
};
|
||||||
|
httpClient.DefaultRequestHeaders.Add("Authorization", $"Bot {api_key}");
|
||||||
|
httpClient.DefaultRequestHeaders.Add("User-Agent", $"DiscordBot ({StaticProperties.LibraryWebsite}, {StaticProperties.LibraryVersion})");
|
||||||
|
}
|
||||||
|
|
||||||
internal RestClient(string api_key, IHttpClientWrapper http_client){
|
internal RestClient(string base_url, string api_key, HttpMessageHandler msg_handler){
|
||||||
Log.Debug("REST: Creating new rest client. Base url: {base_url}", http_client.BaseAddress?.AbsoluteUri);
|
Log.Debug("REST: Creating new rest client. Base url: {base_url}", base_url);
|
||||||
httpClient = http_client;
|
httpClient = new HttpClient(msg_handler){
|
||||||
|
BaseAddress=new Uri(base_url)
|
||||||
|
};
|
||||||
httpClient.DefaultRequestHeaders.Add("Authorization", $"Bot {api_key}");
|
httpClient.DefaultRequestHeaders.Add("Authorization", $"Bot {api_key}");
|
||||||
httpClient.DefaultRequestHeaders.Add("User-Agent", $"DiscordBot ({StaticProperties.LibraryWebsite}, {StaticProperties.LibraryVersion})");
|
httpClient.DefaultRequestHeaders.Add("User-Agent", $"DiscordBot ({StaticProperties.LibraryWebsite}, {StaticProperties.LibraryVersion})");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
public readonly struct RestError
|
public readonly struct RestError
|
||||||
{
|
{
|
||||||
public required int Code {get; init;}
|
public int? Code {get; init;}
|
||||||
public required string Message {get; init;}
|
public required string Message {get; init;}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user