using System; using System.Collections.Generic; using System.IO; using Paca.Mobile.Core; using Xunit; namespace Paca.Tests.Mobile; /// /// Gate 147 ~ 150: 모바일 오프라인 미디어 라이브러리 & 스토리지 대시보드 기계적 검증 /// public class MobileOfflineLibraryDashboardGateTests { [Fact] public void Gate147_OfflineMediaItem_DisplayFormatting() { var item1 = new OfflineMediaItem( Id: "media-1", FileName: "RickRoll_4K.mp4", SizeBytes: 104_857_600L, // 100 MB LocalFilePath: "/data/user/0/com.paca.mobile/files/RickRoll_4K.mp4", DownloadedAt: DateTimeOffset.UtcNow, IsIntegrityVerified: true ); Assert.Equal("100.0 MB", item1.DisplaySize); Assert.True(item1.IsIntegrityVerified); var item2 = new OfflineMediaItem( Id: "media-2", FileName: "LongVideo_HDR.mkv", SizeBytes: 1_610_612_736L, // 1.5 GB LocalFilePath: "/data/user/0/com.paca.mobile/files/LongVideo_HDR.mkv", DownloadedAt: DateTimeOffset.UtcNow, IsIntegrityVerified: true ); Assert.Equal("1.5 GB", item2.DisplaySize); } [Fact] public void Gate148_LocalStorageDashboard_Calculates_Usage_Percentages() { // 총 128 GB (137,438,953,472 B), 남은 용량 64 GB, Paca 사용 6.4 GB (5%) long totalStorage = 128L * 1024 * 1024 * 1024; long freeStorage = 64L * 1024 * 1024 * 1024; long pacaStorage = (long)(totalStorage * 0.05); // 5% var dashboard = LocalStorageDashboard.Calculate(totalStorage, freeStorage, pacaStorage); Assert.Equal(5.0, Math.Round(dashboard.PacaUsagePercent, 1)); Assert.Equal(50.0, Math.Round(dashboard.FreePercent, 1)); Assert.Contains("Paca", dashboard.StorageSummaryText); Assert.Contains("여유", dashboard.StorageSummaryText); } [Fact] public void Gate149_OfflineLibraryManager_Filtering_And_Sorting() { var manager = new OfflineLibraryManager(); manager.RegisterMedia(new OfflineMediaItem("id-1", "Alpha.mp4", 50_000_000, "/path/1", DateTimeOffset.UtcNow.AddHours(-2), true)); manager.RegisterMedia(new OfflineMediaItem("id-2", "Beta.mp3", 10_000_000, "/path/2", DateTimeOffset.UtcNow.AddHours(-1), true)); manager.RegisterMedia(new OfflineMediaItem("id-3", "Gamma.mp4", 200_000_000, "/path/3", DateTimeOffset.UtcNow, true)); // 1. 최신순 정렬 검증 (Gamma -> Beta -> Alpha) var recentList = manager.GetItems(MediaFilter.All, MediaSortOrder.NewestFirst); Assert.Equal(3, recentList.Count); Assert.Equal("Gamma.mp4", recentList[0].FileName); Assert.Equal("Beta.mp3", recentList[1].FileName); Assert.Equal("Alpha.mp4", recentList[2].FileName); // 2. 용량 큰 순 정렬 검증 (Gamma(200MB) -> Alpha(50MB) -> Beta(10MB)) var sizeList = manager.GetItems(MediaFilter.All, MediaSortOrder.LargestFirst); Assert.Equal("Gamma.mp4", sizeList[0].FileName); Assert.Equal("Alpha.mp4", sizeList[1].FileName); Assert.Equal("Beta.mp3", sizeList[2].FileName); // 3. 오디오만 필터링 검증 var audioList = manager.GetItems(MediaFilter.AudioOnly, MediaSortOrder.NewestFirst); Assert.Single(audioList); Assert.Equal("Beta.mp3", audioList[0].FileName); // 4. 비디오만 필터링 검증 var videoList = manager.GetItems(MediaFilter.VideoOnly, MediaSortOrder.NewestFirst); Assert.Equal(2, videoList.Count); Assert.DoesNotContain(videoList, x => x.FileName.EndsWith(".mp3")); } [Fact] public void Gate150_OfflineLibraryManager_Deletion_Updates_Quota() { var manager = new OfflineLibraryManager(); manager.RegisterMedia(new OfflineMediaItem("id-1", "Video1.mp4", 100_000_000, "/path/1", DateTimeOffset.UtcNow, true)); manager.RegisterMedia(new OfflineMediaItem("id-2", "Video2.mp4", 50_000_000, "/path/2", DateTimeOffset.UtcNow, true)); Assert.Equal(150_000_000L, manager.TotalPacaBytes); // id-1 삭제 var removed = manager.RemoveMedia("id-1"); Assert.True(removed); Assert.Equal(50_000_000L, manager.TotalPacaBytes); Assert.Single(manager.GetItems(MediaFilter.All, MediaSortOrder.NewestFirst)); } }