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));
}
}