using System.IO.Compression;
using System.Net.Http.Json;
using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using OpenNest.Data;
namespace OpenNest.Server.Tests;
/// Neutral, code-built drawing library fixtures for the server tests.
internal static class DrawingLibraryFixtures
{
public static readonly JsonSerializerOptions Options = new(JsonSerializerDefaults.Web)
{ Converters = { new JsonStringEnumConverter() } };
public static DrawingLibraryRecord Record(string name = "Synthetic bracket", Guid? id = null) => new()
{
Id = id ?? Guid.NewGuid(),
Name = name,
Customer = "Synthetic customer",
MaterialName = "Synthetic Steel",
MaterialGrade = "Grade A",
Thickness = 0.25,
Units = Units.Inches,
CutType = CutType.Laser,
Notes = "Synthetic notes",
SavedBy = "Synthetic operator",
};
/// A real ZIP archive whose single entry holds .
public static byte[] Package(string content = "synthetic")
{
using var buffer = new MemoryStream();
using (var archive = new ZipArchive(buffer, ZipArchiveMode.Create, leaveOpen: true))
{
var entry = archive.CreateEntry("nest.json");
entry.LastWriteTime = new DateTimeOffset(2026, 1, 1, 0, 0, 0, TimeSpan.Zero);
using var stream = entry.Open();
stream.Write(Encoding.UTF8.GetBytes(content));
}
return buffer.ToArray();
}
public static string Sha256(byte[] bytes) => Convert.ToHexString(SHA256.HashData(bytes)).ToLowerInvariant();
public static MultipartFormDataContent Body(string metadataJson, byte[]? package)
{
var body = new MultipartFormDataContent();
body.Add(new StringContent(metadataJson), "metadata");
if (package is not null)
body.Add(new ByteArrayContent(package), "package", "drawing.nest");
return body;
}
public static MultipartFormDataContent Body(DrawingLibraryRecord record, byte[]? package) =>
Body(JsonSerializer.Serialize(record, Options), package);
public static async Task Upload(HttpClient client, DrawingLibraryRecord record, byte[] package)
{
using var response = await client.PostAsync("/api/drawings", Body(record, package));
response.EnsureSuccessStatusCode();
return (await response.Content.ReadFromJsonAsync(Options))!;
}
public static HttpRequestMessage Guarded(HttpMethod method, string url, string? ifMatch, HttpContent? content = null)
{
var request = new HttpRequestMessage(method, url) { Content = content };
if (ifMatch is not null)
request.Headers.TryAddWithoutValidation("If-Match", ifMatch);
return request;
}
}