110 lines
4.2 KiB
C#
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));
|
|
}
|
|
}
|