using System; using System.Collections.Generic; using System.IO; using System.Security.Cryptography; using System.Text; using System.Text.Json; using Paca.Mobile.Core; using Paca.Tests.Infrastructure; using Xunit; namespace Paca.Tests.Core; /// /// Gate 171 ~ 174: 기기 교체 및 무결성 보장을 위한 Paca Vault 스냅샷 백업 & 복원 엔진 기계적 검증 /// public class PacaVaultBackupRestoreGateTests { [Fact] public void Gate171_VaultSnapshot_Creation_And_Integrity() { var favorites = new List { "https://youtu.be/abc", "https://x.com/def" }; var queueUrls = new List { "https://chzzk.naver.com/video/1" }; var snapshot = PacaVaultSnapshot.Create("device-alpha", favorites, queueUrls); Assert.Equal("device-alpha", snapshot.SourceDeviceId); Assert.Equal(2, snapshot.Favorites.Count); Assert.Single(snapshot.QueueUrls); Assert.True(snapshot.VerifyChecksum()); // 조작된 스냅샷 체크섬 검증 실패 var tampered = snapshot with { Favorites = new List { "https://malicious.com" } }; Assert.False(tampered.VerifyChecksum()); } [Fact] public void Gate172_VaultSnapshot_Corrupted_ThrowsException() { var invalidJson = "{\"SourceDeviceId\":\"x\",\"Checksum\":\"invalid-hash\"}"; Assert.ThrowsAny(() => { var snapshot = JsonSerializer.Deserialize(invalidJson); if (snapshot == null || !snapshot.VerifyChecksum()) { throw new InvalidDataException("Checksum verification failed"); } }); } [Fact] public void Gate173_VaultRestorer_Merge_Strategy() { var currentFavorites = new List { "https://youtu.be/1", "https://youtu.be/2" }; var backupFavorites = new List { "https://youtu.be/2", "https://youtu.be/3" }; var merged = VaultRestorer.MergeLists(currentFavorites, backupFavorites); // 중복 제거되어 1, 2, 3 총 3개 존재 확인 Assert.Equal(3, merged.Count); Assert.Contains("https://youtu.be/1", merged); Assert.Contains("https://youtu.be/2", merged); Assert.Contains("https://youtu.be/3", merged); } [Fact] public void Gate174_ServerHost_VaultEndpoints_Registered() { var serverHostPath = Path.Combine(SourceTree.Root, "src", "Paca.Server", "ServerHost.cs"); Assert.True(File.Exists(serverHostPath), "ServerHost.cs must exist"); var code = File.ReadAllText(serverHostPath); Assert.Contains("/api/vault/backup", code); Assert.Contains("/api/vault/restore", code); } }