014b5edd31
PR Checks / test-and-build (pull_request) Successful in 15m52s
Add format and location steps to the Telegram /newsession wizard, persist offline addresses in sessions.location_address, and render online links/offline addresses in schedule messages. Bump version to 3.10.0.
108 lines
4.5 KiB
C#
108 lines
4.5 KiB
C#
using GmRelay.Bot.Features.Sessions.CreateSession;
|
|
using GmRelay.Shared.Features.Sessions.CreateSession.Wizard;
|
|
using GmRelay.Shared.Platform;
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
|
using Npgsql;
|
|
using static GmRelay.Bot.Tests.Features.Sessions.CreateSession.Wizard.WizardTestFakes;
|
|
|
|
namespace GmRelay.Bot.Tests.Features.Sessions.CreateSession.Wizard;
|
|
|
|
[Collection(CreateSessionHandlerPostgresCollection.Name)]
|
|
public sealed class CreateSessionHandlerSubmitSingleDraftTests(CreateSessionHandlerPostgresFixture fixture)
|
|
{
|
|
[Fact]
|
|
public async Task SubmitDraftAsync_CompleteSinglePayload_PublishesScheduleAndStoresMessageRefs()
|
|
{
|
|
var connectionString = await fixture.CreateMigratedDatabaseAsync();
|
|
await using var dataSource = NpgsqlDataSource.Create(connectionString);
|
|
var drafts = new FakeWizardDraftRepository();
|
|
var wizardMessenger = new FakeWizardMessenger();
|
|
var platformMessenger = new FakePlatformMessenger();
|
|
|
|
var sut = new CreateSessionHandler(
|
|
drafts,
|
|
new GmRelay.Shared.Features.Sessions.CreateSession.CreateSessionHandler(dataSource),
|
|
wizardMessenger,
|
|
NullLogger<CreateSessionHandler>.Instance,
|
|
platformMessenger,
|
|
dataSource);
|
|
|
|
var payload = new WizardPayload
|
|
{
|
|
Type = WizardCreationType.Single,
|
|
Title = "Тест публикации",
|
|
System = "Dnd5e",
|
|
DurationMinutes = 240,
|
|
Format = WizardSessionFormat.Online,
|
|
JoinLink = "https://vtt.example/game",
|
|
Visibility = WizardVisibility.Public,
|
|
Single = new WizardSingleInput
|
|
{
|
|
ScheduledAt = DateTimeOffset.UtcNow.AddDays(7),
|
|
MaxPlayers = null,
|
|
},
|
|
};
|
|
var draft = NewDraft(WizardStepNames.Confirm, payload, ownerId: 111111111);
|
|
draft.ChatId = "-1003916537960";
|
|
draft.DraftMessageId = "7";
|
|
drafts.Seed(draft);
|
|
|
|
await sut.SubmitDraftAsync(draft, CancellationToken.None);
|
|
|
|
Assert.Single(platformMessenger.CreatedThreads);
|
|
Assert.Equal("Тест публикации", platformMessenger.CreatedThreads[0].Title);
|
|
Assert.Single(platformMessenger.SentSchedules);
|
|
Assert.Equal("456", platformMessenger.SentSchedules[0].Group.ExternalThreadId);
|
|
Assert.Contains(draft.Id, drafts.DeletedIds);
|
|
Assert.Contains(wizardMessenger.Edits, edit => edit.Text.Contains("✅ Создано: 1 сессия", StringComparison.Ordinal));
|
|
|
|
await using var connection = await dataSource.OpenConnectionAsync();
|
|
await using var command = new NpgsqlCommand(
|
|
"""
|
|
SELECT thread_id, batch_message_id, topic_created_by_bot
|
|
FROM sessions
|
|
ORDER BY created_at DESC
|
|
LIMIT 1
|
|
""",
|
|
connection);
|
|
await using var reader = await command.ExecuteReaderAsync();
|
|
Assert.True(await reader.ReadAsync());
|
|
Assert.Equal(456, reader.GetInt32(0));
|
|
Assert.Equal(789, reader.GetInt32(1));
|
|
Assert.True(reader.GetBoolean(2));
|
|
}
|
|
}
|
|
|
|
internal sealed class FakePlatformMessenger : IPlatformMessenger
|
|
{
|
|
public List<(PlatformGroup Group, string Title)> CreatedThreads { get; } = new();
|
|
|
|
public List<PlatformScheduleMessage> SentSchedules { get; } = new();
|
|
|
|
public Task<PlatformMessageRef> CreateThreadAsync(PlatformGroup group, string title, CancellationToken ct)
|
|
{
|
|
CreatedThreads.Add((group, title));
|
|
return Task.FromResult(new PlatformMessageRef(group.Platform, group.ExternalGroupId, "456", string.Empty));
|
|
}
|
|
|
|
public Task<PlatformMessageRef> SendScheduleAsync(PlatformScheduleMessage message, CancellationToken ct)
|
|
{
|
|
SentSchedules.Add(message);
|
|
return Task.FromResult(new PlatformMessageRef(
|
|
message.Group.Platform,
|
|
message.Group.ExternalGroupId,
|
|
message.Group.ExternalThreadId,
|
|
"789"));
|
|
}
|
|
|
|
public Task UpdateScheduleAsync(PlatformScheduleMessage message, CancellationToken ct) => Task.CompletedTask;
|
|
|
|
public Task SendGroupMessageAsync(PlatformGroup group, string htmlText, CancellationToken ct) => Task.CompletedTask;
|
|
|
|
public Task SendPrivateMessageAsync(PlatformPrivateMessage message, CancellationToken ct) => Task.CompletedTask;
|
|
|
|
public Task AnswerInteractionAsync(PlatformInteractionReply reply, CancellationToken ct) => Task.CompletedTask;
|
|
|
|
public Task SendCalendarFileAsync(PlatformCalendarFile file, CancellationToken ct) => Task.CompletedTask;
|
|
}
|