using System; using System.IO; using System.Linq; using Paca.Mobile.Core; using Paca.Tests.Infrastructure; using Xunit; namespace Paca.Tests.Core; /// /// Gate 187 ~ 190: 미디어 인텔리전스 챕터 네비게이션 & 자막 동기화 트랙 기계적 검증 /// public class MediaChapterAndSubtitleGateTests { [Fact] public void Gate187_ChapterMetadataParser_Extracts_Timestamps() { var description = """ 영상 타임라인 안내: 00:00 오프닝 및 소개 02:15 데스크톱 게이트웨이 서비스 설명 10:45 모바일 원클릭 LAN 자동 발견 데모 25:30 질의응답 및 마무리 """; var chapters = ChapterMetadataParser.ParseFromDescription(description); Assert.Equal(4, chapters.Count); Assert.Equal("오프닝 및 소개", chapters[0].Title); Assert.Equal(TimeSpan.Zero, chapters[0].StartTime); Assert.Equal(TimeSpan.FromMinutes(2) + TimeSpan.FromSeconds(15), chapters[0].EndTime); Assert.Equal("데스크톱 게이트웨이 서비스 설명", chapters[1].Title); Assert.Equal(TimeSpan.FromMinutes(2) + TimeSpan.FromSeconds(15), chapters[1].StartTime); Assert.Equal(TimeSpan.FromMinutes(10) + TimeSpan.FromSeconds(45), chapters[1].EndTime); } [Fact] public void Gate188_ChapterMetadataParser_Finds_Active_Chapter() { var description = """ 00:00 파트 A 05:00 파트 B 15:00 파트 C """; var chapters = ChapterMetadataParser.ParseFromDescription(description); // 03:30 시청 중 -> 파트 A 활성 var active1 = ChapterMetadataParser.GetActiveChapter(chapters, TimeSpan.FromMinutes(3.5)); Assert.NotNull(active1); Assert.Equal("파트 A", active1.Title); // 07:00 시청 중 -> 파트 B 활성 var active2 = ChapterMetadataParser.GetActiveChapter(chapters, TimeSpan.FromMinutes(7)); Assert.NotNull(active2); Assert.Equal("파트 B", active2.Title); } [Fact] public void Gate189_SubtitleStreamTrack_Formatting() { var track = new SubtitleStreamTrack( LanguageCode: "ko", LanguageName: "한국어 (자동 생성)", VttUrl: "http://localhost:52100/api/subtitles/video123?lang=ko", IsDefault: true ); Assert.Equal("ko", track.LanguageCode); Assert.True(track.IsDefault); Assert.Contains("lang=ko", track.VttUrl); } [Fact] public void Gate190_ServerHost_Subtitles_Endpoint_Audit() { 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/subtitles/{id}", code); } }