157 lines
5.1 KiB
C#
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);
|
|
}
|
|
}
|