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 System.IO;
using System.Threading.Tasks;
using Paca.Mobile.Core;
using Xunit;
namespace Paca.Tests.Mobile;
public class MobileAdMobInterstitialAndRewardedGateTests
{
private static readonly string SolutionRoot = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, "..", "..", "..", "..", ".."));
[Fact]
public async Task Gate_AdMobWaterfallController_ShowInterstitial_DelegatesToAdapter()
{
var directMgr = new MobileAdManager();
var successAdapter = new MockAdMobAdapter(shouldSucceed: true);
var controller = new AdMobWaterfallController(successAdapter, directMgr);
var result = await controller.ShowInterstitialAsync();
Assert.True(result);
var failureAdapter = new MockAdMobAdapter(shouldSucceed: false);
var failController = new AdMobWaterfallController(failureAdapter, directMgr);
var failResult = await failController.ShowInterstitialAsync();
Assert.False(failResult);
}
[Fact]
public async Task Gate_AdMobWaterfallController_ShowRewarded_DelegatesToAdapter()
{
var directMgr = new MobileAdManager();
var successAdapter = new MockAdMobAdapter(shouldSucceed: true);
var controller = new AdMobWaterfallController(successAdapter, directMgr);
var result = await controller.ShowRewardedAsync();
Assert.True(result);
var failureAdapter = new MockAdMobAdapter(shouldSucceed: false);
var failController = new AdMobWaterfallController(failureAdapter, directMgr);
var failResult = await failController.ShowRewardedAsync();
Assert.False(failResult);
}
[Fact]
public async Task Gate_AdMobRewardCoordinator_AutomaticallyGrantsBoost_OnRewardEarned()
{
var tokenManager = new RewardedBoostTokenManager();
Assert.False(tokenManager.IsBoostActive);
var mockAdapter = new MockAdMobAdapter(shouldSucceed: true);
var coordinator = new AdMobRewardCoordinator(mockAdapter, tokenManager);
var shown = await coordinator.RequestAndShowRewardAdAsync();
Assert.True(shown);
Assert.True(tokenManager.IsBoostActive);
Assert.True(tokenManager.RemainingBoostTime.TotalMinutes > 50);
}
[Fact]
public void Gate_AndroidAdMobAdapter_SourceAudit_EnsuresRealRewardEventAndInvocation()
{
var adapterPath = Path.Combine(SolutionRoot, "src", "Paca.Mobile", "Platforms", "Android", "AndroidAdMobAdapter.cs");
Assert.True(File.Exists(adapterPath), $"AndroidAdMobAdapter.cs must exist at {adapterPath}");
var code = File.ReadAllText(adapterPath);
Assert.Contains("public event Action<string, double>? OnUserEarnedReward;", code);
Assert.Contains("OnUserEarnedReward?.Invoke", code);
}
}