using System; using System.Collections.Generic; using System.IO; using System.Linq; using Paca.Mobile.Core; using Xunit; namespace Paca.Tests.Mobile; /// /// 직관적 다운로드 큐, 다운로드 파일 브라우징, 필터링, 정렬 및 일괄 정리 게이트 (Gate 146 ~ Gate 152) /// public class MobileIntuitiveUxGateTests { [Fact] public void Gate146_MobileLibraryFileManager_Scan_Audit() { var manager = new MobileLibraryFileManager(); var fakeFiles = new List { new("v1.mp4", "/storage/emulated/0/Download/v1.mp4", 1024 * 1024 * 50, DateTime.UtcNow.AddMinutes(-10), LocalMediaType.Video), new("a1.mp3", "/storage/emulated/0/Download/a1.mp3", 1024 * 1024 * 5, DateTime.UtcNow.AddMinutes(-5), LocalMediaType.Audio), new("doc.pdf", "/storage/emulated/0/Download/doc.pdf", 1024 * 100, DateTime.UtcNow, LocalMediaType.Other) }; manager.SetFiles(fakeFiles); Assert.Equal(3, manager.Files.Count); Assert.Equal("50.0 MB", fakeFiles[0].FormattedSize); Assert.Equal("5.0 MB", fakeFiles[1].FormattedSize); } [Fact] public void Gate147_MobileLibraryFilterEngine_Category_Audit() { var filter = new MobileLibraryFilterEngine(); var files = new List { new("vid1.mp4", "/path/vid1.mp4", 500, DateTime.UtcNow, LocalMediaType.Video), new("vid2.webm", "/path/vid2.webm", 300, DateTime.UtcNow, LocalMediaType.Video), new("song.mp3", "/path/song.mp3", 100, DateTime.UtcNow, LocalMediaType.Audio), new("podcast.m4a", "/path/podcast.m4a", 150, DateTime.UtcNow, LocalMediaType.Audio) }; var videos = filter.FilterByCategory(files, LibraryCategoryFilter.Video); Assert.Equal(2, videos.Count); Assert.All(videos, f => Assert.Equal(LocalMediaType.Video, f.Type)); var audios = filter.FilterByCategory(files, LibraryCategoryFilter.Audio); Assert.Equal(2, audios.Count); Assert.All(audios, f => Assert.Equal(LocalMediaType.Audio, f.Type)); var all = filter.FilterByCategory(files, LibraryCategoryFilter.All); Assert.Equal(4, all.Count); } [Fact] public void Gate148_MobileLibrarySortEngine_MultiCriteria_Audit() { var sorter = new MobileLibrarySortEngine(); var files = new List { new("Banana.mp4", "/path/b", 100, DateTime.UtcNow.AddHours(-2), LocalMediaType.Video), new("Apple.mp4", "/path/a", 500, DateTime.UtcNow.AddHours(-1), LocalMediaType.Video), new("Cherry.mp4", "/path/c", 200, DateTime.UtcNow, LocalMediaType.Video) }; // 최신순 (DateDesc) var byDate = sorter.Sort(files, LibrarySortCriteria.DateDesc); Assert.Equal("Cherry.mp4", byDate[0].FileName); Assert.Equal("Banana.mp4", byDate[2].FileName); // 이름순 (NameAsc) var byName = sorter.Sort(files, LibrarySortCriteria.NameAsc); Assert.Equal("Apple.mp4", byName[0].FileName); Assert.Equal("Cherry.mp4", byName[2].FileName); // 크기순 (SizeDesc) var bySize = sorter.Sort(files, LibrarySortCriteria.SizeDesc); Assert.Equal("Apple.mp4", bySize[0].FileName); // 500 Assert.Equal("Banana.mp4", bySize[2].FileName); // 100 } [Fact] public void Gate149_MobileLibraryBatchManager_Cleanup_Audit() { var batch = new MobileLibraryBatchManager(); var files = new List { new("corrupt.part", "/path/corrupt.part", 0, DateTime.UtcNow, LocalMediaType.Other), new("normal.mp4", "/path/normal.mp4", 1024, DateTime.UtcNow, LocalMediaType.Video), new("empty.tmp", "/path/empty.tmp", 0, DateTime.UtcNow, LocalMediaType.Other) }; var cleaned = batch.PurgeEmptyFiles(files); Assert.Single(cleaned); Assert.Equal("normal.mp4", cleaned[0].FileName); } [Fact] public void Gate150_MobileQuickDownloadBar_ClipboardDetection_Audit() { var quickBar = new MobileQuickDownloadBar(); Assert.False(quickBar.TryDetectDownloadableMedia("안녕하세요 일반 텍스트입니다.", out _)); Assert.True(quickBar.TryDetectDownloadableMedia("이 영상 봐봐 https://youtu.be/dQw4w9WgXcQ 짱이야", out var extractedUrl)); Assert.Equal("https://youtu.be/dQw4w9WgXcQ", extractedUrl); } [Fact] public void Gate151_DownloadsPage_HubModel_Audit() { // 큐 관리와 파일 보관함을 한 곳에서 탭으로 쉽게 전환하는 통합 허브 모델 var hub = new DownloadsHubModel(); Assert.Equal(DownloadsHubTab.Queue, hub.CurrentTab); hub.SwitchTab(DownloadsHubTab.CompletedLibrary); Assert.Equal(DownloadsHubTab.CompletedLibrary, hub.CurrentTab); } [Fact] public void Gate152_EndToEndDownloadsAndLibraryJourneyAudit_Audit() { var qm = new MobileQueueManager(); var library = new MobileLibraryFileManager(); var filter = new MobileLibraryFilterEngine(); var sorter = new MobileLibrarySortEngine(); // 1. 큐에 비디오 및 오디오 다운로드 등록 var item1 = qm.Enqueue("https://example.com/v1.mp4", "Epic Nature 4K"); var item2 = qm.Enqueue("https://example.com/a1.m4a", "Chill Beats"); // 2. 다운로드 완료 시 보관함에 자동 등록 item1.Status = MobileQueueStatus.Completed; item2.Status = MobileQueueStatus.Completed; library.SetFiles(new List { new(item1.Title + ".mp4", "/storage/v1.mp4", 1024 * 1024 * 80, DateTime.UtcNow.AddMinutes(-2), LocalMediaType.Video), new(item2.Title + ".m4a", "/storage/a1.m4a", 1024 * 1024 * 10, DateTime.UtcNow, LocalMediaType.Audio) }); // 3. 비디오만 필터링 var videosOnly = filter.FilterByCategory(library.Files, LibraryCategoryFilter.Video); Assert.Single(videosOnly); Assert.Equal("Epic Nature 4K.mp4", videosOnly[0].FileName); // 4. 최신순 정렬 var sorted = sorter.Sort(library.Files, LibrarySortCriteria.DateDesc); Assert.Equal("Chill Beats.m4a", sorted[0].FileName); } }