microsoft/TypeAgent
Publicmirrored fromhttps://github.com/microsoft/TypeAgentAvailable
dotnet/autoShell.Tests/AudioCommandHandlerTests.cs
163lines · modecode
| 1 | // Copyright (c) Microsoft Corporation. |
| 2 | // Licensed under the MIT License. |
| 3 | |
| 4 | using autoShell.Handlers; |
| 5 | using autoShell.Services; |
| 6 | using Moq; |
| 7 | using Newtonsoft.Json.Linq; |
| 8 | |
| 9 | namespace autoShell.Tests; |
| 10 | |
| 11 | public class AudioCommandHandlerTests |
| 12 | { |
| 13 | private readonly Mock<IAudioService> _audioMock = new(); |
| 14 | private readonly AudioCommandHandler _handler; |
| 15 | |
| 16 | public AudioCommandHandlerTests() |
| 17 | { |
| 18 | _handler = new AudioCommandHandler(_audioMock.Object); |
| 19 | } |
| 20 | // --- Volume --- |
| 21 | |
| 22 | /// <summary> |
| 23 | /// Verifies that valid integer percentage values are forwarded to <see cref="IAudioService.SetVolume"/>. |
| 24 | /// </summary> |
| 25 | [Theory] |
| 26 | [InlineData("0", 0)] |
| 27 | [InlineData("50", 50)] |
| 28 | [InlineData("100", 100)] |
| 29 | public void Volume_ValidPercent_SetsVolume(string input, int expected) |
| 30 | { |
| 31 | _audioMock.Setup(a => a.GetVolume()).Returns(75); |
| 32 | |
| 33 | Handle("Volume", input); |
| 34 | |
| 35 | _audioMock.Verify(a => a.SetVolume(expected), Times.Once); |
| 36 | } |
| 37 | |
| 38 | /// <summary> |
| 39 | /// Verifies that setting volume reads and saves the current level before applying the new one. |
| 40 | /// </summary> |
| 41 | [Fact] |
| 42 | public void Volume_SavesCurrentVolumeBeforeSetting() |
| 43 | { |
| 44 | _audioMock.Setup(a => a.GetVolume()).Returns(42); |
| 45 | |
| 46 | Handle("Volume", "80"); |
| 47 | |
| 48 | // GetVolume should have been called to save the current level |
| 49 | _audioMock.Verify(a => a.GetVolume(), Times.Once); |
| 50 | } |
| 51 | |
| 52 | /// <summary> |
| 53 | /// Verifies that non-integer input does not trigger a <see cref="IAudioService.SetVolume"/> call. |
| 54 | /// </summary> |
| 55 | [Theory] |
| 56 | [InlineData("")] |
| 57 | [InlineData("abc")] |
| 58 | [InlineData("12.5")] |
| 59 | public void Volume_InvalidInput_DoesNotCallSetVolume(string input) |
| 60 | { |
| 61 | Handle("Volume", input); |
| 62 | |
| 63 | _audioMock.Verify(a => a.SetVolume(It.IsAny<int>()), Times.Never); |
| 64 | } |
| 65 | |
| 66 | // --- RestoreVolume --- |
| 67 | |
| 68 | /// <summary> |
| 69 | /// Verifies that RestoreVolume restores the volume to the level saved before the last change. |
| 70 | /// </summary> |
| 71 | [Fact] |
| 72 | public void RestoreVolume_AfterVolumeChange_RestoresSavedLevel() |
| 73 | { |
| 74 | _audioMock.Setup(a => a.GetVolume()).Returns(65); |
| 75 | |
| 76 | // First set volume (saves 65) |
| 77 | Handle("Volume", "20"); |
| 78 | _audioMock.Invocations.Clear(); |
| 79 | |
| 80 | // Then restore |
| 81 | Handle("RestoreVolume", ""); |
| 82 | |
| 83 | _audioMock.Verify(a => a.SetVolume(65), Times.Once); |
| 84 | } |
| 85 | |
| 86 | /// <summary> |
| 87 | /// Verifies that RestoreVolume defaults to zero when no prior volume change has been recorded. |
| 88 | /// </summary> |
| 89 | [Fact] |
| 90 | public void RestoreVolume_WithoutPriorChange_RestoresZero() |
| 91 | { |
| 92 | Handle("RestoreVolume", ""); |
| 93 | |
| 94 | _audioMock.Verify(a => a.SetVolume(0), Times.Once); |
| 95 | } |
| 96 | |
| 97 | /// <summary> |
| 98 | /// Verifies that RestoreVolume uses the actual saved volume, not a hardcoded value, |
| 99 | /// by using a different initial volume than the other RestoreVolume test. |
| 100 | /// </summary> |
| 101 | [Fact] |
| 102 | public void RestoreVolume_DifferentInitialVolume_RestoresSavedLevel() |
| 103 | { |
| 104 | _audioMock.Setup(a => a.GetVolume()).Returns(30); |
| 105 | |
| 106 | Handle("Volume", "80"); |
| 107 | _audioMock.Invocations.Clear(); |
| 108 | |
| 109 | Handle("RestoreVolume", ""); |
| 110 | |
| 111 | _audioMock.Verify(a => a.SetVolume(30), Times.Once); |
| 112 | } |
| 113 | |
| 114 | // --- Mute --- |
| 115 | |
| 116 | /// <summary> |
| 117 | /// Verifies that valid boolean string values are forwarded to <see cref="IAudioService.SetMute"/>. |
| 118 | /// </summary> |
| 119 | [Theory] |
| 120 | [InlineData("true", true)] |
| 121 | [InlineData("True", true)] |
| 122 | [InlineData("false", false)] |
| 123 | [InlineData("False", false)] |
| 124 | public void Mute_ValidBool_SetsMute(string input, bool expected) |
| 125 | { |
| 126 | Handle("Mute", input); |
| 127 | |
| 128 | _audioMock.Verify(a => a.SetMute(expected), Times.Once); |
| 129 | } |
| 130 | |
| 131 | /// <summary> |
| 132 | /// Verifies that non-boolean input does not trigger a <see cref="IAudioService.SetMute"/> call. |
| 133 | /// </summary> |
| 134 | [Theory] |
| 135 | [InlineData("")] |
| 136 | [InlineData("yes")] |
| 137 | [InlineData("1")] |
| 138 | [InlineData("on")] |
| 139 | public void Mute_InvalidInput_DoesNotCallSetMute(string input) |
| 140 | { |
| 141 | Handle("Mute", input); |
| 142 | |
| 143 | _audioMock.Verify(a => a.SetMute(It.IsAny<bool>()), Times.Never); |
| 144 | } |
| 145 | |
| 146 | // --- Unknown key --- |
| 147 | |
| 148 | /// <summary> |
| 149 | /// Verifies that an unknown command key does not invoke any audio service methods. |
| 150 | /// </summary> |
| 151 | [Fact] |
| 152 | public void Handle_UnknownKey_DoesNothing() |
| 153 | { |
| 154 | Handle("UnknownAudioCmd", "value"); |
| 155 | |
| 156 | _audioMock.VerifyNoOtherCalls(); |
| 157 | } |
| 158 | |
| 159 | private void Handle(string key, string value) |
| 160 | { |
| 161 | _handler.Handle(key, value, JToken.FromObject(value)); |
| 162 | } |
| 163 | } |
| 164 | |