using LiveRecorder.Application.Abstractions.Notifications; using LiveRecorder.Application.Abstractions.Scripting; using LiveRecorder.Application.Abstractions.Platforms; using LiveRecorder.Application.Models.Reports; using LiveRecorder.Application.Models.Settings; using LiveRecorder.Application.Services; using LiveRecorder.Domain.Entities; using LiveRecorder.Domain.Enums; namespace LiveRecorder.Tests; public sealed class LiveRoomStatusServiceTests { [Fact] public async Task ApplySnapshotAsync_passes_event_script_output_to_notifications() { var email = new FakeEmailNotificationService(); var webhook = new FakeWebhookNotificationService(); var eventScript = new FakeEventScriptService { LiveStartedResult = new EventScriptExecutionResultDto { Success = true, Message = "ok", CustomLogOutput = "line one from script\nline two from script" } }; var service = new LiveRoomStatusService(email, webhook, eventScript); var now = DateTimeOffset.UtcNow; var liveRoom = new LiveRoom( LivePlatformType.Douyin, "https://live.douyin.com/123456", "123456", "https://live.douyin.com/123456", now); var snapshot = new LiveStatusSnapshot( true, "Sample title", "Sample anchor", "anchor-1", AvatarUrl: null, CoverUrl: null, 1, "live"); await service.ApplySnapshotAsync(liveRoom, snapshot, now); Assert.Equal(eventScript.LiveStartedResult.CustomLogOutput, email.LastLiveStartedEventScriptOutput); Assert.Equal(eventScript.LiveStartedResult.CustomLogOutput, webhook.LastLiveStartedEventScriptOutput); Assert.True(liveRoom.HasSentLiveNotificationForCurrentSession); } private sealed class FakeEmailNotificationService : IEmailNotificationService { public string? LastLiveStartedEventScriptOutput { get; private set; } public Task SendLiveStartedAsync( LiveRoom liveRoom, CancellationToken cancellationToken = default, string? eventScriptOutput = null) { LastLiveStartedEventScriptOutput = eventScriptOutput; return Task.CompletedTask; } public Task SendExceptionAsync( string source, string summary, string? detail = null, LiveRoom? liveRoom = null, RecordTask? recordTask = null, CancellationToken cancellationToken = default, string? eventScriptOutput = null) => Task.CompletedTask; public Task SendTestAsync(SendTestEmailRequest request, CancellationToken cancellationToken = default) => Task.CompletedTask; public Task SendDailyReviewAsync(DailyReviewReportDto report, CancellationToken cancellationToken = default) => Task.CompletedTask; } private sealed class FakeWebhookNotificationService : IWebhookNotificationService { public string? LastLiveStartedEventScriptOutput { get; private set; } public Task SendLiveStartedAsync( LiveRoom liveRoom, CancellationToken cancellationToken = default, string? eventScriptOutput = null) { LastLiveStartedEventScriptOutput = eventScriptOutput; return Task.CompletedTask; } public Task SendExceptionAsync( string source, string summary, string? detail = null, LiveRoom? liveRoom = null, RecordTask? recordTask = null, CancellationToken cancellationToken = default, string? eventScriptOutput = null) => Task.CompletedTask; public Task SendTestAsync( SendTestWebhookRequest request, CancellationToken cancellationToken = default) => Task.FromResult(new WebhookTestResultDto { Success = true, Message = "ok" }); public Task SendDailyReviewAsync( DailyReviewReportDto report, CancellationToken cancellationToken = default) => Task.CompletedTask; } private sealed class FakeEventScriptService : IEventScriptService { public EventScriptExecutionResultDto? LiveStartedResult { get; init; } public Task RunLiveStartedAsync( LiveRoom liveRoom, DateTimeOffset occurredAt, CancellationToken cancellationToken = default) => Task.FromResult(LiveStartedResult); public Task RunLiveEndedAsync( LiveRoom liveRoom, DateTimeOffset occurredAt, CancellationToken cancellationToken = default) => Task.FromResult(null); public Task RunSegmentCompletedAsync( LiveRoom? liveRoom, RecordSession recordSession, RecordTask recordTask, RecordResult? recordResult, string segmentFilePath, DateTimeOffset occurredAt, bool forceRun = false, CancellationToken cancellationToken = default) => Task.FromResult(null); public Task TestAsync( TestEventScriptRequest request, CancellationToken cancellationToken = default) => Task.FromResult(new EventScriptTestResultDto { Success = true, Message = "ok" }); } }