using System; using System.IO; using Paca.Core.Config; using Paca.Core.Detection; using Paca.Core.Platform; using Paca.Core.Social; using Paca.Core.Util; using Xunit; namespace Paca.Tests.Core; public class SmartMediaNamingAndThumbnailGateTests { [Theory] [InlineData("1a099dac52a596d88", true)] [InlineData("1a0984368a2930f5", true)] [InlineData("e3b0c44298fc1c149afbf4c8996fb924", true)] [InlineData("550e8400-e29b-41d4-a716-446655440000", true)] [InlineData("code-1_desktop-6d44c7cb5f84", true)] [InlineData("my_dog_playing", false)] [InlineData("trailer_2024_1080p", false)] [InlineData("lecture_part1", false)] [InlineData("video", false)] [InlineData("cat", false)] public void Gate_FileNameUtil_IsObfuscatedHash(string name, bool expected) { bool actual = FileNameUtil.IsObfuscatedHash(name); Assert.Equal(expected, actual); } [Theory] [InlineData("[유머] 오늘의 귀여운 고양이 모음 | 루리웹 유머 게시판", "[유머] 오늘의 귀여운 고양이 모음")] [InlineData("[잡담] 질문 하나 드립니다. - 루리웹", "[잡담] 질문 하나 드립니다.")] [InlineData("Issue #42: Bug in video player · paca/paca · GitHub", "Issue #42: Bug in video player")] [InlineData("신규 기능 릴리즈 안내 - YouTube", "신규 기능 릴리즈 안내")] [InlineData("PACA - Media Browser", "PACA")] public void Gate_FileNameUtil_CleanWebTitle(string rawTitle, string expectedClean) { string actual = FileNameUtil.CleanWebTitle(rawTitle); Assert.Equal(expectedClean, actual); } [Fact] public void Gate_FileNameUtil_DeriveSmartTitle_PrioritizesPageTitleForObfuscatedHash() { var mediaUri = new Uri("https://img.ruliweb.com/2024/09/13/1a099dac52a596d88.mp4"); var pageTitle = "[유머] 오늘의 귀여운 고양이 모음 | 루리웹 유머 게시판"; // 단일 미디어 var singleTitle = FileNameUtil.DeriveSmartTitle(pageTitle, mediaUri, index: 0); Assert.Equal("[유머] 오늘의 귀여운 고양이 모음", singleTitle); // 복수 미디어 중 1번째, 2번째 var multi1 = FileNameUtil.DeriveSmartTitle(pageTitle, mediaUri, index: 1); var multi2 = FileNameUtil.DeriveSmartTitle(pageTitle, mediaUri, index: 2); Assert.Equal("[유머] 오늘의 귀여운 고양이 모음 #1", multi1); Assert.Equal("[유머] 오늘의 귀여운 고양이 모음 #2", multi2); } [Fact] public void Gate_FileNameUtil_DeriveSmartTitle_KeepsMeaningfulFileNameWhenNoPageTitle() { var mediaUri = new Uri("https://example.com/assets/game_trailer_final.mp4"); var title = FileNameUtil.DeriveSmartTitle(null, mediaUri, index: 0); Assert.Equal("game_trailer_final", title); } [Fact] public void Gate_DetectionContext_Supports_Thumbnail_And_Index() { var ctx = new DetectionContext( Url: "https://example.com/video.mp4", PageUrl: "https://example.com", Kind: MediaKind.Direct, ContentType: "video/mp4", Title: "Test Video", Tag: "Direct", ThumbnailUrl: "https://example.com/poster.jpg", MediaIndex: 2 ); Assert.Equal("https://example.com/poster.jpg", ctx.ThumbnailUrl); Assert.Equal(2, ctx.MediaIndex); } [Fact] public void Gate_MediaMuxer_ResolveFfmpeg_Discovers_ToolsDir() { var muxer = DesktopMediaMuxer.Default; var config = new AppConfig(); // FfmpegPath 비워둠 var resolved = muxer.ResolveFfmpeg(config); // 사용자 PC의 AppData/Paca/tools/ffmpeg.exe 가 존재하므로 이를 자동 발견해야 함 if (File.Exists(Path.Combine(YtDlpRunner.ToolsDir, OperatingSystem.IsWindows() ? "ffmpeg.exe" : "ffmpeg"))) { Assert.NotNull(resolved); Assert.True(File.Exists(resolved)); } } }