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:
parent
a88aafa1e5
commit
0e568f1f0a
975 changed files with 130593 additions and 16783 deletions
118
tests/Paca.Tests/Mobile/MobileMenuContractGateTests.cs
Normal file
118
tests/Paca.Tests/Mobile/MobileMenuContractGateTests.cs
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
using System.Linq;
|
||||
using Paca.Mobile.Core;
|
||||
using Xunit;
|
||||
|
||||
namespace Paca.Tests.Mobile;
|
||||
|
||||
public sealed class MobileMenuContractGateTests
|
||||
{
|
||||
[Fact]
|
||||
public void MenuCoordinator_DomainContext_NormalizesHttpAndHttpsUrls()
|
||||
{
|
||||
// Assert domain extraction and security scheme
|
||||
var domain1 = MobileMenuCoordinator.FormatDomainContext("https://www.youtube.com/watch?v=12345");
|
||||
Assert.Equal("youtube.com", domain1);
|
||||
Assert.True(MobileMenuCoordinator.IsSecureScheme("https://www.youtube.com/watch?v=12345"));
|
||||
|
||||
var domain2 = MobileMenuCoordinator.FormatDomainContext("paca://newtab");
|
||||
Assert.Equal("PACA 새 탭", domain2);
|
||||
Assert.False(MobileMenuCoordinator.IsSecureScheme("paca://newtab"));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MenuCoordinator_QuickControls_EnforcesFourPillarsAndActiveStates()
|
||||
{
|
||||
var context = new MobileMenuContext(
|
||||
CurrentUrl: "https://example.com/article",
|
||||
CurrentTitle: "Sample Article",
|
||||
IsDesktopMode: true,
|
||||
ThemeMode: MobileThemeMode.Dark,
|
||||
IsBookmarked: true,
|
||||
SniffedVideoCount: 3,
|
||||
IsP2pConnected: true
|
||||
);
|
||||
|
||||
var items = MobileMenuCoordinator.BuildMenuItems(context);
|
||||
var quickItems = items.Where(i => i.Category == MobileMenuCategory.QuickControls).ToList();
|
||||
|
||||
// Miller's / Hick-Hyman Law: Exact 4 quick controls
|
||||
Assert.Equal(4, quickItems.Count);
|
||||
Assert.Contains(quickItems, i => i.ActionId == MobileMenuActionId.ToggleDesktopMode && i.IsActive);
|
||||
Assert.Contains(quickItems, i => i.ActionId == MobileMenuActionId.ToggleThemeMode);
|
||||
Assert.Contains(quickItems, i => i.ActionId == MobileMenuActionId.OpenInPrivateTab);
|
||||
Assert.Contains(quickItems, i => i.ActionId == MobileMenuActionId.ShareAndCopyLink);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MenuCoordinator_BrowsingAndMedia_ContainsCoreActionsWithDynamicStatus()
|
||||
{
|
||||
var context = new MobileMenuContext(
|
||||
CurrentUrl: "https://example.com/video",
|
||||
CurrentTitle: "Sample Video",
|
||||
IsDesktopMode: false,
|
||||
ThemeMode: MobileThemeMode.Light,
|
||||
IsBookmarked: true,
|
||||
SniffedVideoCount: 2,
|
||||
IsP2pConnected: false
|
||||
);
|
||||
|
||||
var items = MobileMenuCoordinator.BuildMenuItems(context);
|
||||
var browsingItems = items.Where(i => i.Category == MobileMenuCategory.BrowsingAndMedia).ToList();
|
||||
|
||||
Assert.Equal(4, browsingItems.Count);
|
||||
|
||||
var bookmarkItem = browsingItems.First(i => i.ActionId == MobileMenuActionId.ToggleBookmark);
|
||||
Assert.True(bookmarkItem.IsActive);
|
||||
Assert.Equal("북마크 해제", bookmarkItem.Title);
|
||||
|
||||
var p2pItem = browsingItems.First(i => i.ActionId == MobileMenuActionId.SendTabToDesktopP2P);
|
||||
Assert.False(p2pItem.IsActive);
|
||||
Assert.Contains("오프라인", p2pItem.Subtitle);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MenuCoordinator_IntelligenceAndSettings_ShowsSniffedBadgeAndSync()
|
||||
{
|
||||
var context = new MobileMenuContext(
|
||||
CurrentUrl: "https://example.com/stream",
|
||||
CurrentTitle: "Stream Page",
|
||||
IsDesktopMode: false,
|
||||
ThemeMode: MobileThemeMode.Dark,
|
||||
IsBookmarked: false,
|
||||
SniffedVideoCount: 5,
|
||||
IsP2pConnected: true
|
||||
);
|
||||
|
||||
var items = MobileMenuCoordinator.BuildMenuItems(context);
|
||||
var intelItems = items.Where(i => i.Category == MobileMenuCategory.IntelligenceAndSettings).ToList();
|
||||
|
||||
var snifferItem = intelItems.FirstOrDefault(i => i.ActionId == MobileMenuActionId.OpenVideoSnifferList);
|
||||
Assert.NotNull(snifferItem);
|
||||
Assert.Equal("5", snifferItem.BadgeText);
|
||||
|
||||
var syncItem = intelItems.FirstOrDefault(i => i.ActionId == MobileMenuActionId.OpenSyncSettings);
|
||||
Assert.NotNull(syncItem);
|
||||
Assert.Contains("연결됨", syncItem.Subtitle);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void MenuCoordinator_AllItems_HaveNonEmptyAutomationNamesForAccessibility()
|
||||
{
|
||||
var context = new MobileMenuContext(
|
||||
CurrentUrl: "https://example.com",
|
||||
CurrentTitle: "Example",
|
||||
IsDesktopMode: false,
|
||||
ThemeMode: MobileThemeMode.Dark,
|
||||
IsBookmarked: false,
|
||||
SniffedVideoCount: 0,
|
||||
IsP2pConnected: true
|
||||
);
|
||||
|
||||
var items = MobileMenuCoordinator.BuildMenuItems(context);
|
||||
foreach (var item in items)
|
||||
{
|
||||
Assert.False(string.IsNullOrWhiteSpace(item.AutomationName), $"Item {item.ActionId} must have an AutomationName");
|
||||
Assert.False(string.IsNullOrWhiteSpace(item.IconGlyph), $"Item {item.ActionId} must have an IconGlyph");
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue