using System.Net.Http.Headers; using System.Net.Http.Json; using System.Text; using System.Text.Json; namespace Azaion.E2E.Helpers; public sealed class ApiClient : IDisposable { private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, PropertyNameCaseInsensitive = true }; private readonly HttpClient _httpClient; private readonly bool _disposeClient; public ApiClient(HttpClient httpClient, bool disposeClient = false) { _httpClient = httpClient; _disposeClient = disposeClient; } public void Dispose() { if (_disposeClient) _httpClient.Dispose(); } public void SetAuthToken(string token) { _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); } public async Task LoginAsync(string email, string password, CancellationToken cancellationToken = default) { using var response = await PostAsync("/login", new { email, password }, cancellationToken).ConfigureAwait(false); response.EnsureSuccessStatusCode(); var body = await response.Content.ReadFromJsonAsync(JsonOptions, cancellationToken) .ConfigureAwait(false); if (body?.Token is not { Length: > 0 } t) throw new InvalidOperationException("Login response did not contain a token."); return t; } public Task PostAsync(string url, T body, CancellationToken cancellationToken = default) { var json = JsonSerializer.Serialize(body, JsonOptions); var content = new StringContent(json, Encoding.UTF8, "application/json"); return _httpClient.PostAsync(url, content, cancellationToken); } public Task GetAsync(string url, CancellationToken cancellationToken = default) => _httpClient.GetAsync(url, cancellationToken); public Task PutAsync(string url, CancellationToken cancellationToken = default) => _httpClient.PutAsync(url, null, cancellationToken); public Task PutAsync(string url, T body, CancellationToken cancellationToken = default) { var json = JsonSerializer.Serialize(body, JsonOptions); var content = new StringContent(json, Encoding.UTF8, "application/json"); return _httpClient.PutAsync(url, content, cancellationToken); } public Task DeleteAsync(string url, CancellationToken cancellationToken = default) => _httpClient.DeleteAsync(url, cancellationToken); public Task UploadFileAsync(string url, byte[] fileContent, string fileName, string formFieldName = "data", CancellationToken cancellationToken = default) { var content = new MultipartFormDataContent(); var fileContentBytes = new ByteArrayContent(fileContent); fileContentBytes.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream"); content.Add(fileContentBytes, formFieldName, fileName); return _httpClient.PostAsync(url, content, cancellationToken); } private sealed class LoginResponse { public string Token { get; init; } = ""; } }