127 lines
4.5 KiB
C#
127 lines
4.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using Paca.Mobile.Core;
|
|
using Xunit;
|
|
|
|
namespace Paca.Tests.Mobile;
|
|
|
|
/// <summary>
|
|
/// Gate 167 ~ 170: PacaDrop 다중 미디어 배치 번들링 & 자동 스트리밍 언패커 기계적 검증
|
|
/// </summary>
|
|
public class MobilePacaDropBatchBundleGateTests
|
|
{
|
|
[Fact]
|
|
public void Gate167_BatchBundleManifest_Integrity()
|
|
{
|
|
var file1Data = Encoding.UTF8.GetBytes("Media Content 1 - 4K Video Stream");
|
|
var file2Data = Encoding.UTF8.GetBytes("Media Content 2 - 128k Audio Track");
|
|
|
|
var entries = new List<BundleEntryMetadata>
|
|
{
|
|
new("video1.mp4", file1Data.Length, Convert.ToHexString(SHA256.HashData(file1Data))),
|
|
new("audio1.mp3", file2Data.Length, Convert.ToHexString(SHA256.HashData(file2Data)))
|
|
};
|
|
|
|
var manifest = new BatchBundleManifest("bundle-001", entries, DateTimeOffset.UtcNow);
|
|
|
|
Assert.Equal("bundle-001", manifest.BundleId);
|
|
Assert.Equal(2, manifest.Entries.Count);
|
|
Assert.Equal(file1Data.Length + file2Data.Length, manifest.TotalBytes);
|
|
Assert.True(manifest.VerifyEntry("video1.mp4", file1Data));
|
|
Assert.False(manifest.VerifyEntry("video1.mp4", Encoding.UTF8.GetBytes("Corrupted")));
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Gate168_BatchBundle_Pack_And_Unpack_Streaming()
|
|
{
|
|
var file1Data = Encoding.UTF8.GetBytes("Payload for Track 1");
|
|
var file2Data = Encoding.UTF8.GetBytes("Payload for Track 2");
|
|
|
|
using var bundleStream = new MemoryStream();
|
|
|
|
// 1. 번들 생성 (PC 측 동작 시뮬레이션)
|
|
await PacaBatchBundlePacker.PackAsync(bundleStream, new Dictionary<string, byte[]>
|
|
{
|
|
["intro.mp4"] = file1Data,
|
|
["outro.mp3"] = file2Data
|
|
});
|
|
|
|
bundleStream.Position = 0;
|
|
|
|
// 2. 모바일 언패커로 추출 (모바일 수신 시뮬레이션)
|
|
var tempExtractDir = Path.Combine(Path.GetTempPath(), "Paca_Test_Bundle_" + Guid.NewGuid().ToString("N"));
|
|
Directory.CreateDirectory(tempExtractDir);
|
|
|
|
try
|
|
{
|
|
var extractedFiles = await PacaBatchBundleExtractor.ExtractAsync(bundleStream, tempExtractDir);
|
|
|
|
Assert.Equal(2, extractedFiles.Count);
|
|
Assert.True(File.Exists(Path.Combine(tempExtractDir, "intro.mp4")));
|
|
Assert.True(File.Exists(Path.Combine(tempExtractDir, "outro.mp3")));
|
|
|
|
var read1 = await File.ReadAllBytesAsync(Path.Combine(tempExtractDir, "intro.mp4"));
|
|
var read2 = await File.ReadAllBytesAsync(Path.Combine(tempExtractDir, "outro.mp3"));
|
|
|
|
Assert.Equal(file1Data, read1);
|
|
Assert.Equal(file2Data, read2);
|
|
}
|
|
finally
|
|
{
|
|
if (Directory.Exists(tempExtractDir))
|
|
{
|
|
Directory.Delete(tempExtractDir, recursive: true);
|
|
}
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public async Task Gate169_BatchBundle_CorruptedEntry_FailsSafely()
|
|
{
|
|
using var garbageStream = new MemoryStream(Encoding.UTF8.GetBytes("Not A Valid Paca Bundle Data"));
|
|
var tempExtractDir = Path.Combine(Path.GetTempPath(), "Paca_Corrupt_" + Guid.NewGuid().ToString("N"));
|
|
Directory.CreateDirectory(tempExtractDir);
|
|
|
|
try
|
|
{
|
|
await Assert.ThrowsAnyAsync<Exception>(async () =>
|
|
{
|
|
await PacaBatchBundleExtractor.ExtractAsync(garbageStream, tempExtractDir);
|
|
});
|
|
}
|
|
finally
|
|
{
|
|
if (Directory.Exists(tempExtractDir)) Directory.Delete(tempExtractDir, recursive: true);
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void Gate170_AutoIngestToLibraryManager()
|
|
{
|
|
var manager = new OfflineLibraryManager();
|
|
var extractedEntries = new List<BundleExtractedFile>
|
|
{
|
|
new("item-1", "video.mp4", 50_000_000, "/temp/video.mp4", true),
|
|
new("item-2", "song.mp3", 5_000_000, "/temp/song.mp3", true)
|
|
};
|
|
|
|
foreach (var entry in extractedEntries)
|
|
{
|
|
manager.RegisterMedia(new OfflineMediaItem(
|
|
entry.Id,
|
|
entry.FileName,
|
|
entry.SizeBytes,
|
|
entry.FilePath,
|
|
DateTimeOffset.UtcNow,
|
|
entry.IsChecksumVerified
|
|
));
|
|
}
|
|
|
|
Assert.Equal(55_000_000L, manager.TotalPacaBytes);
|
|
Assert.Equal(2, manager.GetItems(MediaFilter.All, MediaSortOrder.NewestFirst).Count);
|
|
}
|
|
}
|