Files
LlamaCasty/ytLive.Tests/AboutHubTests.cs
T
gramps 6208cb9409 feat(ui): route locked tiers through About
Keep non-owner resolution choices visible but muted. Selecting one preserves the free tier and opens About; external navigation is only the explicit llamacasty.com link. Ref: https://streamlabs.com/desktop
2026-11-02 09:41:38 -08:00

129 lines
5.2 KiB
C#

using System;
using System.Windows;
using Microsoft.Data.Sqlite;
using System.Windows.Controls;
using System.Windows.Threading;
using Xunit;
using ytLive.Controls;
using ytLive.Services.Entitlement;
using ytLive.ViewModels;
namespace ytLive.Tests;
/// <summary>
/// The About overlay is the in-app creator hub: it opens from the real window,
/// and its licensing sub-panel surfaces the full THIRD-PARTY-NOTICES.txt
/// in-app (scrolling text, never the OS viewer / Notepad). Drives the real VM
/// through the real window — same real-App + temp-DB pattern as the round-clip
/// and source-naming tests.
/// </summary>
[Collection("RealApp")]
public sealed class AboutHubTests
{
private readonly RealAppHost _app;
public AboutHubTests(RealAppHost app)
{
_app = app;
}
[Fact]
public void About_Opens_InApp_Licensing_Loads_Shipped_Notices()
{
_app.Run(Run);
}
private void Run()
{
var tempDb = System.IO.Path.Combine(System.IO.Path.GetTempPath(), $"ytLlive-about-{Guid.NewGuid():N}.db");
MainViewModel.LayoutPathOverride = tempDb;
var window = new MainWindow();
var vm = (MainViewModel)window.DataContext;
try
{
// About hub opens (the wordmark / gear menu entry point).
vm.OpenAboutCommand.Execute(null);
Assert.True(vm.IsAboutOpen);
Assert.False(vm.IsLicensesOpen);
// The hub links resolve to real destinations.
Assert.Equal("https://youtube.com/@llamachileshop", MainViewModel.ChannelUrl);
Assert.Equal("https://mastodon.llamachile.tube/@gramps", MainViewModel.MastodonUrl);
Assert.Equal("https://buymeacoffee.com/llamachiley", MainViewModel.CoffeeUrl);
Assert.Equal("https://llamacasty.com", MainViewModel.PremiumUrl);
// The licensing panel loads the full shipped notices text in-app.
vm.OpenLicensesCommand.Execute(null);
Assert.True(vm.IsLicensesOpen);
Assert.False(string.IsNullOrWhiteSpace(vm.LicensesText));
Assert.Contains("Third-Party Notices", vm.LicensesText, StringComparison.OrdinalIgnoreCase);
Assert.Contains("LGPL", vm.LicensesText, StringComparison.OrdinalIgnoreCase);
// Back returns to the hub view (code-behind click handler path is
// equivalent; here we assert the VM contract the handler uses).
vm.IsLicensesOpen = false;
Assert.True(vm.IsAboutOpen);
}
finally
{
window.Close();
MainViewModel.LayoutPathOverride = null;
SqliteConnection.ClearAllPools();
try { System.IO.File.Delete(tempDb); } catch { /* best-effort cleanup */ }
}
}
[Fact]
public void Selecting_a_locked_quality_opens_about_and_keeps_the_free_tier_selected()
{
_app.Run(() =>
{
var tempDb = System.IO.Path.Combine(System.IO.Path.GetTempPath(), $"llamacasty-upgrade-{Guid.NewGuid():N}.db");
MainViewModel.LayoutPathOverride = tempDb;
MainWindow? window = null;
try
{
window = new MainWindow();
var vm = (MainViewModel)window.DataContext;
vm.EntitlementOverride = new FakeEntitlement(false);
var freeTier = vm.QualityOptions.Single(option => !option.RequiresPro);
var lockedTier = vm.QualityOptions.First(option => option.RequiresPro);
vm.SelectedQuality = freeTier;
window.Show();
var picker = (ComboBox)window.FindName("QualityPicker");
picker.IsDropDownOpen = true;
picker.UpdateLayout();
Dispatcher.CurrentDispatcher.Invoke(() => { }, DispatcherPriority.Loaded);
var lockedItem = (ComboBoxItem)picker.ItemContainerGenerator.ContainerFromItem(lockedTier)!;
Assert.True(lockedItem.IsEnabled);
Assert.Equal(0.55, lockedItem.Opacity);
Assert.Equal(Application.Current.Resources["Brush.OnSurfaceDisabled"], lockedItem.Foreground);
picker.SelectedItem = lockedTier;
picker.UpdateLayout();
Assert.Same(freeTier, vm.SelectedQuality);
Assert.True(vm.IsAboutOpen);
var about = (OverlayHost)window.FindName("AboutOverlay");
var copy = (TextBlock)about.FindName("UpgradeCopy");
var link = (Button)about.FindName("UpgradeLinkButton");
Assert.Contains("720p30", copy.Text);
Assert.Contains("one-time purchase", copy.Text, StringComparison.OrdinalIgnoreCase);
Assert.Contains("no subscription", copy.Text, StringComparison.OrdinalIgnoreCase);
Assert.Contains("llamacasty.com", link.Content!.ToString());
Assert.Same(vm.OpenPremiumCommand, link.Command);
}
finally
{
window?.Close();
MainViewModel.LayoutPathOverride = null;
SqliteConnection.ClearAllPools();
try { System.IO.File.Delete(tempDb); } catch { /* best-effort cleanup */ }
}
});
}
}