Files
itworx-knowledge-hub-Public/tests/backend/ItWorx.KnowledgeHub.IntegrationTests/Infrastructure/SetupHelper.cs
T

157 lines
5.1 KiB
C#

using System.Net.Http.Json;
using System.Text.Json;
using ItWorx.KnowledgeHub.Contracts.Auth;
using ItWorx.KnowledgeHub.Contracts.Setup;
namespace ItWorx.KnowledgeHub.IntegrationTests.Infrastructure;
public sealed record CsrfToken(string Value, string HeaderName);
/// <summary>Shared helpers so every test class does not re-implement the first-run
/// setup and CSRF handshake used to reach an authenticated state.</summary>
public static class SetupHelper
{
private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web);
public static async Task<CsrfToken> GetCsrfTokenAsync(HttpClient client)
{
var response = await client.GetFromJsonAsync<CsrfTokenResponse>("/api/v1/auth/csrf", JsonOptions)
?? throw new InvalidOperationException("No CSRF token returned.");
return new CsrfToken(response.Token, response.HeaderName);
}
public static async Task<HttpResponseMessage> CompleteFirstRunSetupAsync(
HttpClient client,
string workspaceName,
string displayName,
string email,
string password)
{
var csrf = await GetCsrfTokenAsync(client);
using var request = new HttpRequestMessage(HttpMethod.Post, "/api/v1/setup/complete")
{
Content = JsonContent.Create(
new CompleteSetupRequest(workspaceName, displayName, email, password),
options: JsonOptions)
};
request.Headers.Add(csrf.HeaderName, csrf.Value);
return await client.SendAsync(request);
}
public static async Task<HttpResponseMessage> LoginAsync(HttpClient client, string email, string password)
{
return await client.PostAsJsonAsync(
"/api/v1/auth/login",
new LoginRequest(email, password),
JsonOptions);
}
public static async Task<HttpResponseMessage> PostWithCsrfAsync<TBody>(
HttpClient client,
string path,
TBody body)
{
var csrf = await GetCsrfTokenAsync(client);
using var request = new HttpRequestMessage(HttpMethod.Post, path)
{
Content = JsonContent.Create(body, options: JsonOptions)
};
request.Headers.Add(csrf.HeaderName, csrf.Value);
return await client.SendAsync(request);
}
public static async Task<HttpResponseMessage> PatchWithCsrfAsync<TBody>(
HttpClient client,
string path,
TBody body)
{
var csrf = await GetCsrfTokenAsync(client);
using var request = new HttpRequestMessage(HttpMethod.Patch, path)
{
Content = JsonContent.Create(body, options: JsonOptions)
};
request.Headers.Add(csrf.HeaderName, csrf.Value);
return await client.SendAsync(request);
}
public static async Task<HttpResponseMessage> PutWithCsrfAsync<TBody>(
HttpClient client,
string path,
TBody body,
string? ifMatch = null)
{
var csrf = await GetCsrfTokenAsync(client);
using var request = new HttpRequestMessage(HttpMethod.Put, path)
{
Content = JsonContent.Create(body, options: JsonOptions)
};
request.Headers.Add(csrf.HeaderName, csrf.Value);
if (ifMatch is not null)
{
request.Headers.Add("If-Match", $"\"{ifMatch}\"");
}
return await client.SendAsync(request);
}
public static async Task<HttpResponseMessage> PostWithCsrfAndIfMatchAsync<TBody>(
HttpClient client,
string path,
TBody body,
string ifMatch)
{
var csrf = await GetCsrfTokenAsync(client);
using var request = new HttpRequestMessage(HttpMethod.Post, path)
{
Content = JsonContent.Create(body, options: JsonOptions)
};
request.Headers.Add(csrf.HeaderName, csrf.Value);
request.Headers.Add("If-Match", $"\"{ifMatch}\"");
return await client.SendAsync(request);
}
public static async Task<HttpResponseMessage> DeleteWithCsrfAsync(HttpClient client, string path)
{
var csrf = await GetCsrfTokenAsync(client);
using var request = new HttpRequestMessage(HttpMethod.Delete, path);
request.Headers.Add(csrf.HeaderName, csrf.Value);
return await client.SendAsync(request);
}
public static string? GetETag(HttpResponseMessage response) =>
response.Headers.ETag?.Tag.Trim('"');
public static async Task<HttpResponseMessage> PostMultipartWithCsrfAsync(
HttpClient client,
string path,
byte[] fileBytes,
string fileName,
string contentType)
{
var csrf = await GetCsrfTokenAsync(client);
using var content = new MultipartFormDataContent();
var fileContent = new ByteArrayContent(fileBytes);
fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(contentType);
content.Add(fileContent, "file", fileName);
using var request = new HttpRequestMessage(HttpMethod.Post, path) { Content = content };
request.Headers.Add(csrf.HeaderName, csrf.Value);
return await client.SendAsync(request);
}
}