101 lines
3.6 KiB
C#
101 lines
3.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using Xunit;
|
|
using ytLive.Services;
|
|
|
|
namespace ytLive.Tests;
|
|
|
|
/// <summary>
|
|
/// TASK 20 step 2 integration: custom hotkey bindings survive a DB round-trip.
|
|
/// Save a mix of modifier chords and unbound actions to a temp LayoutStore,
|
|
/// load them back, and verify that (a) custom chords match, (b) unbound actions
|
|
/// are absent, and (c) actions the user didn't touch retain their defaults.
|
|
/// </summary>
|
|
public sealed class HotkeyConfigTests : IDisposable
|
|
{
|
|
private readonly string _tempDb;
|
|
|
|
public HotkeyConfigTests()
|
|
{
|
|
_tempDb = System.IO.Path.Combine(
|
|
System.IO.Path.GetTempPath(),
|
|
$"ytLlive-hotkeycfg-{Guid.NewGuid():N}.db");
|
|
}
|
|
|
|
[Fact]
|
|
public void HotkeyBindings_Persist_RoundTrip()
|
|
{
|
|
// Arrange: create a fresh DB
|
|
using (new LayoutStore(_tempDb)) { }
|
|
Microsoft.Data.Sqlite.SqliteConnection.ClearAllPools();
|
|
|
|
var bindings = new Dictionary<HotkeyId, HotkeyChord?>
|
|
{
|
|
[HotkeyId.SceneStarting] = new HotkeyChord(HotkeyChord.MOD_CONTROL, 0x79), // Ctrl+F10
|
|
[HotkeyId.ToggleMicMute] = null, // explicitly unbound
|
|
[HotkeyId.StartStopStream] = new HotkeyChord(HotkeyChord.MOD_ALT | HotkeyChord.MOD_SHIFT, 0x7B), // Alt+Shift+F12
|
|
};
|
|
|
|
// Act: save then load
|
|
using (var store = new LayoutStore(_tempDb))
|
|
{
|
|
store.SaveHotkeyBindings(bindings);
|
|
}
|
|
Microsoft.Data.Sqlite.SqliteConnection.ClearAllPools();
|
|
|
|
Dictionary<HotkeyId, HotkeyChord> loaded;
|
|
using (var store = new LayoutStore(_tempDb))
|
|
{
|
|
loaded = store.LoadHotkeyBindings();
|
|
}
|
|
|
|
// Assert: custom modifier chord round-trips correctly
|
|
Assert.True(loaded.TryGetValue(HotkeyId.SceneStarting, out var sceneStarting));
|
|
Assert.Equal(HotkeyChord.MOD_CONTROL, sceneStarting!.Modifiers);
|
|
Assert.Equal(0x79u, sceneStarting.VirtualKey);
|
|
|
|
// Assert: explicitly unbound action is absent
|
|
Assert.False(loaded.ContainsKey(HotkeyId.ToggleMicMute));
|
|
|
|
// Assert: multi-modifier chord round-trips correctly
|
|
Assert.True(loaded.TryGetValue(HotkeyId.StartStopStream, out var startStop));
|
|
Assert.Equal(HotkeyChord.MOD_ALT | HotkeyChord.MOD_SHIFT, startStop!.Modifiers);
|
|
Assert.Equal(0x7Bu, startStop.VirtualKey);
|
|
|
|
// Assert: untouched actions are absent (caller fills defaults)
|
|
Assert.False(loaded.ContainsKey(HotkeyId.SceneBrb));
|
|
Assert.False(loaded.ContainsKey(HotkeyId.TraxPlayPause));
|
|
}
|
|
|
|
[Fact]
|
|
public void HotkeyChord_DisplayString_FormatsModifiers()
|
|
{
|
|
var ctrlF10 = new HotkeyChord(HotkeyChord.MOD_CONTROL, 0x79);
|
|
Assert.Equal("Ctrl+F10", ctrlF10.ToDisplayString());
|
|
|
|
var altShiftF12 = new HotkeyChord(HotkeyChord.MOD_ALT | HotkeyChord.MOD_SHIFT, 0x7B);
|
|
Assert.Equal("Alt+Shift+F12", altShiftF12.ToDisplayString());
|
|
|
|
var bareF5 = new HotkeyChord(0, 0x74);
|
|
Assert.Equal("F5", bareF5.ToDisplayString());
|
|
|
|
var none = HotkeyChord.DisplayString(null);
|
|
Assert.Equal("None", none);
|
|
}
|
|
|
|
[Fact]
|
|
public void HotkeyChord_StorageRoundTrip()
|
|
{
|
|
var original = new HotkeyChord(HotkeyChord.MOD_CONTROL | HotkeyChord.MOD_WIN, 0x7B);
|
|
var stored = original.ToString();
|
|
var parsed = HotkeyChord.ParseStorage(stored);
|
|
Assert.Equal(original, parsed);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
Microsoft.Data.Sqlite.SqliteConnection.ClearAllPools();
|
|
try { System.IO.File.Delete(_tempDb); } catch { }
|
|
}
|
|
}
|