feat(mobile): advance Paca.Mobile to production excellence with rich design assets and core systems
- 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
This commit is contained in:
parent
dbc50abb71
commit
f1949024fc
81 changed files with 8611 additions and 0 deletions
107
tests/Paca.Tests/Mobile/MobileAdvancedConnectivityGateTests.cs
Normal file
107
tests/Paca.Tests/Mobile/MobileAdvancedConnectivityGateTests.cs
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Paca.Mobile.Core;
|
||||
using Xunit;
|
||||
|
||||
namespace Paca.Tests.Mobile;
|
||||
|
||||
/// <summary>
|
||||
/// 로컬 기기 디스커버리, 원격 클립보드, 절전/데이터 가드 및 복원성 게이트 (Gate 109 ~ Gate 114)
|
||||
/// </summary>
|
||||
public class MobileAdvancedConnectivityGateTests
|
||||
{
|
||||
[Fact]
|
||||
public void Gate109_PacaHostBeacon_Discovery_Audit()
|
||||
{
|
||||
var beacon = new PacaHostBeacon();
|
||||
var beaconPayload = "PACA_BEACON|DESKTOP-PACA|192.168.1.100:52100|token123";
|
||||
var host = beacon.ParseBeacon(beaconPayload);
|
||||
|
||||
Assert.NotNull(host);
|
||||
Assert.Equal("DESKTOP-PACA", host.HostName);
|
||||
Assert.Equal("192.168.1.100:52100", host.Endpoint);
|
||||
Assert.Equal("token123", host.AuthToken);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Gate110_CrossDeviceClipboardSync_Audit()
|
||||
{
|
||||
var clipSync = new CrossDeviceClipboardSync();
|
||||
string? receivedUrl = null;
|
||||
clipSync.OnMediaUrlReceived += url => receivedUrl = url;
|
||||
|
||||
// PC로부터 수신된 클립보드 패킷 처리
|
||||
clipSync.ProcessIncomingPayload("https://twitter.com/test/status/123456");
|
||||
Assert.Equal("https://twitter.com/test/status/123456", receivedUrl);
|
||||
|
||||
// 비미디어 텍스트는 필터링되어 무시되어야 함
|
||||
receivedUrl = null;
|
||||
clipSync.ProcessIncomingPayload("Hello this is not a media url");
|
||||
Assert.Null(receivedUrl);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Gate111_MobilePowerSaverPolicy_Audit()
|
||||
{
|
||||
var policy = new MobilePowerSaverPolicy();
|
||||
// 기본 6 세그먼트
|
||||
Assert.Equal(6, policy.GetRecommendedSegments(batteryLevelPercent: 80, isCharging: false));
|
||||
|
||||
// 배터리 15% 이하 저전력 모드 -> 2개로 제한
|
||||
Assert.Equal(2, policy.GetRecommendedSegments(batteryLevelPercent: 12, isCharging: false));
|
||||
|
||||
// 충전 중일 때는 100% 터보 허용
|
||||
Assert.Equal(16, policy.GetRecommendedSegments(batteryLevelPercent: 12, isCharging: true));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Gate112_MobileDataSaverGuard_Audit()
|
||||
{
|
||||
var dataGuard = new MobileDataSaverGuard();
|
||||
// 100MB 기본 임계값
|
||||
Assert.Equal(100_000_000L, dataGuard.CellularWarningThresholdBytes);
|
||||
|
||||
// Wi-Fi 상태에서는 대용량도 즉시 허용
|
||||
Assert.True(dataGuard.CanDownload(fileSizeBytes: 500_000_000, isWifi: true));
|
||||
|
||||
// 셀룰러 상태에서 500MB는 경고 플래그
|
||||
Assert.False(dataGuard.CanDownload(fileSizeBytes: 500_000_000, isWifi: false));
|
||||
|
||||
// 셀룰러 상태에서 50MB는 허용
|
||||
Assert.True(dataGuard.CanDownload(fileSizeBytes: 50_000_000, isWifi: false));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Gate113_MobileThumbnailCacheManager_Audit()
|
||||
{
|
||||
var cache = new MobileThumbnailCacheManager();
|
||||
Assert.Null(cache.Get("test-key"));
|
||||
|
||||
cache.Put("test-key", new byte[] { 0xFF, 0xD8, 0xFF });
|
||||
var cached = cache.Get("test-key");
|
||||
Assert.NotNull(cached);
|
||||
Assert.Equal(3, cached.Length);
|
||||
|
||||
// 캐시 삭제
|
||||
cache.Evict("test-key");
|
||||
Assert.Null(cache.Get("test-key"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Gate114_NetworkFlapping_Stress_Resilience_Audit()
|
||||
{
|
||||
var qm = new MobileQueueManager();
|
||||
var guard = new MobileNetworkGuard(qm);
|
||||
var item = qm.Enqueue("https://example.com/live.m3u8", "Live Stream");
|
||||
item.Status = MobileQueueStatus.Downloading;
|
||||
|
||||
// 10회 연속 단절 및 재연결 플래핑 스트레스
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
guard.OnNetworkLost();
|
||||
Assert.Equal(MobileQueueStatus.PausedNetwork, item.Status);
|
||||
guard.OnNetworkRestored(isWifi: (i % 2 == 0));
|
||||
Assert.Equal(MobileQueueStatus.Downloading, item.Status);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue