using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace ManagerService.Tests.Infrastructure
{
///
/// Fabrique d'HttpClient sans réseau, pour les chemins qui sondent le poids d'un blob
/// par HEAD (ResourceSizeProbe). Les tailles sont données par URL ; une URL
/// absente de la table répond sans Content-Length, ce qui est exactement le cas
/// « blob introuvable » que le backfill doit inventorier au lieu de le compter pour zéro.
///
public class FakeHttpClientFactory : IHttpClientFactory
{
private readonly IDictionary _sizesByUrl;
private readonly ISet _throwingUrls;
public FakeHttpClientFactory(IDictionary sizesByUrl = null, ISet throwingUrls = null)
{
_sizesByUrl = sizesByUrl ?? new Dictionary();
_throwingUrls = throwingUrls ?? new HashSet();
}
public HttpClient CreateClient(string name = "") =>
new HttpClient(new StubHandler(_sizesByUrl, _throwingUrls));
private class StubHandler : HttpMessageHandler
{
private readonly IDictionary _sizesByUrl;
private readonly ISet _throwingUrls;
public StubHandler(IDictionary sizesByUrl, ISet throwingUrls)
{
_sizesByUrl = sizesByUrl;
_throwingUrls = throwingUrls;
}
protected override Task SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
{
var url = request.RequestUri!.ToString();
if (_throwingUrls.Contains(url))
throw new HttpRequestException("hôte injoignable");
var response = new HttpResponseMessage(HttpStatusCode.OK);
if (_sizesByUrl.TryGetValue(url, out var size))
{
// Content-Length ne se pose que sur un contenu : un HEAD réel renvoie
// l'en-tête sans le corps, ce que StringContent + la longueur imite
// suffisamment pour la sonde, qui ne lit que l'en-tête.
response.Content = new ByteArrayContent(Array.Empty());
response.Content.Headers.ContentLength = size;
}
else
{
response.StatusCode = HttpStatusCode.NotFound;
response.Content = new ByteArrayContent(Array.Empty());
response.Content.Headers.ContentLength = null;
}
return Task.FromResult(response);
}
}
}
}