Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a391c51761 |
@@ -23,11 +23,18 @@ internal static class SessionListMessageRenderer
|
||||
|
||||
public static IReadOnlyList<PlatformMessageAction> RenderActions(IReadOnlyList<SessionListItemDto> sessions)
|
||||
{
|
||||
if (sessions.Count == 0 || !sessions.First().CanManage)
|
||||
if (sessions.Count == 0)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
return sessions.First().CanManage
|
||||
? RenderManagerActions(sessions)
|
||||
: RenderPlayerActions(sessions);
|
||||
}
|
||||
|
||||
private static IReadOnlyList<PlatformMessageAction> RenderManagerActions(IReadOnlyList<SessionListItemDto> sessions)
|
||||
{
|
||||
var actions = new List<PlatformMessageAction>();
|
||||
|
||||
foreach (var session in sessions)
|
||||
@@ -60,4 +67,31 @@ internal static class SessionListMessageRenderer
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
private static IReadOnlyList<PlatformMessageAction> RenderPlayerActions(IReadOnlyList<SessionListItemDto> sessions)
|
||||
{
|
||||
var actions = new List<PlatformMessageAction>();
|
||||
|
||||
foreach (var session in sessions)
|
||||
{
|
||||
var dateTitle = session.ScheduledAt.FormatMoscowShort();
|
||||
|
||||
if (session.IsUserActive || session.IsUserWaitlisted)
|
||||
{
|
||||
actions.Add(new PlatformMessageAction(
|
||||
$"leave_session:{session.Id}",
|
||||
session.IsUserWaitlisted ? $"✖️ Выйти из ожидания {dateTitle}" : $"✖️ Выйти {dateTitle}",
|
||||
$"leave_session:{session.Id}"));
|
||||
}
|
||||
else
|
||||
{
|
||||
actions.Add(new PlatformMessageAction(
|
||||
$"join_session:{session.Id}",
|
||||
$"✅ Записаться {dateTitle}",
|
||||
$"join_session:{session.Id}"));
|
||||
}
|
||||
}
|
||||
|
||||
return actions;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,17 @@ using Npgsql;
|
||||
|
||||
namespace GmRelay.Shared.Features.Sessions.ListSessions;
|
||||
|
||||
public sealed record SessionListItemDto(Guid Id, string Title, DateTime ScheduledAt, string Status, int? MaxPlayers, int PlayerCount, int WaitlistCount, bool CanManage);
|
||||
public sealed record SessionListItemDto(
|
||||
Guid Id,
|
||||
string Title,
|
||||
DateTime ScheduledAt,
|
||||
string Status,
|
||||
int? MaxPlayers,
|
||||
int PlayerCount,
|
||||
int WaitlistCount,
|
||||
bool CanManage,
|
||||
bool IsUserActive,
|
||||
bool IsUserWaitlisted);
|
||||
|
||||
public sealed record SessionListResult(
|
||||
IReadOnlyList<SessionListItemDto> Sessions,
|
||||
@@ -29,7 +39,27 @@ public sealed class ListSessionsHandler(
|
||||
WHERE gm.group_id = s.group_id
|
||||
AND manager_player.platform = @Platform
|
||||
AND manager_player.external_user_id = @ExternalUserId
|
||||
) AS CanManage
|
||||
) AS CanManage,
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM session_participants user_sp
|
||||
JOIN players user_p ON user_p.id = user_sp.player_id
|
||||
WHERE user_sp.session_id = s.id
|
||||
AND user_sp.is_gm = false
|
||||
AND user_sp.registration_status = @Active
|
||||
AND user_p.platform = @Platform
|
||||
AND user_p.external_user_id = @ExternalUserId
|
||||
) AS IsUserActive,
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM session_participants user_sp
|
||||
JOIN players user_p ON user_p.id = user_sp.player_id
|
||||
WHERE user_sp.session_id = s.id
|
||||
AND user_sp.is_gm = false
|
||||
AND user_sp.registration_status = @Waitlisted
|
||||
AND user_p.platform = @Platform
|
||||
AND user_p.external_user_id = @ExternalUserId
|
||||
) AS IsUserWaitlisted
|
||||
FROM sessions s
|
||||
JOIN game_groups g ON s.group_id = g.id
|
||||
LEFT JOIN session_participants sp ON s.id = sp.session_id
|
||||
|
||||
+68
-5
@@ -20,7 +20,9 @@ public sealed class SessionListMessageRendererTests
|
||||
4,
|
||||
3,
|
||||
1,
|
||||
true)
|
||||
true,
|
||||
false,
|
||||
false)
|
||||
};
|
||||
|
||||
var text = SessionListMessageRenderer.RenderText(sessions);
|
||||
@@ -41,22 +43,83 @@ public sealed class SessionListMessageRendererTests
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Render_ShouldHideManagerActions_WhenUserCannotManage()
|
||||
public void Render_ShouldIncludeJoinAction_WhenPlayerIsNotRegistered()
|
||||
{
|
||||
var sessionId = Guid.NewGuid();
|
||||
var sessions = new[]
|
||||
{
|
||||
new SessionListItemDto(
|
||||
Guid.NewGuid(),
|
||||
sessionId,
|
||||
"Ravenloft",
|
||||
new DateTime(2026, 5, 7, 16, 30, 0, DateTimeKind.Utc),
|
||||
SessionStatus.Planned,
|
||||
4,
|
||||
3,
|
||||
0,
|
||||
false,
|
||||
false,
|
||||
false)
|
||||
};
|
||||
|
||||
var actions = SessionListMessageRenderer.RenderActions(sessions);
|
||||
var shortDate = new DateTime(2026, 5, 7, 16, 30, 0, DateTimeKind.Utc).FormatMoscowShort();
|
||||
|
||||
Assert.Single(actions);
|
||||
Assert.Contains(actions, a => a.Payload == $"join_session:{sessionId}");
|
||||
Assert.Contains(actions, a => a.Label == $"✅ Записаться {shortDate}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Render_ShouldIncludeLeaveAction_WhenPlayerIsActive()
|
||||
{
|
||||
var sessionId = Guid.NewGuid();
|
||||
var sessions = new[]
|
||||
{
|
||||
new SessionListItemDto(
|
||||
sessionId,
|
||||
"Ravenloft",
|
||||
new DateTime(2026, 5, 7, 16, 30, 0, DateTimeKind.Utc),
|
||||
SessionStatus.Planned,
|
||||
4,
|
||||
3,
|
||||
0,
|
||||
false,
|
||||
true,
|
||||
false)
|
||||
};
|
||||
|
||||
var actions = SessionListMessageRenderer.RenderActions(sessions);
|
||||
var shortDate = new DateTime(2026, 5, 7, 16, 30, 0, DateTimeKind.Utc).FormatMoscowShort();
|
||||
|
||||
Assert.Single(actions);
|
||||
Assert.Contains(actions, a => a.Payload == $"leave_session:{sessionId}");
|
||||
Assert.Contains(actions, a => a.Label == $"✖️ Выйти {shortDate}");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Render_ShouldIncludeLeaveWaitlistAction_WhenPlayerIsWaitlisted()
|
||||
{
|
||||
var sessionId = Guid.NewGuid();
|
||||
var sessions = new[]
|
||||
{
|
||||
new SessionListItemDto(
|
||||
sessionId,
|
||||
"Ravenloft",
|
||||
new DateTime(2026, 5, 7, 16, 30, 0, DateTimeKind.Utc),
|
||||
SessionStatus.Planned,
|
||||
4,
|
||||
3,
|
||||
1,
|
||||
false)
|
||||
false,
|
||||
false,
|
||||
true)
|
||||
};
|
||||
|
||||
var actions = SessionListMessageRenderer.RenderActions(sessions);
|
||||
Assert.Empty(actions);
|
||||
var shortDate = new DateTime(2026, 5, 7, 16, 30, 0, DateTimeKind.Utc).FormatMoscowShort();
|
||||
|
||||
Assert.Single(actions);
|
||||
Assert.Contains(actions, a => a.Payload == $"leave_session:{sessionId}");
|
||||
Assert.Contains(actions, a => a.Label == $"✖️ Выйти из ожидания {shortDate}");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user