125 lines
4.7 KiB
C#
125 lines
4.7 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using Microsoft.Data.Sqlite;
|
|
using Xunit;
|
|
using ytLive.Models;
|
|
using ytLive.ViewModels;
|
|
|
|
namespace ytLive.Tests;
|
|
|
|
/// <summary>
|
|
/// TASK 27 integration: the (+) menu's YouTube Chat row gates on one chat layer
|
|
/// per layout (same rule as the webcam's app-wide identity), and ChatBox layers
|
|
/// created before the "YouTube Chat" default (legacy name "Chat") heal to the
|
|
/// picklist's label on load — creator renames stay untouched.
|
|
/// Real-App + temp-DB pattern (see WebcamMenuGateTests).
|
|
/// </summary>
|
|
[Collection("RealApp")]
|
|
public sealed class ChatLayerGateTests
|
|
{
|
|
[Fact]
|
|
public void LegacyChatName_Heals_And_CanAddYouTubeChat_Gates_On_The_Existing_Layer()
|
|
{
|
|
_app.Run(Run);
|
|
}
|
|
|
|
private readonly RealAppHost _app;
|
|
|
|
public ChatLayerGateTests(RealAppHost app) => _app = app;
|
|
|
|
private void Run()
|
|
{
|
|
var tempDb = Path.Combine(Path.GetTempPath(), $"ytLlive-chatgate-{Guid.NewGuid():N}.db");
|
|
MainViewModel.LayoutPathOverride = tempDb;
|
|
var window = default(MainWindow);
|
|
try
|
|
{
|
|
using (var schema = new ytLive.Services.LayoutStore(tempDb)) { }
|
|
SqliteConnection.ClearAllPools();
|
|
SeedDatabaseWithLegacyChatLayer(tempDb);
|
|
|
|
window = new MainWindow();
|
|
var vm = (MainViewModel)window.DataContext;
|
|
|
|
var starting = vm.Scenes.Single(s => SceneCatalog.Is(s.Name, SceneCatalog.Starting));
|
|
var live = vm.Scenes.Single(s => SceneCatalog.Is(s.Name, SceneCatalog.Live));
|
|
|
|
var chatLayer = Assert.Single(starting.Elements.OfType<Source>()
|
|
.Where(s => s.Type == SourceType.ChatBox).ToList());
|
|
Assert.Equal("YouTube Chat", chatLayer.Name);
|
|
|
|
vm.StagedScene = live;
|
|
Assert.False(vm.CanAddYouTubeChat,
|
|
"chat layer exists in another scene — Add YouTube Chat must be greyed out");
|
|
|
|
vm.StagedScene = starting;
|
|
Assert.False(vm.CanAddYouTubeChat, "staged scene itself has the chat layer");
|
|
|
|
vm.SaveLayoutNow();
|
|
using (var connection = new SqliteConnection($"Data Source={tempDb}"))
|
|
{
|
|
connection.Open();
|
|
using var names = connection.CreateCommand();
|
|
names.CommandText =
|
|
"SELECT Name FROM Source WHERE Type = 'ChatBox';";
|
|
Assert.Equal("YouTube Chat", (string)names.ExecuteScalar()!);
|
|
}
|
|
|
|
vm.RemoveSourceCommand.Execute(chatLayer);
|
|
Assert.True(vm.CanAddYouTubeChat,
|
|
"the only chat layer was removed — the (+) item re-enables");
|
|
}
|
|
finally
|
|
{
|
|
window?.Close();
|
|
MainViewModel.LayoutPathOverride = null;
|
|
SqliteConnection.ClearAllPools();
|
|
try { File.Delete(tempDb); } catch { /* best-effort cleanup */ }
|
|
}
|
|
}
|
|
|
|
/// <summary>Five canonical scenes + a ChatBox layer still carrying the
|
|
/// pre-rename default name "Chat" in Starting.</summary>
|
|
private static void SeedDatabaseWithLegacyChatLayer(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 background = connection.CreateCommand())
|
|
{
|
|
background.CommandText =
|
|
@"INSERT INTO Source (Id, SceneId, Type, Name, IsEnabled, X, Y, Width, Height, IsBackground, SortOrder)
|
|
VALUES ('bg-1', 'scene-starting', 'Background', 'Background', 1, 0, 0, 1920, 1080, 1, 0);";
|
|
background.ExecuteNonQuery();
|
|
}
|
|
|
|
using (var chat = connection.CreateCommand())
|
|
{
|
|
chat.CommandText =
|
|
@"INSERT INTO Source (Id, SceneId, Type, Name, IsEnabled, X, Y, Width, Height, IsBackground, SortOrder)
|
|
VALUES ('chat-1', 'scene-starting', 'ChatBox', 'Chat', 1, 1400, 20, 500, 648, 0, 1);";
|
|
chat.ExecuteNonQuery();
|
|
}
|
|
}
|
|
}
|