microsoft/TypeAgent
Publicmirrored fromhttps://github.com/microsoft/TypeAgentAvailable
dotnet/autoShell.Tests/CommandDispatcherIntegrationTests.cs
172lines · modecode
| 1 | // Copyright (c) Microsoft Corporation. |
| 2 | // Licensed under the MIT License. |
| 3 | |
| 4 | using autoShell.Logging; |
| 5 | using autoShell.Services; |
| 6 | using Moq; |
| 7 | using Newtonsoft.Json.Linq; |
| 8 | |
| 9 | namespace autoShell.Tests; |
| 10 | |
| 11 | /// <summary> |
| 12 | /// Integration tests that exercise the full <see cref="CommandDispatcher.Create"/> → <see cref="CommandDispatcher.Dispatch"/> → handler → service pipeline |
| 13 | /// using mock services. These verify that <see cref="CommandDispatcher"/> wiring is correct. |
| 14 | /// </summary> |
| 15 | public class CommandDispatcherIntegrationTests |
| 16 | { |
| 17 | private readonly Mock<IRegistryService> _registryMock = new(); |
| 18 | private readonly Mock<ISystemParametersService> _systemParamsMock = new(); |
| 19 | private readonly Mock<IProcessService> _processMock = new(); |
| 20 | private readonly Mock<IAudioService> _audioMock = new(); |
| 21 | private readonly Mock<IAppRegistry> _appRegistryMock = new(); |
| 22 | private readonly Mock<IDebuggerService> _debuggerMock = new(); |
| 23 | private readonly Mock<IBrightnessService> _brightnessMock = new(); |
| 24 | private readonly Mock<IDisplayService> _displayMock = new(); |
| 25 | private readonly Mock<IWindowService> _windowMock = new(); |
| 26 | private readonly Mock<INetworkService> _networkMock = new(); |
| 27 | private readonly Mock<IVirtualDesktopService> _virtualDesktopMock = new(); |
| 28 | private readonly Mock<ILogger> _loggerMock = new(); |
| 29 | private readonly CommandDispatcher _dispatcher; |
| 30 | |
| 31 | public CommandDispatcherIntegrationTests() |
| 32 | { |
| 33 | _dispatcher = CommandDispatcher.Create( |
| 34 | _loggerMock.Object, |
| 35 | _registryMock.Object, |
| 36 | _systemParamsMock.Object, |
| 37 | _processMock.Object, |
| 38 | _audioMock.Object, |
| 39 | _appRegistryMock.Object, |
| 40 | _debuggerMock.Object, |
| 41 | _brightnessMock.Object, |
| 42 | _displayMock.Object, |
| 43 | _windowMock.Object, |
| 44 | _networkMock.Object, |
| 45 | _virtualDesktopMock.Object); |
| 46 | } |
| 47 | |
| 48 | /// <summary> |
| 49 | /// Verifies that a Volume command dispatched through <see cref="CommandDispatcher.Create"/> reaches the audio service. |
| 50 | /// </summary> |
| 51 | [Fact] |
| 52 | public void Dispatch_Volume_ReachesAudioService() |
| 53 | { |
| 54 | _audioMock.Setup(a => a.GetVolume()).Returns(50); |
| 55 | |
| 56 | Dispatch("""{"Volume": "75"}"""); |
| 57 | |
| 58 | _audioMock.Verify(a => a.SetVolume(75), Times.Once); |
| 59 | } |
| 60 | |
| 61 | /// <summary> |
| 62 | /// Verifies that a Mute command dispatched through <see cref="CommandDispatcher.Create"/> reaches the audio service. |
| 63 | /// </summary> |
| 64 | [Fact] |
| 65 | public void Dispatch_Mute_ReachesAudioService() |
| 66 | { |
| 67 | Dispatch("""{"Mute": "true"}"""); |
| 68 | |
| 69 | _audioMock.Verify(a => a.SetMute(true), Times.Once); |
| 70 | } |
| 71 | |
| 72 | /// <summary> |
| 73 | /// Verifies that a LaunchProgram command dispatched through <see cref="CommandDispatcher.Create"/> reaches the process service. |
| 74 | /// </summary> |
| 75 | [Fact] |
| 76 | public void Dispatch_LaunchProgram_ReachesProcessService() |
| 77 | { |
| 78 | _appRegistryMock.Setup(a => a.ResolveProcessName("notepad")).Returns("notepad"); |
| 79 | _processMock.Setup(p => p.GetProcessesByName("notepad")).Returns([]); |
| 80 | _appRegistryMock.Setup(a => a.GetExecutablePath("notepad")).Returns("notepad.exe"); |
| 81 | |
| 82 | Dispatch("""{"LaunchProgram": "notepad"}"""); |
| 83 | |
| 84 | _processMock.Verify(p => p.Start(It.IsAny<System.Diagnostics.ProcessStartInfo>()), Times.Once); |
| 85 | } |
| 86 | |
| 87 | /// <summary> |
| 88 | /// Verifies that a SetWallpaper command dispatched through <see cref="CommandDispatcher.Create"/> reaches the system parameters service. |
| 89 | /// </summary> |
| 90 | [Fact] |
| 91 | public void Dispatch_SetWallpaper_ReachesSystemParamsService() |
| 92 | { |
| 93 | Dispatch("""{"SetWallpaper": "C:\\wallpaper.jpg"}"""); |
| 94 | |
| 95 | _systemParamsMock.Verify(s => s.SetParameter(0x0014, 0, @"C:\wallpaper.jpg", 3), Times.Once); |
| 96 | } |
| 97 | |
| 98 | /// <summary> |
| 99 | /// Verifies that a ConnectWifi command dispatched through <see cref="CommandDispatcher.Create"/> reaches the network service. |
| 100 | /// </summary> |
| 101 | [Fact] |
| 102 | public void Dispatch_ConnectWifi_ReachesNetworkService() |
| 103 | { |
| 104 | Dispatch("""{"ConnectWifi": "{\"ssid\": \"MyNetwork\", \"password\": \"pass123\"}"}"""); |
| 105 | |
| 106 | _networkMock.Verify(n => n.ConnectToWifi(It.IsAny<string>(), It.IsAny<string>()), Times.Once); |
| 107 | } |
| 108 | |
| 109 | /// <summary> |
| 110 | /// Verifies that a NextDesktop command dispatched through <see cref="CommandDispatcher.Create"/> reaches the virtual desktop service. |
| 111 | /// </summary> |
| 112 | [Fact] |
| 113 | public void Dispatch_NextDesktop_ReachesVirtualDesktopService() |
| 114 | { |
| 115 | Dispatch("""{"NextDesktop": ""}"""); |
| 116 | |
| 117 | _virtualDesktopMock.Verify(v => v.NextDesktop(), Times.Once); |
| 118 | } |
| 119 | |
| 120 | /// <summary> |
| 121 | /// Verifies that a SetThemeMode command dispatched through <see cref="CommandDispatcher.Create"/> reaches the registry service. |
| 122 | /// </summary> |
| 123 | [Fact] |
| 124 | public void Dispatch_SetThemeMode_ReachesRegistryService() |
| 125 | { |
| 126 | Dispatch("""{"SetThemeMode": "dark"}"""); |
| 127 | |
| 128 | _registryMock.Verify(r => r.SetValue( |
| 129 | It.IsAny<string>(), "AppsUseLightTheme", 0, It.IsAny<Microsoft.Win32.RegistryValueKind>()), Times.Once); |
| 130 | } |
| 131 | |
| 132 | /// <summary> |
| 133 | /// Verifies that an unknown command does not throw and logs a debug message. |
| 134 | /// </summary> |
| 135 | [Fact] |
| 136 | public void Dispatch_UnknownCommand_DoesNotThrow() |
| 137 | { |
| 138 | var ex = Record.Exception(() => Dispatch("""{"NonExistentCommand": "value"}""")); |
| 139 | |
| 140 | Assert.Null(ex); |
| 141 | } |
| 142 | |
| 143 | /// <summary> |
| 144 | /// Verifies that multiple commands in a single JSON object are all dispatched. |
| 145 | /// </summary> |
| 146 | [Fact] |
| 147 | public void Dispatch_MultipleCommands_AllReachServices() |
| 148 | { |
| 149 | _audioMock.Setup(a => a.GetVolume()).Returns(50); |
| 150 | |
| 151 | Dispatch("""{"Volume": "80", "Mute": "false"}"""); |
| 152 | |
| 153 | _audioMock.Verify(a => a.SetVolume(80), Times.Once); |
| 154 | _audioMock.Verify(a => a.SetMute(false), Times.Once); |
| 155 | } |
| 156 | |
| 157 | /// <summary> |
| 158 | /// Verifies that quit stops processing and returns true. |
| 159 | /// </summary> |
| 160 | [Fact] |
| 161 | public void Dispatch_Quit_ReturnsTrue() |
| 162 | { |
| 163 | bool result = _dispatcher.Dispatch(JObject.Parse("""{"quit": ""}""")); |
| 164 | |
| 165 | Assert.True(result); |
| 166 | } |
| 167 | |
| 168 | private void Dispatch(string json) |
| 169 | { |
| 170 | _dispatcher.Dispatch(JObject.Parse(json)); |
| 171 | } |
| 172 | } |
| 173 | |