221 lines
8.4 KiB
C#
221 lines
8.4 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using Microsoft.Data.Sqlite;
|
|
using Xunit;
|
|
using ytLive.Models;
|
|
using ytLive.Services;
|
|
|
|
namespace ytLive.Tests;
|
|
|
|
public sealed class LayoutStoreSnapshotTests
|
|
{
|
|
[Fact]
|
|
public void SameBuild_OpensCurrentLayout_WithoutChangingDefaultSnapshot()
|
|
{
|
|
var path = Path.Combine(Path.GetTempPath(), $"ytLlive-layout-snapshot-{Guid.NewGuid():N}.db");
|
|
const string buildId = "build-a";
|
|
try
|
|
{
|
|
using (var store = new LayoutStore(path))
|
|
{
|
|
var factory = MakeScene("Factory title");
|
|
store.Save(new[] { factory }, null, null);
|
|
store.PrepareLayoutSnapshots(buildId);
|
|
|
|
store.Save(new[] { MakeScene("Creator edit") }, null, null);
|
|
}
|
|
|
|
using (var reopened = new LayoutStore(path))
|
|
{
|
|
reopened.PrepareLayoutSnapshots(buildId);
|
|
var current = Assert.Single(reopened.Load());
|
|
Assert.Equal("Creator edit", Assert.Single(current.Elements.OfType<Source>()).Name);
|
|
|
|
using var connection = GetConnection(path);
|
|
using var command = connection.CreateCommand();
|
|
command.CommandText = "SELECT Value FROM LayoutSnapshotState WHERE Key = 'CurrentBuildId';";
|
|
Assert.Equal(buildId, command.ExecuteScalar());
|
|
|
|
command.CommandText = "SELECT Name FROM DefaultSource;";
|
|
Assert.Equal("Factory title", command.ExecuteScalar());
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
SqliteConnection.ClearAllPools();
|
|
try { File.Delete(path); } catch { /* best-effort cleanup */ }
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void DifferentBuild_RestoresTheDefaultSnapshotBeforeLoading()
|
|
{
|
|
var path = Path.Combine(Path.GetTempPath(), $"ytLlive-layout-snapshot-{Guid.NewGuid():N}.db");
|
|
try
|
|
{
|
|
using (var store = new LayoutStore(path))
|
|
{
|
|
store.Save(new[] { MakeScene("Factory title") }, null, null);
|
|
store.PrepareLayoutSnapshots("build-a");
|
|
store.Save(new[] { MakeScene("Creator edit") }, null, null);
|
|
}
|
|
|
|
using (var reopened = new LayoutStore(path))
|
|
{
|
|
reopened.PrepareLayoutSnapshots("build-b");
|
|
var restored = Assert.Single(reopened.Load());
|
|
Assert.Equal("Factory title", Assert.Single(restored.Elements.OfType<Source>()).Name);
|
|
|
|
using var connection = GetConnection(path);
|
|
using var command = connection.CreateCommand();
|
|
command.CommandText = "SELECT Value FROM LayoutSnapshotState WHERE Key = 'CurrentBuildId';";
|
|
Assert.Equal("build-b", command.ExecuteScalar());
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
SqliteConnection.ClearAllPools();
|
|
try { File.Delete(path); } catch { /* best-effort cleanup */ }
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void ResetOneScene_RestoresItsFactoryLayers_AndKeepsOtherSceneEdits()
|
|
{
|
|
var path = Path.Combine(Path.GetTempPath(), $"ytLlive-layout-snapshot-{Guid.NewGuid():N}.db");
|
|
var starting = MakeScene(SceneCatalog.Starting, "Factory starting");
|
|
var brb = MakeScene(SceneCatalog.Brb, "Factory BRB");
|
|
try
|
|
{
|
|
using (var store = new LayoutStore(path))
|
|
{
|
|
store.Save(new[] { starting, brb }, null, null);
|
|
store.PrepareLayoutSnapshots("build-a");
|
|
store.Save(new[]
|
|
{
|
|
MakeScene(starting.Id, starting.Name, "Edited starting"),
|
|
MakeScene(brb.Id, brb.Name, "Edited BRB"),
|
|
}, null, null);
|
|
}
|
|
|
|
using (var reopened = new LayoutStore(path))
|
|
{
|
|
reopened.PrepareLayoutSnapshots("build-a");
|
|
Assert.True(reopened.RestoreDefaultScene(starting.Id));
|
|
|
|
var scenes = reopened.Load();
|
|
Assert.Equal("Factory starting", Assert.Single(scenes.Single(s => s.Id == starting.Id).Elements.OfType<Source>()).Name);
|
|
Assert.Equal("Edited BRB", Assert.Single(scenes.Single(s => s.Id == brb.Id).Elements.OfType<Source>()).Name);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
SqliteConnection.ClearAllPools();
|
|
try { File.Delete(path); } catch { /* best-effort cleanup */ }
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void DifferentBuild_RestoresWebcamPlacement_WithoutReplacingChosenCamera()
|
|
{
|
|
var path = Path.Combine(Path.GetTempPath(), $"ytLlive-layout-snapshot-{Guid.NewGuid():N}.db");
|
|
var sceneId = Guid.NewGuid().ToString();
|
|
var defaultWebcam = new Webcam { Id = "factory-webcam", DeviceId = "factory-device", Name = "Factory camera" };
|
|
var chosenWebcam = new Webcam { Id = "chosen-webcam", DeviceId = "chosen-device", Name = "Chosen camera" };
|
|
try
|
|
{
|
|
using (var store = new LayoutStore(path))
|
|
{
|
|
store.Save(new[] { MakeWebcamScene(sceneId, defaultWebcam.Id, 20) }, defaultWebcam, null);
|
|
store.PrepareLayoutSnapshots("build-a");
|
|
store.Save(new[] { MakeWebcamScene(sceneId, chosenWebcam.Id, 200) }, chosenWebcam, null);
|
|
}
|
|
|
|
using (var reopened = new LayoutStore(path))
|
|
{
|
|
reopened.PrepareLayoutSnapshots("build-b");
|
|
var restored = Assert.Single(reopened.Load());
|
|
var config = Assert.Single(restored.Elements.OfType<WebcamSceneConfig>());
|
|
Assert.Equal(chosenWebcam.DeviceId, reopened.Webcam?.DeviceId);
|
|
Assert.Equal(chosenWebcam.Id, config.WebcamId);
|
|
Assert.Equal(20, config.X);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
SqliteConnection.ClearAllPools();
|
|
try { File.Delete(path); } catch { /* best-effort cleanup */ }
|
|
}
|
|
}
|
|
|
|
[Fact]
|
|
public void ResetAllScenes_RestoresTheFactorySnapshot()
|
|
{
|
|
var path = Path.Combine(Path.GetTempPath(), $"ytLlive-layout-snapshot-{Guid.NewGuid():N}.db");
|
|
var starting = MakeScene(SceneCatalog.Starting, "Factory starting");
|
|
var brb = MakeScene(SceneCatalog.Brb, "Factory BRB");
|
|
try
|
|
{
|
|
using (var store = new LayoutStore(path))
|
|
{
|
|
store.Save(new[] { starting, brb }, null, null);
|
|
store.PrepareLayoutSnapshots("build-a");
|
|
store.Save(new[]
|
|
{
|
|
MakeScene(starting.Id, starting.Name, "Edited starting"),
|
|
MakeScene(brb.Id, brb.Name, "Edited BRB"),
|
|
}, null, null);
|
|
}
|
|
|
|
using (var reopened = new LayoutStore(path))
|
|
{
|
|
reopened.PrepareLayoutSnapshots("build-a");
|
|
Assert.True(reopened.RestoreAllDefaults());
|
|
|
|
var scenes = reopened.Load();
|
|
Assert.Equal("Factory starting", Assert.Single(scenes.Single(s => s.Name == SceneCatalog.Starting).Elements.OfType<Source>()).Name);
|
|
Assert.Equal("Factory BRB", Assert.Single(scenes.Single(s => s.Name == SceneCatalog.Brb).Elements.OfType<Source>()).Name);
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
SqliteConnection.ClearAllPools();
|
|
try { File.Delete(path); } catch { /* best-effort cleanup */ }
|
|
}
|
|
}
|
|
|
|
private static Scene MakeScene(string sourceName)
|
|
=> MakeScene(SceneCatalog.Starting, sourceName);
|
|
|
|
private static Scene MakeScene(string sceneName, string sourceName)
|
|
=> new()
|
|
{
|
|
Name = sceneName,
|
|
Elements = { new Source { Name = sourceName, Type = SourceType.TextOverlay } },
|
|
};
|
|
|
|
private static Scene MakeScene(string id, string sceneName, string sourceName)
|
|
=> new()
|
|
{
|
|
Id = id,
|
|
Name = sceneName,
|
|
Elements = { new Source { Name = sourceName, Type = SourceType.TextOverlay } },
|
|
};
|
|
|
|
private static Scene MakeWebcamScene(string id, string webcamId, double x)
|
|
=> new()
|
|
{
|
|
Id = id,
|
|
Name = SceneCatalog.Live,
|
|
Elements = { new WebcamSceneConfig { WebcamId = webcamId, Name = "Webcam", X = x, Y = 20, Width = 320, Height = 180 } },
|
|
};
|
|
|
|
private static SqliteConnection GetConnection(string path)
|
|
{
|
|
var connection = new SqliteConnection($"Data Source={path}");
|
|
connection.Open();
|
|
return connection;
|
|
}
|
|
}
|