This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user