using System.Text;
using System.Xml;
using Ludarium.Application;
using Ludarium.Domain;
namespace Ludarium.UnitTests;
public sealed class CatalogImportTests
{
[Fact]
public async Task LogiqxImportIsVersionedStreamingAndDeterministic()
{
const string xml = """
""";
var store = new CapturingCatalogStore();
var importer = new LogiqxCatalogImporter(store);
await using var input = new MemoryStream(Encoding.UTF8.GetBytes(xml));
var source = await importer.ImportLogiqxAsync("Synthetic DAT", "2026.07", input, CancellationToken.None);
Assert.Equal("Ready", source.State); Assert.Equal(1, source.EntryCount); Assert.Equal(64, source.Sha256?.Length);
var entry = Assert.Single(store.Entries);
Assert.Equal("Example Game", entry.GameName); Assert.Equal("cbf43926", entry.Crc32);
Assert.Equal(1, store.MatchCalls);
}
[Fact]
public async Task LogiqxImportRejectsDocumentTypes()
{
const string xml = "]>";
var importer = new LogiqxCatalogImporter(new CapturingCatalogStore());
await using var input = new MemoryStream(Encoding.UTF8.GetBytes(xml));
await Assert.ThrowsAsync(() => importer.ImportLogiqxAsync("Hostile", "1", input, CancellationToken.None));
}
private sealed class CapturingCatalogStore : ICatalogStore
{
public List Entries { get; } = [];
public int MatchCalls { get; private set; }
public Task UpsertCatalogSourceAsync(CatalogSource source, CancellationToken cancellationToken) => Task.CompletedTask;
public Task UpsertCatalogEntriesAsync(IReadOnlyList entries, CancellationToken cancellationToken) { Entries.AddRange(entries); return Task.CompletedTask; }
public Task> ListCatalogSourcesAsync(CancellationToken cancellationToken) => Task.FromResult>([]);
public Task MatchCatalogAsync(Guid sourceId, CancellationToken cancellationToken) { MatchCalls++; return Task.FromResult(Entries.Count); }
public Task> ListMatchCandidatesAsync(CancellationToken cancellationToken) => Task.FromResult>([]);
}
}