/ src / modules / keyboardmanager / KeyboardManagerEngineTest / OSLevelShortcutRemappingTests.cpp
OSLevelShortcutRemappingTests.cpp
   1  #include "pch.h"
   2  
   3  // Suppressing 26466 - Don't use static_cast downcasts - in CppUnitTest.h
   4  #pragma warning(push)
   5  #pragma warning(disable : 26466)
   6  #include "CppUnitTest.h"
   7  #pragma warning(pop)
   8  
   9  #include "MockedInput.h"
  10  #include <keyboardmanager/KeyboardManagerEngineLibrary/State.h>
  11  #include <keyboardmanager/KeyboardManagerEngineLibrary/KeyboardEventHandlers.h>
  12  #include "TestHelpers.h"
  13  #include <common/interop/shared_constants.h>
  14  
  15  using namespace Microsoft::VisualStudio::CppUnitTestFramework;
  16  
  17  namespace RemappingLogicTests
  18  {
  19      // Tests for shortcut remapping logic
  20      TEST_CLASS (OSLevelShortcutRemappingTests)
  21      {
  22      private:
  23          KeyboardManagerInput::MockedInput mockedInputHandler;
  24          State testState;
  25  
  26      public:
  27          TEST_METHOD_INITIALIZE(InitializeTestEnv)
  28          {
  29              // Reset test environment
  30              TestHelpers::ResetTestEnv(mockedInputHandler, testState);
  31  
  32              // Set HandleOSLevelShortcutRemapEvent as the hook procedure
  33              std::function<intptr_t(LowlevelKeyboardEvent*)> currentHookProc = std::bind(&KeyboardEventHandlers::HandleOSLevelShortcutRemapEvent, std::ref(mockedInputHandler), std::placeholders::_1, std::ref(testState));
  34              mockedInputHandler.SetHookProc([currentHookProc](LowlevelKeyboardEvent* data) {
  35                  if (data->lParam->dwExtraInfo != KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG)
  36                  {
  37                      return currentHookProc(data);
  38                  }
  39                  else
  40                  {
  41                      return 1LL;
  42                  }
  43              });
  44          }
  45  
  46          // Tests for shortcut to shortcut remappings
  47  
  48          // Test if correct keyboard states are set for a 2 key shortcut remap with different modifiers key down
  49          TEST_METHOD (RemappedTwoKeyShortcutWithDiffModifiers_ShouldSetTargetShortcutDown_OnKeyDown)
  50          {
  51              // Remap Ctrl+A to Alt+V
  52              Shortcut src;
  53              src.SetKey(VK_CONTROL);
  54              src.SetKey(0x41);
  55              Shortcut dest;
  56              dest.SetKey(VK_MENU);
  57              dest.SetKey(0x56);
  58              testState.AddOSLevelShortcut(src, dest);
  59  
  60              std::vector<INPUT> inputs{
  61                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
  62                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
  63              };
  64  
  65              // Send Ctrl+A keydown
  66              mockedInputHandler.SendVirtualInput(inputs);
  67  
  68              // Ctrl and A key states should be unchanged, Alt and V key states should be true
  69              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
  70              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
  71              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true);
  72              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), true);
  73          }
  74  
  75          // Test if correct keyboard states are set for a 2 key shortcut remap with same modifiers key down
  76          TEST_METHOD (RemappedTwoKeyShortcutWithSameModifiers_ShouldSetTargetShortcutDown_OnKeyDown)
  77          {
  78              // Remap Ctrl+A to Ctrl+V
  79              Shortcut src;
  80              src.SetKey(VK_CONTROL);
  81              src.SetKey(0x41);
  82              Shortcut dest;
  83              dest.SetKey(VK_CONTROL);
  84              dest.SetKey(0x56);
  85              testState.AddOSLevelShortcut(src, dest);
  86  
  87              std::vector<INPUT> inputs{
  88                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
  89                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
  90              };
  91  
  92              // Send Ctrl+A keydown
  93              mockedInputHandler.SendVirtualInput(inputs);
  94  
  95              // A key state should be unchanged, Ctrl and V key states should be true
  96              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
  97              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
  98              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), true);
  99          }
 100  
 101          // Test if correct keyboard states are set for a 2 key shortcut remap with different modifiers key down followed by key up
 102          TEST_METHOD (RemappedTwoKeyShortcutWithDiffModifiers_ShouldClearKeyboard_OnKeyUp)
 103          {
 104              // Remap Ctrl+A to Alt+V
 105              Shortcut src;
 106              src.SetKey(VK_CONTROL);
 107              src.SetKey(0x41);
 108              Shortcut dest;
 109              dest.SetKey(VK_MENU);
 110              dest.SetKey(0x56);
 111              testState.AddOSLevelShortcut(src, dest);
 112  
 113              std::vector<INPUT> inputs{
 114                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 115                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 116                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
 117                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
 118              };
 119  
 120              // Send Ctrl+A keydown, followed by A and Ctrl released
 121              mockedInputHandler.SendVirtualInput(inputs);
 122  
 123              // Ctrl, A, Alt, V key states should be false
 124              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
 125              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 126              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
 127              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
 128          }
 129  
 130          // Test if correct keyboard states are set for a 2 key shortcut remap with same modifiers key down followed by key up
 131          TEST_METHOD (RemappedTwoKeyShortcutWithSameModifiers_ShouldClearKeyboard_OnKeyUp)
 132          {
 133              // Remap Ctrl+A to Ctrl+V
 134              Shortcut src;
 135              src.SetKey(VK_CONTROL);
 136              src.SetKey(0x41);
 137              Shortcut dest;
 138              dest.SetKey(VK_CONTROL);
 139              dest.SetKey(0x56);
 140              testState.AddOSLevelShortcut(src, dest);
 141  
 142              std::vector<INPUT> inputs{
 143                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 144                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 145                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
 146                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
 147              };
 148  
 149              // Send Ctrl+A keydown, followed by A and Ctrl released
 150              mockedInputHandler.SendVirtualInput(inputs);
 151  
 152              // Ctrl, A, V key states should be false
 153              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
 154              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 155              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
 156          }
 157  
 158          // Test if correct keyboard states are set when a 2 key shortcut is remapped, and a 3 key shortcut containing those keys is invoked - Ex: Ctrl+A remapped, but user presses Ctrl+Shift+A
 159          TEST_METHOD (RemappedTwoKeyShortcutInvokingAShortcutContainingThoseKeys_ShouldNotBeRemapped_OnKeyDown)
 160          {
 161              // Remap Ctrl+A to Alt+V
 162              Shortcut src;
 163              src.SetKey(VK_CONTROL);
 164              src.SetKey(0x41);
 165              Shortcut dest;
 166              dest.SetKey(VK_MENU);
 167              dest.SetKey(0x56);
 168              testState.AddOSLevelShortcut(src, dest);
 169  
 170              std::vector<INPUT> inputs{
 171                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 172                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT } },
 173                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 174              };
 175  
 176              // Send Ctrl+Shift+A keydown
 177              mockedInputHandler.SendVirtualInput(inputs);
 178  
 179              // Since Ctrl+Shift+A is not remapped, no remapping should be invoked
 180              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
 181              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), true);
 182              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), true);
 183              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
 184              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
 185          }
 186  
 187          // Test if correct keyboard states are set for a 3 key shortcut remap with different modifiers key down
 188          TEST_METHOD (RemappedThreeKeyShortcutWithDiffModifiers_ShouldSetTargetShortcutDown_OnKeyDown)
 189          {
 190              // Remap Ctrl+Shift+A to Alt+LWin+V
 191              Shortcut src;
 192              src.SetKey(VK_CONTROL);
 193              src.SetKey(VK_SHIFT);
 194              src.SetKey(0x41);
 195              Shortcut dest;
 196              dest.SetKey(VK_MENU);
 197              dest.SetKey(VK_LWIN);
 198              dest.SetKey(0x56);
 199              testState.AddOSLevelShortcut(src, dest);
 200  
 201              std::vector<INPUT> inputs{
 202                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 203                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT } },
 204                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 205              };
 206  
 207              // Send Ctrl+Shift+A keydown
 208              mockedInputHandler.SendVirtualInput(inputs);
 209  
 210              // Ctrl, Shift, A key states should be unchanged, Alt, LWin, V key states should be true
 211              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
 212              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
 213              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 214              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true);
 215              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_LWIN), true);
 216              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), true);
 217          }
 218  
 219          // Test if correct keyboard states are set for a 3 key shortcut remap with partially different modifiers key down
 220          TEST_METHOD (RemappedThreeKeyShortcutWithPartiallyDiffModifiers_ShouldSetTargetShortcutDown_OnKeyDown)
 221          {
 222              // Remap Ctrl+Shift+A to Alt+Ctrl+V
 223              Shortcut src;
 224              src.SetKey(VK_CONTROL);
 225              src.SetKey(VK_SHIFT);
 226              src.SetKey(0x41);
 227              Shortcut dest;
 228              dest.SetKey(VK_MENU);
 229              dest.SetKey(VK_CONTROL);
 230              dest.SetKey(0x56);
 231              testState.AddOSLevelShortcut(src, dest);
 232  
 233              std::vector<INPUT> inputs{
 234                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 235                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT } },
 236                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 237              };
 238  
 239              // Send Ctrl+Shift+A keydown
 240              mockedInputHandler.SendVirtualInput(inputs);
 241  
 242              // Shift, A key states should be unchanged, Alt, Ctrl, V key states should be true
 243              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
 244              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 245              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true);
 246              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
 247              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), true);
 248          }
 249  
 250          // Test if correct keyboard states are set for a 3 key shortcut remap with same modifiers key down
 251          TEST_METHOD (RemappedThreeKeyShortcutWithSameModifiers_ShouldSetTargetShortcutDown_OnKeyDown)
 252          {
 253              // Remap Ctrl+Shift+A to Ctrl+Shift+V
 254              Shortcut src;
 255              src.SetKey(VK_CONTROL);
 256              src.SetKey(VK_SHIFT);
 257              src.SetKey(0x41);
 258              Shortcut dest;
 259              dest.SetKey(VK_CONTROL);
 260              dest.SetKey(VK_SHIFT);
 261              dest.SetKey(0x56);
 262              testState.AddOSLevelShortcut(src, dest);
 263  
 264              std::vector<INPUT> inputs{
 265                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 266                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT } },
 267                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 268              };
 269  
 270              // Send Ctrl+Shift+A keydown
 271              mockedInputHandler.SendVirtualInput(inputs);
 272  
 273              // A key state should be unchanged, Ctrl, Shift, V key states should be true
 274              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 275              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
 276              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), true);
 277              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), true);
 278          }
 279  
 280          // Test if correct keyboard states are set for a 3 key shortcut remap with different modifiers key down followed by key up
 281          TEST_METHOD (RemappedThreeKeyShortcutWithDiffModifiers_ShouldClearKeyboard_OnKeyUp)
 282          {
 283              // Remap Ctrl+Shift+A to Alt+LWin+V
 284              Shortcut src;
 285              src.SetKey(VK_CONTROL);
 286              src.SetKey(VK_SHIFT);
 287              src.SetKey(0x41);
 288              Shortcut dest;
 289              dest.SetKey(VK_MENU);
 290              dest.SetKey(VK_LWIN);
 291              dest.SetKey(0x56);
 292              testState.AddOSLevelShortcut(src, dest);
 293  
 294              std::vector<INPUT> inputs{
 295                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 296                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT } },
 297                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 298                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
 299                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT, .dwFlags = KEYEVENTF_KEYUP } },
 300                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
 301              };
 302  
 303              // Send Ctrl+Shift+A keydown, followed by A, Shift and Ctrl released
 304              mockedInputHandler.SendVirtualInput(inputs);
 305  
 306              // Ctrl, Shift, A, Alt, LWin, V key states should be false
 307              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
 308              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
 309              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 310              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
 311              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_LWIN), false);
 312              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
 313          }
 314  
 315          // Test if correct keyboard states are set for a 3 key shortcut remap with partially different modifiers key down followed by key up
 316          TEST_METHOD (RemappedThreeKeyShortcutWithPartiallyDiffModifiers_ShouldClearKeyboard_OnKeyUp)
 317          {
 318              // Remap Ctrl+Shift+A to Alt+Ctrl+V
 319              Shortcut src;
 320              src.SetKey(VK_CONTROL);
 321              src.SetKey(VK_SHIFT);
 322              src.SetKey(0x41);
 323              Shortcut dest;
 324              dest.SetKey(VK_MENU);
 325              dest.SetKey(VK_CONTROL);
 326              dest.SetKey(0x56);
 327              testState.AddOSLevelShortcut(src, dest);
 328  
 329              std::vector<INPUT> inputs{
 330                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 331                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT } },
 332                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 333                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
 334                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT, .dwFlags = KEYEVENTF_KEYUP } },
 335                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
 336              };
 337  
 338              // Send Ctrl+Shift+A keydown, followed by A, Shift and Ctrl released
 339              mockedInputHandler.SendVirtualInput(inputs);
 340  
 341              // Ctrl, Shift, A, Alt, V key states should be false
 342              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
 343              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
 344              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 345              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
 346              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
 347          }
 348  
 349          // Test if correct keyboard states are set for a 3 key shortcut remap with same modifiers key down followed by key up
 350          TEST_METHOD (RemappedThreeKeyShortcutWithSameModifiers_ShouldClearKeyboard_OnKeyUp)
 351          {
 352              // Remap Ctrl+Shift+A to Ctrl+Shift+V
 353              Shortcut src;
 354              src.SetKey(VK_CONTROL);
 355              src.SetKey(VK_SHIFT);
 356              src.SetKey(0x41);
 357              Shortcut dest;
 358              dest.SetKey(VK_CONTROL);
 359              dest.SetKey(VK_SHIFT);
 360              dest.SetKey(0x56);
 361              testState.AddOSLevelShortcut(src, dest);
 362  
 363              std::vector<INPUT> inputs{
 364                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 365                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT } },
 366                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 367                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
 368                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT, .dwFlags = KEYEVENTF_KEYUP } },
 369                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
 370              };
 371  
 372              // Send Ctrl+Shift+A keydown, followed by A, Shift and Ctrl released
 373              mockedInputHandler.SendVirtualInput(inputs);
 374  
 375              // Ctrl, Shift, A, V key states should be false
 376              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
 377              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
 378              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 379              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
 380          }
 381  
 382          // Test if correct keyboard states are set when a 3 key shortcut is remapped, and a 2 key shortcut which is a subset of those keys is invoked - Ex: Ctrl+Shift+A remapped, but user presses Ctrl+A
 383          TEST_METHOD (RemappedThreeKeyShortcutInvokingAShortcutSubsetOfThoseKeys_ShouldNotBeRemapped_OnKeyDown)
 384          {
 385              // Remap Ctrl+Shift+A to Alt+V
 386              Shortcut src;
 387              src.SetKey(VK_CONTROL);
 388              src.SetKey(VK_SHIFT);
 389              src.SetKey(0x41);
 390              Shortcut dest;
 391              dest.SetKey(VK_MENU);
 392              dest.SetKey(0x56);
 393              testState.AddOSLevelShortcut(src, dest);
 394  
 395              std::vector<INPUT> inputs{
 396                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 397                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 398              };
 399  
 400              // Send Ctrl+A keydown
 401              mockedInputHandler.SendVirtualInput(inputs);
 402  
 403              // Since Ctrl+A is not remapped, no remapping should be invoked
 404              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
 405              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), true);
 406              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
 407              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
 408              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
 409          }
 410  
 411          // Test if correct keyboard states are set for a 3 key to 2 key shortcut remap with different modifiers key down
 412          TEST_METHOD (RemappedThreeKeyToTwoKeyShortcutWithDiffModifiers_ShouldSetTargetShortcutDown_OnKeyDown)
 413          {
 414              // Remap Ctrl+Shift+A to Alt+V
 415              Shortcut src;
 416              src.SetKey(VK_CONTROL);
 417              src.SetKey(VK_SHIFT);
 418              src.SetKey(0x41);
 419              Shortcut dest;
 420              dest.SetKey(VK_MENU);
 421              dest.SetKey(0x56);
 422              testState.AddOSLevelShortcut(src, dest);
 423  
 424              std::vector<INPUT> inputs{
 425                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 426                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT } },
 427                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 428              };
 429  
 430              // Send Ctrl+Shift+A keydown
 431              mockedInputHandler.SendVirtualInput(inputs);
 432  
 433              // Ctrl, Shift, A key states should be unchanged, Alt, V key states should be true
 434              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
 435              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
 436              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 437              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true);
 438              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), true);
 439          }
 440  
 441          // Test if correct keyboard states are set for a 3 key to 2 key shortcut remap with partially different modifiers key down
 442          TEST_METHOD (RemappedThreeKeyToTwoKeyShortcutWithPartiallyDiffModifiers_ShouldSetTargetShortcutDown_OnKeyDown)
 443          {
 444              // Remap Ctrl+Shift+A to Ctrl+V
 445              Shortcut src;
 446              src.SetKey(VK_CONTROL);
 447              src.SetKey(VK_SHIFT);
 448              src.SetKey(0x41);
 449              Shortcut dest;
 450              dest.SetKey(VK_CONTROL);
 451              dest.SetKey(0x56);
 452              testState.AddOSLevelShortcut(src, dest);
 453  
 454              std::vector<INPUT> inputs{
 455                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 456                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT } },
 457                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 458              };
 459  
 460              // Send Ctrl+Shift+A keydown
 461              mockedInputHandler.SendVirtualInput(inputs);
 462  
 463              // Shift, A key states should be unchanged, Ctrl, V key states should be true
 464              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
 465              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 466              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
 467              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), true);
 468          }
 469  
 470          // Test if correct keyboard states are set for a 3 key to 2 key shortcut remap with different modifiers key down followed by key up
 471          TEST_METHOD (RemappedThreeKeyToTwoKeyShortcutWithDiffModifiers_ShouldClearKeyboard_OnKeyUp)
 472          {
 473              // Remap Ctrl+Shift+A to Alt+V
 474              Shortcut src;
 475              src.SetKey(VK_CONTROL);
 476              src.SetKey(VK_SHIFT);
 477              src.SetKey(0x41);
 478              Shortcut dest;
 479              dest.SetKey(VK_MENU);
 480              dest.SetKey(0x56);
 481              testState.AddOSLevelShortcut(src, dest);
 482  
 483              std::vector<INPUT> inputs{
 484                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 485                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT } },
 486                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 487                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
 488                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT, .dwFlags = KEYEVENTF_KEYUP } },
 489                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
 490              };
 491  
 492              // Send Ctrl+Shift+A keydown, followed by A, Shift and Ctrl released
 493              mockedInputHandler.SendVirtualInput(inputs);
 494  
 495              // Ctrl, Shift, A, Alt, V key states should be false
 496              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
 497              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
 498              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 499              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
 500              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
 501          }
 502  
 503          // Test if correct keyboard states are set for a 3 key to 2 key shortcut remap with partially different modifiers key down followed by key up
 504          TEST_METHOD (RemappedThreeKeyToTwoKeyShortcutWithPartiallyDiffModifiers_ShouldClearKeyboard_OnKeyUp)
 505          {
 506              // Remap Ctrl+Shift+A to Ctrl+V
 507              Shortcut src;
 508              src.SetKey(VK_CONTROL);
 509              src.SetKey(VK_SHIFT);
 510              src.SetKey(0x41);
 511              Shortcut dest;
 512              dest.SetKey(VK_CONTROL);
 513              dest.SetKey(0x56);
 514              testState.AddOSLevelShortcut(src, dest);
 515  
 516              std::vector<INPUT> inputs{
 517                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 518                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT } },
 519                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 520                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
 521                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT, .dwFlags = KEYEVENTF_KEYUP } },
 522                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
 523              };
 524  
 525              // Send Ctrl+Shift+A keydown, followed by A, Shift and Ctrl released
 526              mockedInputHandler.SendVirtualInput(inputs);
 527  
 528              // Ctrl, Shift, A, V key states should be false
 529              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
 530              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
 531              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 532              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
 533          }
 534  
 535          // Test if correct keyboard states are set for a 2 key to 3 key shortcut remap with different modifiers key down
 536          TEST_METHOD (RemappedTwoKeyToThreeKeyShortcutWithDiffModifiers_ShouldSetTargetShortcutDown_OnKeyDown)
 537          {
 538              // Remap Ctrl+A to Alt+Shift+V
 539              Shortcut src;
 540              src.SetKey(VK_CONTROL);
 541              src.SetKey(0x41);
 542              Shortcut dest;
 543              dest.SetKey(VK_MENU);
 544              dest.SetKey(VK_SHIFT);
 545              dest.SetKey(0x56);
 546              testState.AddOSLevelShortcut(src, dest);
 547  
 548              std::vector<INPUT> inputs{
 549                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 550                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 551              };
 552  
 553              // Send Ctrl+A keydown
 554              mockedInputHandler.SendVirtualInput(inputs);
 555  
 556              // Ctrl, A key states should be unchanged, Alt, Shift, V key states should be true
 557              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
 558              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 559              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true);
 560              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), true);
 561              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), true);
 562          }
 563  
 564          // Test if correct keyboard states are set for a 2 key to 3 key shortcut remap with partially different modifiers key down
 565          TEST_METHOD (RemappedTwoKeyToThreeKeyShortcutWithPartiallyDiffModifiers_ShouldSetTargetShortcutDown_OnKeyDown)
 566          {
 567              // Remap Ctrl+A to Ctrl+Shift+V
 568              Shortcut src;
 569              src.SetKey(VK_CONTROL);
 570              src.SetKey(0x41);
 571              Shortcut dest;
 572              dest.SetKey(VK_CONTROL);
 573              dest.SetKey(VK_SHIFT);
 574              dest.SetKey(0x56);
 575              testState.AddOSLevelShortcut(src, dest);
 576  
 577              std::vector<INPUT> inputs{
 578                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 579                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 580              };
 581  
 582              // Send Ctrl+A keydown
 583              mockedInputHandler.SendVirtualInput(inputs);
 584  
 585              // A key state should be unchanged, Ctrl, Shift, V key states should be true
 586              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 587              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
 588              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), true);
 589              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), true);
 590          }
 591  
 592          // Test if correct keyboard states are set for a 2 key to 3 key shortcut remap with different modifiers key down followed by key up
 593          TEST_METHOD (RemappedTwoKeyToThreeKeyShortcutWithDiffModifiers_ShouldClearKeyboard_OnKeyUp)
 594          {
 595              // Remap Ctrl+A to Alt+Shift+V
 596              Shortcut src;
 597              src.SetKey(VK_CONTROL);
 598              src.SetKey(0x41);
 599              Shortcut dest;
 600              dest.SetKey(VK_MENU);
 601              dest.SetKey(VK_SHIFT);
 602              dest.SetKey(0x56);
 603              testState.AddOSLevelShortcut(src, dest);
 604  
 605              std::vector<INPUT> inputs{
 606                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 607                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 608                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
 609                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
 610              };
 611  
 612              // Send Ctrl+A keydown and A, Ctrl are then released
 613              mockedInputHandler.SendVirtualInput(inputs);
 614  
 615              // Ctrl, A, Alt, Shift, V key states should be unchanged
 616              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
 617              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 618              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
 619              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
 620              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
 621          }
 622  
 623          // Test if correct keyboard states are set for a 2 key to 3 key shortcut remap with partially different modifiers key down followed by key up
 624          TEST_METHOD (RemappedTwoKeyToThreeKeyShortcutWithPartiallyDiffModifiers_ShouldClearKeyboard_OnKeyUp)
 625          {
 626              // Remap Ctrl+A to Ctrl+Shift+V
 627              Shortcut src;
 628              src.SetKey(VK_CONTROL);
 629              src.SetKey(0x41);
 630              Shortcut dest;
 631              dest.SetKey(VK_CONTROL);
 632              dest.SetKey(VK_SHIFT);
 633              dest.SetKey(0x56);
 634              testState.AddOSLevelShortcut(src, dest);
 635  
 636              std::vector<INPUT> inputs{
 637                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 638                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 639                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
 640                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
 641              };
 642  
 643              // Send Ctrl+A keydown and A, Ctrl are then released
 644              mockedInputHandler.SendVirtualInput(inputs);
 645  
 646              // Ctrl, A, Shift, V key states should be unchanged
 647              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
 648              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 649              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
 650              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
 651          }
 652  
 653          // Test if correct keyboard states are set if a shortcut remap is pressed and then an unremapped shortcut with the same modifier is pressed - Ex: Ctrl+A is remapped. User invokes Ctrl+A then releases A and presses C (while Ctrl is held), should invoke Ctrl+C
 654          TEST_METHOD (InvokingUnremappedShortcutAfterRemappedShortcutWithSameModifier_ShouldSetUnremappedShortcut_OnKeyDown)
 655          {
 656              // Remap Ctrl+A to Alt+Shift+V
 657              Shortcut src;
 658              src.SetKey(VK_CONTROL);
 659              src.SetKey(0x41);
 660              Shortcut dest;
 661              dest.SetKey(VK_MENU);
 662              dest.SetKey(VK_SHIFT);
 663              dest.SetKey(0x56);
 664              testState.AddOSLevelShortcut(src, dest);
 665  
 666              std::vector<INPUT> inputs{
 667                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 668                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 669                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
 670                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'C' } },
 671              };
 672  
 673              // Send Ctrl+A keydown, A key up, then C key down
 674              mockedInputHandler.SendVirtualInput(inputs);
 675  
 676              // A, Alt, Shift, V key states should be unchanged, Ctrl, C should be true
 677              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
 678              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 679              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
 680              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
 681              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
 682              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x43), true);
 683          }
 684  
 685          // Test if correct keyboard states are set for a shortcut remap with win both modifier
 686          TEST_METHOD (RemappedShortcutWithWinBothModifier_ShouldSetRemappedShortcut_OnKeyEvent)
 687          {
 688              // Remap Win+A to Alt+V
 689              Shortcut src;
 690              src.SetKey(CommonSharedConstants::VK_WIN_BOTH);
 691              src.SetKey(0x41);
 692              Shortcut dest;
 693              dest.SetKey(VK_MENU);
 694              dest.SetKey(0x56);
 695              testState.AddOSLevelShortcut(src, dest);
 696  
 697              // Remap Alt+D to Win+B
 698              Shortcut dest1;
 699              dest1.SetKey(CommonSharedConstants::VK_WIN_BOTH);
 700              dest1.SetKey(0x42);
 701              Shortcut src1;
 702              src1.SetKey(VK_MENU);
 703              src1.SetKey(0x44);
 704              testState.AddOSLevelShortcut(src1, dest1);
 705  
 706              // Test 2 cases for first remap - LWin, A, A(Up), LWin(Up). RWin, A, A(Up), RWin(Up)
 707              std::vector<INPUT> inputs1{
 708                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_LWIN } },
 709                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 710              };
 711  
 712              // Send LWin+A keydown
 713              mockedInputHandler.SendVirtualInput(inputs1);
 714  
 715              // LWin, RWin, A key states should be unchanged, Alt, V should be true
 716              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_LWIN), false);
 717              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_RWIN), false);
 718              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 719              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true);
 720              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), true);
 721  
 722              std::vector<INPUT> inputs2{
 723                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
 724                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_LWIN, .dwFlags = KEYEVENTF_KEYUP } },
 725              };
 726  
 727              // Release LWin+A
 728              mockedInputHandler.SendVirtualInput(inputs2);
 729  
 730              // LWin, RWin, A, Alt, V key states should be unchanged
 731              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_LWIN), false);
 732              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_RWIN), false);
 733              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 734              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
 735              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
 736  
 737              // Case 1.2
 738              std::vector<INPUT> inputs3{
 739                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_RWIN } },
 740                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 741              };
 742  
 743              // Send RWin+A keydown
 744              mockedInputHandler.SendVirtualInput(inputs3);
 745  
 746              // LWin, RWin, A key states should be unchanged, Alt, V should be true
 747              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_LWIN), false);
 748              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_RWIN), false);
 749              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 750              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true);
 751              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), true);
 752  
 753              std::vector<INPUT> inputs4{
 754                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
 755                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_RWIN, .dwFlags = KEYEVENTF_KEYUP } },
 756              };
 757  
 758              // Release RWin+A
 759              mockedInputHandler.SendVirtualInput(inputs4);
 760  
 761              // LWin, RWin, A, Alt, V key states should be unchanged
 762              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_LWIN), false);
 763              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_RWIN), false);
 764              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 765              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
 766              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
 767  
 768              // Case 2
 769              std::vector<INPUT> inputs5{
 770                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_MENU } },
 771                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'D' } },
 772              };
 773  
 774              // Send Alt+D keydown
 775              mockedInputHandler.SendVirtualInput(inputs5);
 776  
 777              // Alt, D, RWin key states should be unchanged, LWin, B should be true
 778              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_LWIN), true);
 779              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_RWIN), false);
 780              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true);
 781              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
 782              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x44), false);
 783  
 784              std::vector<INPUT> inputs6{
 785                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'D', .dwFlags = KEYEVENTF_KEYUP } },
 786                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_MENU, .dwFlags = KEYEVENTF_KEYUP } },
 787              };
 788  
 789              // Release Alt+D
 790              mockedInputHandler.SendVirtualInput(inputs6);
 791  
 792              // LWin, RWin, B, Alt, D key states should be unchanged
 793              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_LWIN), false);
 794              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_RWIN), false);
 795              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), false);
 796              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
 797              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x44), false);
 798          }
 799  
 800          // Test if correct keyboard states are set if a win both shortcut remap is pressed and then an unremapped shortcut with the LWin modifier is pressed
 801          TEST_METHOD (InvokingUnremappedShortcutWithLWinAfterRemappedShortcutWithWinBothModifier_ShouldSetUnremappedShortcutWithLWinKey_OnKeyDown)
 802          {
 803              // Remap Win+A to Alt+V
 804              Shortcut src;
 805              src.SetKey(CommonSharedConstants::VK_WIN_BOTH);
 806              src.SetKey(0x41);
 807              Shortcut dest;
 808              dest.SetKey(VK_MENU);
 809              dest.SetKey(0x56);
 810              testState.AddOSLevelShortcut(src, dest);
 811  
 812              // LWin, A, A(Up), C(Down)
 813              std::vector<INPUT> inputs{
 814                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_LWIN } },
 815                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 816                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
 817                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'C' } },
 818              };
 819  
 820              // Send LWin+A, release A and press C
 821              mockedInputHandler.SendVirtualInput(inputs);
 822  
 823              // RWin, A, Alt, V key states should be unchanged, LWin, C should be true
 824              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_LWIN), true);
 825              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x43), true);
 826              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_RWIN), false);
 827              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 828              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
 829              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
 830          }
 831  
 832          // Test if correct keyboard states are set if a win both shortcut remap is pressed and then an unremapped shortcut with the RWin modifier is pressed
 833          TEST_METHOD (InvokingUnremappedShortcutWithRWinAfterRemappedShortcutWithWinBothModifier_ShouldSetUnremappedShortcutWithRWinKey_OnKeyDown)
 834          {
 835              // Remap Win+A to Alt+V
 836              Shortcut src;
 837              src.SetKey(CommonSharedConstants::VK_WIN_BOTH);
 838              src.SetKey(0x41);
 839              Shortcut dest;
 840              dest.SetKey(VK_MENU);
 841              dest.SetKey(0x56);
 842              testState.AddOSLevelShortcut(src, dest);
 843  
 844              // RWin, A, A(Up), C(Down)
 845              std::vector<INPUT> inputs{
 846                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_RWIN } },
 847                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 848                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
 849                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'C' } },
 850              };
 851  
 852              // Send RWin+A, release A and press C
 853              mockedInputHandler.SendVirtualInput(inputs);
 854  
 855              // LWin, A, Alt, V key states should be unchanged, RWin, C should be true
 856              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_LWIN), false);
 857              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_RWIN), true);
 858              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x43), true);
 859              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 860              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
 861              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
 862          }
 863  
 864          // Test if target modifier is still held down even if the action key of the original shortcut is released - required for Alt+Tab/Win+Space cases
 865          TEST_METHOD (RemappedShortcutModifiers_ShouldBeDetectedAsPressed_OnReleasingActionKeyButHoldingModifiers)
 866          {
 867              // Remap Ctrl+A to Alt+Tab
 868              Shortcut src;
 869              src.SetKey(VK_CONTROL);
 870              src.SetKey(0x41);
 871              Shortcut dest;
 872              dest.SetKey(VK_MENU);
 873              dest.SetKey(VK_TAB);
 874              testState.AddOSLevelShortcut(src, dest);
 875  
 876              std::vector<INPUT> inputs{
 877                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 878                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 879                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
 880              };
 881  
 882              // Send Ctrl+A, release A
 883              mockedInputHandler.SendVirtualInput(inputs);
 884  
 885              // Ctrl, A, Tab key states should be unchanged, Alt should be true
 886              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
 887              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 888              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true);
 889              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_TAB), false);
 890          }
 891  
 892          // Test if invoking two remapped shortcuts (with different modifiers between original and new shortcut) that share modifiers in succession sets the correct keyboard states
 893          TEST_METHOD (TwoRemappedShortcutsWithDifferentModifiersThatShareModifiers_ShouldSetRemappedKeyStates_OnPressingSecondShortcutActionKeyAfterInvokingFirstShortcutRemap)
 894          {
 895              // Remap Alt+A to Ctrl+C
 896              Shortcut src;
 897              src.SetKey(VK_MENU);
 898              src.SetKey(0x41);
 899              Shortcut dest;
 900              dest.SetKey(VK_CONTROL);
 901              dest.SetKey(0x43);
 902              testState.AddOSLevelShortcut(src, dest);
 903  
 904              // Remap Alt+V to Ctrl+X
 905              Shortcut src1;
 906              src1.SetKey(VK_MENU);
 907              src1.SetKey(0x56);
 908              Shortcut dest1;
 909              dest1.SetKey(VK_CONTROL);
 910              dest1.SetKey(0x58);
 911              testState.AddOSLevelShortcut(src1, dest1);
 912  
 913              std::vector<INPUT> inputs{
 914                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_MENU } },
 915                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 916                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
 917                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'V' } },
 918              };
 919  
 920              // Send Alt+A, release A, press V
 921              mockedInputHandler.SendVirtualInput(inputs);
 922  
 923              // Alt, A, C, V key states should be unchanged, Ctrl, X should be true
 924              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
 925              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 926              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x43), false);
 927              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
 928              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
 929              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x58), true);
 930          }
 931  
 932          // Test if invoking two remapped shortcuts (with same modifiers between original and new shortcut) that share modifiers in succession sets the correct keyboard states
 933          TEST_METHOD (TwoRemappedShortcutsWithSameModifiersThatShareModifiers_ShouldSetRemappedKeyStates_OnPressingSecondShortcutActionKeyAfterInvokingFirstShortcutRemap)
 934          {
 935              // Remap Ctrl+A to Ctrl+C
 936              Shortcut src;
 937              src.SetKey(VK_CONTROL);
 938              src.SetKey(0x41);
 939              Shortcut dest;
 940              dest.SetKey(VK_CONTROL);
 941              dest.SetKey(0x43);
 942              testState.AddOSLevelShortcut(src, dest);
 943  
 944              // Remap Ctrl+V to Ctrl+X
 945              Shortcut src1;
 946              src1.SetKey(VK_CONTROL);
 947              src1.SetKey(0x56);
 948              Shortcut dest1;
 949              dest1.SetKey(VK_CONTROL);
 950              dest1.SetKey(0x58);
 951              testState.AddOSLevelShortcut(src1, dest1);
 952  
 953              std::vector<INPUT> inputs{
 954                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 955                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 956                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
 957                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'V' } },
 958              };
 959  
 960              // Send Ctrl+A, release A, press V
 961              mockedInputHandler.SendVirtualInput(inputs);
 962  
 963              // A, C, V key states should be unchanged, Ctrl, X should be true
 964              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 965              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x43), false);
 966              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
 967              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
 968              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x58), true);
 969          }
 970  
 971          // Tests for shortcut to key remappings
 972  
 973          // Test if correct keyboard states are set for a 2 key shortcut to a single key remap not containing that key on key down followed by key up
 974          TEST_METHOD (RemappedTwoKeyShortcutToSingleKeyNotContainingThatKey_ShouldSetCorrectKeyStates_OnKeyEvents)
 975          {
 976              // Remap Ctrl+A to Alt
 977              Shortcut src;
 978              src.SetKey(VK_CONTROL);
 979              src.SetKey(0x41);
 980              testState.AddOSLevelShortcut(src, (DWORD)VK_MENU);
 981  
 982              std::vector<INPUT> inputs1{
 983                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
 984                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
 985              };
 986  
 987              // Send Ctrl+A keydown
 988              mockedInputHandler.SendVirtualInput(inputs1);
 989  
 990              // Ctrl, A should be false, Alt should be true
 991              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
 992              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
 993              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true);
 994  
 995              std::vector<INPUT> inputs2{
 996                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
 997                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
 998              };
 999  
