using System; using System.Collections.Generic; using System.Linq; using Paca.Core.Config; using Paca.Mobile.Core; using Xunit; namespace Paca.Tests.Mobile; /// /// 모바일 & 데스크톱 융합 복합 E2E 사용자 여정 시나리오 (Gate 98 ~ Gate 102) /// public class MobileComplexJourneyTests { [Fact] public void Gate98_Journey1_Discover_To_Enqueue_To_Pin_To_TurboDownload_Audit() { // 1. 모바일에서 YouTube URL 탐색 var url = "https://www.youtube.com/watch?v=sample123"; var detection = MobileDiscoveryEngine.DetectPlatform(url); Assert.True(detection.IsSupported); Assert.Equal("YouTube", detection.PlatformName); // 2. 큐 관리자에 등록 var qm = new MobileQueueManager(); var item1 = qm.Enqueue("https://example.com/other.mp4", "Other Video"); var item2 = qm.Enqueue(url, "Trending Sample Video"); // 3. 중요한 항목 상단 고정 (Pin to Top) qm.Pin(item2.Id); Assert.True(item2.IsPinned); Assert.Equal(item2.Id, qm.Items[0].Id); // 0번째 인덱스로 승격 // 4. 터보 모드 설정 연계 var cfg = new AppConfig(); cfg.TurboModeEnabled = true; cfg.MaxConcurrentSegments = 16; Assert.True(cfg.TurboModeEnabled); Assert.Equal(16, cfg.MaxConcurrentSegments); } [Fact] public void Gate99_Journey2_NetworkLost_To_GuardPause_To_RestoredResume_Audit() { var qm = new MobileQueueManager(); var item1 = qm.Enqueue("https://example.com/v1.mp4", "Video 1"); var item2 = qm.Enqueue("https://example.com/v2.mp4", "Video 2"); item1.Status = MobileQueueStatus.Downloading; item2.Status = MobileQueueStatus.Downloading; var guard = new MobileNetworkGuard(qm); // 엘리베이터 진입으로 LTE/Wi-Fi 신호 상실 guard.OnNetworkLost(); Assert.Equal(MobileQueueStatus.PausedNetwork, item1.Status); Assert.Equal(MobileQueueStatus.PausedNetwork, item2.Status); // Wi-Fi 재연결 감지 시 자동 재개 guard.OnNetworkRestored(isWifi: true); Assert.Equal(MobileQueueStatus.Downloading, item1.Status); Assert.Equal(MobileQueueStatus.Downloading, item2.Status); } [Fact] public void Gate100_Journey3_PcTabSync_To_RemoteDownload_To_FavoritesStash_Audit() { // 1. PC에서 열린 탭 동기화 수신 var syncEngine = new MobileTabSyncEngine(); var pcTabs = new List { new("tab-101", "Spring Concert Live", "https://vimeo.com/998877") }; syncEngine.UpdateRemoteTabs(pcTabs); Assert.Single(syncEngine.RemoteTabs); // 2. 모바일에서 원격 다운로드 요청 string? downloadedUrl = null; syncEngine.OnRemoteDownloadRequested += u => downloadedUrl = u; syncEngine.RequestRemoteDownload("tab-101"); Assert.Equal("https://vimeo.com/998877", downloadedUrl); // 3. 완료 후 모바일 보관함(Stash) 및 즐겨찾기에 등록 var favManager = new MobileFavoritesManager(); var fav = favManager.AddFavorite(downloadedUrl!, "Spring Concert Live", "음악"); favManager.ToggleStash(fav.Id); Assert.True(fav.IsStashedForDownload); Assert.Equal("음악", fav.Tag); } [Fact] public void Gate101_Journey4_Deduplication_To_FailureRetry_Lifecycle_Audit() { var qm = new MobileQueueManager(); var item = qm.Enqueue("https://example.com/stream.m3u8", "HLS Live Stream"); item.Status = MobileQueueStatus.Downloading; // 서버 503 에러로 실패 발생 item.Status = MobileQueueStatus.Failed; item.ErrorMessage = "HTTP 503 Service Unavailable"; // 사용자 실패 항목 재시도 트리거 var retried = qm.RetryFailedItems(); Assert.Equal(1, retried); Assert.Equal(MobileQueueStatus.Queued, item.Status); Assert.Null(item.ErrorMessage); } [Fact] public void Gate102_Journey5_Preferences_Persistence_And_ThemeSwitch_Audit() { var settings = new MobileSettingsManager(); settings.ThemeMode = MobileThemeMode.Dark; settings.SpeedLimitKbps = 5120; // 5MB/s settings.WifiOnlyDownload = true; settings.NotifyOnCompletion = true; var palette = MobileThemeSystem.GetPalette(settings.ThemeMode); Assert.Equal("#0B0C10", palette.Background); Assert.Equal("#5E56E8", palette.Accent); // 테마를 고대비로 전환 settings.ThemeMode = MobileThemeMode.HighContrast; var hcPalette = MobileThemeSystem.GetPalette(settings.ThemeMode); Assert.Equal("#000000", hcPalette.Background); Assert.Equal("#FFFF00", hcPalette.Accent); } }