using System; using System.IO; using System.Linq; using Microsoft.Data.Sqlite; using Xunit; using ytLive.Models; using ytLive.Services; using ytLive.ViewModels; namespace ytLive.Tests; /// /// Take-2 fix (2026-09-01): configs reference the webcam by IDENTITY GUID while /// CameraManager sessions are keyed by DEVICE id — the output resolver looked up the /// wrong dictionary and the camera was structurally invisible on stream/recordings /// while the preview (bitmap path) looked fine. DeviceKeyForWebcam is the mapping; /// this test seeds a layout whose identity differs from its device id and asserts /// the map (plus unknown-id passthrough). /// [Collection("RealApp")] public sealed class WebcamOutputKeyTests { private readonly RealAppHost _app; public WebcamOutputKeyTests(RealAppHost app) => _app = app; [Fact] public void DeviceKeyForWebcam_Maps_Identity_To_Device() { _app.Run(Run); } private void Run() { var tempDb = Path.Combine(Path.GetTempPath(), $"ytLlive-wckey-{Guid.NewGuid():N}.db"); MainViewModel.LayoutPathOverride = tempDb; var window = default(MainWindow); try { using (var schema = new LayoutStore(tempDb)) { } SqliteConnection.ClearAllPools(); Seed(tempDb); window = new MainWindow(); var vm = (MainViewModel)window.DataContext; Assert.Equal("dev-physical-9", vm.DeviceKeyForWebcam("wid-identity-7")); Assert.Equal("unknown-id", vm.DeviceKeyForWebcam("unknown-id")); } finally { if (window != null) window.Close(); MainViewModel.LayoutPathOverride = null; SqliteConnection.ClearAllPools(); try { File.Delete(tempDb); } catch { /* best-effort */ } } } private static void Seed(string path) { using var connection = new SqliteConnection($"Data Source={path}"); connection.Open(); var scenes = new (string Id, string Name)[] { ("scene-starting", "Starting"), ("scene-live", "Live"), ("scene-brb", "BRB"), ("scene-chat", "Chat"), ("scene-ending", "Ending"), }; foreach (var (id, name) in scenes) { using var cmd = connection.CreateCommand(); cmd.CommandText = "INSERT INTO Scene (Id, Name, HasBackground, SortOrder) VALUES ($id, $name, 1, $order);"; cmd.Parameters.AddWithValue("$id", id); cmd.Parameters.AddWithValue("$name", name); cmd.Parameters.AddWithValue("$order", Array.IndexOf(scenes, (id, name))); cmd.ExecuteNonQuery(); } using (var webcam = connection.CreateCommand()) { webcam.CommandText = "INSERT INTO Webcam (Id, DeviceId, Name) VALUES ('wid-identity-7', 'dev-physical-9', 'Cam');"; webcam.ExecuteNonQuery(); } using (var config = connection.CreateCommand()) { config.CommandText = @"INSERT INTO WebcamSceneConfig (SceneId, WebcamId, IsVisible, X, Y, Width, Height, Opacity, SortOrder) VALUES ('scene-live', 'wid-identity-7', 1, 100, 100, 480, 270, 1, 0);"; config.ExecuteNonQuery(); } } }