using Xunit; using ytLive.Models; using ytLive.ViewModels; namespace ytLive.Tests; /// /// The backdrop is a permanent, non-deletable bottom layer holding live /// desktop/game capture, and it exists only in the canonical Live scene (see /// ). Every backdrop-enabled scene /// () is healed to have exactly one, inserted /// first; it is never reorderable or removable by the UI. Scenes without the /// flag never get one. /// public class BackdropTests { [Fact] public void EnsureBackdrop_OnEmptyScene_InsertsFullFrameBackdrop() { var scene = new Scene { Name = "S", HasBackdrop = true }; var backdrop = MainViewModel.EnsureBackdrop(scene); Assert.NotNull(backdrop); Assert.Single(scene.Elements); Assert.Same(backdrop, scene.Elements[0]); Assert.True(backdrop.IsBackdrop); Assert.True(backdrop.IsEnabled); Assert.Equal(SourceType.DisplayCapture, backdrop.Type); Assert.Equal(0, backdrop.X); Assert.Equal(0, backdrop.Y); Assert.Equal(1920, backdrop.Width); Assert.Equal(1080, backdrop.Height); } [Fact] public void EnsureBackdrop_ExistingBackdrop_IsIdempotent() { var scene = new Scene { Name = "S", HasBackdrop = true }; var first = MainViewModel.EnsureBackdrop(scene); var second = MainViewModel.EnsureBackdrop(scene); Assert.Same(first, second); Assert.Single(scene.Elements); } [Fact] public void EnsureBackdrop_HealsMissingBackdropAtIndexZero() { var scene = new Scene { Name = "S", HasBackdrop = true }; var image = new Source { Name = "Logo", Type = SourceType.Image }; scene.Elements.Add(image); MainViewModel.EnsureBackdrop(scene); Assert.Equal(2, scene.Elements.Count); Assert.True(((Source)scene.Elements[0]).IsBackdrop); Assert.Same(image, scene.Elements[1]); } [Fact] public void EnsureBackdrop_SceneWithoutHasBackdrop_ReturnsNullAndInsertsNothing() { var scene = new Scene { Name = "Ending", HasBackdrop = false }; var backdrop = MainViewModel.EnsureBackdrop(scene); Assert.Null(backdrop); Assert.Empty(scene.Elements); } [Theory] [InlineData(SourceType.DisplayCapture, true)] [InlineData(SourceType.WindowCapture, true)] [InlineData(SourceType.Background, false)] [InlineData(SourceType.Image, false)] [InlineData(SourceType.TextOverlay, false)] public void Source_IsLiveCapture_OnlyForDisplayAndWindow(SourceType type, bool expected) { Assert.Equal(expected, new Source { Type = type }.IsLiveCapture); } [Fact] public void Source_DisplaySource_IsVideoImageSource_WhenLiveCapture() { var source = new Source { Type = SourceType.DisplayCapture }; var bitmap = new System.Windows.Media.Imaging.WriteableBitmap( 2, 2, 96, 96, System.Windows.Media.PixelFormats.Bgra32, null); source.VideoImageSource = bitmap; Assert.Same(bitmap, source.DisplaySource); } [Fact] public void Source_DisplaySource_IsImageSource_WhenNotLiveCapture() { var source = new Source { Type = SourceType.Background }; var bitmap = new System.Windows.Media.Imaging.WriteableBitmap( 2, 2, 96, 96, System.Windows.Media.PixelFormats.Bgra32, null); source.VideoImageSource = bitmap; Assert.NotSame(bitmap, source.DisplaySource); Assert.Null(source.DisplaySource); } [Fact] public void Source_TypeChange_RaisesDisplaySource() { var source = new Source { Type = SourceType.Image }; var raised = new List(); source.PropertyChanged += (_, e) => raised.Add(e.PropertyName ?? string.Empty); source.Type = SourceType.DisplayCapture; Assert.Contains(nameof(Source.IsLiveCapture), raised); Assert.Contains(nameof(Source.DisplaySource), raised); } }