diff --git a/src/GmRelay.Bot/Infrastructure/Telegram/TelegramPlatformMessenger.cs b/src/GmRelay.Bot/Infrastructure/Telegram/TelegramPlatformMessenger.cs index 067d0d5..3171238 100644 --- a/src/GmRelay.Bot/Infrastructure/Telegram/TelegramPlatformMessenger.cs +++ b/src/GmRelay.Bot/Infrastructure/Telegram/TelegramPlatformMessenger.cs @@ -59,16 +59,24 @@ public sealed class TelegramPlatformMessenger( public async Task UpdateScheduleAsync(PlatformScheduleMessage message, CancellationToken ct) { EnsureTelegram(message.Group.Platform); - if (message.ExistingMessage is null) + var existingMessage = message.ExistingMessage; + if (existingMessage is null) { throw new ArgumentException("Existing schedule message reference is required.", nameof(message)); } + EnsureTelegram(existingMessage.Platform); + if (!string.Equals(message.Group.ExternalGroupId, existingMessage.ExternalGroupId, StringComparison.Ordinal) || + !string.Equals(message.Group.ExternalThreadId, existingMessage.ExternalThreadId, StringComparison.Ordinal)) + { + throw new ArgumentException("Existing schedule message reference must match the schedule group.", nameof(message)); + } + var renderResult = TelegramSessionBatchRenderer.Render(message.View); await BatchMessageEditor.EditBatchMessageAsync( bot, - chatId: ParseLong(message.Group.ExternalGroupId), - messageId: ParseInt(message.ExistingMessage.ExternalMessageId), + chatId: ParseLong(existingMessage.ExternalGroupId), + messageId: ParseInt(existingMessage.ExternalMessageId), text: renderResult.Text, replyMarkup: renderResult.Markup, ct); diff --git a/tests/GmRelay.Bot.Tests/Infrastructure/Telegram/TelegramPlatformMessengerTests.cs b/tests/GmRelay.Bot.Tests/Infrastructure/Telegram/TelegramPlatformMessengerTests.cs new file mode 100644 index 0000000..7652435 --- /dev/null +++ b/tests/GmRelay.Bot.Tests/Infrastructure/Telegram/TelegramPlatformMessengerTests.cs @@ -0,0 +1,44 @@ +using GmRelay.Bot.Infrastructure.Telegram; +using GmRelay.Shared.Platform; +using GmRelay.Shared.Rendering; +using Microsoft.Extensions.Logging.Abstractions; + +namespace GmRelay.Bot.Tests.Infrastructure.Telegram; + +public sealed class TelegramPlatformMessengerTests +{ + [Fact] + public async Task UpdateScheduleAsync_ShouldRejectNonTelegramExistingMessageReference() + { + var messenger = CreateMessenger(); + var message = new PlatformScheduleMessage( + new PlatformGroup(PlatformKind.Telegram, "100", "Telegram group"), + CreateView(), + new PlatformMessageRef(PlatformKind.Discord, "100", null, "200")); + + await Assert.ThrowsAsync( + () => messenger.UpdateScheduleAsync(message, CancellationToken.None)); + } + + [Fact] + public async Task UpdateScheduleAsync_ShouldRejectMismatchedGroupAndExistingMessageReference() + { + var messenger = CreateMessenger(); + var message = new PlatformScheduleMessage( + new PlatformGroup(PlatformKind.Telegram, "100", "Telegram group", ExternalThreadId: "7"), + CreateView(), + new PlatformMessageRef(PlatformKind.Telegram, "101", "7", "200")); + + var exception = await Assert.ThrowsAsync( + () => messenger.UpdateScheduleAsync(message, CancellationToken.None)); + + Assert.Equal("message", exception.ParamName); + Assert.Contains("Existing schedule message reference must match the schedule group.", exception.Message); + } + + private static TelegramPlatformMessenger CreateMessenger() => + new(null!, NullLogger.Instance); + + private static SessionBatchViewModel CreateView() => + new("Test batch", []); +}