using GmRelay.Shared.Domain; using GmRelay.Shared.Rendering; namespace GmRelay.Bot.Tests.Rendering; public sealed class SessionBatchViewBuilderTests { [Fact] public void Build_ShouldOrderSessionsByDate() { 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, "https://example.com/game"), 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, "https://example.com/game") }; 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 result = SessionBatchViewBuilder.Build("Campaign", sessions, participants); Assert.Equal("Campaign", result.Title); Assert.Equal(3, result.Sessions.Count); Assert.Equal(firstSessionId, result.Sessions[0].SessionId); Assert.Equal(secondSessionId, result.Sessions[1].SessionId); Assert.Equal(cancelledSessionId, result.Sessions[2].SessionId); } [Fact] public void Build_ShouldCalculatePlayerCounts() { var sessionId = Guid.NewGuid(); var sessions = new[] { new SessionBatchDto(sessionId, DateTime.UtcNow, SessionStatus.Planned, 4, "https://example.com/game") }; var participants = new[] { new ParticipantBatchDto(sessionId, "Alice", "alice", ParticipantRegistrationStatus.Active), new ParticipantBatchDto(sessionId, "Bob", null, ParticipantRegistrationStatus.Active), new ParticipantBatchDto(sessionId, "Charlie", null, ParticipantRegistrationStatus.Waitlisted) }; var result = SessionBatchViewBuilder.Build("Test", sessions, participants); var session = result.Sessions[0]; Assert.Equal(2, session.ActivePlayerCount); Assert.Equal(4, session.MaxPlayers); Assert.True(session.ActivePlayers.Count == 2); Assert.True(session.WaitlistedPlayers.Count == 1); } [Fact] public void Build_ShouldIncludeActionsForActiveSessions() { var sessionId = Guid.NewGuid(); var sessions = new[] { new SessionBatchDto(sessionId, DateTime.UtcNow, SessionStatus.Planned, 4, "https://example.com/game") }; var participants = Array.Empty(); var result = SessionBatchViewBuilder.Build("Test", sessions, participants); var actions = result.Sessions[0].AvailableActions; Assert.Equal(2, actions.Count); Assert.Equal("join_session", result.Sessions[0].AvailableActions[0].ActionKey); Assert.Equal("leave_session", result.Sessions[0].AvailableActions[1].ActionKey); Assert.Equal(sessionId, actions[0].SessionId); Assert.Equal(sessionId, actions[1].SessionId); } [Fact] public void Build_ShouldNotIncludeActionsForCancelledSessions() { var sessionId = Guid.NewGuid(); var sessions = new[] { new SessionBatchDto(sessionId, DateTime.UtcNow, SessionStatus.Cancelled, null, "") }; var participants = Array.Empty(); var result = SessionBatchViewBuilder.Build("Test", sessions, participants); Assert.Empty(result.Sessions[0].AvailableActions); } [Fact] public void Build_ShouldMarkWaitlistActionWhenFull() { var sessionId = Guid.NewGuid(); var sessions = new[] { new SessionBatchDto(sessionId, DateTime.UtcNow, SessionStatus.Planned, 1, "https://example.com/game") }; var participants = new[] { new ParticipantBatchDto(sessionId, "Alice", "alice", ParticipantRegistrationStatus.Active) }; var result = SessionBatchViewBuilder.Build("Test", sessions, participants); var joinAction = result.Sessions[0].AvailableActions.First(a => a.ActionKey == "join_session"); Assert.Contains("ожидания", joinAction.Label); } [Fact] public void Build_ShouldIncludePlayerUsernames() { var sessionId = Guid.NewGuid(); var sessions = new[] { new SessionBatchDto(sessionId, DateTime.UtcNow, SessionStatus.Planned, null, "https://example.com/game") }; var participants = new[] { new ParticipantBatchDto(sessionId, "Alice", "alice", ParticipantRegistrationStatus.Active) }; var result = SessionBatchViewBuilder.Build("Test", sessions, participants); var player = result.Sessions[0].ActivePlayers[0]; Assert.Equal("Alice", player.DisplayName); Assert.Equal("alice", player.TelegramUsername); } [Fact] public void Build_ShouldHandleEmptySessions() { var result = SessionBatchViewBuilder.Build("Empty", Array.Empty(), Array.Empty()); Assert.Equal("Empty", result.Title); Assert.Empty(result.Sessions); } [Fact] public void Build_ShouldHandleConfirmedStatus() { var sessionId = Guid.NewGuid(); var sessions = new[] { new SessionBatchDto(sessionId, DateTime.UtcNow, SessionStatus.Confirmed, 4, "https://example.com/game") }; var participants = Array.Empty(); var result = SessionBatchViewBuilder.Build("Test", sessions, participants); Assert.Equal(SessionStatus.Confirmed, result.Sessions[0].Status); Assert.Equal(2, result.Sessions[0].AvailableActions.Count); Assert.Equal("join_session", result.Sessions[0].AvailableActions[0].ActionKey); Assert.Equal("leave_session", result.Sessions[0].AvailableActions[1].ActionKey); Assert.Equal(sessionId, result.Sessions[0].AvailableActions[0].SessionId); Assert.Equal(sessionId, result.Sessions[0].AvailableActions[1].SessionId); } [Fact] public void Build_ShouldHandleNullMaxPlayers() { var sessionId = Guid.NewGuid(); var sessions = new[] { new SessionBatchDto(sessionId, DateTime.UtcNow, SessionStatus.Planned, null, "https://example.com/game") }; var participants = Array.Empty(); var result = SessionBatchViewBuilder.Build("Test", sessions, participants); Assert.Null(result.Sessions[0].MaxPlayers); var joinAction = result.Sessions[0].AvailableActions.First(a => a.ActionKey == "join_session"); Assert.DoesNotContain("ожидания", joinAction.Label); } [Fact] public void Build_ShouldPassThroughNewFields() { var sessionId = Guid.NewGuid(); var sessions = new[] { new SessionBatchDto( sessionId, DateTime.UtcNow, SessionStatus.Planned, 4, "https://example.com/game", "Offline", "Moscow", "A short description", "D\u0026D 5e", 240, true) }; var participants = Array.Empty(); var result = SessionBatchViewBuilder.Build("Test", sessions, participants); var session = result.Sessions[0]; Assert.Equal("A short description", session.Description); Assert.Equal("D\u0026D 5e", session.System); Assert.Equal(240, session.DurationMinutes); Assert.True(session.IsOneShot); Assert.Equal("Offline", session.Format); Assert.Equal("Moscow", session.LocationAddress); } }