feat(rendering): display description, system, duration, format, type and location in Telegram game card
This commit is contained in:
@@ -149,4 +149,36 @@ public sealed class SessionBatchViewBuilderTests
|
||||
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<ParticipantBatchDto>();
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,9 +16,9 @@ public sealed class TelegramSessionBatchRendererTests
|
||||
|
||||
var sessions = new[]
|
||||
{
|
||||
new SessionBatchDto(secondSessionId, new DateTime(2026, 4, 27, 18, 0, 0, DateTimeKind.Utc), SessionStatus.Planned, 4, "https://example.com/game2"),
|
||||
new SessionBatchDto(secondSessionId, new DateTime(2026, 4, 27, 18, 0, 0, DateTimeKind.Utc), SessionStatus.Planned, 4, "https://example.com/game2", "Online", null),
|
||||
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/game1")
|
||||
new SessionBatchDto(firstSessionId, new DateTime(2026, 4, 26, 18, 0, 0, DateTimeKind.Utc), SessionStatus.Planned, 2, "https://example.com/game1", "Online", null)
|
||||
};
|
||||
var participants = new[]
|
||||
{
|
||||
@@ -35,7 +35,7 @@ public sealed class TelegramSessionBatchRendererTests
|
||||
Assert.Contains("Charlie", text);
|
||||
Assert.Contains("Bob", text);
|
||||
Assert.Contains("Сессия отменена", text);
|
||||
Assert.Contains("Ссылка на игру", text);
|
||||
Assert.Contains("Ссылка:", text);
|
||||
Assert.Contains("https://example.com/game1", text);
|
||||
Assert.Contains("https://example.com/game2", text);
|
||||
|
||||
@@ -67,7 +67,7 @@ public sealed class TelegramSessionBatchRendererTests
|
||||
public void Render_ShouldShowWaitlistButtonWhenFull()
|
||||
{
|
||||
var sessionId = Guid.NewGuid();
|
||||
var sessions = new[] { new SessionBatchDto(sessionId, DateTime.UtcNow, SessionStatus.Planned, 1, "https://example.com/game") };
|
||||
var sessions = new[] { new SessionBatchDto(sessionId, DateTime.UtcNow, SessionStatus.Planned, 1, "https://example.com/game", "Online", null) };
|
||||
var participants = new[] { new ParticipantBatchDto(sessionId, "Alice", "alice", ParticipantRegistrationStatus.Active) };
|
||||
|
||||
var view = SessionBatchViewBuilder.Build("Test", sessions, participants);
|
||||
@@ -130,7 +130,7 @@ public sealed class TelegramSessionBatchRendererTests
|
||||
var (text, markup) = TelegramSessionBatchRenderer.Render(view);
|
||||
var buttons = markup.InlineKeyboard.SelectMany(row => row).ToList();
|
||||
|
||||
Assert.DoesNotContain("Ссылка на игру", text);
|
||||
Assert.DoesNotContain("Ссылка:", text);
|
||||
Assert.Contains("📅", text);
|
||||
Assert.Equal(2, buttons.Count);
|
||||
}
|
||||
@@ -155,9 +155,9 @@ public sealed class TelegramSessionBatchRendererTests
|
||||
var view = SessionBatchViewBuilder.Build("Offline Test", sessions, participants);
|
||||
var (text, _) = TelegramSessionBatchRenderer.Render(view);
|
||||
|
||||
Assert.Contains("📍 Адрес:", text);
|
||||
Assert.Contains("📍 <b>Адрес:</b>", text);
|
||||
Assert.Contains("Москва, ул. Кубиков, 12", text);
|
||||
Assert.DoesNotContain("Ссылка на игру", text);
|
||||
Assert.DoesNotContain("Ссылка:", text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -180,7 +180,7 @@ public sealed class TelegramSessionBatchRendererTests
|
||||
var view = SessionBatchViewBuilder.Build("Online Test", sessions, participants);
|
||||
var (text, _) = TelegramSessionBatchRenderer.Render(view);
|
||||
|
||||
Assert.Contains("🔗 Ссылка на игру", text);
|
||||
Assert.Contains("🔗 <b>Ссылка:</b>", text);
|
||||
Assert.Contains("https://vtt.example/game", text);
|
||||
Assert.DoesNotContain("📍 Адрес:", text);
|
||||
}
|
||||
@@ -189,7 +189,7 @@ public sealed class TelegramSessionBatchRendererTests
|
||||
public void Render_ShouldEncodeHtmlInJoinLink()
|
||||
{
|
||||
var sessionId = Guid.NewGuid();
|
||||
var sessions = new[] { new SessionBatchDto(sessionId, DateTime.UtcNow, SessionStatus.Planned, 4, "https://example.com/test?a=1&b=2") };
|
||||
var sessions = new[] { new SessionBatchDto(sessionId, DateTime.UtcNow, SessionStatus.Planned, 4, "https://example.com/test?a=1&b=2", "Online", null) };
|
||||
var participants = Array.Empty<ParticipantBatchDto>();
|
||||
|
||||
var view = SessionBatchViewBuilder.Build("Test", sessions, participants);
|
||||
@@ -198,4 +198,77 @@ public sealed class TelegramSessionBatchRendererTests
|
||||
Assert.Contains("a=1&b=2", text);
|
||||
Assert.DoesNotContain("a=1&b=2" + "\"", text); // make sure & is encoded
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Render_ShouldShowStructuredGameCard()
|
||||
{
|
||||
var sessionId = Guid.NewGuid();
|
||||
var sessions = new[]
|
||||
{
|
||||
new SessionBatchDto(
|
||||
sessionId,
|
||||
new DateTime(2026, 6, 13, 16, 0, 0, DateTimeKind.Utc),
|
||||
SessionStatus.Planned,
|
||||
4,
|
||||
"https://vtt.example/game",
|
||||
"Hybrid",
|
||||
"Moscow, Kubik Bar",
|
||||
"Mystery one-shot in Bamberg.",
|
||||
"D\u0026D 5e",
|
||||
240,
|
||||
true)
|
||||
};
|
||||
var participants = new[]
|
||||
{
|
||||
new ParticipantBatchDto(sessionId, "Alice", "alice", ParticipantRegistrationStatus.Active),
|
||||
new ParticipantBatchDto(sessionId, "Bob", null, ParticipantRegistrationStatus.Waitlisted)
|
||||
};
|
||||
|
||||
var view = SessionBatchViewBuilder.Build("Structured Test", sessions, participants);
|
||||
var (text, markup) = TelegramSessionBatchRenderer.Render(view);
|
||||
|
||||
Assert.Contains("🏷", text);
|
||||
Assert.Contains("Система:", text);
|
||||
Assert.Contains("D\u0026amp;D 5e", text);
|
||||
Assert.Contains("Формат:", text);
|
||||
Assert.Contains("Hybrid", text);
|
||||
Assert.Contains("Тип:", text);
|
||||
Assert.Contains("One-shot", text);
|
||||
Assert.Contains("⏱", text);
|
||||
Assert.Contains("Длительность:", text);
|
||||
Assert.Contains("4 ч", text);
|
||||
Assert.Contains("📝", text);
|
||||
Assert.Contains("Описание:", text);
|
||||
Assert.Contains("Mystery one-shot in Bamberg.", text);
|
||||
Assert.Contains("🔗", text);
|
||||
Assert.Contains("Ссылка:", text);
|
||||
Assert.Contains("📍", text);
|
||||
Assert.Contains("Адрес:", text);
|
||||
Assert.Contains("@alice", text);
|
||||
Assert.Contains("Bob", text);
|
||||
Assert.Contains("Лист ожидания", text);
|
||||
|
||||
var buttons = markup.InlineKeyboard.SelectMany(row => row).ToList();
|
||||
Assert.Equal(2, buttons.Count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Render_ShouldHandleMissingOptionalFields()
|
||||
{
|
||||
var sessionId = Guid.NewGuid();
|
||||
var sessions = new[] { new SessionBatchDto(sessionId, DateTime.UtcNow, SessionStatus.Planned, 4, "") };
|
||||
var participants = Array.Empty<ParticipantBatchDto>();
|
||||
|
||||
var view = SessionBatchViewBuilder.Build("Minimal", sessions, participants);
|
||||
var (text, _) = TelegramSessionBatchRenderer.Render(view);
|
||||
|
||||
Assert.Contains("📅", text);
|
||||
Assert.Contains("👥", text);
|
||||
Assert.DoesNotContain("Система:", text);
|
||||
Assert.DoesNotContain("Формат:", text);
|
||||
Assert.DoesNotContain("Длительность:", text);
|
||||
Assert.DoesNotContain("Описание:", text);
|
||||
Assert.DoesNotContain("Ссылка:", text);
|
||||
Assert.DoesNotContain("Адрес:", text);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user