using System.Collections.Generic; using System.Linq; using Xunit; using ytLive.Models; namespace ytLive.Tests; /// Creator ruling (2026-10-30): the Scoreboard layer — YT_ACTIVITY_TICKER — is AVAILABLE TO /// ALL SCENES. It therefore heals into every scene like the Background and Brand logo, and a scene /// can never end up with two of them. public class ScoreboardHealerTests { private static Scene SceneWith(string name) { var scene = new Scene { Name = name }; scene.Elements.Add(new Source { Name = "Background", Type = SourceType.Background, IsBackground = true }); scene.Elements.Add(new Source { Name = "Brand logo", Type = SourceType.Image, IsBrandLogo = true }); return scene; } [Fact] public void Every_scene_gets_exactly_one_scoreboard_below_the_background() { var scenes = new List { SceneWith(SceneCatalog.Starting), SceneWith(SceneCatalog.Live), SceneWith(SceneCatalog.Brb), }; Assert.True(ScoreboardHealer.Ensure(scenes)); foreach (var scene in scenes) { var boards = scene.Elements.OfType().Where(s => s.IsScoreboard).ToList(); Assert.Single(boards); Assert.Equal("Scoreboard", boards[0].Name); Assert.Equal(0, boards[0].X); Assert.Equal(1920, boards[0].Width); Assert.Equal(ScoreboardHealer.StripHeight, boards[0].Height); // Topmost: a full-width strip over the scene, and the Brand logo keeps its documented // place directly above the background. Assert.Equal(scene.Elements.Count - 1, scene.Elements.IndexOf(boards[0])); Assert.Equal("Brand logo", scene.Elements[1].Name); } // Idempotent: a second pass changes nothing (no duplicate strips, no churn). Assert.False(ScoreboardHealer.Ensure(scenes)); foreach (var scene in scenes) Assert.Single(scene.Elements.OfType().Where(s => s.IsScoreboard)); // A scene that somehow has two is healed back to one. scenes[0].Elements.Add(new Source { Name = "Scoreboard2", Type = SourceType.Scoreboard }); Assert.True(ScoreboardHealer.Ensure(scenes)); Assert.Single(scenes[0].Elements.OfType().Where(s => s.IsScoreboard)); } }