1000              // Release Ctrl+A
1001              mockedInputHandler.SendVirtualInput(inputs2);
1002  
1003              // Ctrl, A, Alt should be false
1004              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1005              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1006              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
1007          }
1008  
1009          // Test if correct keyboard states are set for a 3 key shortcut to a single key remap not containing that key on key down followed by key up
1010          TEST_METHOD (RemappedThreeKeyShortcutToSingleKeyNotContainingThatKey_ShouldSetCorrectKeyStates_OnKeyEvents)
1011          {
1012              // Remap Ctrl+Shift+A to Alt
1013              Shortcut src;
1014              src.SetKey(VK_CONTROL);
1015              src.SetKey(VK_SHIFT);
1016              src.SetKey(0x41);
1017              testState.AddOSLevelShortcut(src, (DWORD)VK_MENU);
1018  
1019              std::vector<INPUT> inputs1{
1020                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1021                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT } },
1022                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1023              };
1024  
1025              // Send Ctrl+Shift+A keydown
1026              mockedInputHandler.SendVirtualInput(inputs1);
1027  
1028              // Ctrl, Shift, A should be false, Alt should be true
1029              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1030              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
1031              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1032              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true);
1033  
1034              std::vector<INPUT> inputs2{
1035                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
1036                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT, .dwFlags = KEYEVENTF_KEYUP } },
1037                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
1038              };
1039  
1040              // Release Ctrl+Shift+A
1041              mockedInputHandler.SendVirtualInput(inputs2);
1042  
1043              // Ctrl, Shift, A, Alt should be false
1044              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1045              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
1046              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1047              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
1048          }
1049  
1050          // Test if correct keyboard states are set for a 2 key shortcut to a single key remap containing that key on key down followed by key up
1051          TEST_METHOD (RemappedTwoKeyShortcutToSingleKeyContainingThatKey_ShouldSetCorrectKeyStates_OnKeyEvents)
1052          {
1053              // Remap Ctrl+A to Ctrl
1054              Shortcut src;
1055              src.SetKey(VK_CONTROL);
1056              src.SetKey(0x41);
1057              testState.AddOSLevelShortcut(src, (DWORD)VK_CONTROL);
1058  
1059              std::vector<INPUT> inputs1{
1060                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1061                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1062              };
1063  
1064              // Send Ctrl+A keydown
1065              mockedInputHandler.SendVirtualInput(inputs1);
1066  
1067              // A should be false, Ctrl should be true
1068              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
1069              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1070  
1071              std::vector<INPUT> inputs2{
1072                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
1073                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
1074              };
1075  
1076              // Release Ctrl+A
1077              mockedInputHandler.SendVirtualInput(inputs2);
1078  
1079              // Ctrl, A should be false
1080              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1081              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1082          }
1083  
1084          // Test if correct keyboard states are set for a 3 key shortcut to a single key remap containing that key on key down followed by key up
1085          TEST_METHOD (RemappedThreeKeyShortcutToSingleKeyContainingThatKey_ShouldSetCorrectKeyStates_OnKeyEvents)
1086          {
1087              // Remap Ctrl+Shift+A to Ctrl
1088              Shortcut src;
1089              src.SetKey(VK_CONTROL);
1090              src.SetKey(VK_SHIFT);
1091              src.SetKey(0x41);
1092              testState.AddOSLevelShortcut(src, (DWORD)VK_CONTROL);
1093  
1094              std::vector<INPUT> inputs1{
1095                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1096                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT } },
1097                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1098              };
1099  
1100              // Send Ctrl+Shift+A keydown
1101              mockedInputHandler.SendVirtualInput(inputs1);
1102  
1103              // Shift, A should be false, Ctrl should be true
1104              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
1105              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
1106              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1107  
1108              std::vector<INPUT> inputs2{
1109                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
1110                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT, .dwFlags = KEYEVENTF_KEYUP } },
1111                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
1112              };
1113  
1114              // Release Ctrl+Shift+A
1115              mockedInputHandler.SendVirtualInput(inputs2);
1116  
1117              // Ctrl, Shift, A should be false
1118              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1119              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
1120              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1121          }
1122  
1123          // Test if keyboard state is not reverted for a shortcut to a single key remap (target key is not a part of the shortcut) on key down followed by releasing the action key
1124          TEST_METHOD (RemappedShortcutToSingleKeyWhereKeyIsNotInShortcut_ShouldNotSetOriginalModifier_OnReleasingActionKey)
1125          {
1126              // Remap Ctrl+A to Alt
1127              Shortcut src;
1128              src.SetKey(VK_CONTROL);
1129              src.SetKey(0x41);
1130              testState.AddOSLevelShortcut(src, (DWORD)VK_MENU);
1131  
1132              std::vector<INPUT> inputs{
1133                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1134                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1135                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
1136              };
1137  
1138              // Press Ctrl+A, release A
1139              mockedInputHandler.SendVirtualInput(inputs);
1140  
1141              // Ctrl, A, Alt should be false
1142              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1143              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1144              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
1145              // Shortcut invoked state should be true
1146              Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isShortcutInvoked);
1147          }
1148  
1149          // Test if keyboard state is not reverted for a shortcut to a single key remap (target key is a modifier in the shortcut) on key down followed by releasing the action key
1150          TEST_METHOD (RemappedShortcutToSingleKeyWhereKeyIsAModifierInShortcut_ShouldNotSetOriginalModifier_OnReleasingActionKey)
1151          {
1152              // Remap Ctrl+A to Ctrl
1153              Shortcut src;
1154              src.SetKey(VK_CONTROL);
1155              src.SetKey(0x41);
1156              testState.AddOSLevelShortcut(src, (DWORD)VK_CONTROL);
1157  
1158              std::vector<INPUT> inputs{
1159                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1160                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1161                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
1162              };
1163  
1164              // Press Ctrl+A, release A
1165              mockedInputHandler.SendVirtualInput(inputs);
1166  
1167              // Both A and Ctrl should be false
1168              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1169              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1170              // Shortcut invoked state should be true
1171              Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isShortcutInvoked);
1172          }
1173  
1174          // Test if keyboard state is not reverted for a shortcut to a single key remap (target key is the action key in the shortcut) on key down followed by releasing the action key
1175          TEST_METHOD (RemappedShortcutToSingleKeyWhereKeyIsActionKeyInShortcut_ShouldNotSetOriginalModifier_OnReleasingActionKey)
1176          {
1177              // Remap Ctrl+A to A
1178              Shortcut src;
1179              src.SetKey(VK_CONTROL);
1180              src.SetKey(0x41);
1181              testState.AddOSLevelShortcut(src, (DWORD)0x41);
1182  
1183              std::vector<INPUT> inputs{
1184                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1185                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1186                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
1187              };
1188  
1189              // Press Ctrl+A, release A
1190              mockedInputHandler.SendVirtualInput(inputs);
1191  
1192              // Ctrl, A should be false
1193              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1194              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1195              // Shortcut invoked state should be true
1196              Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isShortcutInvoked);
1197          }
1198  
1199          // Test if keyboard state is reverted for a shortcut to a single key remap (target key is not a part of the shortcut) on key down followed by releasing the modifier key
1200          TEST_METHOD (RemappedShortcutToSingleKeyWhereKeyIsNotInShortcut_ShouldSetOriginalModifier_OnReleasingModifierKey)
1201          {
1202              // Remap Ctrl+A to Alt
1203              Shortcut src;
1204              src.SetKey(VK_CONTROL);
1205              src.SetKey(0x41);
1206              testState.AddOSLevelShortcut(src, (DWORD)VK_MENU);
1207  
1208              std::vector<INPUT> inputs{
1209                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1210                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1211                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
1212              };
1213  
1214              // Press Ctrl+A, release Ctrl
1215              mockedInputHandler.SendVirtualInput(inputs);
1216  
1217              // A, Alt, Ctrl should be false
1218              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1219              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1220              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
1221              // Shortcut invoked state should be false
1222              Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isShortcutInvoked);
1223          }
1224  
1225          // Test if keyboard state is reverted for a shortcut to a single key remap (target key is a modifier in the shortcut) on key down followed by releasing the modifier key
1226          TEST_METHOD (RemappedShortcutToSingleKeyWhereKeyIsAModifierInShortcut_ShouldSetOriginalModifier_OnReleasingModifierKey)
1227          {
1228              // Remap Ctrl+A to Ctrl
1229              Shortcut src;
1230              src.SetKey(VK_CONTROL);
1231              src.SetKey(0x41);
1232              testState.AddOSLevelShortcut(src, (DWORD)VK_CONTROL);
1233  
1234              std::vector<INPUT> inputs{
1235                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1236                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1237                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
1238              };
1239  
1240              // Press Ctrl+A, release Ctrl
1241              mockedInputHandler.SendVirtualInput(inputs);
1242  
1243              // A, Ctrl should be false
1244              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1245              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1246              // Shortcut invoked state should be false
1247              Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isShortcutInvoked);
1248          }
1249  
1250          // Test if keyboard state is reverted for a shortcut to a single key remap (target key is the action key in the shortcut) on key down followed by releasing the modifier key
1251          TEST_METHOD (RemappedShortcutToSingleKeyWhereKeyIsActionKeyInShortcut_ShouldSetOriginalModifier_ModifierKey)
1252          {
1253              // Remap Ctrl+A to A
1254              Shortcut src;
1255              src.SetKey(VK_CONTROL);
1256              src.SetKey(0x41);
1257              testState.AddOSLevelShortcut(src, (DWORD)0x41);
1258  
1259              std::vector<INPUT> inputs{
1260                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1261                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1262                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
1263              };
1264  
1265              // Press Ctrl+A, release Ctrl
1266              mockedInputHandler.SendVirtualInput(inputs);
1267  
1268              // A, Ctrl should be false
1269              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1270              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1271          }
1272  
1273          // Test if remap is invoked for a shortcut to a single key remap when the shortcut is invoked along with other keys pressed before it
1274          TEST_METHOD (RemappedShortcutToSingleKey_ShouldBeInvoked_IfOtherKeysArePressedAlongWithIt)
1275          {
1276              // Remap Ctrl+A to Alt
1277              Shortcut src;
1278              src.SetKey(VK_CONTROL);
1279              src.SetKey(0x41);
1280              testState.AddOSLevelShortcut(src, (DWORD)VK_MENU);
1281  
1282              std::vector<INPUT> inputs{
1283                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'B' } },
1284                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1285                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1286              };
1287  
1288              // Press B+Ctrl+A
1289              mockedInputHandler.SendVirtualInput(inputs);
1290  
1291              // A, Ctrl should be false, B, Alt should be true
1292              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1293              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1294              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true);
1295              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true);
1296          }
1297  
1298          // Test if remap is invoked for a shortcut to a single key remap and the keyboard state is reverted back to the physical keys when the shortcut is invoked along with other keys pressed before it and the action key is released
1299          TEST_METHOD (RemappedShortcutToSingleKey_ShouldRevertBackToPhysicalKeys_IfOtherKeysArePressedAlongWithItAndThenActionKeyIsReleased)
1300          {
1301              // Remap Ctrl+A to Alt
1302              Shortcut src;
1303              src.SetKey(VK_CONTROL);
1304              src.SetKey(0x41);
1305              testState.AddOSLevelShortcut(src, (DWORD)VK_MENU);
1306  
1307              std::vector<INPUT> inputs{
1308                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'B' } },
1309                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1310                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1311                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
1312              };
1313  
1314              // Press B+Ctrl+A, release A
1315              mockedInputHandler.SendVirtualInput(inputs);
1316  
1317              // Alt, A should be false, Ctrl, B should be true
1318              Assert::AreEqual(true, mockedInputHandler.GetVirtualKeyState(VK_CONTROL));
1319              Assert::AreEqual(false, mockedInputHandler.GetVirtualKeyState(0x41));
1320              Assert::AreEqual(false, mockedInputHandler.GetVirtualKeyState(VK_MENU));
1321              Assert::AreEqual(true, mockedInputHandler.GetVirtualKeyState(0x42));
1322              // Shortcut invoked state should be false
1323              Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isShortcutInvoked);
1324          }
1325  
1326          // Test that remap is not invoked for a shortcut to a single key remap when a larger remapped shortcut to shortcut containing those shortcut keys is invoked
1327          TEST_METHOD (RemappedShortcutToSingleKey_ShouldNotBeInvoked_IfALargerRemappedShortcutToShortcutContainingThoseShortcutKeysIsInvoked)
1328          {
1329              // Remap Ctrl+A to Alt
1330              Shortcut src;
1331              src.SetKey(VK_CONTROL);
1332              src.SetKey(0x41);
1333              testState.AddOSLevelShortcut(src, (DWORD)VK_MENU);
1334              // Remap Shift+Ctrl+A to Ctrl+V
1335              src.SetKey(VK_SHIFT);
1336              Shortcut dest;
1337              dest.SetKey(VK_CONTROL);
1338              dest.SetKey(0x56);
1339              testState.AddOSLevelShortcut(src, dest);
1340  
1341              std::vector<INPUT> inputs{
1342                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT } },
1343                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1344                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1345              };
1346  
1347              // Press Shift+Ctrl+A
1348              mockedInputHandler.SendVirtualInput(inputs);
1349  
1350              // Alt, A, Shift should be false, Ctrl, V should be true
1351              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
1352              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
1353              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1354              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
1355              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), true);
1356          }
1357  
1358          // Test that remap is not invoked for a shortcut to a single key remap when a larger remapped shortcut to key containing those shortcut keys is invoked
1359          TEST_METHOD (RemappedShortcutToSingleKey_ShouldNotBeInvoked_IfALargerRemappedShortcutToKeyContainingThoseShortcutKeysIsInvoked)
1360          {
1361              // Remap Ctrl+A to Alt
1362              Shortcut src;
1363              src.SetKey(VK_CONTROL);
1364              src.SetKey(0x41);
1365              testState.AddOSLevelShortcut(src, (DWORD)VK_MENU);
1366              // Remap Shift+Ctrl+A to B
1367              src.SetKey(VK_SHIFT);
1368              testState.AddOSLevelShortcut(src, (DWORD)0x42);
1369  
1370              std::vector<INPUT> inputs{
1371                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT } },
1372                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1373                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1374              };
1375  
1376              // Press Shift+Ctrl+A
1377              mockedInputHandler.SendVirtualInput(inputs);
1378  
1379              // Alt, Ctrl, A, Shift should be false, B should be true
1380              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1381              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), false);
1382              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1383              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
1384              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true);
1385          }
1386  
1387          // Test if remap is invoked and then reverted to physical keys for a shortcut to a single key remap when the shortcut is invoked along with other keys pressed after it and then action key is released
1388          TEST_METHOD (RemappedShortcutToSingleKey_ShouldBeInvokedAndThenRevertToPhysicalKeys_IfOtherKeysArePressedAfterItAndActionKeyIsReleased)
1389          {
1390              // Remap Ctrl+A to Alt
1391              Shortcut src;
1392              src.SetKey(VK_CONTROL);
1393              src.SetKey(0x41);
1394              testState.AddOSLevelShortcut(src, (DWORD)VK_MENU);
1395  
1396              std::vector<INPUT> inputs1{
1397                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1398                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1399                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'B' } },
1400              };
1401  
1402              // Press Ctrl+A+B
1403              mockedInputHandler.SendVirtualInput(inputs1);
1404  
1405              // A, Ctrl should be false, B, Alt should be true
1406              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1407              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1408              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true);
1409              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true);
1410              // Shortcut invoked state should be true
1411              Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isShortcutInvoked);
1412  
1413              std::vector<INPUT> inputs2{
1414                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
1415              };
1416  
1417              // Release A
1418              mockedInputHandler.SendVirtualInput(inputs2);
1419  
1420              // A, Alt should be false, Ctrl, B should be true
1421              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
1422              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1423              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
1424              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true);
1425              // Shortcut invoked state should be false
1426              Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isShortcutInvoked);
1427          }
1428  
1429          // Test if remap is invoked and then reverted to physical keys for a shortcut to a single key remap when the shortcut is invoked along with other keys pressed after it and modifier key is released
1430          TEST_METHOD (RemappedShortcutToSingleKey_ShouldBeInvokedAndThenRevertToPhysicalKeys_IfOtherKeysArePressedAfterItAndModifierKeyIsReleased)
1431          {
1432              // Remap Ctrl+A to Alt
1433              Shortcut src;
1434              src.SetKey(VK_CONTROL);
1435              src.SetKey(0x41);
1436              testState.AddOSLevelShortcut(src, (DWORD)VK_MENU);
1437              std::vector<INPUT> inputs1{
1438                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1439                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1440                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'B' } },
1441              };
1442  
1443              // Press Ctrl+A+B
1444              mockedInputHandler.SendVirtualInput(inputs1);
1445  
1446              // A, Ctrl should be false, B, Alt should be true
1447              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1448              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1449              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), true);
1450              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true);
1451              // Shortcut invoked state should be true
1452              Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isShortcutInvoked);
1453  
1454              std::vector<INPUT> inputs2{
1455                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
1456              };
1457  
1458              // Release Ctrl
1459              mockedInputHandler.SendVirtualInput(inputs2);
1460  
1461              // Ctrl, Alt, A should be false, B should be true
1462              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1463              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1464              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
1465              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true);
1466              // Shortcut invoked state should be false
1467              Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isShortcutInvoked);
1468          }
1469  
1470          // Test if remap is invoked and then reverted to physical keys for a shortcut to a single key remap when the shortcut is invoked and action key is released and then other keys pressed after it
1471          TEST_METHOD (RemappedShortcutToSingleKey_ShouldBeInvokedAndThenRevertToPhysicalKeys_IfActionKeyIsReleasedAndThenOtherKeysArePressedAfterIt)
1472          {
1473              // Remap Ctrl+A to Alt
1474              Shortcut src;
1475              src.SetKey(VK_CONTROL);
1476              src.SetKey(0x41);
1477              testState.AddOSLevelShortcut(src, (DWORD)VK_MENU);
1478  
1479              std::vector<INPUT> inputs1{
1480                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1481                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1482                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
1483              };
1484  
1485              // Press Ctrl+A, release A
1486              mockedInputHandler.SendVirtualInput(inputs1);
1487  
1488              // A, Ctrl, Alt should be false
1489              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1490              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1491              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
1492              // Shortcut invoked state should be true
1493              Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isShortcutInvoked);
1494  
1495              std::vector<INPUT> inputs2{
1496                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'B' } },
1497              };
1498  
1499              // Press B
1500              mockedInputHandler.SendVirtualInput(inputs2);
1501  
1502              // A, Alt should be false, Ctrl, B should be true
1503              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
1504              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1505              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
1506              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true);
1507              // Shortcut invoked state should be false
1508              Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isShortcutInvoked);
1509          }
1510  
1511          // Test if Windows left key state is set when a shortcut remap to Win both is invoked
1512          TEST_METHOD (RemappedShortcutToWinBoth_ShouldSetLWinKeyState_OnKeyEvent)
1513          {
1514              // Remap Ctrl+A to Win both
1515              Shortcut src;
1516              src.SetKey(VK_CONTROL);
1517              src.SetKey(0x41);
1518              testState.AddOSLevelShortcut(src, (DWORD)CommonSharedConstants::VK_WIN_BOTH);
1519  
1520              std::vector<INPUT> inputs1{
1521                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1522                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1523              };
1524  
1525              // Press Ctrl+A
1526              mockedInputHandler.SendVirtualInput(inputs1);
1527  
1528              // A, Ctrl should be false, LWin should be true
1529              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1530              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1531              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_LWIN), true);
1532  
1533              std::vector<INPUT> inputs2{
1534                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
1535                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
1536              };
1537  
1538              // Release A, Ctrl
1539              mockedInputHandler.SendVirtualInput(inputs2);
1540  
1541              // Ctrl, A, LWin should be false
1542              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1543              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1544              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
1545          }
1546  
1547          // Tests for interaction between shortcut to shortcut and shortcut to key remappings
1548  
1549          // Test if invoking two remapped shortcuts that share modifiers, where the first one remaps to a key and the second one remaps to a shortcut, in succession sets the correct keyboard states
1550          TEST_METHOD (TwoRemappedShortcutsThatShareModifiersWhereFirstOneRemapsToAKeyAndSecondOneRemapsToAShortcut_ShouldSetRemappedKeyStates_OnPressingSecondShortcutActionKeyAfterInvokingFirstShortcutRemap)
1551          {
1552              // Remap Alt+A to D
1553              Shortcut src;
1554              src.SetKey(VK_MENU);
1555              src.SetKey(0x41);
1556              testState.AddOSLevelShortcut(src, (DWORD)0x44);
1557  
1558              // Remap Alt+V to Ctrl+X
1559              Shortcut src1;
1560              src1.SetKey(VK_MENU);
1561              src1.SetKey(0x56);
1562              Shortcut dest1;
1563              dest1.SetKey(VK_CONTROL);
1564              dest1.SetKey(0x58);
1565              testState.AddOSLevelShortcut(src1, dest1);
1566  
1567              std::vector<INPUT> inputs{
1568                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_MENU } },
1569                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1570                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
1571                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'V' } },
1572              };
1573  
1574              // Send Alt+A, release A, press V
1575              mockedInputHandler.SendVirtualInput(inputs);
1576  
1577              // Alt, A, D, V key states should be unchanged, Ctrl, X should be true
1578              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
1579              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1580              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x44), false);
1581              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
1582              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
1583              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x58), true);
1584          }
1585  
1586          // Test if invoking two remapped shortcuts that share modifiers, where the first one remaps to a key and the second one remaps to a key, in succession sets the correct keyboard states
1587          TEST_METHOD (TwoRemappedShortcutsThatShareModifiersWhereFirstOneRemapsToAKeyAndSecondOneRemapsToAKey_ShouldSetRemappedKeyStates_OnPressingSecondShortcutActionKeyAfterInvokingFirstShortcutRemap)
1588          {
1589              // Remap Alt+A to D
1590              Shortcut src;
1591              src.SetKey(VK_MENU);
1592              src.SetKey(0x41);
1593              testState.AddOSLevelShortcut(src, (DWORD)0x44);
1594  
1595              // Remap Alt+V to X
1596              Shortcut src1;
1597              src1.SetKey(VK_MENU);
1598              src1.SetKey(0x56);
1599              testState.AddOSLevelShortcut(src1, (DWORD)0x58);
1600  
1601              std::vector<INPUT> inputs{
1602                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_MENU } },
1603                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1604                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
1605                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'V' } },
1606              };
1607  
1608              // Send Alt+A, release A, press V
1609              mockedInputHandler.SendVirtualInput(inputs);
1610  
1611              // Alt, A, D, V key states should be unchanged, X should be true
1612              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
1613              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1614              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x44), false);
1615              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
1616              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x58), true);
1617          }
1618  
1619          // Test if invoking two remapped shortcuts that share modifiers, where the first one remaps to a shortcut and the second one remaps to a key, in succession sets the correct keyboard states
1620          TEST_METHOD (TwoRemappedShortcutsThatShareModifiersWhereFirstOneRemapsToAShortcutAndSecondOneRemapsToAKey_ShouldSetRemappedKeyStates_OnPressingSecondShortcutActionKeyAfterInvokingFirstShortcutRemap)
1621          {
1622              // Remap Alt+A to Ctrl+C
1623              Shortcut src;
1624              src.SetKey(VK_MENU);
1625              src.SetKey(0x41);
1626              Shortcut dest;
1627              dest.SetKey(VK_CONTROL);
1628              dest.SetKey(0x43);
1629              testState.AddOSLevelShortcut(src, dest);
1630  
1631              // Remap Alt+V to X
1632              Shortcut src1;
1633              src1.SetKey(VK_MENU);
1634              src1.SetKey(0x56);
1635              testState.AddOSLevelShortcut(src1, (DWORD)0x58);
1636  
1637              std::vector<INPUT> inputs{
1638                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_MENU } },
1639                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1640                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
1641                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'V' } },
1642              };
1643  
1644              // Send Alt+A, release A, press V
1645              mockedInputHandler.SendVirtualInput(inputs);
1646  
1647              // Alt, A, C, V, Ctrl key states should be unchanged, X should be true
1648              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_MENU), false);
1649              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1650              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x44), false);
1651              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
1652              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1653              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x58), true);
1654          }
1655  
1656          // Test if correct keyboard states are set if a shortcut to single key remap is pressed and then an unremapped shortcut with the same modifier is pressed - Ex: Ctrl+A is remapped. User invokes Ctrl+A then releases A and presses C (while Ctrl is held), should invoke Ctrl+C
1657          TEST_METHOD (InvokingUnremappedShortcutAfterRemappedShortcutToSingleKeyWithSameModifier_ShouldSetUnremappedShortcut_OnKeyDown)
1658          {
1659              // Remap Ctrl+A to V
1660              Shortcut src;
1661              src.SetKey(VK_CONTROL);
1662              src.SetKey(0x41);
1663              testState.AddOSLevelShortcut(src, (DWORD)0x56);
1664  
1665              std::vector<INPUT> inputs{
1666                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1667                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1668                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
1669                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'C' } },
1670              };
1671  
1672              // Send Ctrl+A keydown, A key up, then C key down
1673              mockedInputHandler.SendVirtualInput(inputs);
1674  
1675              // A, V key states should be unchanged, Ctrl, C should be true
1676              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
1677              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1678              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), false);
1679              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x43), true);
1680          }
1681  
1682          // Tests for IME Caps Lock workaround on shortcut remappings
1683  
1684          // Test if SendVirtualInput is sent exactly once with the suppress flag when Win+CapsLock is remapped to shortcut containing Ctrl
1685          TEST_METHOD (HandleShortcutRemapEvent_ShouldSendVirtualInputWithSuppressFlagExactlyOnce_WhenWinCapsLockIsMappedToShortcutContainingCtrl)
1686          {
1687              // Set sendvirtualinput call count condition to return true if the key event was sent with the suppress flag
1688              mockedInputHandler.SetSendVirtualInputTestHandler([](LowlevelKeyboardEvent* data) {
1689                  if (data->lParam->dwExtraInfo == KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG)
1690                      return true;
1691                  else
1692                      return false;
1693              });
1694  
1695              // Remap Win+CapsLock to Ctrl+A
1696              Shortcut src;
1697              src.SetKey(CommonSharedConstants::VK_WIN_BOTH);
1698              src.SetKey(VK_CAPITAL);
1699              Shortcut dest;
1700              dest.SetKey(VK_CONTROL);
1701              dest.SetKey(0x41);
1702              testState.AddOSLevelShortcut(src, dest);
1703  
1704              std::vector<INPUT> inputs{
1705                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_LWIN } },
1706                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CAPITAL } },
1707              };
1708  
1709              // Send LWin+CapsLock keydown
1710              mockedInputHandler.SendVirtualInput(inputs);
1711  
1712              // SendVirtualInput should be called exactly once with the above condition
1713              Assert::AreEqual(1, mockedInputHandler.GetSendVirtualInputCallCount());
1714          }
1715  
1716          // Test if SendVirtualInput is sent exactly once with the suppress flag when Win+CapsLock is remapped to Ctrl
1717          TEST_METHOD (HandleShortcutRemapEvent_ShouldSendVirtualInputWithSuppressFlagExactlyOnce_WhenWinCapsLockIsMappedToCtrl)
1718          {
1719              // Set sendvirtualinput call count condition to return true if the key event was sent with the suppress flag
1720              mockedInputHandler.SetSendVirtualInputTestHandler([](LowlevelKeyboardEvent* data) {
1721                  if (data->lParam->dwExtraInfo == KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG)
1722                      return true;
1723                  else
1724                      return false;
1725              });
1726  
1727              // Remap Win+CapsLock to Ctrl+A
1728              Shortcut src;
1729              src.SetKey(CommonSharedConstants::VK_WIN_BOTH);
1730              src.SetKey(VK_CAPITAL);
1731              testState.AddOSLevelShortcut(src, (DWORD)VK_CONTROL);
1732  
1733              std::vector<INPUT> inputs{
1734                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_LWIN } },
1735                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CAPITAL } },
1736              };
1737  
1738              // Send LWin+CapsLock keydown
1739              mockedInputHandler.SendVirtualInput(inputs);
1740  
1741              // SendVirtualInput should be called exactly once with the above condition
1742              Assert::AreEqual(1, mockedInputHandler.GetSendVirtualInputCallCount());
1743          }
1744  
1745          // Test if SendVirtualInput is sent exactly once with the suppress flag when shortcut containing Ctrl is remapped to shortcut Win+CapsLock and Ctrl is pressed again while shortcut remap is invoked
1746          TEST_METHOD (HandleShortcutRemapEvent_ShouldSendVirtualInputWithSuppressFlagExactlyOnce_WhenShortcutContainingCtrlIsMappedToWinCapsLockAndCtrlIsPressedWhileInvoked)
1747          {
1748              // Set sendvirtualinput call count condition to return true if the key event was sent with the suppress flag
1749              mockedInputHandler.SetSendVirtualInputTestHandler([](LowlevelKeyboardEvent* data) {
1750                  if (data->lParam->dwExtraInfo == KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG)
1751                      return true;
1752                  else
1753                      return false;
1754              });
1755  
1756              // Remap Ctrl+A to Win+CapsLock
1757              Shortcut src;
1758              src.SetKey(VK_CONTROL);
1759              src.SetKey(0x41);
1760              Shortcut dest;
1761              dest.SetKey(CommonSharedConstants::VK_WIN_BOTH);
1762              dest.SetKey(VK_CAPITAL);
1763              testState.AddOSLevelShortcut(src, dest);
1764  
1765              std::vector<INPUT> inputs{
1766                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1767                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1768                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1769              };
1770  
1771              // Send Ctrl+A keydown followed by Ctrl
1772              mockedInputHandler.SendVirtualInput(inputs);
1773  
1774              // SendVirtualInput should be called exactly once with the above condition
1775              Assert::AreEqual(1, mockedInputHandler.GetSendVirtualInputCallCount());
1776          }
1777  
1778          // Test if SendVirtualInput is sent exactly once with the suppress flag when shortcut containing Ctrl is remapped to shortcut Win+CapsLock and Shift is pressed again while shortcut remap is invoked
1779          TEST_METHOD (HandleShortcutRemapEvent_ShouldSendVirtualInputWithSuppressFlagExactlyOnce_WhenShortcutContainingCtrlIsMappedToWinCapsLockAndShiftIsPressedWhileInvoked)
1780          {
1781              // Set sendvirtualinput call count condition to return true if the key event was sent with the suppress flag
1782              mockedInputHandler.SetSendVirtualInputTestHandler([](LowlevelKeyboardEvent* data) {
1783                  if (data->lParam->dwExtraInfo == KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG)
1784                      return true;
1785                  else
1786                      return false;
1787              });
1788  
1789              // Remap Ctrl+A to Win+CapsLock
1790              Shortcut src;
1791              src.SetKey(VK_CONTROL);
1792              src.SetKey(0x41);
1793              Shortcut dest;
1794              dest.SetKey(CommonSharedConstants::VK_WIN_BOTH);
1795              dest.SetKey(VK_CAPITAL);
1796              testState.AddOSLevelShortcut(src, dest);
1797  
1798              std::vector<INPUT> inputs{
1799                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1800                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1801                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT } },
1802              };
1803  
1804              // Send Ctrl+A keydown followed by Shift
1805              mockedInputHandler.SendVirtualInput(inputs);
1806  
1807              // SendVirtualInput should be called exactly once with the above condition
1808              Assert::AreEqual(1, mockedInputHandler.GetSendVirtualInputCallCount());
1809          }
1810  
1811          // Test if SendVirtualInput is sent exactly once with the suppress flag when shortcut containing Ctrl is remapped to CapsLock and Ctrl is pressed again while shortcut remap is invoked
1812          TEST_METHOD (HandleShortcutRemapEvent_ShouldSendVirtualInputWithSuppressFlagExactlyOnce_WhenShortcutContainingCtrlIsMappedToCapsLockAndCtrlIsPressedWhileInvoked)
1813          {
1814              // Set sendvirtualinput call count condition to return true if the key event was sent with the suppress flag
1815              mockedInputHandler.SetSendVirtualInputTestHandler([](LowlevelKeyboardEvent* data) {
1816                  if (data->lParam->dwExtraInfo == KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG)
1817                      return true;
1818                  else
1819                      return false;
1820              });
1821  
1822              // Remap Ctrl+A to CapsLock
1823              Shortcut src;
1824              src.SetKey(VK_CONTROL);
1825              src.SetKey(0x41);
1826              testState.AddOSLevelShortcut(src, (DWORD)VK_CAPITAL);
1827  
1828              std::vector<INPUT> inputs{
1829                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1830                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1831                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1832              };
1833  
1834              // Send Ctrl+A keydown followed by Ctrl
1835              mockedInputHandler.SendVirtualInput(inputs);
1836  
1837              // SendVirtualInput should be called exactly once with the above condition
1838              Assert::AreEqual(1, mockedInputHandler.GetSendVirtualInputCallCount());
1839          }
1840  
1841          // Test if SendVirtualInput is sent exactly once with the suppress flag when shortcut containing Ctrl is remapped to CapsLock and Shift is pressed again while shortcut remap is invoked
1842          TEST_METHOD (HandleShortcutRemapEvent_ShouldSendVirtualInputWithSuppressFlagExactlyOnce_WhenShortcutContainingCtrlIsMappedToCapsLockAndShiftIsPressedWhileInvoked)
1843          {
1844              // Set sendvirtualinput call count condition to return true if the key event was sent with the suppress flag
1845              mockedInputHandler.SetSendVirtualInputTestHandler([](LowlevelKeyboardEvent* data) {
1846                  if (data->lParam->dwExtraInfo == KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG)
1847                      return true;
1848                  else
1849                      return false;
1850              });
1851  
1852              // Remap Ctrl+A to CapsLock
1853              Shortcut src;
1854              src.SetKey(VK_CONTROL);
1855              src.SetKey(0x41);
1856              testState.AddOSLevelShortcut(src, (DWORD)VK_CAPITAL);
1857  
1858              std::vector<INPUT> inputs{
1859                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1860                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1861                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT } },
1862              };
1863  
1864              // Send Ctrl+A keydown followed by Shift
1865              mockedInputHandler.SendVirtualInput(inputs);
1866  
1867              // SendVirtualInput should be called exactly once with the above condition
1868              Assert::AreEqual(1, mockedInputHandler.GetSendVirtualInputCallCount());
1869          }
1870  
1871          // Tests for all types of shortcut remappings
1872  
1873          // Test that the shortcut remap state is not reset when an unrelated key up message is sent - required to handle programs sending dummy key up messages
1874          TEST_METHOD (ShortcutRemap_ShouldNotGetReset_OnSendingKeyUpForAKeyNotPresentInTheShortcutAfterInvokingTheShortcut)
1875          {
1876              // Remap Ctrl+A to Ctrl+V
1877              Shortcut src;
1878              src.SetKey(VK_CONTROL);
1879              src.SetKey(0x41);
1880              Shortcut dest;
1881              dest.SetKey(VK_CONTROL);
1882              dest.SetKey(0x56);
1883              testState.AddOSLevelShortcut(src, dest);
1884  
1885              std::vector<INPUT> inputs{
1886                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1887                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
1888                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'B', .dwFlags = KEYEVENTF_KEYUP } },
1889              };
1890  
1891              // Send Ctrl+A keydown, then B key up
1892              mockedInputHandler.SendVirtualInput(inputs);
1893  
1894              // A key state should be unchanged, Ctrl, V should be true
1895              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
1896              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x41), false);
1897              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x56), true);
1898  
1899              // Shortcut invoked state should be true
1900              Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isShortcutInvoked);
1901          }
1902  
1903          // Tests for shortcut disable remappings
1904  
1905          // Test that shortcut is disabled if the current shortcut pressed matches the exact shortcut which was remapped to Disable
1906          TEST_METHOD (ShortcutDisable_ShouldDisableShortcut_OnExactMatch)
1907          {
1908              Shortcut src;
1909              src.SetKey(VK_CONTROL);
1910              WORD actionKey = 0x41;
1911              src.SetKey(actionKey);
1912              WORD disableKey = CommonSharedConstants::VK_DISABLED;
1913  
1914              testState.AddOSLevelShortcut(src, disableKey);
1915  
1916              std::vector<INPUT> inputs{
1917                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1918                  { .type = INPUT_KEYBOARD, .ki = { .wVk = actionKey } },
1919              };
1920  
1921              // send Ctrl+A
1922              mockedInputHandler.SendVirtualInput(inputs);
1923  
1924              // Check that Ctrl+A was released and Disable key was not sent
1925              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
1926              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(actionKey), false);
1927          }
1928  
1929          // Test that shortcut is not disabled if the shortcut which was remapped to Disable is a subset of the keys currently pressed
1930          TEST_METHOD (ShortcutDisable_ShouldNotDisableShortcut_OnSubsetMatch)
1931          {
1932              Shortcut src;
1933              src.SetKey(VK_CONTROL);
1934              WORD actionKey = 0x41;
1935              src.SetKey(actionKey);
1936              WORD disableKey = CommonSharedConstants::VK_DISABLED;
1937  
1938              testState.AddOSLevelShortcut(src, disableKey);
1939  
1940              std::vector<INPUT> inputs{
1941                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1942                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT } },
1943                  { .type = INPUT_KEYBOARD, .ki = { .wVk = actionKey } },
1944              };
1945  
1946              // send Ctrl+Shift+A
1947              mockedInputHandler.SendVirtualInput(inputs);
1948  
1949              // Check that Ctrl+Shift+A was not released and Disable key was not sent
1950              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
1951              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_SHIFT), true);
1952              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(actionKey), true);
1953          }
1954  
1955          // Test that shortcut is not disabled if the shortcut which was remapped to Disable is pressed followed by another key
1956          TEST_METHOD (ShortcutDisable_ShouldNotDisableShortcutSuperset_AfterShortcutWasDisabled)
1957          {
1958              Shortcut src;
1959              src.SetKey(VK_CONTROL);
1960              WORD actionKey = 0x41;
1961              src.SetKey(actionKey);
1962              WORD disableKey = CommonSharedConstants::VK_DISABLED;
1963  
1964              testState.AddOSLevelShortcut(src, disableKey);
1965  
1966              std::vector<INPUT> inputs1{
1967                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
1968                  { .type = INPUT_KEYBOARD, .ki = { .wVk = actionKey } },
1969              };
1970  
1971              // send Ctrl+A
1972              mockedInputHandler.SendVirtualInput(inputs1);
1973  
1974              std::vector<INPUT> inputs2{
1975                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'B' } },
1976              };
1977  
1978              mockedInputHandler.SendVirtualInput(inputs2);
1979  
1980              // Check that Ctrl+A+B was pressed
1981              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
1982              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(actionKey), true);
1983              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true);
1984              // Shortcut invoked state should be false
1985              Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isShortcutInvoked);
1986          }
1987  
1988          // Test that shortcut is not disabled if the shortcut which was remapped to Disable is pressed and the action key is released, followed by pressing another key
1989          TEST_METHOD (ShortcutDisable_ShouldNotDisableShortcutSuperset_AfterActionKeyWasReleasedAndAnotherKeyWasPressedAfterIt)
1990          {
1991              Shortcut src;
1992              src.SetKey(VK_CONTROL);
1993              WORD actionKey = 0x41;
1994              src.SetKey(actionKey);
1995              WORD disableKey = CommonSharedConstants::VK_DISABLED;
1996  
1997              testState.AddOSLevelShortcut(src, disableKey);
1998  
1999              std::vector<INPUT> inputs1{
2000                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
2001                  { .type = INPUT_KEYBOARD, .ki = { .wVk = actionKey } },
2002                  { .type = INPUT_KEYBOARD, .ki = { .wVk = actionKey, .dwFlags = KEYEVENTF_KEYUP } },
2003              };
2004  
2005              // send Ctrl+A, release A
2006              mockedInputHandler.SendVirtualInput(inputs1);
2007  
2008              // Check that no keys are pressed
2009              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), false);
2010              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(actionKey), false);
2011              // Shortcut invoked state should be true
2012              Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isShortcutInvoked);
2013  
2014              std::vector<INPUT> inputs2{
2015                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'B' } },
2016              };
2017  
2018              // send B
2019              mockedInputHandler.SendVirtualInput(inputs2);
2020  
2021              // Check that Ctrl+B was pressed
2022              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(VK_CONTROL), true);
2023              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(actionKey), false);
2024              Assert::AreEqual(mockedInputHandler.GetVirtualKeyState(0x42), true);
2025              // Shortcut invoked state should be false
2026              Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isShortcutInvoked);
2027          }
2028  
2029          // Test that the isOriginalActionKeyPressed flag is set to true on exact match of the shortcut
2030          TEST_METHOD (ShortcutDisable_ShouldSetIsOriginalActionKeyPressed_OnExactMatch)
2031          {
2032              Shortcut src;
2033              src.SetKey(VK_CONTROL);
2034              WORD actionKey = 0x41;
2035              src.SetKey(actionKey);
2036              WORD disableKey = CommonSharedConstants::VK_DISABLED;
2037  
2038              testState.AddOSLevelShortcut(src, disableKey);
2039  
2040              std::vector<INPUT> inputs{
2041                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
2042                  { .type = INPUT_KEYBOARD, .ki = { .wVk = actionKey } },
2043              };
2044  
2045              // send Ctrl+A
2046              mockedInputHandler.SendVirtualInput(inputs);
2047  
2048              // IsOriginalActionKeyPressed state should be true
2049              Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed);
2050          }
2051  
2052          // Test that the isOriginalActionKeyPressed flag is set to false on releasing the action key
2053          TEST_METHOD (ShortcutDisable_ShouldResetIsOriginalActionKeyPressed_OnReleasingActionKey)
2054          {
2055              Shortcut src;
2056              src.SetKey(VK_CONTROL);
2057              WORD actionKey = 0x41;
2058              src.SetKey(actionKey);
2059              WORD disableKey = CommonSharedConstants::VK_DISABLED;
2060  
2061              testState.AddOSLevelShortcut(src, disableKey);
2062  
2063              std::vector<INPUT> inputs1{
2064                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
2065                  { .type = INPUT_KEYBOARD, .ki = { .wVk = actionKey } },
2066              };
2067  
2068              // send Ctrl+A
2069              mockedInputHandler.SendVirtualInput(inputs1);
2070  
2071              // IsOriginalActionKeyPressed state should be true
2072              Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed);
2073  
2074              std::vector<INPUT> inputs2{
2075                  { .type = INPUT_KEYBOARD, .ki = { .wVk = actionKey, .dwFlags = KEYEVENTF_KEYUP } },
2076              };
2077  
2078              // release A
2079              mockedInputHandler.SendVirtualInput(inputs2);
2080  
2081              // IsOriginalActionKeyPressed state should be false
2082              Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed);
2083          }
2084  
2085          // Test that the isOriginalActionKeyPressed flag is set to true on pressing the action key again after releasing the action key
2086          TEST_METHOD (ShortcutDisable_ShouldSetIsOriginalActionKeyPressed_OnPressingActionKeyAfterReleasingActionKey)
2087          {
2088              Shortcut src;
2089              src.SetKey(VK_CONTROL);
2090              WORD actionKey = 0x41;
2091              src.SetKey(actionKey);
2092              WORD disableKey = CommonSharedConstants::VK_DISABLED;
2093  
2094              testState.AddOSLevelShortcut(src, disableKey);
2095  
2096              std::vector<INPUT> inputs1{
2097                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
2098                  { .type = INPUT_KEYBOARD, .ki = { .wVk = actionKey } },
2099                  { .type = INPUT_KEYBOARD, .ki = { .wVk = actionKey, .dwFlags = KEYEVENTF_KEYUP } }
2100              };
2101  
2102              // send Ctrl+A, release A
2103              mockedInputHandler.SendVirtualInput(inputs1);
2104  
2105              // IsOriginalActionKeyPressed state should be false
2106              Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed);
2107  
2108              std::vector<INPUT> inputs2{
2109                  { .type = INPUT_KEYBOARD, .ki = { .wVk = actionKey } },
2110              };
2111  
2112              // press A
2113              mockedInputHandler.SendVirtualInput(inputs2);
2114  
2115              // IsOriginalActionKeyPressed state should be true
2116              Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed);
2117          }
2118  
2119          // Test that the isOriginalActionKeyPressed flag is set to false on releasing the modifier key
2120          TEST_METHOD (ShortcutDisable_ShouldResetIsOriginalActionKeyPressed_OnReleasingModifierKey)
2121          {
2122              Shortcut src;
2123              src.SetKey(VK_CONTROL);
2124              WORD actionKey = 0x41;
2125              src.SetKey(actionKey);
2126              WORD disableKey = CommonSharedConstants::VK_DISABLED;
2127  
2128              testState.AddOSLevelShortcut(src, disableKey);
2129  
2130              std::vector<INPUT> inputs1{
2131                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
2132                  { .type = INPUT_KEYBOARD, .ki = { .wVk = actionKey } },
2133              };
2134  
2135              // send Ctrl+A
2136              mockedInputHandler.SendVirtualInput(inputs1);
2137  
2138              // IsOriginalActionKeyPressed state should be true
2139              Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed);
2140  
2141              std::vector<INPUT> inputs2{
2142                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
2143              };
2144  
2145              // release Ctrl
2146              mockedInputHandler.SendVirtualInput(inputs2);
2147  
2148              // IsOriginalActionKeyPressed state should be false
2149              Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed);
2150          }
2151  
2152          // Test that the isOriginalActionKeyPressed flag is set to false on pressing another key
2153          TEST_METHOD (ShortcutDisable_ShouldResetIsOriginalActionKeyPressed_OnPressingAnotherKey)
2154          {
2155              Shortcut src;
2156              src.SetKey(VK_CONTROL);
2157              WORD actionKey = 0x41;
2158              src.SetKey(actionKey);
2159              WORD disableKey = CommonSharedConstants::VK_DISABLED;
2160  
2161              testState.AddOSLevelShortcut(src, disableKey);
2162  
2163              std::vector<INPUT> inputs1{
2164                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
2165                  { .type = INPUT_KEYBOARD, .ki = { .wVk = actionKey } },
2166              };
2167  
2168              // send Ctrl+A
2169              mockedInputHandler.SendVirtualInput(inputs1);
2170  
2171              // IsOriginalActionKeyPressed state should be true
2172              Assert::AreEqual(true, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed);
2173  
2174              std::vector<INPUT> inputs2{
2175                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'B' } },
2176              };
2177  
2178              // press B
2179              mockedInputHandler.SendVirtualInput(inputs2);
2180  
2181              // IsOriginalActionKeyPressed state should be false
2182              Assert::AreEqual(false, testState.osLevelShortcutReMap[src].isOriginalActionKeyPressed);
2183          }
2184  
2185          // Tests for dummy key events in shortcut remaps
2186  
2187          // Test if one set of dummy key events is sent before releasing the modifier when shortcut is remapped to a shortcut not containing original shortcut modifiers on invoking the shortcut. Example: Win+A->Ctrl+V, press Win+A, since Win will be released here we need to send a dummy event before it
2188          TEST_METHOD (HandleShortcutRemapEvent_ShouldSendOneSetOfDummyKeyEventsBeforeReleasingTheModifier_WhenShortcutIsRemappedToAShortcutNotContainingOriginalShortcutModifiersOnInvoke)
2189          {
2190              // Set sendvirtualinput call count condition to return true if the key event was a dummy key and LWin is pressed
2191              mockedInputHandler.SetSendVirtualInputTestHandler([this](LowlevelKeyboardEvent* data) {
2192                  if (data->lParam->vkCode == KeyboardManagerConstants::DUMMY_KEY && mockedInputHandler.GetVirtualKeyState(VK_LWIN))
2193                      return true;
2194                  else
2195                      return false;
2196              });
2197  
2198              // Remap Win+A to Ctrl+V
2199              Shortcut src;
2200              src.SetKey(CommonSharedConstants::VK_WIN_BOTH);
2201              src.SetKey(0x41);
2202              Shortcut dest;
2203              dest.SetKey(VK_CONTROL);
2204              dest.SetKey(0x56);
2205              testState.AddOSLevelShortcut(src, dest);
2206  
2207              std::vector<INPUT> inputs{
2208                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_LWIN } },
2209                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
2210              };
2211  
2212              // Send LWin+A
2213              mockedInputHandler.SendVirtualInput(inputs);
2214  
2215              // SendVirtualInput should be called exactly twice with the above condition (since two dummy key events are sent in one set)
2216              Assert::AreEqual(2, mockedInputHandler.GetSendVirtualInputCallCount());
2217              // LWin should be released
2218              Assert::AreEqual(false, mockedInputHandler.GetVirtualKeyState(VK_LWIN));
2219          }
2220  
2221          // Test if one set of dummy key events is sent after setting the modifier when three key shortcut is remapped to a shortcut on releasing action key and a modifier. Example: Win+Ctrl+A->Ctrl+V, press Win+Ctrl+A and release A then Ctrl, since Win will be pressed here we need to send a dummy event after it
2222          TEST_METHOD (HandleShortcutRemapEvent_ShouldSendOneSetOfDummyKeyEventsAfterSettingTheModifier_When3KeyShortcutIsRemappedToShortcutOnReleasingActionKeyAndAModifier)
2223          {
2224              // Remap Win+Ctrl+A to Ctrl+V
2225              Shortcut src;
2226              src.SetKey(CommonSharedConstants::VK_WIN_BOTH);
2227              src.SetKey(VK_CONTROL);
2228              src.SetKey(0x41);
2229              Shortcut dest;
2230              dest.SetKey(VK_CONTROL);
2231              dest.SetKey(0x56);
2232              testState.AddOSLevelShortcut(src, dest);
2233  
2234              std::vector<INPUT> inputs1{
2235                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_LWIN } },
2236                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
2237                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
2238              };
2239  
2240              // Send LWin+Ctrl+A
2241              mockedInputHandler.SendVirtualInput(inputs1);
2242  
2243              // Set sendvirtualinput call count condition to return true if the key event was a dummy key and LWin is pressed
2244              mockedInputHandler.SetSendVirtualInputTestHandler([this](LowlevelKeyboardEvent* data) {
2245                  if (data->lParam->vkCode == KeyboardManagerConstants::DUMMY_KEY && mockedInputHandler.GetVirtualKeyState(VK_LWIN))
2246                      return true;
2247                  else
2248                      return false;
2249              });
2250  
2251              std::vector<INPUT> inputs2{
2252                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
2253              };
2254  
2255              // Release Ctrl
2256              mockedInputHandler.SendVirtualInput(inputs2);
2257  
2258              // SendVirtualInput should be called exactly twice with the above condition (since two dummy key events are sent in one set)
2259              Assert::AreEqual(2, mockedInputHandler.GetSendVirtualInputCallCount());
2260              // LWin should be pressed
2261              Assert::AreEqual(true, mockedInputHandler.GetVirtualKeyState(VK_LWIN));
2262          }
2263  
2264          // Test if one set of dummy key events is sent before releasing the modifier when shortcut is remapped to a single key on invoking the shortcut. Example: Win+A->V, press Win+A, since Win will be released here we need to send a dummy event before it
2265          TEST_METHOD (HandleShortcutRemapEvent_ShouldSendOneSetOfDummyKeyEventsBeforeReleasingTheModifier_WhenShortcutIsRemappedToASingleKeyOnInvoke)
2266          {
2267              // Set sendvirtualinput call count condition to return true if the key event was a dummy key and LWin is pressed
2268              mockedInputHandler.SetSendVirtualInputTestHandler([this](LowlevelKeyboardEvent* data) {
2269                  if (data->lParam->vkCode == KeyboardManagerConstants::DUMMY_KEY && mockedInputHandler.GetVirtualKeyState(VK_LWIN))
2270                      return true;
2271                  else
2272                      return false;
2273              });
2274  
2275              // Remap Win+A toV
2276              Shortcut src;
2277              src.SetKey(CommonSharedConstants::VK_WIN_BOTH);
2278              src.SetKey(0x41);
2279              testState.AddOSLevelShortcut(src, (DWORD)0x56);
2280  
2281              std::vector<INPUT> inputs{
2282                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_LWIN } },
2283                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
2284              };
2285  
2286              // Send LWin+A
2287              mockedInputHandler.SendVirtualInput(inputs);
2288  
2289              // SendVirtualInput should be called exactly twice with the above condition (since two dummy key events are sent in one set)
2290              Assert::AreEqual(2, mockedInputHandler.GetSendVirtualInputCallCount());
2291              // LWin should be released
2292              Assert::AreEqual(false, mockedInputHandler.GetVirtualKeyState(VK_LWIN));
2293          }
2294  
2295          // Test if one set of dummy key events is sent after setting the modifier when shortcut is remapped to a single key on releasing action key and a modifier. Example: Win+A->V, press Shift+Win+A and release A, since Win will be pressed here we need to send a dummy event after it
2296          TEST_METHOD (HandleShortcutRemapEvent_ShouldSendOneSetOfDummyKeyEventsAfterSettingTheModifier_WhenShortcutIsRemappedToSingleKeyOnReleasingActionKeyAndAModifier)
2297          {
2298              // Remap Win+Ctrl+A to V
2299              Shortcut src;
2300              src.SetKey(CommonSharedConstants::VK_WIN_BOTH);
2301              src.SetKey(VK_CONTROL);
2302              src.SetKey(0x41);
2303              testState.AddOSLevelShortcut(src, (DWORD)0x56);
2304  
2305              std::vector<INPUT> inputs1{
2306                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_LWIN } },
2307                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL } },
2308                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
2309              };
2310  
2311              // Send LWin+Ctrl+A
2312              mockedInputHandler.SendVirtualInput(inputs1);
2313  
2314              // Set sendvirtualinput call count condition to return true if the key event was a dummy key and LWin is pressed
2315              mockedInputHandler.SetSendVirtualInputTestHandler([this](LowlevelKeyboardEvent* data) {
2316                  if (data->lParam->vkCode == KeyboardManagerConstants::DUMMY_KEY && mockedInputHandler.GetVirtualKeyState(VK_LWIN))
2317                      return true;
2318                  else
2319                      return false;
2320              });
2321  
2322              std::vector<INPUT> inputs2{
2323                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_CONTROL, .dwFlags = KEYEVENTF_KEYUP } },
2324              };
2325  
2326              // Release Ctrl
2327              mockedInputHandler.SendVirtualInput(inputs2);
2328  
2329              // SendVirtualInput should be called exactly twice with the above condition (since two dummy key events are sent in one set)
2330              Assert::AreEqual(2, mockedInputHandler.GetSendVirtualInputCallCount());
2331              // LWin should be pressed
2332              Assert::AreEqual(true, mockedInputHandler.GetVirtualKeyState(VK_LWIN));
2333          }
2334  
2335          // Test if one set of dummy key events is sent after setting the modifier when shortcut is remapped to a single key on invoking shortcut after pressing another key and then releasing the action key. Example: Win+A->V, press Shift+Win+A and release A, since Win will be pressed here we need to send a dummy event after it
2336          TEST_METHOD (HandleShortcutRemapEvent_ShouldSendOneSetOfDummyKeyEventsAfterSettingTheModifier_WhenShortcutIsRemappedToSingleKeyOnInvokingTheShortcutAfterPressingAnotherKeyAndThenReleasingTheActionKey)
2337          {
2338              // Remap Win+A to V
2339              Shortcut src;
2340              src.SetKey(CommonSharedConstants::VK_WIN_BOTH);
2341              src.SetKey(0x41);
2342              testState.AddOSLevelShortcut(src, (DWORD)0x56);
2343  
2344              std::vector<INPUT> inputs1{
2345                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_SHIFT } },
2346                  { .type = INPUT_KEYBOARD, .ki = { .wVk = VK_LWIN } },
2347                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A' } },
2348              };
2349  
2350              // Send Shift+LWin+A
2351              mockedInputHandler.SendVirtualInput(inputs1);
2352  
2353              // Set sendvirtualinput call count condition to return true if the key event was a dummy key and LWin is pressed
2354              mockedInputHandler.SetSendVirtualInputTestHandler([this](LowlevelKeyboardEvent* data) {
2355                  if (data->lParam->vkCode == KeyboardManagerConstants::DUMMY_KEY && mockedInputHandler.GetVirtualKeyState(VK_LWIN))
2356                      return true;
2357                  else
2358                      return false;
2359              });
2360  
2361              std::vector<INPUT> inputs2{
2362                  { .type = INPUT_KEYBOARD, .ki = { .wVk = 'A', .dwFlags = KEYEVENTF_KEYUP } },
2363              };
2364  
2365              // Release A
2366              mockedInputHandler.SendVirtualInput(inputs2);
2367  
2368              // SendVirtualInput should be called exactly twice with the above condition (since two dummy key events are sent in one set)
2369              Assert::AreEqual(2, mockedInputHandler.GetSendVirtualInputCallCount());
2370              // LWin should be pressed
2371              Assert::AreEqual(true, mockedInputHandler.GetVirtualKeyState(VK_LWIN));
2372          }
2373      };
2374  }