General.cs
  1  // Copyright (c) Microsoft Corporation
  2  // The Microsoft Corporation licenses this file to you under the MIT license.
  3  // See the LICENSE file in the project root for more information.
  4  
  5  using System;
  6  
  7  using Microsoft.PowerToys.Settings.UI.Library;
  8  using Microsoft.PowerToys.Settings.UI.UnitTests.BackwardsCompatibility;
  9  using Microsoft.PowerToys.Settings.UI.UnitTests.Mocks;
 10  using Microsoft.PowerToys.Settings.UI.ViewModels;
 11  using Microsoft.VisualStudio.TestTools.UnitTesting;
 12  using Moq;
 13  
 14  using JsonSerializer = System.Text.Json.JsonSerializer;
 15  
 16  namespace ViewModelTests
 17  {
 18      [TestClass]
 19      public class General
 20      {
 21          public const string GeneralSettingsFileName = "Test\\GeneralSettings";
 22  
 23          private Mock<SettingsUtils> mockGeneralSettingsUtils;
 24  
 25          [TestInitialize]
 26          public void SetUpStubSettingUtils()
 27          {
 28              mockGeneralSettingsUtils = ISettingsUtilsMocks.GetStubSettingsUtils<GeneralSettings>();
 29          }
 30  
 31          private sealed class TestGeneralViewModel : GeneralViewModel
 32          {
 33              public TestGeneralViewModel(
 34                  Microsoft.PowerToys.Settings.UI.Library.Interfaces.ISettingsRepository<GeneralSettings> settingsRepository,
 35                  string runAsAdminText,
 36                  string runAsUserText,
 37                  bool isElevated,
 38                  bool isAdmin,
 39                  Func<string, int> ipcMSGCallBackFunc,
 40                  Func<string, int> ipcMSGRestartAsAdminMSGCallBackFunc,
 41                  Func<string, int> ipcMSGCheckForUpdatesCallBackFunc,
 42                  string configFileSubfolder = "")
 43                  : base(settingsRepository, runAsAdminText, runAsUserText, isElevated, isAdmin, ipcMSGCallBackFunc, ipcMSGRestartAsAdminMSGCallBackFunc, ipcMSGCheckForUpdatesCallBackFunc, configFileSubfolder)
 44              {
 45              }
 46  
 47              protected override Microsoft.UI.Dispatching.DispatcherQueue GetDispatcherQueue()
 48              {
 49                  return null;
 50              }
 51          }
 52  
 53          [TestMethod]
 54          [DataRow("v0.18.2")]
 55          [DataRow("v0.19.2")]
 56          [DataRow("v0.20.1")]
 57          [DataRow("v0.21.1")]
 58          [DataRow("v0.22.0")]
 59          public void OriginalFilesModificationTest(string version)
 60          {
 61              var settingPathMock = new Mock<SettingPath>();
 62              var fileMock = BackCompatTestProperties.GetGeneralSettingsIOProvider(version);
 63  
 64              var mockGeneralSettingsUtils = new SettingsUtils(fileMock.Object, settingPathMock.Object);
 65              GeneralSettings originalGeneralSettings = mockGeneralSettingsUtils.GetSettingsOrDefault<GeneralSettings>();
 66  
 67              var generalSettingsRepository = new BackCompatTestProperties.MockSettingsRepository<GeneralSettings>(mockGeneralSettingsUtils);
 68  
 69              // Initialise View Model with test Config files
 70              // Arrange
 71              Func<string, int> sendMockIPCConfigMSG = msg => 0;
 72              Func<string, int> sendRestartAdminIPCMessage = msg => 0;
 73              Func<string, int> sendCheckForUpdatesIPCMessage = msg => 0;
 74              var viewModel = new TestGeneralViewModel(
 75                  settingsRepository: generalSettingsRepository,
 76                  runAsAdminText: "GeneralSettings_RunningAsAdminText",
 77                  runAsUserText: "GeneralSettings_RunningAsUserText",
 78                  isElevated: false,
 79                  isAdmin: false,
 80                  ipcMSGCallBackFunc: sendMockIPCConfigMSG,
 81                  ipcMSGRestartAsAdminMSGCallBackFunc: sendRestartAdminIPCMessage,
 82                  ipcMSGCheckForUpdatesCallBackFunc: sendCheckForUpdatesIPCMessage,
 83                  configFileSubfolder: string.Empty);
 84  
 85              // Verify that the old settings persisted
 86              Assert.AreEqual(originalGeneralSettings.AutoDownloadUpdates, viewModel.AutoDownloadUpdates);
 87              Assert.AreEqual(originalGeneralSettings.PowertoysVersion, viewModel.PowerToysVersion);
 88              Assert.AreEqual(originalGeneralSettings.RunElevated, viewModel.RunElevated);
 89              Assert.AreEqual(originalGeneralSettings.Startup, viewModel.Startup);
 90  
 91              // Verify that the stub file was used
 92              var expectedCallCount = 2;  // once via the view model, and once by the test (GetSettings<T>)
 93              BackCompatTestProperties.VerifyGeneralSettingsIOProviderWasRead(fileMock, expectedCallCount);
 94          }
 95  
 96          [TestMethod]
 97          public void IsElevatedShouldUpdateRunasAdminStatusAttrsWhenSuccessful()
 98          {
 99              // Arrange
100              Func<string, int> sendMockIPCConfigMSG = msg => { return 0; };
101              Func<string, int> sendRestartAdminIPCMessage = msg => { return 0; };
102              Func<string, int> sendCheckForUpdatesIPCMessage = msg => { return 0; };
103              GeneralViewModel viewModel = new TestGeneralViewModel(
104                  settingsRepository: SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object),
105                  "GeneralSettings_RunningAsAdminText",
106                  "GeneralSettings_RunningAsUserText",
107                  false,
108                  false,
109                  sendMockIPCConfigMSG,
110                  sendRestartAdminIPCMessage,
111                  sendCheckForUpdatesIPCMessage,
112                  GeneralSettingsFileName);
113  
114              Assert.AreEqual(viewModel.RunningAsUserDefaultText, viewModel.RunningAsText);
115              Assert.IsFalse(viewModel.IsElevated);
116  
117              // Act
118              viewModel.IsElevated = true;
119  
120              // Assert
121              Assert.AreEqual(viewModel.RunningAsAdminDefaultText, viewModel.RunningAsText);
122              Assert.IsTrue(viewModel.IsElevated);
123          }
124  
125          [TestMethod]
126          public void StartupShouldEnableRunOnStartUpWhenSuccessful()
127          {
128              // Assert
129              Func<string, int> sendMockIPCConfigMSG = msg =>
130              {
131                  OutGoingGeneralSettings snd = JsonSerializer.Deserialize<OutGoingGeneralSettings>(msg);
132                  Assert.IsTrue(snd.GeneralSettings.Startup);
133                  return 0;
134              };
135  
136              // Arrange
137              Func<string, int> sendRestartAdminIPCMessage = msg => { return 0; };
138              Func<string, int> sendCheckForUpdatesIPCMessage = msg => { return 0; };
139              GeneralViewModel viewModel = new TestGeneralViewModel(
140                  settingsRepository: SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object),
141                  "GeneralSettings_RunningAsAdminText",
142                  "GeneralSettings_RunningAsUserText",
143                  false,
144                  false,
145                  sendMockIPCConfigMSG,
146                  sendRestartAdminIPCMessage,
147                  sendCheckForUpdatesIPCMessage,
148                  GeneralSettingsFileName);
149              Assert.IsFalse(viewModel.Startup);
150  
151              // act
152              viewModel.Startup = true;
153          }
154  
155          [TestMethod]
156          public void RunElevatedShouldEnableAlwaysRunElevatedWhenSuccessful()
157          {
158              // Assert
159              Func<string, int> sendMockIPCConfigMSG = msg =>
160              {
161                  OutGoingGeneralSettings snd = JsonSerializer.Deserialize<OutGoingGeneralSettings>(msg);
162                  Assert.IsTrue(snd.GeneralSettings.RunElevated);
163                  return 0;
164              };
165  
166              Func<string, int> sendRestartAdminIPCMessage = msg => { return 0; };
167              Func<string, int> sendCheckForUpdatesIPCMessage = msg => { return 0; };
168  
169              // Arrange
170              GeneralViewModel viewModel = new TestGeneralViewModel(
171                  settingsRepository: SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object),
172                  "GeneralSettings_RunningAsAdminText",
173                  "GeneralSettings_RunningAsUserText",
174                  false,
175                  false,
176                  sendMockIPCConfigMSG,
177                  sendRestartAdminIPCMessage,
178                  sendCheckForUpdatesIPCMessage,
179                  GeneralSettingsFileName);
180  
181              Assert.IsFalse(viewModel.RunElevated);
182  
183              // act
184              viewModel.RunElevated = true;
185          }
186  
187          [TestMethod]
188          public void IsLightThemeRadioButtonCheckedShouldThemeToLightWhenSuccessful()
189          {
190              // Arrange
191              GeneralViewModel viewModel = null;
192  
193              // Assert
194              Func<string, int> sendMockIPCConfigMSG = msg =>
195              {
196                  OutGoingGeneralSettings snd = JsonSerializer.Deserialize<OutGoingGeneralSettings>(msg);
197                  Assert.AreEqual("light", snd.GeneralSettings.Theme);
198                  return 0;
199              };
200  
201              Func<string, int> sendRestartAdminIPCMessage = msg => { return 0; };
202              Func<string, int> sendCheckForUpdatesIPCMessage = msg => { return 0; };
203              viewModel = new TestGeneralViewModel(
204                  settingsRepository: SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object),
205                  "GeneralSettings_RunningAsAdminText",
206                  "GeneralSettings_RunningAsUserText",
207                  false,
208                  false,
209                  sendMockIPCConfigMSG,
210                  sendRestartAdminIPCMessage,
211                  sendCheckForUpdatesIPCMessage,
212                  GeneralSettingsFileName);
213              Assert.AreNotEqual(1, viewModel.ThemeIndex);
214  
215              // act
216              viewModel.ThemeIndex = 1;
217          }
218  
219          [TestMethod]
220          public void IsDarkThemeRadioButtonCheckedShouldThemeToDarkWhenSuccessful()
221          {
222              // Arrange
223              // Assert
224              Func<string, int> sendMockIPCConfigMSG = msg =>
225              {
226                  OutGoingGeneralSettings snd = JsonSerializer.Deserialize<OutGoingGeneralSettings>(msg);
227                  Assert.AreEqual("dark", snd.GeneralSettings.Theme);
228                  return 0;
229              };
230  
231              Func<string, int> sendRestartAdminIPCMessage = msg => { return 0; };
232              Func<string, int> sendCheckForUpdatesIPCMessage = msg => { return 0; };
233              GeneralViewModel viewModel = new TestGeneralViewModel(
234                  settingsRepository: SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object),
235                  "GeneralSettings_RunningAsAdminText",
236                  "GeneralSettings_RunningAsUserText",
237                  false,
238                  false,
239                  sendMockIPCConfigMSG,
240                  sendRestartAdminIPCMessage,
241                  sendCheckForUpdatesIPCMessage,
242                  GeneralSettingsFileName);
243              Assert.AreNotEqual(0, viewModel.ThemeIndex);
244  
245              // act
246              viewModel.ThemeIndex = 0;
247          }
248  
249          [TestMethod]
250          public void IsShowSysTrayIconEnabledByDefaultShouldDisableWhenSuccessful()
251          {
252              // Arrange
253              // Assert
254              Func<string, int> sendMockIPCConfigMSG = msg =>
255              {
256                  OutGoingGeneralSettings snd = JsonSerializer.Deserialize<OutGoingGeneralSettings>(msg);
257                  Assert.IsFalse(snd.GeneralSettings.ShowSysTrayIcon);
258                  return 0;
259              };
260  
261              Func<string, int> sendRestartAdminIPCMessage = msg => { return 0; };
262              Func<string, int> sendCheckForUpdatesIPCMessage = msg => { return 0; };
263              GeneralViewModel viewModel = new TestGeneralViewModel(
264                  settingsRepository: SettingsRepository<GeneralSettings>.GetInstance(mockGeneralSettingsUtils.Object),
265                  "GeneralSettings_RunningAsAdminText",
266                  "GeneralSettings_RunningAsUserText",
267                  false,
268                  false,
269                  sendMockIPCConfigMSG,
270                  sendRestartAdminIPCMessage,
271                  sendCheckForUpdatesIPCMessage,
272                  GeneralSettingsFileName);
273              Assert.IsTrue(viewModel.ShowSysTrayIcon);
274  
275              // Act
276              viewModel.ShowSysTrayIcon = false;
277          }
278  
279          [TestMethod]
280          public void AllModulesAreEnabledByDefault()
281          {
282              // arrange
283              EnabledModules modules = new EnabledModules();
284  
285              // Assert
286              Assert.IsTrue(modules.FancyZones);
287              Assert.IsTrue(modules.ImageResizer);
288              Assert.IsTrue(modules.PowerPreview);
289              Assert.IsTrue(modules.ShortcutGuide);
290              Assert.IsTrue(modules.PowerRename);
291              Assert.IsTrue(modules.PowerLauncher);
292              Assert.IsTrue(modules.ColorPicker);
293          }
294      }
295  }