using LiveRecorder.Domain.Enums; using LiveRecorder.Infrastructure.Services; namespace LiveRecorder.Tests; public sealed class OrphanedSegmentRecoveryTests : IDisposable { private readonly string _temporaryDirectory = Path.Combine( Path.GetTempPath(), $"liverecorder-orphan-recovery-{Guid.NewGuid():N}"); [Fact] public void DiscoverRecoverableSegments_FindsExactNonEmptySegmentFilesInOrder() { Directory.CreateDirectory(_temporaryDirectory); var pattern = Path.Combine(_temporaryDirectory, "224332_186东北男大_%05d.mp4"); File.WriteAllBytes(Path.Combine(_temporaryDirectory, "224332_186东北男大_00003.ts"), [3]); File.WriteAllBytes(Path.Combine(_temporaryDirectory, "224332_186东北男大_00001.ts"), [1]); File.WriteAllBytes(Path.Combine(_temporaryDirectory, "224332_186东北男大_00002.ts"), [2]); File.WriteAllBytes(Path.Combine(_temporaryDirectory, "other_00004.ts"), [4]); File.WriteAllBytes(Path.Combine(_temporaryDirectory, "224332_186东北男大_00004.ts"), []); File.WriteAllText(Path.Combine(_temporaryDirectory, "224332_186东北男大_00001.xml"), ""); var segments = FfmpegService.DiscoverRecoverableSegments( pattern, RecordOutputFormat.Mp4, RecordSaveMode.Segmented); Assert.Equal([1, 2, 3], segments.Select(segment => segment.SegmentIndex)); Assert.Equal( Path.Combine(_temporaryDirectory, "224332_186东北男大_00002.ts"), segments[1].RecorderPath); Assert.Equal( Path.Combine(_temporaryDirectory, "224332_186东北男大_00002.mp4"), segments[1].OutputPath); } [Theory] [InlineData(RecordOutputFormat.Ts, RecordSaveMode.Segmented)] [InlineData(RecordOutputFormat.Mp4, RecordSaveMode.SingleFile)] public void DiscoverRecoverableSegments_RejectsUnsupportedRecordingModes( RecordOutputFormat outputFormat, RecordSaveMode saveMode) { Directory.CreateDirectory(_temporaryDirectory); var pattern = Path.Combine(_temporaryDirectory, "record_%05d.mp4"); File.WriteAllBytes(Path.Combine(_temporaryDirectory, "record_00001.ts"), [1]); var segments = FfmpegService.DiscoverRecoverableSegments(pattern, outputFormat, saveMode); Assert.Empty(segments); } [Fact] public void DiscoverRecoverableSegments_IsIdempotentAndDoesNotModifySourceFiles() { Directory.CreateDirectory(_temporaryDirectory); var sourcePath = Path.Combine(_temporaryDirectory, "record_00001.ts"); var pattern = Path.Combine(_temporaryDirectory, "record_%05d.mp4"); File.WriteAllBytes(sourcePath, [1, 2, 3]); var first = FfmpegService.DiscoverRecoverableSegments(pattern, RecordOutputFormat.Mp4, RecordSaveMode.Segmented); var second = FfmpegService.DiscoverRecoverableSegments(pattern, RecordOutputFormat.Mp4, RecordSaveMode.Segmented); Assert.Equal(first, second); Assert.True(File.Exists(sourcePath)); Assert.Equal(3, new FileInfo(sourcePath).Length); Assert.False(File.Exists(Path.ChangeExtension(sourcePath, ".mp4"))); } public void Dispose() { if (Directory.Exists(_temporaryDirectory)) { Directory.Delete(_temporaryDirectory, recursive: true); } } }