using GmRelay.Shared.Platform; using GmRelay.Shared.Rendering; namespace GmRelay.Bot.Tests.Platform; public sealed class PlatformContractsTests { [Fact] public void PlatformKind_ShouldDefineTelegramDiscordAndMaxSentinel() { Assert.Equal(0, (int)PlatformKind.Telegram); Assert.Equal(1, (int)PlatformKind.Discord); Assert.Equal(2, (int)PlatformKind.Max); } [Fact] public void PlatformContracts_ShouldBeTelegramAssemblyFree() { var contractTypes = new[] { typeof(PlatformUser), typeof(PlatformGroup), typeof(PlatformMessageRef), typeof(PlatformMessageAction), typeof(PlatformScheduleMessage), typeof(PlatformPrivateMessage), typeof(PlatformInteractionReply), typeof(PlatformCalendarFile), typeof(IPlatformMessenger) }; Assert.All(contractTypes, type => Assert.DoesNotContain( "Telegram", string.Join(" ", type.Assembly.GetReferencedAssemblies().Select(value => value.Name)), StringComparison.OrdinalIgnoreCase)); } [Fact] public void PlatformScheduleMessage_ShouldCarrySharedViewModelWithoutPlatformTypes() { var sessionId = Guid.Parse("aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"); var view = SessionBatchViewBuilder.Build( "Campaign", [new SessionBatchDto(sessionId, new DateTime(2026, 5, 15, 16, 0, 0, DateTimeKind.Utc), "Planned", 4, "https://example.test/game")], []); var group = new PlatformGroup(PlatformKind.Discord, "guild-1", "Guild", "channel-1", "thread-1"); var message = new PlatformScheduleMessage(group, view, ExistingMessage: null); 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); } }