Files
LlamaCasty/ytLive.Tests/SocialBarAppearanceTests.cs
T
gramps 51d9dd09c7 fix(socials): the bar disappeared from the preview when the plate was off
My own regression from the previous commit: the plate Border WRAPPED the bar's content and its
Visibility was bound to BarBackgroundEnabled — so with the plate off (the default) the preview
collapsed the entire social bar. Nothing was wrong with the data; the element was there and
invisible.

Fix: the wrapper is always laid out. "Plate off" now means a TRANSPARENT background
(`SocialBarBackgroundBrush` returns Transparent when disabled) and zero padding, "on" means the
colour/opacity plate with 18,6 padding — which also matches what the renderer bakes for the
output, so preview and broadcast agree.

Guard (new fact in SocialBarAppearanceTests): the preview must never visibility-gate the bar on
BarBackgroundEnabled, the wrapper must bind SocialBarBackgroundBrush, and the plate's switching
must be Padding.
2026-10-30 09:06:53 -07:00

93 lines
4.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Media;
using Xunit;
using ytLive.Models;
using ytLive.Services;
using ytLive.Services.Compositor;
namespace ytLive.Tests;
/// <summary>The creator (2026-10-30): the social bar was hard-wired white-on-transparent. It now
/// takes a text colour, an optional background plate with its own colour and opacity, and a text
/// drop shadow — set in the Socials drawer.
///
/// <para>These knobs are painting rules, so the test paints the real strip and inspects its
/// pixels. Anything less would pass while the bar rendered unchanged.</para></summary>
public class SocialBarAppearanceTests
{
private static readonly List<SocialEntry> Entries = new()
{
new SocialEntry { Service = SocialService.YouTube, Handle = "creator", ProfileUrl = "https://youtube.com/@creator" },
};
[Fact]
public void The_bar_paints_the_chosen_text_colour_plate_and_shadow()
{
Exception? failure = null;
var results = new List<string>();
var thread = new Thread(() =>
{
try
{
// 1. Default look: white glyphs, no plate, no shadow.
var plain = Render(SocialBarStyle.Default);
Assert.NotNull(plain);
Assert.True(Count(plain!, (r, g, b, a) => r > 200 && g > 200 && b > 200 && a > 200) > 0,
"white glyphs must be painted by default");
Assert.Equal(0, Count(plain!, (r, g, b, a) => b > 150 && r < 80 && g < 80));
// 2. Text colour: red glyphs, nothing white.
var red = Render(new SocialBarStyle("#FF0000", false, "#000000", 0.55, false));
Assert.True(Count(red!, (r, g, b, a) => r > 180 && g < 80 && b < 80 && a > 200) > 0,
"the text colour must reach the glyph pixels");
Assert.Equal(0, Count(red!, (r, g, b, a) => r > 200 && g > 200 && b > 200 && a > 200));
// 3. Plate: blue at 55% — half-transparent blue pixels must appear.
var plated = Render(new SocialBarStyle("#FFFFFF", true, "#0000FF", 0.55, false));
Assert.True(Count(plated!, (r, g, b, a) => b > 150 && r < 60 && g < 60 && a is > 100 and < 170) > 200,
"the plate must fill with its colour at the chosen opacity");
// 4. Shadow: dark semi-transparent pixels appear beside the glyphs.
var shadowed = Render(new SocialBarStyle("#FFFFFF", false, "#000000", 0.55, true));
Assert.True(Count(shadowed!, (r, g, b, a) => r < 60 && g < 60 && b < 60 && a is > 0 and < 200)
> Count(plain!, (r, g, b, a) => r < 60 && g < 60 && b < 60 && a is > 0 and < 200),
"the drop shadow must add dark pixels behind the glyphs");
}
catch (Exception ex) { failure = ex; }
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
thread.Join();
Assert.Null(failure);
}
[Fact]
public void The_preview_bar_is_never_hidden_by_the_plate_switch()
{
// Regression, 2026-10-30: the plate Border wrapped the whole bar and its Visibility was
// bound to BarBackgroundEnabled, so turning the plate off (the default) removed the bar
// from the preview entirely. "Plate off" must mean a transparent plate.
var preview = SourceAssert.Text("Controls", "PreviewPane.xaml");
Assert.DoesNotContain("Socials.BarBackgroundEnabled, Converter={StaticResource BoolToVis}", preview);
Assert.Contains("{Binding SocialBarBackgroundBrush}", preview);
// The plate's PADDING is what switches with the toggle, not the element's presence.
Assert.Contains("<Setter Property=\"Padding\" Value=\"18,6\"/>", preview);
}
private static VideoFrame? Render(SocialBarStyle style) => SocialBarRenderer.Render(Entries, style);
private static int Count(VideoFrame frame, Func<int, int, int, int, bool> predicate)
{
var hits = 0;
for (var i = 0; i < frame.BgraPixels.Length; i += 4)
if (predicate(frame.BgraPixels[i + 2], frame.BgraPixels[i + 1], frame.BgraPixels[i], frame.BgraPixels[i + 3]))
hits++;
return hits;
}
}