feat(platform): route scheduler notifications through platform messenger
PR Checks / test-and-build (pull_request) Successful in 7m9s
PR Checks / test-and-build (pull_request) Successful in 7m9s
This commit is contained in:
@@ -20,11 +20,14 @@ public sealed class DiscordNewSessionHandlerTests
|
||||
[Fact]
|
||||
public void ParseTimeInput_ShouldParseDiscordDateFormat()
|
||||
{
|
||||
var result = DiscordNewSessionHandler.ParseTimeInput("2026-05-20 19:30");
|
||||
var expected = FutureDateAt1930();
|
||||
var result = DiscordNewSessionHandler.ParseTimeInput(
|
||||
expected.ToString("yyyy-MM-dd HH:mm", System.Globalization.CultureInfo.InvariantCulture));
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(2026, result.Value.Year);
|
||||
Assert.Equal(5, result.Value.Month);
|
||||
Assert.Equal(20, result.Value.Day);
|
||||
Assert.Equal(expected.Year, result.Value.Year);
|
||||
Assert.Equal(expected.Month, result.Value.Month);
|
||||
Assert.Equal(expected.Day, result.Value.Day);
|
||||
Assert.Equal(19, result.Value.Hour);
|
||||
Assert.Equal(30, result.Value.Minute);
|
||||
}
|
||||
@@ -39,11 +42,14 @@ public sealed class DiscordNewSessionHandlerTests
|
||||
[Fact]
|
||||
public void ParseTimeInput_ShouldParseRussianDateFormat()
|
||||
{
|
||||
var result = DiscordNewSessionHandler.ParseTimeInput("20.05.2026 19:30");
|
||||
var expected = FutureDateAt1930();
|
||||
var result = DiscordNewSessionHandler.ParseTimeInput(
|
||||
expected.ToString("dd.MM.yyyy HH:mm", System.Globalization.CultureInfo.InvariantCulture));
|
||||
|
||||
Assert.True(result.IsSuccess);
|
||||
Assert.Equal(2026, result.Value.Year);
|
||||
Assert.Equal(5, result.Value.Month);
|
||||
Assert.Equal(20, result.Value.Day);
|
||||
Assert.Equal(expected.Year, result.Value.Year);
|
||||
Assert.Equal(expected.Month, result.Value.Month);
|
||||
Assert.Equal(expected.Day, result.Value.Day);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@@ -141,4 +147,17 @@ public sealed class DiscordNewSessionHandlerTests
|
||||
Assert.Contains("DiscordSessionBatchRenderer.Render", source, StringComparison.Ordinal);
|
||||
Assert.Contains("WithEmbeds", source, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private static DateTimeOffset FutureDateAt1930()
|
||||
{
|
||||
var future = DateTimeOffset.UtcNow.AddDays(7);
|
||||
return new DateTimeOffset(
|
||||
future.Year,
|
||||
future.Month,
|
||||
future.Day,
|
||||
19,
|
||||
30,
|
||||
0,
|
||||
TimeSpan.Zero);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,21 @@ public sealed class DiscordPlatformMessengerTests
|
||||
Assert.Contains("interactionReplies.Store(reply)", source, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DiscordPlatformMessenger_ShouldSupportSchedulerNotifications()
|
||||
{
|
||||
var source = await ReadRepositoryFileAsync("src/GmRelay.DiscordBot/Infrastructure/Discord/DiscordPlatformMessenger.cs");
|
||||
|
||||
Assert.Contains("SendConfirmationRequestAsync", source, StringComparison.Ordinal);
|
||||
Assert.Contains("UpdateConfirmationRequestAsync", source, StringComparison.Ordinal);
|
||||
Assert.Contains("SendJoinLinkNotificationAsync", source, StringComparison.Ordinal);
|
||||
Assert.Contains("SendDirectSessionNotificationAsync", source, StringComparison.Ordinal);
|
||||
Assert.Contains("UpdateRescheduleVoteAsync", source, StringComparison.Ordinal);
|
||||
Assert.Contains("DiscordSessionBatchRenderer", source, StringComparison.Ordinal);
|
||||
Assert.Contains("DiscordRescheduleVotingRenderer", source, StringComparison.Ordinal);
|
||||
Assert.Contains("GetDMChannelAsync", source, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private static async Task<string> ReadRepositoryFileAsync(string relativePath)
|
||||
{
|
||||
var directory = new DirectoryInfo(AppContext.BaseDirectory);
|
||||
|
||||
@@ -61,7 +61,7 @@ public sealed class DiscordProjectStructureTests
|
||||
var prChecks = File.ReadAllText(Path.Combine(repoRoot, ".gitea", "workflows", "pr-checks.yml"));
|
||||
var deploy = File.ReadAllText(Path.Combine(repoRoot, ".gitea", "workflows", "deploy.yml"));
|
||||
|
||||
Assert.Contains("gmrelay-discord-bot:2.6.0", compose);
|
||||
Assert.Contains("gmrelay-discord-bot:2.7.0", compose);
|
||||
Assert.Contains("Discord__Token=${DISCORD_BOT_TOKEN:?Set DISCORD_BOT_TOKEN in .env}", compose);
|
||||
Assert.Contains("src/GmRelay.DiscordBot/Dockerfile", deploy);
|
||||
Assert.Contains("DISCORD_BOT_TOKEN", deploy);
|
||||
@@ -75,13 +75,13 @@ public sealed class DiscordProjectStructureTests
|
||||
{
|
||||
var repoRoot = GetRepoRoot();
|
||||
|
||||
Assert.Contains("<Version>2.6.0</Version>", File.ReadAllText(Path.Combine(repoRoot, "Directory.Build.props")));
|
||||
Assert.Contains("VERSION: 2.6.0", File.ReadAllText(Path.Combine(repoRoot, ".gitea", "workflows", "deploy.yml")));
|
||||
Assert.Contains("gmrelay-bot:2.6.0", File.ReadAllText(Path.Combine(repoRoot, "compose.yaml")));
|
||||
Assert.Contains("gmrelay-web:2.6.0", File.ReadAllText(Path.Combine(repoRoot, "compose.yaml")));
|
||||
Assert.Contains("gmrelay-discord-bot:2.6.0", File.ReadAllText(Path.Combine(repoRoot, "compose.yaml")));
|
||||
Assert.Contains("<Version>2.7.0</Version>", File.ReadAllText(Path.Combine(repoRoot, "Directory.Build.props")));
|
||||
Assert.Contains("VERSION: 2.7.0", File.ReadAllText(Path.Combine(repoRoot, ".gitea", "workflows", "deploy.yml")));
|
||||
Assert.Contains("gmrelay-bot:2.7.0", File.ReadAllText(Path.Combine(repoRoot, "compose.yaml")));
|
||||
Assert.Contains("gmrelay-web:2.7.0", File.ReadAllText(Path.Combine(repoRoot, "compose.yaml")));
|
||||
Assert.Contains("gmrelay-discord-bot:2.7.0", File.ReadAllText(Path.Combine(repoRoot, "compose.yaml")));
|
||||
Assert.Contains(
|
||||
"v2.6.0",
|
||||
"v2.7.0",
|
||||
File.ReadAllText(Path.Combine(repoRoot, "src", "GmRelay.Web", "Components", "Layout", "NavMenu.razor")));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
namespace GmRelay.Bot.Tests.Discord;
|
||||
|
||||
public sealed class DiscordRescheduleDeadlineBoundaryTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task DiscordDeadlineService_ShouldUsePlatformMessengerForMessageUpdates()
|
||||
{
|
||||
var source = await ReadRepositoryFileAsync(
|
||||
"src/GmRelay.DiscordBot/Features/Sessions/DiscordRescheduleVotingDeadlineService.cs");
|
||||
|
||||
Assert.DoesNotContain("RestClient", source, StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("ModifyMessageAsync", source, StringComparison.Ordinal);
|
||||
Assert.Contains("UpdateRescheduleVoteAsync", source, StringComparison.Ordinal);
|
||||
Assert.Contains("IPlatformMessenger", source, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private static async Task<string> ReadRepositoryFileAsync(string relativePath)
|
||||
{
|
||||
var directory = new DirectoryInfo(AppContext.BaseDirectory);
|
||||
while (directory is not null)
|
||||
{
|
||||
var candidate = Path.Combine(directory.FullName, relativePath);
|
||||
if (File.Exists(candidate))
|
||||
return await File.ReadAllTextAsync(candidate);
|
||||
|
||||
directory = directory.Parent;
|
||||
}
|
||||
|
||||
throw new FileNotFoundException($"Could not locate repository file '{relativePath}'.");
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,16 @@ public sealed class DiscordSessionInteractionModuleSourceTests
|
||||
Assert.Contains("MessageFlags.Ephemeral", source, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Module_ShouldRouteRsvpButtonsToNeutralHandler()
|
||||
{
|
||||
var source = await ReadRepositoryFileAsync("src/GmRelay.DiscordBot/Features/Sessions/DiscordSessionInteractionModule.cs");
|
||||
|
||||
Assert.Contains("[ComponentInteraction(\"rsvp\")", source, StringComparison.Ordinal);
|
||||
Assert.Contains("HandleRsvpHandler", source, StringComparison.Ordinal);
|
||||
Assert.Contains("PlatformKind.Discord", source, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private static async Task<string> ReadRepositoryFileAsync(string relativePath)
|
||||
{
|
||||
var directory = new DirectoryInfo(AppContext.BaseDirectory);
|
||||
|
||||
@@ -82,6 +82,9 @@ public sealed class DiscordStartupTests
|
||||
Assert.Contains("DiscordPermissionChecker", program);
|
||||
Assert.Contains("DiscordPlatformMessenger", program);
|
||||
Assert.Contains("IPlatformMessenger", program);
|
||||
Assert.Contains("PlatformSchedulerOptions(PlatformKind.Discord)", program);
|
||||
Assert.Contains("AddHostedService<SessionSchedulerService>", program);
|
||||
Assert.Contains("HandleRsvpHandler", program);
|
||||
}
|
||||
|
||||
private static string ReadProgram()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using GmRelay.Bot.Features.Confirmation.HandleRsvp;
|
||||
using GmRelay.Shared.Features.Confirmation.HandleRsvp;
|
||||
using GmRelay.Shared.Domain;
|
||||
|
||||
namespace GmRelay.Bot.Tests.Features.Confirmation.HandleRsvp;
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
namespace GmRelay.Bot.Tests.Infrastructure.Scheduling;
|
||||
|
||||
public sealed class SchedulerNotificationSourceTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("src/GmRelay.Shared/Features/Confirmation/SendConfirmation/SendConfirmationHandler.cs")]
|
||||
[InlineData("src/GmRelay.Shared/Features/Confirmation/HandleRsvp/HandleRsvpHandler.cs")]
|
||||
[InlineData("src/GmRelay.Shared/Features/Reminders/SendOneHourReminder/SendOneHourReminderHandler.cs")]
|
||||
[InlineData("src/GmRelay.Shared/Features/Reminders/SendJoinLink/SendJoinLinkHandler.cs")]
|
||||
public async Task SchedulerNotificationHandlers_ShouldUsePlatformMessengerWithoutSdkClients(string relativePath)
|
||||
{
|
||||
var source = await ReadRepositoryFileAsync(relativePath);
|
||||
|
||||
Assert.True(
|
||||
source.Contains("IPlatformMessenger", StringComparison.Ordinal) ||
|
||||
source.Contains("PlatformDirectNotificationSender", StringComparison.Ordinal),
|
||||
"Handler should use IPlatformMessenger directly or through PlatformDirectNotificationSender.");
|
||||
Assert.DoesNotContain("Telegram.Bot", source, StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("ITelegramBotClient", source, StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("NetCord", source, StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("RestClient", source, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DiscordProgram_ShouldRegisterSharedSchedulerForDiscordPlatform()
|
||||
{
|
||||
var program = await ReadRepositoryFileAsync("src/GmRelay.DiscordBot/Program.cs");
|
||||
|
||||
Assert.Contains("PlatformSchedulerOptions(PlatformKind.Discord)", program, StringComparison.Ordinal);
|
||||
Assert.Contains("AddHostedService<SessionSchedulerService>", program, StringComparison.Ordinal);
|
||||
Assert.Contains("DbSessionTriggerStore", program, StringComparison.Ordinal);
|
||||
Assert.Contains("SendConfirmationHandler", program, StringComparison.Ordinal);
|
||||
Assert.Contains("SendJoinLinkHandler", program, StringComparison.Ordinal);
|
||||
Assert.Contains("SendOneHourReminderHandler", program, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private static async Task<string> ReadRepositoryFileAsync(string relativePath)
|
||||
{
|
||||
var directory = new DirectoryInfo(AppContext.BaseDirectory);
|
||||
while (directory is not null)
|
||||
{
|
||||
var candidate = Path.Combine(directory.FullName, relativePath);
|
||||
if (File.Exists(candidate))
|
||||
{
|
||||
return await File.ReadAllTextAsync(candidate);
|
||||
}
|
||||
|
||||
directory = directory.Parent;
|
||||
}
|
||||
|
||||
throw new FileNotFoundException($"Could not locate repository file '{relativePath}'.");
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,8 @@
|
||||
using GmRelay.Bot.Features.Confirmation.SendConfirmation;
|
||||
using GmRelay.Bot.Features.Reminders.SendJoinLink;
|
||||
using GmRelay.Bot.Features.Reminders.SendOneHourReminder;
|
||||
using GmRelay.Bot.Infrastructure.Scheduling;
|
||||
using GmRelay.Shared.Features.Confirmation.SendConfirmation;
|
||||
using GmRelay.Shared.Features.Reminders.SendJoinLink;
|
||||
using GmRelay.Shared.Features.Reminders.SendOneHourReminder;
|
||||
using GmRelay.Shared.Infrastructure.Scheduling;
|
||||
using GmRelay.Shared.Platform;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
|
||||
namespace GmRelay.Bot.Tests.Infrastructure.Scheduling;
|
||||
@@ -211,4 +212,9 @@ public sealed class SessionSchedulerServiceTests
|
||||
return Task.FromResult<IReadOnlyList<Guid>>(SessionsNeedingJoinLink);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class FakeSystemClock : ISystemClock
|
||||
{
|
||||
public DateTimeOffset UtcNow { get; set; } = DateTimeOffset.UtcNow;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
namespace GmRelay.Bot.Tests.Infrastructure.Scheduling;
|
||||
|
||||
public sealed class SessionTriggerStoreSourceTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task DbSessionTriggerStore_ShouldFilterTriggersByConfiguredPlatform()
|
||||
{
|
||||
var source = await ReadRepositoryFileAsync(
|
||||
"src/GmRelay.Shared/Infrastructure/Scheduling/ISessionTriggerStore.cs");
|
||||
|
||||
Assert.Contains("PlatformSchedulerOptions", source, StringComparison.Ordinal);
|
||||
Assert.Contains("JOIN game_groups g ON g.id = s.group_id", source, StringComparison.Ordinal);
|
||||
Assert.Contains("g.platform = @Platform", source, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private static async Task<string> ReadRepositoryFileAsync(string relativePath)
|
||||
{
|
||||
var directory = new DirectoryInfo(AppContext.BaseDirectory);
|
||||
while (directory is not null)
|
||||
{
|
||||
var candidate = Path.Combine(directory.FullName, relativePath);
|
||||
if (File.Exists(candidate))
|
||||
{
|
||||
return await File.ReadAllTextAsync(candidate);
|
||||
}
|
||||
|
||||
directory = directory.Parent;
|
||||
}
|
||||
|
||||
throw new FileNotFoundException($"Could not locate repository file '{relativePath}'.");
|
||||
}
|
||||
}
|
||||
+20
@@ -39,6 +39,26 @@ public sealed class TelegramPlatformMessengerSourceTests
|
||||
Assert.Contains("BatchMessageEditor.EditBatchMessageAsync", source, StringComparison.Ordinal);
|
||||
Assert.Contains("AnswerCallbackQuery", source, StringComparison.Ordinal);
|
||||
Assert.Contains("SendDocument", source, StringComparison.Ordinal);
|
||||
Assert.Contains("SendConfirmationRequestAsync", source, StringComparison.Ordinal);
|
||||
Assert.Contains("UpdateConfirmationRequestAsync", source, StringComparison.Ordinal);
|
||||
Assert.Contains("SendJoinLinkNotificationAsync", source, StringComparison.Ordinal);
|
||||
Assert.Contains("SendDirectSessionNotificationAsync", source, StringComparison.Ordinal);
|
||||
Assert.Contains("UpdateRescheduleVoteAsync", source, StringComparison.Ordinal);
|
||||
Assert.Contains("messageThreadId", source, StringComparison.Ordinal);
|
||||
Assert.Contains("ParseMode.Html", source, StringComparison.Ordinal);
|
||||
Assert.Contains("InlineKeyboardButton.WithCallbackData", source, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RescheduleVotingDeadlineService_ShouldUsePlatformMessengerForVoteMessageUpdates()
|
||||
{
|
||||
var source = await ReadRepositoryFileAsync(
|
||||
"src/GmRelay.Bot/Features/Sessions/RescheduleSession/RescheduleVotingDeadlineService.cs");
|
||||
|
||||
Assert.DoesNotContain("ITelegramBotClient", source, StringComparison.Ordinal);
|
||||
Assert.DoesNotContain(".EditMessageText(", source, StringComparison.Ordinal);
|
||||
Assert.Contains("UpdateRescheduleVoteAsync", source, StringComparison.Ordinal);
|
||||
Assert.Contains("IPlatformMessenger", source, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private static async Task<string> ReadRepositoryFileAsync(string relativePath)
|
||||
|
||||
+11
-8
@@ -22,25 +22,25 @@ public sealed class TelegramTopicIntegrationSmokeTests
|
||||
[Fact]
|
||||
public async Task GroupNotifications_ShouldSendToStoredForumTopic()
|
||||
{
|
||||
var confirmationHandler = await ReadRepositoryFileAsync("src/GmRelay.Bot/Features/Confirmation/SendConfirmation/SendConfirmationHandler.cs");
|
||||
var joinLinkHandler = await ReadRepositoryFileAsync("src/GmRelay.Bot/Features/Reminders/SendJoinLink/SendJoinLinkHandler.cs");
|
||||
var rsvpHandler = await ReadRepositoryFileAsync("src/GmRelay.Bot/Features/Confirmation/HandleRsvp/HandleRsvpHandler.cs");
|
||||
var confirmationHandler = await ReadRepositoryFileAsync("src/GmRelay.Shared/Features/Confirmation/SendConfirmation/SendConfirmationHandler.cs");
|
||||
var joinLinkHandler = await ReadRepositoryFileAsync("src/GmRelay.Shared/Features/Reminders/SendJoinLink/SendJoinLinkHandler.cs");
|
||||
var rsvpHandler = await ReadRepositoryFileAsync("src/GmRelay.Shared/Features/Confirmation/HandleRsvp/HandleRsvpHandler.cs");
|
||||
var cancelHandler = await ReadRepositoryFileAsync("src/GmRelay.Bot/Features/Sessions/CreateSession/CancelSessionHandler.cs");
|
||||
var initiateRescheduleHandler = await ReadRepositoryFileAsync("src/GmRelay.Bot/Features/Sessions/RescheduleSession/InitiateRescheduleHandler.cs");
|
||||
var rescheduleInputHandler = await ReadRepositoryFileAsync("src/GmRelay.Bot/Features/Sessions/RescheduleSession/HandleRescheduleTimeInputHandler.cs");
|
||||
var rescheduleDeadlineService = await ReadRepositoryFileAsync("src/GmRelay.Bot/Features/Sessions/RescheduleSession/RescheduleVotingDeadlineService.cs");
|
||||
var telegramMessenger = await ReadRepositoryFileAsync("src/GmRelay.Bot/Infrastructure/Telegram/TelegramPlatformMessenger.cs");
|
||||
|
||||
Assert.Contains("int? ThreadId", confirmationHandler, StringComparison.Ordinal);
|
||||
Assert.Contains("s.thread_id AS ThreadId", confirmationHandler, StringComparison.Ordinal);
|
||||
Assert.Contains("messageThreadId: session.ThreadId", confirmationHandler, StringComparison.Ordinal);
|
||||
Assert.Contains("ExternalThreadId", confirmationHandler, StringComparison.Ordinal);
|
||||
|
||||
Assert.Contains("int? ThreadId", joinLinkHandler, StringComparison.Ordinal);
|
||||
Assert.Contains("s.thread_id AS ThreadId", joinLinkHandler, StringComparison.Ordinal);
|
||||
Assert.Contains("messageThreadId: session.ThreadId", joinLinkHandler, StringComparison.Ordinal);
|
||||
Assert.Contains("ExternalThreadId", joinLinkHandler, StringComparison.Ordinal);
|
||||
|
||||
Assert.Contains("int? ThreadId", rsvpHandler, StringComparison.Ordinal);
|
||||
Assert.Contains("s.thread_id AS ThreadId", rsvpHandler, StringComparison.Ordinal);
|
||||
Assert.Contains("messageThreadId: session.ThreadId", rsvpHandler, StringComparison.Ordinal);
|
||||
Assert.Contains("PlatformMessageRef ConfirmationMessage", rsvpHandler, StringComparison.Ordinal);
|
||||
Assert.Contains("UpdateConfirmationRequestAsync", rsvpHandler, StringComparison.Ordinal);
|
||||
|
||||
Assert.Contains("int? MessageThreadId", cancelHandler, StringComparison.Ordinal);
|
||||
Assert.Contains("TelegramPlatformIds.Group(command.ChatId, command.MessageThreadId)", cancelHandler, StringComparison.Ordinal);
|
||||
@@ -55,6 +55,9 @@ public sealed class TelegramTopicIntegrationSmokeTests
|
||||
Assert.Contains("int? ThreadId", rescheduleDeadlineService, StringComparison.Ordinal);
|
||||
Assert.Contains("s.thread_id AS ThreadId", rescheduleDeadlineService, StringComparison.Ordinal);
|
||||
Assert.Contains("TelegramPlatformIds.Group(telegramFields.TelegramChatId, telegramFields.ThreadId)", rescheduleDeadlineService, StringComparison.Ordinal);
|
||||
|
||||
Assert.Contains("messageThreadId", telegramMessenger, StringComparison.Ordinal);
|
||||
Assert.Contains("ExternalThreadId", telegramMessenger, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
private static async Task<string> ReadRepositoryFileAsync(string relativePath)
|
||||
|
||||
@@ -51,4 +51,42 @@ public sealed class PlatformContractsTests
|
||||
Assert.Equal(PlatformKind.Discord, message.Group.Platform);
|
||||
Assert.Same(view, message.View);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PlatformNotificationContracts_ShouldBeSdkAssemblyFree()
|
||||
{
|
||||
var contractTypes = new[]
|
||||
{
|
||||
typeof(PlatformSessionParticipant),
|
||||
typeof(PlatformConfirmationRequest),
|
||||
typeof(PlatformJoinLinkNotification),
|
||||
typeof(PlatformDirectSessionNotification),
|
||||
typeof(PlatformRsvpMessageUpdate),
|
||||
typeof(PlatformRsvpOutcomeNotification),
|
||||
typeof(PlatformRescheduleVoteUpdate)
|
||||
};
|
||||
|
||||
Assert.All(contractTypes, type =>
|
||||
{
|
||||
var refs = string.Join(" ", type.Assembly.GetReferencedAssemblies().Select(value => value.Name));
|
||||
Assert.DoesNotContain("Telegram", refs, StringComparison.OrdinalIgnoreCase);
|
||||
Assert.DoesNotContain("NetCord", refs, StringComparison.OrdinalIgnoreCase);
|
||||
});
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void PlatformMessenger_ShouldExposeSchedulerNotificationOperations()
|
||||
{
|
||||
var methods = typeof(IPlatformMessenger)
|
||||
.GetMethods()
|
||||
.Select(method => method.Name)
|
||||
.ToHashSet(StringComparer.Ordinal);
|
||||
|
||||
Assert.Contains("SendConfirmationRequestAsync", methods);
|
||||
Assert.Contains("UpdateConfirmationRequestAsync", methods);
|
||||
Assert.Contains("SendJoinLinkNotificationAsync", methods);
|
||||
Assert.Contains("SendDirectSessionNotificationAsync", methods);
|
||||
Assert.Contains("SendRsvpOutcomeAsync", methods);
|
||||
Assert.Contains("UpdateRescheduleVoteAsync", methods);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user