using System; using System.Collections.Generic; using Paca.Mobile.Core; using Xunit; namespace Paca.Tests.Mobile; /// /// 모바일 네이티브 컨트롤, 햅틱, 타이포 스케일러, 볼트, 오리엔테이션 게이트 (Gate 115 ~ Gate 122) /// public class MobileAdvancedNativeGateTests { [Fact] public void Gate115_MobileTypographyScaler_Audit() { var scaler = new MobileTypographyScaler(); // 기본 1.0x 스케일 Assert.Equal(14.0, scaler.GetScaledFontSize(baseFontSize: 14.0, textScaleFactor: 1.0)); // 1.5x 접근성 큰 글꼴 Assert.Equal(21.0, scaler.GetScaledFontSize(baseFontSize: 14.0, textScaleFactor: 1.5)); // 최대 상한선(2.0x 초과 방지 클램핑) Assert.Equal(28.0, scaler.GetScaledFontSize(baseFontSize: 14.0, textScaleFactor: 2.5)); } [Fact] public void Gate116_MobileOrientationSensor_Landscape_Audit() { var sensor = new MobileOrientationSensor(); Assert.Equal(MobileScreenOrientation.Portrait, sensor.CurrentOrientation); Assert.False(sensor.IsFullscreenVideo); // 가로 회전 감지 sensor.OnOrientationChanged(MobileScreenOrientation.Landscape); Assert.Equal(MobileScreenOrientation.Landscape, sensor.CurrentOrientation); Assert.True(sensor.IsFullscreenVideo); // 컨트롤 자동 숨김 타이머 (3초) Assert.Equal(3000, sensor.ControlsAutoHideTimeoutMs); } [Fact] public void Gate117_MobileHapticFeedback_Audit() { var haptic = new MobileHapticFeedback(); HapticFeedbackType? triggered = null; haptic.OnHapticTriggered += type => triggered = type; haptic.NotifySuccess(); Assert.Equal(HapticFeedbackType.Success, triggered); haptic.NotifyError(); Assert.Equal(HapticFeedbackType.Error, triggered); haptic.NotifySelectionChange(); Assert.Equal(HapticFeedbackType.LightClick, triggered); } [Fact] public void Gate118_MobileQueueReorderEngine_Audit() { var qm = new MobileQueueManager(); var item1 = qm.Enqueue("https://example.com/1.mp4", "Video 1"); var item2 = qm.Enqueue("https://example.com/2.mp4", "Video 2"); var item3 = qm.Enqueue("https://example.com/3.mp4", "Video 3"); var reorder = new MobileQueueReorderEngine(qm); // item3을 맨 앞으로 이동 (index 2 -> 0) reorder.MoveItem(fromIndex: 2, toIndex: 0); Assert.Equal(item3.Id, qm.Items[0].Id); Assert.Equal(item1.Id, qm.Items[1].Id); Assert.Equal(item2.Id, qm.Items[2].Id); } [Fact] public void Gate119_MobileBackgroundWorker_Notification_Audit() { var worker = new MobileBackgroundWorker(); Assert.False(worker.IsForegroundServiceRunning); worker.StartService("Paca 다운로드 진행 중", totalActiveDownloads: 2); Assert.True(worker.IsForegroundServiceRunning); Assert.Equal("Paca 다운로드 진행 중 (2개 활성)", worker.LastNotificationTitle); worker.StopService(); Assert.False(worker.IsForegroundServiceRunning); } [Fact] public void Gate120_MobileMediaVault_Encryption_Audit() { var vault = new MobileMediaVault(); var plainBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; var password = "SafePassword123!"; // 암호화 var encrypted = vault.EncryptMedia(plainBytes, password); Assert.NotEqual(plainBytes, encrypted); // 복호화 var decrypted = vault.DecryptMedia(encrypted, password); Assert.Equal(plainBytes, decrypted); } [Fact] public void Gate121_MobileAdBlockEngine_EasyList_Audit() { var adBlock = new MobileAdBlockEngine(); Assert.True(adBlock.IsAdUrl("https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js")); Assert.True(adBlock.IsAdUrl("https://adservice.google.com/adsid/google/ui")); Assert.True(adBlock.IsAdUrl("https://securepubads.g.doubleclick.net/gampad/ads")); // 정상 미디어 URL은 허용 Assert.False(adBlock.IsAdUrl("https://www.youtube.com/watch?v=dQw4w9WgXcQ")); Assert.False(adBlock.IsAdUrl("https://vimeo.com/12345678")); } [Fact] public void Gate122_MobileResolutionPicker_Estimation_Audit() { var picker = new MobileResolutionPicker(); // 1080p 60fps 비디오 10분(600초) 예상 용량 계산 var estimate1080p = picker.EstimateSizeAndDownloadTime( durationSec: 600, resolution: "1080p", currentNetworkSpeedKbps: 10240 // 10MB/s (80Mbps) ); Assert.True(estimate1080p.EstimatedSizeBytes > 0); Assert.True(estimate1080p.EstimatedDurationSec > 0); Assert.Equal("1080p Full HD", estimate1080p.ResolutionLabel); } }