Decky/tests/Decky.Core.Tests/DeckApiClientTests.cs
2026-07-19 13:10:55 -07:00

90 lines
3.4 KiB
C#

using System.Net;
using System.Text;
using Decky.Core.Api;
using Decky.Core.Configuration;
namespace Decky.Core.Tests;
public sealed class DeckApiClientTests
{
[Fact]
public void Connection_options_reject_insecure_remote_servers()
{
var exception = Assert.Throws<ArgumentException>(() =>
DeckConnectionOptions.Create("http://cloud.example.test", "elijah", "app-password"));
Assert.Contains("HTTPS", exception.Message, StringComparison.Ordinal);
}
[Fact]
public async Task GetBoardsAsync_sends_required_headers_and_deserializes_response()
{
HttpRequestMessage? capturedRequest = null;
var handler = new StubHttpMessageHandler(request =>
{
capturedRequest = CloneRequest(request);
return JsonResponse("[{\"id\":10,\"title\":\"Homework\",\"color\":\"ff0000\"}]");
});
using var httpClient = new HttpClient(handler);
var options = DeckConnectionOptions.Create("https://cloud.example.test", "elijah", "app-password");
var client = new DeckApiClient(
httpClient,
options,
new Uri("https://cloud.example.test/index.php/apps/deck/api/v1.0/"));
var boards = await client.GetBoardsAsync();
Assert.Single(boards);
Assert.Equal("Homework", boards[0].Title);
Assert.NotNull(capturedRequest);
Assert.Equal(
"https://cloud.example.test/index.php/apps/deck/api/v1.0/boards",
capturedRequest.RequestUri!.ToString());
Assert.Equal("true", capturedRequest.Headers.GetValues("OCS-APIRequest").Single());
Assert.Equal("Basic", capturedRequest.Headers.Authorization!.Scheme);
}
[Fact]
public async Task ConnectAsync_falls_back_to_rewritten_path_after_not_found()
{
var requestedPaths = new List<string>();
var handler = new StubHttpMessageHandler(request =>
{
requestedPaths.Add(request.RequestUri!.AbsolutePath);
return request.RequestUri.AbsolutePath.Contains("/index.php/", StringComparison.Ordinal)
? new HttpResponseMessage(HttpStatusCode.NotFound)
: JsonResponse("[]");
});
using var httpClient = new HttpClient(handler);
var options = DeckConnectionOptions.Create("https://cloud.example.test", "elijah", "app-password");
var client = await DeckApiClient.ConnectAsync(httpClient, options);
Assert.Equal("https://cloud.example.test/apps/deck/api/v1.0/", client.ApiBaseUri.ToString());
Assert.Equal(2, requestedPaths.Count);
}
private static HttpResponseMessage JsonResponse(string json) => new(HttpStatusCode.OK)
{
Content = new StringContent(json, Encoding.UTF8, "application/json"),
};
private static HttpRequestMessage CloneRequest(HttpRequestMessage request)
{
var clone = new HttpRequestMessage(request.Method, request.RequestUri);
foreach (var header in request.Headers)
{
clone.Headers.TryAddWithoutValidation(header.Key, header.Value);
}
return clone;
}
private sealed class StubHttpMessageHandler(
Func<HttpRequestMessage, HttpResponseMessage> responseFactory) : HttpMessageHandler
{
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken) => Task.FromResult(responseFactory(request));
}
}