using System;
using System.IO;
using System.Linq;
using Microsoft.Data.Sqlite;
using Xunit;
using ytLive.ViewModels;
namespace ytLive.Tests;
///
/// Scene-strip ordering vs F-keys (creator's report 2026-10-10). The five
/// canonical scenes are loaded ORDER BY SortOrder, and a session can
/// persist Chat before BRB, so the thumbnail strip renders in the wrong order
/// while each tab's F-key label is name-derived — "the ordering of the 5
/// screens and their corresponding F-key is out of sequence". Fix: the VM
/// reorders Scenes to the canonical F1-F5 order (Starting, Live, BRB, Chat,
/// Ending) at load; the next save re-stamps SortOrder to the corrected order.
///
[Collection("RealApp")]
public sealed class SceneOrderTests
{
private readonly RealAppHost _app;
public SceneOrderTests(RealAppHost app) => _app = app;
[Fact]
public void Scenes_Load_Into_Canonical_FKey_Order_Whatever_The_SortOrder_Rows()
{
_app.Run(() =>
{
using var layout = new TempSwappedOrderLayout();
var vm = new MainViewModel();
var names = vm.Scenes.Select(s => s.Name).ToArray();
Assert.Equal(new[] { "Starting", "Live", "BRB", "Chat", "Ending" }, names);
var keys = vm.Scenes.Select(s => s.HotkeyLabel).ToArray();
Assert.Equal(new[] { "F1", "F2", "F3", "F4", "F5" }, keys);
// The heal persists: a save re-stamps SortOrder, so a fresh load (the
// thumbnail strip's rendering source) keeps the canonical order.
vm.SaveLayoutNow();
using var reloaded = new Services.LayoutStore(layout.DbPath);
Assert.Equal(new[] { "Starting", "Live", "BRB", "Chat", "Ending" },
reloaded.Load().Select(s => s.Name).ToArray());
});
}
/// Creates a DB whose five scenes are persisted with Chat BEFORE
/// BRB — the exact stale state found on the creator's box.
private sealed class TempSwappedOrderLayout : IDisposable
{
public string DbPath { get; }
private readonly string _path;
public TempSwappedOrderLayout()
{
_path = Path.Combine(Path.GetTempPath(), $"ytLive-sceneorder-{Guid.NewGuid():N}.db");
DbPath = _path;
using (var schema = new Services.LayoutStore(_path)) { }
SqliteConnection.ClearAllPools();
MainViewModel.LayoutPathOverride = _path;
using var connection = new SqliteConnection($"Data Source={_path}");
connection.Open();
using (var cmd = connection.CreateCommand())
{
cmd.CommandText = """
INSERT INTO Scene (Id, Name, IsHidden, IsChatScene, HasBackground, SortOrder)
VALUES
('scene-starting', 'Starting', 0, 0, 1, 0),
('scene-live', 'Live', 0, 0, 1, 1),
('scene-chat', 'Chat', 0, 1, 1, 2),
('scene-brb', 'BRB', 0, 0, 1, 3),
('scene-ending', 'Ending', 0, 0, 1, 4);
""";
cmd.ExecuteNonQuery();
}
}
public void Dispose()
{
MainViewModel.LayoutPathOverride = null;
SqliteConnection.ClearAllPools();
try { File.Delete(_path); } catch { /* best-effort cleanup */ }
}
}
}