TASK 51 slice 3: per-scene webcam BackgroundEffect + BackgroundStrength on WebcamSceneConfig, persisted via additive guarded columns; radio-pill bools RemoveBackground/BlurBackground (Unit: bg-effect config)

This commit is contained in:
2026-10-09 10:19:48 -07:00
parent 227ee8fca6
commit 55210b9a61
9 changed files with 126 additions and 13 deletions
@@ -128,6 +128,57 @@ public class LayoutStorePersistenceTests
}
}
/// <summary>TASK 51 slice 3: each scene's webcam background effect + strength survives a
/// save and a reopen; a pre-TASK-51 DB (no columns) migrates in place and reads None/0.5.</summary>
[Fact]
public void Webcam_Background_Effect_Round_Trips_Per_Scene_And_Legacy_Db_Migrates()
{
var path = Path.Combine(Path.GetTempPath(), $"ytLlive-layout-{Guid.NewGuid():N}.db");
try
{
var webcam = new Webcam { DeviceId = "real-device", Name = "Logitech" };
var live = new Scene { Name = "Live" };
live.Elements.Add(new WebcamSceneConfig { WebcamId = webcam.Id, Width = 480, Height = 270, BackgroundEffect = BackgroundEffect.Remove, BackgroundStrength = 0.2 });
var chat = new Scene { Name = "Chat" };
chat.Elements.Add(new WebcamSceneConfig { WebcamId = webcam.Id, Width = 480, Height = 270, BackgroundEffect = BackgroundEffect.Blur, BackgroundStrength = 0.8 });
using (var store = new LayoutStore(path))
store.Save(new[] { live, chat }, webcam, null);
using (var reopened = new LayoutStore(path))
{
var scenes = reopened.Load();
var liveCfg = scenes.Single(s => s.Name == "Live").Elements.OfType<WebcamSceneConfig>().Single();
var chatCfg = scenes.Single(s => s.Name == "Chat").Elements.OfType<WebcamSceneConfig>().Single();
Assert.Equal(BackgroundEffect.Remove, liveCfg.BackgroundEffect);
Assert.Equal(0.2, liveCfg.BackgroundStrength, 6);
Assert.Equal(BackgroundEffect.Blur, chatCfg.BackgroundEffect);
Assert.Equal(0.8, chatCfg.BackgroundStrength, 6);
}
// Simulate a DB written before TASK 51: drop the two columns, reopen.
SqliteConnection.ClearAllPools();
using (var raw = new SqliteConnection($"Data Source={path}"))
{
raw.Open();
using var cmd = raw.CreateCommand();
cmd.CommandText = "ALTER TABLE WebcamSceneConfig DROP COLUMN BackgroundEffect; ALTER TABLE WebcamSceneConfig DROP COLUMN BackgroundStrength;";
cmd.ExecuteNonQuery();
}
SqliteConnection.ClearAllPools();
using (var legacy = new LayoutStore(path))
{
var cfg = legacy.Load().SelectMany(s => s.Elements).OfType<WebcamSceneConfig>().First();
Assert.Equal(BackgroundEffect.None, cfg.BackgroundEffect);
Assert.Equal(0.5, cfg.BackgroundStrength, 6);
}
}
finally
{
SqliteConnection.ClearAllPools();
try { File.Delete(path); } catch { /* best-effort cleanup */ }
}
}
// The background (schema v5): permanent bottom layer holding live desktop/game
// capture. IsBackground + CaptureKey must survive a save + reload so a
// re-designated target isn't lost on restart.