feat(37): expose the all-scenes factory reset

App Settings now offers a clearly described all-scenes reset. It is disabled
while live or recording and reloads the restored layout immediately. The
integration test drives the real VM command and checks the Settings binding.
614 tests green, clean build with 0 warnings.

Reference: OBS Scene Collections are a distinct saved set of scenes and sources:
https://obsproject.com/kb/scene-collections
This commit is contained in:
2026-11-10 18:05:35 -08:00
parent b8eb2b4451
commit 41064bdd13
4 changed files with 72 additions and 1 deletions
@@ -0,0 +1,54 @@
using System;
using System.IO;
using System.Linq;
using Microsoft.Data.Sqlite;
using Xunit;
using ytLive.Models;
using ytLive.ViewModels;
namespace ytLive.Tests;
[Collection("RealApp")]
public sealed class LayoutResetIntegrationTests
{
private readonly RealAppHost _app;
public LayoutResetIntegrationTests(RealAppHost app) => _app = app;
[Fact]
public void SettingsRestoreAll_ReplacesEditedScenesWithFactoryLayout() => _app.Run(() =>
{
var tempDb = Path.Combine(Path.GetTempPath(), $"ytLlive-layout-reset-{Guid.NewGuid():N}.db");
MainViewModel.LayoutPathOverride = tempDb;
MainViewModel? vm = null;
try
{
vm = new MainViewModel();
var starting = vm.Scenes.Single(scene => SceneCatalog.Is(scene.Name, SceneCatalog.Starting));
starting.Elements.Add(new Source
{
Name = "Creator-only layer",
Type = SourceType.TextOverlay,
TextContent = "Not in factory layout",
});
vm.SaveLayoutNow();
Assert.True(vm.RestoreAllLayoutDefaultsCommand.CanExecute(null));
vm.RestoreAllLayoutDefaultsCommand.Execute(null);
Assert.DoesNotContain(vm.Scenes.SelectMany(scene => scene.Elements).OfType<Source>(),
source => source.Name == "Creator-only layer");
var settingsXaml = SourceAssert.Text("Controls", "SettingsDrawer.xaml");
Assert.Contains("Content=\"Restore all scenes\"", settingsXaml);
Assert.Contains("Command=\"{Binding RestoreAllLayoutDefaultsCommand}\"", settingsXaml);
}
finally
{
vm?.Shutdown();
MainViewModel.LayoutPathOverride = null;
SqliteConnection.ClearAllPools();
try { File.Delete(tempDb); } catch { /* best-effort cleanup */ }
}
});
}