using System.Net; using System.Net.Http.Json; using System.Text.Json; using System.Text.Json.Serialization; using OpenNest.Data; namespace OpenNest.Desktop.Tests; /// /// A nest server's /api/settings in memory: lists, creates and replaces documents, or refuses /// every request as an unreachable server while is false. /// internal sealed class FakeSettingsServer : HttpMessageHandler { public const string Url = "http://settings.test/"; // The server's JSON shape: camel-case names and enum names. private static readonly JsonSerializerOptions JsonOptions = new() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, PropertyNameCaseInsensitive = true, Converters = { new JsonStringEnumConverter(JsonNamingPolicy.CamelCase) }, }; public List Records { get; } = []; public bool Online { get; set; } = true; public int Reads { get; private set; } public void Hold(string kind, string key, string json) => Records.Add(new SharedSettingRecord { Kind = kind, Key = key, Json = json, Revision = 1, SavedAt = DateTime.Now }); /// A source in Database mode on this server, keeping its last copy in . public SharedSettingsSource Source(string cachePath) => new(() => new NestStorageSettings { Mode = NestStorageMode.Database, ServerUrl = Url }, url => new SharedSettingsStore(new RemoteSharedSettings(new HttpClient(this, disposeHandler: false), url), cachePath, "tester")); protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (!Online) throw new HttpRequestException("No route to the nest server."); var path = request.RequestUri!.AbsolutePath.Trim('/').Split('/').Select(Uri.UnescapeDataString).ToArray(); if (request.Method == HttpMethod.Get && path is ["api", "settings"]) { Reads++; return JsonResponse(HttpStatusCode.OK, Records); } if (path is ["api", "settings", var kind, var key] && (request.Method == HttpMethod.Post || request.Method == HttpMethod.Put)) { var write = await request.Content!.ReadFromJsonAsync(JsonOptions, cancellationToken); var current = Records.FirstOrDefault(r => r.Kind == kind && r.Key == key); var saved = new SharedSettingRecord { Kind = kind, Key = key, Json = write!.Json, Revision = (current?.Revision ?? 0) + 1, SavedAt = DateTime.Now, SavedBy = write.SavedBy, }; if (current != null) Records.Remove(current); Records.Add(saved); return JsonResponse(current == null ? HttpStatusCode.Created : HttpStatusCode.OK, saved); } return new HttpResponseMessage(HttpStatusCode.NotFound); } private static HttpResponseMessage JsonResponse(HttpStatusCode status, T body) => new(status) { Content = JsonContent.Create(body, options: JsonOptions) }; } /// The two machine user settings in memory. internal sealed class MemoryUserSettings : IMachineUserSettings { public Units DefaultUnit { get; set; } = Units.Inches; public string CuttingParametersJson { get; set; } = ""; public int Saves { get; private set; } string IMachineUserSettings.CuttingParametersJson { get => CuttingParametersJson; set { CuttingParametersJson = value; Saves++; } } }