using System; using System.IO; using System.Linq; using Xunit; using ytLive.Services; namespace ytLive.Tests; /// /// TASK 65 slice 3 — clips on disk, with retention and nothing else. /// /// The rule: write one file, delete the oldest past the count. No gallery, no prompt. The tests pin /// the two ways that could go wrong — a zero-byte clip from an empty ring, and pruning taking something /// that isn't ours. /// public sealed class ClipLibraryTests : IDisposable { private readonly string _root = Path.Combine(Path.GetTempPath(), $"ytLlive-clips-{Guid.NewGuid():N}"); public ClipLibraryTests() => Directory.CreateDirectory(_root); public void Dispose() { try { Directory.Delete(_root, recursive: true); } catch { /* best effort */ } } private ClipLibrary Library() => new(() => _root); [Fact] public void SaveWritesIntoClipsBesideTheRecordings() { var path = Library().Save(new byte[] { 1, 2, 3 }, DateTime.Now, keep: 3); Assert.NotNull(path); Assert.EndsWith(".mp4", path); Assert.Equal(Path.Combine(_root, "clips"), Path.GetDirectoryName(path)); Assert.True(File.Exists(path)); } [Fact] public void AnEmptySnapshotNeverBecomesAZeroByteFile() { Assert.Null(Library().Save(Array.Empty(), DateTime.Now, keep: 3)); Assert.False(Directory.Exists(Path.Combine(_root, "clips")) && Directory.EnumerateFiles(Path.Combine(_root, "clips")).Any()); } [Fact] public void RetentionKeepsTheNewestAndDeletesTheRest() { var library = Library(); var folder = library.EnsureFolder(); for (var i = 0; i < 6; i++) File.WriteAllText(Path.Combine(folder, $"clip-20261110-12000{i}.mp4"), "x"); File.WriteAllText(Path.Combine(folder, "someone-elses-file.mp4"), "keep me"); var removed = library.Prune(keep: 3); Assert.Equal(3, removed); var remaining = library.Recent(); Assert.Equal(3, remaining.Count); Assert.Contains("120005", remaining[0]); // newest first Assert.True(File.Exists(Path.Combine(folder, "someone-elses-file.mp4"))); } [Fact] public void RingBytesFollowLengthAndBitrate_WithHeadroom() { var tenAt8 = ClipLibrary.RingBytesFor(10, 8000); var fifteenAt8 = ClipLibrary.RingBytesFor(15, 8000); Assert.True(tenAt8 > 10L * 8000 * 1000 / 8); // more than the exact wire size Assert.True(fifteenAt8 > tenAt8); Assert.True(tenAt8 < 15L * 1024 * 1024); // and still modest } }