Files
seerr-autoapprove/tests/SeerrAutoApprove.Tests/SeerrClientTests.cs
T
Arne Moerman de189d0c47
Build and Push Docker Image / build-and-push (push) Successful in 1m45s
first commit
2026-10-06 16:54:39 +02:00

110 lines
4.2 KiB
C#

using System.Net;
using System.Text;
using SeerrAutoApprove.Seerr;
namespace SeerrAutoApprove.Tests;
public sealed class SeerrClientTests
{
private sealed class StubHandler(Func<HttpRequestMessage, HttpResponseMessage> respond) : HttpMessageHandler
{
public List<HttpRequestMessage> Requests { get; } = [];
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
Requests.Add(request);
return Task.FromResult(respond(request));
}
}
private sealed class StubFactory(HttpMessageHandler handler) : IHttpClientFactory
{
public HttpClient CreateClient(string name) =>
new(handler, disposeHandler: false) { BaseAddress = new Uri("http://seerr.local/api/v1/") };
}
private static HttpResponseMessage Json(string json) =>
new(HttpStatusCode.OK) { Content = new StringContent(json, Encoding.UTF8, "application/json") };
[Fact]
public async Task Parses_pending_requests_across_pages()
{
const string page1 = """
{
"pageInfo": { "pages": 2, "pageSize": 1, "results": 2, "page": 1 },
"results": [
{
"id": 11, "status": 1, "type": "movie", "is4k": false,
"createdAt": "2026-10-01T10:00:00.000Z",
"requestedBy": { "id": 3, "displayName": "Alice", "email": "alice@example.com" },
"media": { "id": 5, "tmdbId": 603, "mediaType": "movie" },
"seasons": []
}
]
}
""";
const string page2 = """
{
"pageInfo": { "pages": 2, "pageSize": 1, "results": 2, "page": 2 },
"results": [
{
"id": 12, "status": 1, "type": "tv", "is4k": true,
"createdAt": "2026-10-02T10:00:00.000Z",
"requestedBy": { "id": 4, "displayName": "Bob" },
"media": { "id": 6, "tmdbId": 1399, "mediaType": "tv" },
"seasons": [ { "id": 1, "seasonNumber": 1 }, { "id": 2, "seasonNumber": 2 } ]
}
]
}
""";
var handler = new StubHandler(req => Json(req.RequestUri!.Query.Contains("skip=0") ? page1 : page2));
var client = new SeerrClient(new StubFactory(handler));
var requests = await client.GetPendingRequestsAsync(CancellationToken.None);
Assert.Equal(2, requests.Count);
Assert.Equal(11, requests[0].Id);
Assert.False(requests[0].IsSeries);
Assert.Equal(3, requests[0].RequestedBy!.Id);
Assert.Equal(12, requests[1].Id);
Assert.True(requests[1].IsSeries);
Assert.True(requests[1].Is4k);
Assert.Equal(2, requests[1].Seasons.Count);
Assert.All(handler.Requests, r => Assert.Contains("filter=pending", r.RequestUri!.Query));
Assert.Equal("/api/v1/request", handler.Requests[0].RequestUri!.AbsolutePath);
}
[Fact]
public async Task Returns_empty_list_when_nothing_pending()
{
var handler = new StubHandler(_ => Json("""{ "pageInfo": { "pages": 0, "page": 1, "results": 0 }, "results": [] }"""));
var requests = await new SeerrClient(new StubFactory(handler)).GetPendingRequestsAsync(CancellationToken.None);
Assert.Empty(requests);
Assert.Single(handler.Requests);
}
[Fact]
public async Task Approve_posts_to_approve_endpoint()
{
var handler = new StubHandler(_ => Json("{}"));
await new SeerrClient(new StubFactory(handler)).ApproveRequestAsync(42, CancellationToken.None);
var request = Assert.Single(handler.Requests);
Assert.Equal(HttpMethod.Post, request.Method);
Assert.Equal("/api/v1/request/42/approve", request.RequestUri!.AbsolutePath);
}
[Fact]
public async Task Approve_throws_on_error_status()
{
var handler = new StubHandler(_ => new HttpResponseMessage(HttpStatusCode.Conflict));
await Assert.ThrowsAsync<HttpRequestException>(() =>
new SeerrClient(new StubFactory(handler)).ApproveRequestAsync(42, CancellationToken.None));
}
}