using Moq; using PersonalToolBox.Helpers; using PersonalToolBox.Models; using PersonalToolBox.Services; namespace PersonalToolBox.Tests.Helpers; public class HotKeyManagerTests { [Fact] public void TryParseHotKey_ValidCtrlAltT_ReturnsCorrectModifiersAndVk() { var result = HotKeyManager.TryParseHotKey("Ctrl+Alt+T", out uint mod, out uint vk); Assert.True(result); Assert.NotEqual(0u, mod); // 'T' → VK = 0x54 Assert.Equal((uint)'T', vk); } [Fact] public void TryParseHotKey_ValidCtrlShiftF1_ReturnsCorrectVk() { var result = HotKeyManager.TryParseHotKey("Ctrl+Shift+F1", out uint mod, out uint vk); Assert.True(result); Assert.NotEqual(0u, mod); // F1 → VK_F1 = 0x70 Assert.Equal(0x70u, vk); } [Fact] public void TryParseHotKey_OnlyModifier_ReturnsFalse() { var result = HotKeyManager.TryParseHotKey("Ctrl", out _, out _); Assert.False(result); } [Fact] public void TryParseHotKey_OnlyKey_ReturnsFalse() { var result = HotKeyManager.TryParseHotKey("T", out _, out _); Assert.False(result); } [Fact] public void TryParseHotKey_Empty_ReturnsFalse() { var result = HotKeyManager.TryParseHotKey("", out _, out _); Assert.False(result); } [Fact] public void TryParseHotKey_Null_ReturnsFalse() { var result = HotKeyManager.TryParseHotKey(null!, out _, out _); Assert.False(result); } [Fact] public void TryParseHotKey_Whitespace_ReturnsFalse() { var result = HotKeyManager.TryParseHotKey(" ", out _, out _); Assert.False(result); } [Fact] public void TryParseHotKey_WinKey_B_ReturnsCorrectVk() { var result = HotKeyManager.TryParseHotKey("Win+B", out uint mod, out uint vk); Assert.True(result); Assert.Equal((uint)'B', vk); } [Fact] public void TryParseHotKey_UnknownModifier_ReturnsFalse() { var result = HotKeyManager.TryParseHotKey("Foo+T", out _, out _); Assert.False(result); } [Fact] public void RegisterAll_SkipsEmptyHotKeys() { var logMock = new Mock(); var processMock = new Mock(); var manager = new HotKeyManager(logMock.Object, processMock.Object); var tools = new[] { new ToolItem { Name = "NoHotkey", HotKey = "" }, new ToolItem { Name = "BlankHotkey", HotKey = " " } }; // Should not throw manager.RegisterAll(tools); } [Fact] public void RegisterAll_InvalidFormat_LogsWarning() { var logMock = new Mock(); var processMock = new Mock(); var manager = new HotKeyManager(logMock.Object, processMock.Object); // Initialize needs a hwnd, but RegisterAll calls Register which checks _hwnd // So calling RegisterAll without Initialize should be a no-op var tools = new[] { new ToolItem { Name = "Bad", HotKey = "not-a-valid-key" } }; // hwnd is IntPtr.Zero, so should skip silently manager.RegisterAll(tools); // hwnd is zero, so Register is skipped entirely logMock.Verify(x => x.Warning(It.IsAny()), Times.Never); } [Fact] public void TryHandleMessage_NonWMHOTKEY_ReturnsFalse() { var logMock = new Mock(); var processMock = new Mock(); var manager = new HotKeyManager(logMock.Object, processMock.Object); var handled = manager.TryHandleMessage(9999, IntPtr.Zero, IntPtr.Zero); Assert.False(handled); } }