using GmRelay.Shared.Domain; using GmRelay.Shared.Rendering; using Telegram.Bot.Types.ReplyMarkups; namespace GmRelay.Bot.Tests.Rendering; public sealed class TelegramSessionBatchRendererTests { [Fact] public void Render_ShouldProduceSameTextAsOldRenderer() { var firstSessionId = Guid.NewGuid(); var secondSessionId = Guid.NewGuid(); var cancelledSessionId = Guid.NewGuid(); var sessions = new[] { new SessionBatchDto(secondSessionId, new DateTime(2026, 4, 27, 18, 0, 0, DateTimeKind.Utc), SessionStatus.Planned, 4), new SessionBatchDto(cancelledSessionId, new DateTime(2026, 4, 28, 18, 0, 0, DateTimeKind.Utc), SessionStatus.Cancelled, null), new SessionBatchDto(firstSessionId, new DateTime(2026, 4, 26, 18, 0, 0, DateTimeKind.Utc), SessionStatus.Planned, 2) }; var participants = new[] { new ParticipantBatchDto(secondSessionId, "Alice", "alice", ParticipantRegistrationStatus.Active), new ParticipantBatchDto(secondSessionId, "Charlie", null, ParticipantRegistrationStatus.Waitlisted), new ParticipantBatchDto(cancelledSessionId, "Bob", null, ParticipantRegistrationStatus.Active) }; // Old renderer output var (oldText, oldMarkup) = SessionBatchRenderer.Render("Campaign", sessions, participants); // New pipeline output var view = SessionBatchViewBuilder.Build("Campaign", sessions, participants); var (newText, newMarkup) = TelegramSessionBatchRenderer.Render(view); Assert.Equal(oldText, newText); } [Fact] public void Render_ShouldProduceSameButtonsAsOldRenderer() { var firstSessionId = Guid.NewGuid(); var secondSessionId = Guid.NewGuid(); var cancelledSessionId = Guid.NewGuid(); var sessions = new[] { new SessionBatchDto(secondSessionId, new DateTime(2026, 4, 27, 18, 0, 0, DateTimeKind.Utc), SessionStatus.Planned, 4), new SessionBatchDto(cancelledSessionId, new DateTime(2026, 4, 28, 18, 0, 0, DateTimeKind.Utc), SessionStatus.Cancelled, null), new SessionBatchDto(firstSessionId, new DateTime(2026, 4, 26, 18, 0, 0, DateTimeKind.Utc), SessionStatus.Planned, 2) }; var participants = new[] { new ParticipantBatchDto(secondSessionId, "Alice", "alice", ParticipantRegistrationStatus.Active), new ParticipantBatchDto(secondSessionId, "Charlie", null, ParticipantRegistrationStatus.Waitlisted), new ParticipantBatchDto(cancelledSessionId, "Bob", null, ParticipantRegistrationStatus.Active) }; var (_, oldMarkup) = SessionBatchRenderer.Render("Campaign", sessions, participants); var view = SessionBatchViewBuilder.Build("Campaign", sessions, participants); var (_, newMarkup) = TelegramSessionBatchRenderer.Render(view); var oldButtons = oldMarkup.InlineKeyboard.SelectMany(row => row).ToList(); var newButtons = newMarkup.InlineKeyboard.SelectMany(row => row).ToList(); Assert.Equal(oldButtons.Count, newButtons.Count); for (int i = 0; i < oldButtons.Count; i++) { Assert.Equal(oldButtons[i].CallbackData, newButtons[i].CallbackData); Assert.Equal(oldButtons[i].Text, newButtons[i].Text); } } [Fact] public void Render_ShouldSkipButtonsForCancelledSessions() { var cancelledSessionId = Guid.NewGuid(); var sessions = new[] { new SessionBatchDto(cancelledSessionId, DateTime.UtcNow, SessionStatus.Cancelled, null) }; var participants = Array.Empty(); var view = SessionBatchViewBuilder.Build("Test", sessions, participants); var (_, markup) = TelegramSessionBatchRenderer.Render(view); Assert.Empty(markup.InlineKeyboard); } [Fact] public void Render_ShouldShowWaitlistButtonWhenFull() { var sessionId = Guid.NewGuid(); var sessions = new[] { new SessionBatchDto(sessionId, DateTime.UtcNow, SessionStatus.Planned, 1) }; var participants = new[] { new ParticipantBatchDto(sessionId, "Alice", "alice", ParticipantRegistrationStatus.Active) }; var view = SessionBatchViewBuilder.Build("Test", sessions, participants); var (_, markup) = TelegramSessionBatchRenderer.Render(view); var buttons = markup.InlineKeyboard.SelectMany(row => row).ToList(); var joinButton = buttons.First(b => b.CallbackData?.StartsWith("join_session:") == true); Assert.Contains("ожидания", joinButton.Text); } }