using Xunit; using ytLive.Models; using ytLive.ViewModels; namespace ytLive.Tests; /// /// The background is a permanent, non-deletable bottom layer holding live /// desktop/game capture, and it exists only in the canonical Live scene (see /// ). Every background-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 BackgroundTests { [Fact] public void EnsureBackground_OnEmptyScene_InsertsFullFrameBackground() { var scene = new Scene { Name = "S", HasBackground = true }; var background = MainViewModel.EnsureBackground(scene); Assert.NotNull(background); Assert.Single(scene.Elements); Assert.Same(background, scene.Elements[0]); Assert.True(background.IsBackground); Assert.True(background.IsEnabled); // Non-Live scenes get the static-art flavor; only Live captures. Assert.Equal(SourceType.Background, background.Type); Assert.Equal("Background", background.Name); Assert.Equal(0, background.X); Assert.Equal(0, background.Y); Assert.Equal(1920, background.Width); Assert.Equal(1080, background.Height); } [Fact] public void EnsureBackground_ExistingBackground_IsIdempotent() { var scene = new Scene { Name = "S", HasBackground = true }; var first = MainViewModel.EnsureBackground(scene); var second = MainViewModel.EnsureBackground(scene); Assert.Same(first, second); Assert.Single(scene.Elements); } [Fact] public void EnsureBackground_HealsMissingBackgroundAtIndexZero() { var scene = new Scene { Name = "S", HasBackground = true }; var image = new Source { Name = "Logo", Type = SourceType.Image }; scene.Elements.Add(image); MainViewModel.EnsureBackground(scene); Assert.Equal(2, scene.Elements.Count); Assert.True(((Source)scene.Elements[0]).IsBackground); Assert.Same(image, scene.Elements[1]); } [Fact] public void EnsureBackground_SceneWithoutHasBackground_ReturnsNullAndInsertsNothing() { var scene = new Scene { Name = "Ending", HasBackground = false }; var background = MainViewModel.EnsureBackground(scene); Assert.Null(background); 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_FallsBackToImage_WhenLiveCaptureWithNoVideoImage() { var source = new Source { Type = SourceType.DisplayCapture }; Assert.Null(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); } [Fact] public void AllScenes_BackgroundElement_HasIsBackgroundTrue() { foreach (var name in SceneCatalog.All) { var scene = new Scene { Name = name, HasBackground = SceneCatalog.HasBackground(name) }; var bg = new Source { Name = "Background", Type = SourceType.Background }; scene.Elements.Add(bg); Assert.True(bg.IsBackground, $"{name}: Background element must have IsBackground = true for properties panel"); } } [Fact] public void AllScenes_BackgroundElement_IsBackgroundDerivedFromType() { var bg = new Source { Type = SourceType.Background }; Assert.True(bg.IsBackground); var nonBg = new Source { Type = SourceType.Image }; Assert.False(nonBg.IsBackground); var display = new Source { Type = SourceType.DisplayCapture }; Assert.False(display.IsBackground); } [Fact] public void AllScenes_BackgroundElement_SupportsUseDefaultBackground() { foreach (var name in SceneCatalog.All) { var scene = new Scene { Name = name }; var bg = new Source { Name = "Background", Type = SourceType.Background }; scene.Elements.Add(bg); Assert.True(bg.UseDefaultBackground, $"{name}: Background element must default to UseDefaultBackground = true"); } } }