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,70 @@
using System;
using Paca.Mobile.Core;
using Xunit;
namespace Paca.Tests.Core;
public class DownloadTokenBucketRateLimiterGateTests
{
[Fact]
public void Gate453_DownloadTokenBucketRateLimiter_AllowsImmediateConsumption_WhenBucketFull()
{
var now = DateTime.UtcNow;
var limiter = new DownloadTokenBucketRateLimiter(rateBytesPerSec: 1_000_000, burstCapacityBytes: 2_000_000, initialTime: now);
var decision = limiter.Request(500_000, now);
Assert.True(decision.IsAllowedImmediately);
Assert.Equal(TimeSpan.Zero, decision.DelayRequired);
Assert.Equal(1_500_000, limiter.AvailableTokens, 1);
}
[Fact]
public void Gate454_DownloadTokenBucketRateLimiter_CalculatesRequiredDelay_WhenTokensExhausted()
{
var now = DateTime.UtcNow;
var limiter = new DownloadTokenBucketRateLimiter(rateBytesPerSec: 1_000_000, burstCapacityBytes: 1_000_000, initialTime: now);
// Exhaust all tokens
limiter.Request(1_000_000, now);
// Request another 500KB immediately (needs 500ms refill)
var decision = limiter.Request(500_000, now);
Assert.False(decision.IsAllowedImmediately);
Assert.Equal(TimeSpan.FromMilliseconds(500), decision.DelayRequired);
}
[Fact]
public void Gate455_DownloadTokenBucketRateLimiter_RefillsTokensOverTime_UpToCapacity()
{
var now = DateTime.UtcNow;
var limiter = new DownloadTokenBucketRateLimiter(rateBytesPerSec: 1_000_000, burstCapacityBytes: 2_000_000, initialTime: now);
// Consume everything
limiter.Request(2_000_000, now);
Assert.Equal(0, limiter.AvailableTokens, 1);
// Advance time by 3 seconds (3MB generated, capped at 2MB burst)
var future = now.AddSeconds(3);
var decision = limiter.Request(1, future);
Assert.True(decision.IsAllowedImmediately);
Assert.Equal(2_000_000 - 1, limiter.AvailableTokens, 1);
}
[Fact]
public void Gate456_DownloadTokenBucketRateLimiter_DynamicRateAdjustment_PreservesTokens()
{
var now = DateTime.UtcNow;
var limiter = new DownloadTokenBucketRateLimiter(rateBytesPerSec: 1_000_000, burstCapacityBytes: 2_000_000, initialTime: now);
limiter.Request(1_000_000, now);
Assert.Equal(1_000_000, limiter.AvailableTokens, 1);
// Adjust rate to 5 MB/s
limiter.SetRate(5_000_000, now);
Assert.Equal(1_000_000, limiter.AvailableTokens, 1);
Assert.Equal(5_000_000, limiter.RateBytesPerSec);
}
}