e791fc2f4a
PR Checks / test-and-build (pull_request) Successful in 5m3s
Convert join/leave interaction commands to PlatformUser, PlatformGroup, and PlatformMessageRef. Persist and look up participants by platform identity while keeping Telegram callbacks intact. Add V017 migration and TDD coverage. Bump version to 2.1.1.
128 lines
5.7 KiB
C#
128 lines
5.7 KiB
C#
namespace GmRelay.Bot.Tests.Infrastructure.Database;
|
|
|
|
public sealed class PlatformIdentityMigrationTests
|
|
{
|
|
[Fact]
|
|
public async Task MigrationV016_ShouldAddPlatformIdentityColumns()
|
|
{
|
|
var migration = await ReadRepositoryFileAsync("src/GmRelay.Bot/Migrations/V016__add_platform_identity.sql");
|
|
|
|
Assert.Contains("players", migration, StringComparison.Ordinal);
|
|
Assert.Contains("platform", migration, StringComparison.Ordinal);
|
|
Assert.Contains("external_user_id", migration, StringComparison.Ordinal);
|
|
Assert.Contains("external_username", migration, StringComparison.Ordinal);
|
|
|
|
Assert.Contains("game_groups", migration, StringComparison.Ordinal);
|
|
Assert.Contains("external_group_id", migration, StringComparison.Ordinal);
|
|
Assert.Contains("external_channel_id", migration, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task MigrationV016_ShouldCreatePlatformMessagesTable()
|
|
{
|
|
var migration = await ReadRepositoryFileAsync("src/GmRelay.Bot/Migrations/V016__add_platform_identity.sql");
|
|
|
|
Assert.Contains("CREATE TABLE platform_messages", migration, StringComparison.Ordinal);
|
|
Assert.Contains("platform", migration, StringComparison.Ordinal);
|
|
Assert.Contains("group_id", migration, StringComparison.Ordinal);
|
|
Assert.Contains("batch_id", migration, StringComparison.Ordinal);
|
|
Assert.Contains("session_id", migration, StringComparison.Ordinal);
|
|
Assert.Contains("external_thread_id", migration, StringComparison.Ordinal);
|
|
Assert.Contains("external_message_id", migration, StringComparison.Ordinal);
|
|
Assert.Contains("purpose", migration, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task MigrationV016_ShouldBackfillExistingTelegramData()
|
|
{
|
|
var migration = await ReadRepositoryFileAsync("src/GmRelay.Bot/Migrations/V016__add_platform_identity.sql");
|
|
|
|
Assert.Contains("UPDATE players", migration, StringComparison.Ordinal);
|
|
Assert.Contains("UPDATE game_groups", migration, StringComparison.Ordinal);
|
|
Assert.Contains("'Telegram'", migration, StringComparison.Ordinal);
|
|
Assert.Contains("telegram_id", migration, StringComparison.Ordinal);
|
|
Assert.Contains("telegram_chat_id", migration, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task MigrationV016_ShouldNotDropLegacyTelegramColumns()
|
|
{
|
|
var migration = await ReadRepositoryFileAsync("src/GmRelay.Bot/Migrations/V016__add_platform_identity.sql");
|
|
|
|
Assert.DoesNotContain("DROP COLUMN telegram_id", migration, StringComparison.OrdinalIgnoreCase);
|
|
Assert.DoesNotContain("DROP COLUMN telegram_chat_id", migration, StringComparison.OrdinalIgnoreCase);
|
|
Assert.DoesNotContain("DROP COLUMN telegram_username", migration, StringComparison.OrdinalIgnoreCase);
|
|
Assert.DoesNotContain("DROP COLUMN gm_telegram_id", migration, StringComparison.OrdinalIgnoreCase);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Code_ShouldQueryPlayersUsingExternalUserIdFallback()
|
|
{
|
|
var createHandler = await ReadRepositoryFileAsync("src/GmRelay.Bot/Features/Sessions/CreateSession/CreateSessionHandler.cs");
|
|
|
|
Assert.Contains("external_user_id", createHandler, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Code_ShouldQueryGroupsUsingExternalGroupIdFallback()
|
|
{
|
|
var createHandler = await ReadRepositoryFileAsync("src/GmRelay.Bot/Features/Sessions/CreateSession/CreateSessionHandler.cs");
|
|
|
|
Assert.Contains("external_group_id", createHandler, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task JoinSessionHandler_ShouldDualWritePlatformIdentity()
|
|
{
|
|
var handler = await ReadRepositoryFileAsync("src/GmRelay.Bot/Features/Sessions/CreateSession/JoinSessionHandler.cs");
|
|
|
|
Assert.Contains("external_user_id", handler, StringComparison.Ordinal);
|
|
Assert.Contains("external_username", handler, StringComparison.Ordinal);
|
|
Assert.Contains("platform", handler, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task WebSessionService_ShouldDualWritePlatformIdentity()
|
|
{
|
|
var service = await ReadRepositoryFileAsync("src/GmRelay.Web/Services/SessionService.cs");
|
|
|
|
Assert.Contains("external_user_id", service, StringComparison.Ordinal);
|
|
Assert.Contains("external_username", service, StringComparison.Ordinal);
|
|
Assert.Contains("platform", service, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task AttendanceStatsFunction_ShouldReferenceExternalUsername()
|
|
{
|
|
var statsMigration = await ReadRepositoryFileAsync("src/GmRelay.Bot/Migrations/V012__add_attendance_stats.sql");
|
|
|
|
Assert.Contains("external_username", statsMigration, StringComparison.Ordinal);
|
|
}
|
|
|
|
[Fact]
|
|
public async Task MigrationV017_ShouldAllowPlayersWithoutLegacyTelegramId()
|
|
{
|
|
var migration = await ReadRepositoryFileAsync("src/GmRelay.Bot/Migrations/V017__allow_platform_neutral_players.sql");
|
|
|
|
Assert.Contains("ALTER TABLE players", migration, StringComparison.Ordinal);
|
|
Assert.Contains("telegram_id DROP NOT NULL", migration, StringComparison.Ordinal);
|
|
}
|
|
|
|
private static async Task<string> ReadRepositoryFileAsync(string relativePath)
|
|
{
|
|
var directory = new DirectoryInfo(AppContext.BaseDirectory);
|
|
while (directory is not null)
|
|
{
|
|
var candidate = Path.Combine(directory.FullName, relativePath);
|
|
if (File.Exists(candidate))
|
|
{
|
|
return await File.ReadAllTextAsync(candidate);
|
|
}
|
|
|
|
directory = directory.Parent;
|
|
}
|
|
|
|
throw new FileNotFoundException($"Could not locate repository file '{relativePath}'.");
|
|
}
|
|
}
|