feat: send personal player notifications
Deploy Telegram Bot / build-and-push (push) Successful in 3m36s
Deploy Telegram Bot / deploy (push) Successful in 11s

This commit is contained in:
2026-04-27 10:11:11 +03:00
parent 3228e77c7f
commit a8f2b10956
23 changed files with 666 additions and 38 deletions
@@ -0,0 +1,16 @@
using GmRelay.Shared.Domain;
namespace GmRelay.Bot.Tests.Domain;
public sealed class SessionNotificationModeTests
{
[Theory]
[InlineData(SessionNotificationMode.GroupAndDirect, true)]
[InlineData(SessionNotificationMode.GroupOnly, false)]
public void ShouldSendDirectMessages_ReturnsExpectedDecision(
SessionNotificationMode mode,
bool expected)
{
Assert.Equal(expected, mode.ShouldSendDirectMessages());
}
}
@@ -1,4 +1,5 @@
using GmRelay.Web.Services;
using GmRelay.Shared.Domain;
namespace GmRelay.Bot.Tests.Web;
@@ -210,6 +211,53 @@ public sealed class AuthorizedSessionServiceTests
Assert.Equal("https://example.test/b", store.LastUpdatedBatchJoinLink);
}
[Fact]
public async Task UpdateBatchNotificationModeForGmAsync_Throws_WhenBatchBelongsToAnotherGm()
{
var batchId = Guid.NewGuid();
var groupId = Guid.NewGuid();
var store = new FakeSessionStore(
groups:
[
new(groupId, 42, "Alpha", 2002L)
],
sessions:
[
new(Guid.NewGuid(), groupId, "Session A", DateTime.UtcNow, "Planned", "https://example.test/a", batchId, 10, 42, 4, 1, 0)
]);
var service = new AuthorizedSessionService(store);
var action = () => service.UpdateBatchNotificationModeForGmAsync(batchId, 1001L, SessionNotificationMode.GroupOnly);
await Assert.ThrowsAsync<SessionAccessDeniedException>(action);
Assert.False(store.UpdateBatchNotificationModeCalled);
}
[Fact]
public async Task UpdateBatchNotificationModeForGmAsync_UpdatesOwnedBatch()
{
var gmId = 1001L;
var groupId = Guid.NewGuid();
var batchId = Guid.NewGuid();
var store = new FakeSessionStore(
groups:
[
new(groupId, 42, "Alpha", gmId)
],
sessions:
[
new(Guid.NewGuid(), groupId, "Session A", DateTime.UtcNow, "Planned", "https://example.test/a", batchId, 10, 42, 4, 1, 0)
]);
var service = new AuthorizedSessionService(store);
await service.UpdateBatchNotificationModeForGmAsync(batchId, gmId, SessionNotificationMode.GroupOnly);
Assert.True(store.UpdateBatchNotificationModeCalled);
Assert.Equal(batchId, store.LastUpdatedNotificationBatchId);
Assert.Equal(groupId, store.LastUpdatedNotificationGroupId);
Assert.Equal(SessionNotificationMode.GroupOnly, store.LastUpdatedNotificationMode);
}
[Fact]
public async Task RescheduleBatchForGmAsync_RejectsNonPositiveInterval()
{
@@ -295,6 +343,7 @@ public sealed class AuthorizedSessionServiceTests
public bool UpdateCalled { get; private set; }
public bool PromoteCalled { get; private set; }
public bool UpdateBatchDetailsCalled { get; private set; }
public bool UpdateBatchNotificationModeCalled { get; private set; }
public bool RescheduleBatchCalled { get; private set; }
public bool CloneBatchCalled { get; private set; }
public Guid? LastUpdatedSessionId { get; private set; }
@@ -309,6 +358,9 @@ public sealed class AuthorizedSessionServiceTests
public Guid? LastUpdatedBatchGroupId { get; private set; }
public string? LastUpdatedBatchTitle { get; private set; }
public string? LastUpdatedBatchJoinLink { get; private set; }
public Guid? LastUpdatedNotificationBatchId { get; private set; }
public Guid? LastUpdatedNotificationGroupId { get; private set; }
public SessionNotificationMode? LastUpdatedNotificationMode { get; private set; }
public Guid? LastRescheduledBatchId { get; private set; }
public Guid? LastRescheduledBatchGroupId { get; private set; }
public DateTime? LastRescheduledFirstScheduledAt { get; private set; }
@@ -388,6 +440,15 @@ public sealed class AuthorizedSessionServiceTests
return Task.CompletedTask;
}
public Task UpdateBatchNotificationModeAsync(Guid batchId, Guid groupId, SessionNotificationMode notificationMode)
{
UpdateBatchNotificationModeCalled = true;
LastUpdatedNotificationBatchId = batchId;
LastUpdatedNotificationGroupId = groupId;
LastUpdatedNotificationMode = notificationMode;
return Task.CompletedTask;
}
public Task RescheduleBatchAsync(Guid batchId, Guid groupId, DateTime firstScheduledAt, int intervalDays)
{
RescheduleBatchCalled = true;