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,91 @@
using System;
using System.Collections.Generic;
using Paca.Core;
using Xunit;
namespace Paca.Tests.Core;
public class BandwidthScheduleProfileGateTests
{
[Fact]
public void Gate313_BandwidthScheduleProfile_DefinesWorkAndNightProfiles()
{
var workProfile = new BandwidthProfile("WorkHours", MaxBytesPerSecond: 5 * 1024 * 1024, MaxConcurrentTasks: 2);
var nightProfile = new BandwidthProfile("NightUncapped", MaxBytesPerSecond: 0, MaxConcurrentTasks: 8);
Assert.Equal(5 * 1024 * 1024, workProfile.MaxBytesPerSecond);
Assert.Equal(2, workProfile.MaxConcurrentTasks);
Assert.True(nightProfile.IsUnlimited);
Assert.Equal(8, nightProfile.MaxConcurrentTasks);
}
[Fact]
public void Gate314_BandwidthScheduleProfile_SelectsWorkProfile_DuringDaytime()
{
var workProfile = new BandwidthProfile("WorkHours", 5 * 1024 * 1024, 2);
var defaultProfile = new BandwidthProfile("Default", 0, 4);
var config = new BandwidthScheduleConfig
{
IsEnabled = true,
DefaultProfile = defaultProfile,
Rules = new List<BandwidthTimeRule>
{
new(StartTime: TimeSpan.FromHours(9), EndTime: TimeSpan.FromHours(18), Profile: workProfile)
}
};
var dayTime = new DateTime(2026, 9, 4, 14, 30, 0); // 14:30
var active = BandwidthScheduleProfileEngine.GetActiveProfile(dayTime, config);
Assert.Equal("WorkHours", active.ProfileName);
Assert.Equal(5 * 1024 * 1024, active.MaxBytesPerSecond);
}
[Fact]
public void Gate315_BandwidthScheduleProfile_SelectsNightProfile_Overnight()
{
var nightProfile = new BandwidthProfile("NightUncapped", 0, 8);
var defaultProfile = new BandwidthProfile("Default", 10 * 1024 * 1024, 3);
var config = new BandwidthScheduleConfig
{
IsEnabled = true,
DefaultProfile = defaultProfile,
Rules = new List<BandwidthTimeRule>
{
new(StartTime: TimeSpan.FromHours(23), EndTime: TimeSpan.FromHours(7), Profile: nightProfile)
}
};
var overnight = new DateTime(2026, 9, 5, 3, 15, 0); // 03:15
var active = BandwidthScheduleProfileEngine.GetActiveProfile(overnight, config);
Assert.Equal("NightUncapped", active.ProfileName);
Assert.True(active.IsUnlimited);
Assert.Equal(8, active.MaxConcurrentTasks);
}
[Fact]
public void Gate316_BandwidthScheduleProfile_FallsBackToDefault_WhenDisabledOrOutOfRange()
{
var workProfile = new BandwidthProfile("WorkHours", 2 * 1024 * 1024, 1);
var defaultProfile = new BandwidthProfile("Default", 0, 4);
var config = new BandwidthScheduleConfig
{
IsEnabled = false, // Disabled
DefaultProfile = defaultProfile,
Rules = new List<BandwidthTimeRule>
{
new(StartTime: TimeSpan.FromHours(9), EndTime: TimeSpan.FromHours(18), Profile: workProfile)
}
};
var dayTime = new DateTime(2026, 9, 4, 14, 0, 0);
var active = BandwidthScheduleProfileEngine.GetActiveProfile(dayTime, config);
Assert.Equal("Default", active.ProfileName);
Assert.True(active.IsUnlimited);
}
}