feat(ads/seo/release): v1.2.0 with live Google Ads, isolated ad profile, ads.txt, and SEO/AEO/GEO optimization

This commit is contained in:
Yun Chan 2026-09-14 00:39:44 +09:00
parent a88aafa1e5
commit 0e568f1f0a
975 changed files with 130593 additions and 16783 deletions

View file

@ -0,0 +1,85 @@
using System;
using System.IO;
using System.Linq;
using Paca.Mobile.Core;
using Paca.Tests.Infrastructure;
using Xunit;
namespace Paca.Tests.Core;
/// <summary>
/// Gate 187 ~ 190: 미디어 인텔리전스 챕터 네비게이션 & 자막 동기화 트랙 기계적 검증
/// </summary>
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);
}
}