Files
Ludarium-Public/tests/Ludarium.IntegrationTests/DiscoveredGameTitleTests.cs
T
Ludarium release export df869819ce
Public source validation / source (push) Successful in 2m16s
Publish Ludarium source
2026-09-03 02:08:58 +02:00

73 lines
3.6 KiB
C#

using Ludarium.Application;
using Ludarium.Domain;
using Ludarium.Infrastructure;
using Npgsql;
using Testcontainers.PostgreSql;
namespace Ludarium.IntegrationTests;
/// <summary>
/// The title a scan derives from a file name.
/// </summary>
/// <remarks>
/// The extensions stripped from a derived title were listed separately in SQL from the extensions
/// the identifier recognises, and the two drifted apart: a Mega Drive ROM was identified correctly
/// and then presented as "Sonic Adventure md". Both now read one vocabulary, and a catalog that
/// already carries the old spelling keeps its game rather than gaining a second one.
/// </remarks>
public sealed class DiscoveredGameTitleTests
{
[Fact]
[Trait("Category", "Container")]
public async Task ACartridgeExtensionDoesNotSurviveIntoTheTitle()
{
if (!string.Equals(Environment.GetEnvironmentVariable("LUDARIUM_RUN_CONTAINER_TESTS"), "1", StringComparison.Ordinal))
return;
await using var postgres = new PostgreSqlBuilder("postgres:16.15-bookworm")
.WithDatabase("ludarium_title_test")
.WithUsername("ludarium")
.WithPassword("synthetic-test-password")
.Build();
await postgres.StartAsync();
await using var dataSource = NpgsqlDataSource.Create(postgres.GetConnectionString());
var store = new PostgresStore(dataSource);
await store.InitializeAsync(CancellationToken.None);
var library = LibraryRoot.Create("Title fixture",
Path.GetFullPath(Path.Combine(Path.GetTempPath(), "ludarium-title-library")), LibraryKind.Rom) with
{ IsReadOnly = true, IsAvailable = true };
await store.UpsertLibraryAsync(library, CancellationToken.None);
// The catalog already holds this game under the spelling the old query produced, discovered by
// a scan rather than named by hand: a manually named game keeps the operator's title.
await using (var legacy = dataSource.CreateCommand("""
INSERT INTO games(id,title,version,data,origin)
VALUES(md5('ludarium:game:sonic adventure.md')::uuid, 'Sonic Adventure md', 1,
jsonb_build_object('id', md5('ludarium:game:sonic adventure.md')::uuid,
'title', 'Sonic Adventure md', 'createdAt', now(), 'version', 1, 'origin', 0), 0)
"""))
await legacy.ExecuteNonQueryAsync(CancellationToken.None);
foreach (var (path, platform) in new[]
{
("roms/genesis/Sonic Adventure.md", "genesis"),
("roms/mastersystem/Alex Quest.sms", "mastersystem"),
("roms/gamegear/Pocket Racer.gg", "gamegear"),
})
await store.UpsertArtifactAsync(
new(Guid.NewGuid(), library.Id, path, 65_536, DateTimeOffset.UtcNow.AddDays(-1),
ArtifactState.Present, MediaType.Rom, Confidence.Deterministic, null,
DateTimeOffset.UtcNow.AddDays(-1), DateTimeOffset.UtcNow.AddDays(-1), null, platform),
null, [], CancellationToken.None);
await store.SynchronizeDiscoveredGamesAsync(library.Id, CancellationToken.None);
var catalog = await store.SearchGamesAsync(new GameQuery { PageSize = 50 }, CancellationToken.None);
var titles = catalog.Items.Select(game => game.Title).OrderBy(title => title, StringComparer.Ordinal).ToArray();
Assert.Equal(["Alex Quest", "Pocket Racer", "Sonic Adventure"], titles);
// The pre-existing row was recognised as the same game, so no duplicate was left behind.
Assert.Equal(3, catalog.Total);
}
}