using System; using System.Collections.Generic; using Paca.Mobile.Core; using Xunit; namespace Paca.Tests.Core; public class OfflineMediaPrefetcherGateTests { private readonly List _seriesPlaylist = new() { "ep-1", "ep-2", "ep-3", "ep-4", "ep-5" }; [Fact] public void Gate389_OfflineMediaPrefetcher_DecidesToPrefetch_WhenThresholdAndConditionsMet() { var policy = new PrefetchPolicy(RequireWifi: true, MinBatteryPercent: 50, PlaybackProgressThresholdPercent: 70.0, MaxPrefetchCount: 2); var env = new DeviceEnvironmentStatus(IsWifiConnected: true, BatteryPercent: 80); // Currently watching ep-2 at 75% progress var decision = OfflineMediaPrefetcher.EvaluatePrefetchDecision( _seriesPlaylist, currentPlayingId: "ep-2", currentProgressPercent: 75.0, env, policy); Assert.True(decision.ShouldPrefetch); Assert.Equal(2, decision.ItemsToPrefetch.Count); Assert.Equal("ep-3", decision.ItemsToPrefetch[0]); Assert.Equal("ep-4", decision.ItemsToPrefetch[1]); } [Fact] public void Gate390_OfflineMediaPrefetcher_Waits_WhenProgressBelowThreshold() { var policy = new PrefetchPolicy(true, 50, 70.0, 2); var env = new DeviceEnvironmentStatus(true, 85); // Currently watching ep-1 at 40% progress (below 70%) var decision = OfflineMediaPrefetcher.EvaluatePrefetchDecision( _seriesPlaylist, "ep-1", 40.0, env, policy); Assert.False(decision.ShouldPrefetch); Assert.Empty(decision.ItemsToPrefetch); Assert.Contains("진행률", decision.ReasonMessage); } [Fact] public void Gate391_OfflineMediaPrefetcher_Blocks_OnCellularOrLowBattery() { var policy = new PrefetchPolicy(RequireWifi: true, MinBatteryPercent: 50, PlaybackProgressThresholdPercent: 70.0, MaxPrefetchCount: 2); // On cellular network var cellularEnv = new DeviceEnvironmentStatus(IsWifiConnected: false, BatteryPercent: 90); var decCellular = OfflineMediaPrefetcher.EvaluatePrefetchDecision(_seriesPlaylist, "ep-2", 80.0, cellularEnv, policy); Assert.False(decCellular.ShouldPrefetch); Assert.Contains("Wi-Fi", decCellular.ReasonMessage); // Low battery (30%) var lowBatteryEnv = new DeviceEnvironmentStatus(IsWifiConnected: true, BatteryPercent: 30); var decBattery = OfflineMediaPrefetcher.EvaluatePrefetchDecision(_seriesPlaylist, "ep-2", 80.0, lowBatteryEnv, policy); Assert.False(decBattery.ShouldPrefetch); Assert.Contains("배터리", decBattery.ReasonMessage); } [Fact] public void Gate392_OfflineMediaPrefetcher_HandlesEndOfPlaylistGracefully() { var policy = new PrefetchPolicy(true, 50, 70.0, 2); var env = new DeviceEnvironmentStatus(true, 90); // Watching the final episode (ep-5) var decision = OfflineMediaPrefetcher.EvaluatePrefetchDecision( _seriesPlaylist, "ep-5", 85.0, env, policy); Assert.False(decision.ShouldPrefetch); Assert.Empty(decision.ItemsToPrefetch); Assert.Contains("마지막", decision.ReasonMessage); } }