- Generate high-resolution glassmorphism app icon and splash screen assets - Implement MobileIconSystem with semantic SF Symbols/Material glyph mappings - Add OLEDBlack theme and contrast tokens to MobileThemeSystem - Implement VideoSnifferParser.NegotiateBestQuality for multi-stream quality resolution - Enhance DiscoverPage, FavoritesPage, and SyncSettingsPage with production controls - Add Gate 103-114 test suites with 100% test pass rate
135 lines
4.8 KiB
C#
135 lines
4.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Paca.Mobile.Core;
|
|
using Xunit;
|
|
|
|
namespace Paca.Tests.Mobile;
|
|
|
|
/// <summary>
|
|
/// 모바일 네이티브 컨트롤, 햅틱, 타이포 스케일러, 볼트, 오리엔테이션 게이트 (Gate 115 ~ Gate 122)
|
|
/// </summary>
|
|
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);
|
|
}
|
|
}
|