XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Text.Json;
using XFEExtension.NetCore.XUnit.Attributes;
using XFEEDToolBox.Core.Data;
using XFEEDToolBox.Core.Models;

namespace XFEEDToolBox.Test;

[TestFixture]
public class ObservedFixtureTests
{
    [Test] public void ParsesCapturedListAndTradeResponseFields()
    {
        using var doc = JsonDocument.Parse(File.ReadAllText(Path.Combine(AppContext.BaseDirectory, "Fixtures", "captured-commodities.json")));
        var samples = doc.RootElement.EnumerateArray().ToArray(); Check.Equal(2, samples.Length);
        foreach (var sample in samples)
        {
            var time = sample.Time("observedAt")!.Value;
            var quotes = sample.Get("commodities").Items().Select(x => MarketParser.ParseQuote(x, 3224123392, time, DataSource.Capture)).ToArray();
            Check.Equal("platinum", quotes[0].Commodity); Check.Equal(223785L, quotes[0].SellPrice); Check.Equal(time, quotes[0].CollectedAt);
            Check.That(quotes.All(q => q.Source == DataSource.Capture));
        }
    }
}

[TestFixture, Explicit("Reads user supplied evidence / external public data; opt in manually.")]
public class LiveIntegrationTests
{
    private static void Save(string file, object result)
    {
        var folder = Path.GetFullPath(Path.Combine("artifacts", "integration")); Directory.CreateDirectory(folder);
        File.WriteAllText(Path.Combine(folder, file), JsonSerializer.Serialize(result, ToolboxSettings.JsonOptions));
    }
    [Test] public async Task ImportsActualCaptureArchive()
    {
        var path = Environment.GetEnvironmentVariable("XFE_ED_CAPTURE") ?? throw new InvalidOperationException("Set XFE_ED_CAPTURE to the provided capture archive.");
        using var temp = new TemporaryDirectory(); var repo = temp.Repository();
        var count = await CaptureImporter.ImportAsync(path, repo);
        var rows = repo.Search("", 3224123392, 0, 1000);
        Save("capture-import.json", new { count.Stations, count.Quotes, storedQuotes = rows.Count, onlyHistorical = rows.All(x => x.Quote.Source == DataSource.Capture), importedInventory = false });
        Check.Equal(1, count.Stations); Check.Equal(404, rows.Count); Check.That(rows.All(x => x.Quote.Source == DataSource.Capture));
    }
    [Test] public async Task ReadsActualLocalJournal()
    {
        await using var monitor = new JournalMonitor(new ToolboxSettings().JournalDirectory);
        var quoteCount = 0; monitor.MarketChanged += m => quoteCount = m.Quotes.Count;
        await monitor.StartAsync();
        var p = monitor.State; var active = p.Ships.FirstOrDefault(x => x.ShipId == p.CurrentShipId);
        JsonElement expectedLoadout = default;
        foreach (var path in Directory.EnumerateFiles(monitor.DirectoryPath, "Journal.*.log").Order(StringComparer.Ordinal))
        {
            using var file = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete);
            using var reader = new StreamReader(file);
            while (await reader.ReadLineAsync() is { } line)
            {
                try
                {
                    using var doc = JsonDocument.Parse(line);
                    var e = doc.RootElement;
                    if (e.Text("event") == "Loadout" && e.Long("ShipID", -1) == p.CurrentShipId && e.Time() <= p.UpdatedAt) expectedLoadout = e.Clone();
                }
                catch (JsonException) { }
            }
        }
        var expectedModules = expectedLoadout.Get("Modules").EnumerateArray().ToArray();
        Check.Equal(expectedModules.Length, active!.Modules.Count);
        for (var i = 0; i < expectedModules.Length; i++)
        {
            var raw = expectedModules[i]; var parsed = active.Modules[i];
            Check.Equal(raw.GetProperty("Slot").GetString(), parsed.Slot); Check.Equal(raw.GetProperty("Item").GetString(), parsed.Item);
            Check.Equal(raw.GetProperty("On").GetBoolean(), parsed.Enabled); Check.Equal(raw.GetProperty("Priority").GetInt32(), parsed.Priority);
            if (raw.TryGetProperty("Engineering", out var engineering))
            {
                var modifiers = engineering.GetProperty("Modifiers").EnumerateArray().ToArray();
                Check.Equal(modifiers.Length, parsed.Engineering!.Modifiers.Count);
                for (var m = 0; m < modifiers.Length; m++)
                {
                    Check.Equal(modifiers[m].GetProperty("Label").GetString(), parsed.Engineering.Modifiers[m].Label);
                    if (modifiers[m].TryGetProperty("Value", out var value) && value.ValueKind == JsonValueKind.Number) Check.Equal(value.GetDouble(), parsed.Engineering.Modifiers[m].Value!.Value);
                }
            }
        }
        Save("local-journal.json", new { balanceAvailable = p.Credits != null, p.CreditsReliable, capacityAvailable = p.CargoCapacity > 0, cargoItems = p.Inventory.Count, materialItems = p.Materials.Count,
            ships = p.Ships.Count, configuredShips = p.Ships.Count(x => x.ConfigurationAt != null), activeShipType = active?.Type, activeModules = active?.Modules.Count,
            engineeredModules = active?.Modules.Count(x => x.Engineering != null), engineeringParameters = active?.Modules.Sum(x => x.Engineering?.Modifiers.Count ?? 0),
            storedModules = p.StoredModules.Count, quoteCount, eventsRead = monitor.EventsRead, independentlyComparedModules = expectedModules.Length, checks = ReadAcceptance.Build(p, monitor.LocalMarket), updatedAt = p.UpdatedAt, gameBuild = p.GameBuild });
        Check.That(monitor.State.Credits != null); Check.That(quoteCount > 0);
        Check.That(active?.Modules.Count > 0, "Current ship Loadout was not read.");
    }
    [Test] public async Task ReadsActualSpanshSystem()
    {
        using var temp = new TemporaryDirectory(); var repo = temp.Repository(); using var http = new HttpClient { Timeout = TimeSpan.FromSeconds(25) };
        using var timeout = new CancellationTokenSource(TimeSpan.FromSeconds(40));
        var result = await new SpanshImporter(repo, http).ImportSystemAsync("Vaka", token: timeout.Token);
        var origin = repo.GetStation(3224123392);
        Save("spansh.json", new { result.Systems, result.Stations, result.Quotes, originCoordinates = origin?.Position, originSecurity = origin?.Security, originDistanceLs = origin?.DistanceToArrivalLs });
        Check.That(result.Quotes > 0 && origin?.Position != null && origin.Security != SecurityLevel.Unknown);
    }
    [Test] public async Task ReceivesActualEddnStream()
    {
        using var temp = new TemporaryDirectory(); var repo = temp.Repository();
        await using var feed = new EddnSubscriber(repo); feed.Start("tcp://eddn.edcd.io:9500");
        var until = DateTimeOffset.UtcNow.AddSeconds(45);
        while (feed.MarketsAccepted == 0 && DateTimeOffset.UtcNow < until) await Task.Delay(250);
        Save("eddn.json", new { feed.MessagesReceived, feed.MarketsAccepted, feed.Status, feed.LastMessageAt, actualStreamValidated = feed.MessagesReceived > 0, commodityValidated = feed.MarketsAccepted > 0, storedQuotes = repo.Statistics().Quotes });
        Check.That(feed.MarketsAccepted > 0, "No live commodity snapshot was accepted during the 45 second observation window.");
    }
}