using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace Jellyfin.Plugin.Floatplane.Tests;
/// Maps request URLs (prefix match on path, or a predicate) to canned responses and records requests.
internal sealed class FakeHttpHandler : HttpMessageHandler
{
private readonly List<(Func Match, Func Respond)> _routes = new();
public List Requests { get; } = new();
public FakeHttpHandler On(string pathPrefix, Func respond)
{
_routes.Add((r => r.RequestUri!.AbsolutePath.StartsWith(pathPrefix, StringComparison.Ordinal), respond));
return this;
}
public FakeHttpHandler On(Func match, Func respond)
{
_routes.Add((match, respond));
return this;
}
public static HttpResponseMessage Json(string body, HttpStatusCode status = HttpStatusCode.OK)
=> new(status) { Content = new StringContent(body, System.Text.Encoding.UTF8, "application/json") };
protected override Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
Requests.Add(request);
foreach (var (match, respond) in _routes)
{
if (match(request))
{
var response = respond(request);
response.RequestMessage = request;
return Task.FromResult(response);
}
}
var notFound = new HttpResponseMessage(HttpStatusCode.NotFound) { RequestMessage = request, Content = new StringContent("no route for " + request.RequestUri) };
return Task.FromResult(notFound);
}
}
/// Mirrors the registrator: one named client with the plugin User-Agent.
internal sealed class FakeHttpClientFactory : IHttpClientFactory
{
private readonly HttpMessageHandler _handler;
public FakeHttpClientFactory(HttpMessageHandler handler)
{
_handler = handler;
}
public HttpClient CreateClient(string name)
{
var client = new HttpClient(_handler, disposeHandler: false);
client.DefaultRequestHeaders.UserAgent.ParseAdd(Plugin.UserAgent);
return client;
}
}