diff --git a/PowerToys.sln b/PowerToys.sln index e6ae7896fe..2b6d42305f 100644 --- a/PowerToys.sln +++ b/PowerToys.sln @@ -793,6 +793,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.Apps.U EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.Bookmarks.UnitTests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.Bookmarks.UnitTests\Microsoft.CmdPal.Ext.Bookmarks.UnitTests.csproj", "{E816D7B3-4688-4ECB-97CC-3D8E798F3832}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.WebSearch.UnitTests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.WebSearch.UnitTests\Microsoft.CmdPal.Ext.WebSearch.UnitTests.csproj", "{E816D7B2-4688-4ECB-97CC-3D8E798F3831}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.Ext.Shell.UnitTests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.Ext.Shell.UnitTests\Microsoft.CmdPal.Ext.Shell.UnitTests.csproj", "{E816D7B4-4688-4ECB-97CC-3D8E798F3833}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|ARM64 = Debug|ARM64 @@ -2871,6 +2875,22 @@ Global {E816D7B3-4688-4ECB-97CC-3D8E798F3832}.Release|ARM64.Build.0 = Release|ARM64 {E816D7B3-4688-4ECB-97CC-3D8E798F3832}.Release|x64.ActiveCfg = Release|x64 {E816D7B3-4688-4ECB-97CC-3D8E798F3832}.Release|x64.Build.0 = Release|x64 + {E816D7B2-4688-4ECB-97CC-3D8E798F3831}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {E816D7B2-4688-4ECB-97CC-3D8E798F3831}.Debug|ARM64.Build.0 = Debug|ARM64 + {E816D7B2-4688-4ECB-97CC-3D8E798F3831}.Debug|x64.ActiveCfg = Debug|x64 + {E816D7B2-4688-4ECB-97CC-3D8E798F3831}.Debug|x64.Build.0 = Debug|x64 + {E816D7B2-4688-4ECB-97CC-3D8E798F3831}.Release|ARM64.ActiveCfg = Release|ARM64 + {E816D7B2-4688-4ECB-97CC-3D8E798F3831}.Release|ARM64.Build.0 = Release|ARM64 + {E816D7B2-4688-4ECB-97CC-3D8E798F3831}.Release|x64.ActiveCfg = Release|x64 + {E816D7B2-4688-4ECB-97CC-3D8E798F3831}.Release|x64.Build.0 = Release|x64 + {E816D7B4-4688-4ECB-97CC-3D8E798F3833}.Debug|ARM64.ActiveCfg = Debug|ARM64 + {E816D7B4-4688-4ECB-97CC-3D8E798F3833}.Debug|ARM64.Build.0 = Debug|ARM64 + {E816D7B4-4688-4ECB-97CC-3D8E798F3833}.Debug|x64.ActiveCfg = Debug|x64 + {E816D7B4-4688-4ECB-97CC-3D8E798F3833}.Debug|x64.Build.0 = Debug|x64 + {E816D7B4-4688-4ECB-97CC-3D8E798F3833}.Release|ARM64.ActiveCfg = Release|ARM64 + {E816D7B4-4688-4ECB-97CC-3D8E798F3833}.Release|ARM64.Build.0 = Release|ARM64 + {E816D7B4-4688-4ECB-97CC-3D8E798F3833}.Release|x64.ActiveCfg = Release|x64 + {E816D7B4-4688-4ECB-97CC-3D8E798F3833}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -3184,6 +3204,8 @@ Global {00D8659C-2068-40B6-8B86-759CD6284BBB} = {8EF25507-2575-4ADE-BF7E-D23376903AB8} {E816D7B1-4688-4ECB-97CC-3D8E798F3830} = {8EF25507-2575-4ADE-BF7E-D23376903AB8} {E816D7B3-4688-4ECB-97CC-3D8E798F3832} = {8EF25507-2575-4ADE-BF7E-D23376903AB8} + {E816D7B2-4688-4ECB-97CC-3D8E798F3831} = {8EF25507-2575-4ADE-BF7E-D23376903AB8} + {E816D7B4-4688-4ECB-97CC-3D8E798F3833} = {8EF25507-2575-4ADE-BF7E-D23376903AB8} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0} diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Shell.UnitTests/Microsoft.CmdPal.Ext.Shell.UnitTests.csproj b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Shell.UnitTests/Microsoft.CmdPal.Ext.Shell.UnitTests.csproj new file mode 100644 index 0000000000..74aeb04b39 --- /dev/null +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Shell.UnitTests/Microsoft.CmdPal.Ext.Shell.UnitTests.csproj @@ -0,0 +1,23 @@ + + + + + + false + true + Microsoft.CmdPal.Ext.Shell.UnitTests + $(SolutionDir)$(Platform)\$(Configuration)\WinUI3Apps\CmdPal\tests\ + false + false + + + + + + + + + + + + diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Shell.UnitTests/QueryTests.cs b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Shell.UnitTests/QueryTests.cs new file mode 100644 index 0000000000..bf9fcac406 --- /dev/null +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Shell.UnitTests/QueryTests.cs @@ -0,0 +1,146 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.CmdPal.Common.Services; +using Microsoft.CmdPal.Ext.Shell.Pages; +using Microsoft.CmdPal.Ext.UnitTestBase; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; + +namespace Microsoft.CmdPal.Ext.Shell.UnitTests; + +[TestClass] +public class QueryTests : CommandPaletteUnitTestBase +{ + private static Mock CreateMockHistoryService(IList historyItems = null) + { + var mockHistoryService = new Mock(); + var history = historyItems ?? new List(); + + mockHistoryService.Setup(x => x.GetRunHistory()) + .Returns(() => history.ToList().AsReadOnly()); + + mockHistoryService.Setup(x => x.AddRunHistoryItem(It.IsAny())) + .Callback(item => + { + if (!string.IsNullOrWhiteSpace(item)) + { + history.Remove(item); + history.Insert(0, item); + } + }); + + mockHistoryService.Setup(x => x.ClearRunHistory()) + .Callback(() => history.Clear()); + + return mockHistoryService; + } + + private static Mock CreateMockHistoryServiceWithCommonCommands() + { + var commonCommands = new List + { + "ping google.com", + "ipconfig /all", + "curl https://api.github.com", + "dir", + "cd ..", + "git status", + "npm install", + "python --version", + }; + + return CreateMockHistoryService(commonCommands); + } + + [TestMethod] + public void ValidateHistoryFunctionality() + { + // Setup + var settings = Settings.CreateDefaultSettings(); + + // Act + settings.AddCmdHistory("test-command"); + + // Assert + Assert.AreEqual(1, settings.Count["test-command"]); + } + + [TestMethod] + [DataRow("ping bing.com", "ping.exe")] + [DataRow("curl bing.com", "curl.exe")] + [DataRow("ipconfig /all", "ipconfig.exe")] + public async Task QueryWithoutHistoryCommand(string command, string exeName) + { + // Setup + var settings = Settings.CreateDefaultSettings(); + var mockHistory = CreateMockHistoryService(); + + var pages = new ShellListPage(settings, mockHistory.Object); + + pages.UpdateSearchText(string.Empty, command); + + // wait for about 1s. + await Task.Delay(1000); + + var commandList = pages.GetItems(); + + Assert.AreEqual(1, commandList.Length); + + var executeCommand = commandList.FirstOrDefault(); + Assert.IsNotNull(executeCommand); + Assert.IsNotNull(executeCommand.Icon); + Assert.IsTrue(executeCommand.Title.Contains(exeName), $"expect ${exeName} but got ${executeCommand.Title}"); + } + + [TestMethod] + [DataRow("ping bing.com", "ping.exe")] + [DataRow("curl bing.com", "curl.exe")] + [DataRow("ipconfig /all", "ipconfig.exe")] + public async Task QueryWithHistoryCommands(string command, string exeName) + { + // Setup + var settings = Settings.CreateDefaultSettings(); + var mockHistoryService = CreateMockHistoryServiceWithCommonCommands(); + + var pages = new ShellListPage(settings, mockHistoryService.Object); + + // Test: Search for a command that exists in history + pages.UpdateSearchText(string.Empty, command); + + await Task.Delay(1000); + + var commandList = pages.GetItems(); + + // Should find at least the ping command from history + Assert.IsTrue(commandList.Length > 1); + + var expectedCommand = commandList.FirstOrDefault(); + Assert.IsNotNull(expectedCommand); + Assert.IsNotNull(expectedCommand.Icon); + Assert.IsTrue(expectedCommand.Title.Contains(exeName), $"expect ${exeName} but got ${expectedCommand.Title}"); + } + + [TestMethod] + public async Task EmptyQueryWithHistoryCommands() + { + // Setup + var settings = Settings.CreateDefaultSettings(); + var mockHistoryService = CreateMockHistoryServiceWithCommonCommands(); + + var pages = new ShellListPage(settings, mockHistoryService.Object); + + pages.UpdateSearchText("abcdefg", string.Empty); + + await Task.Delay(1000); + + var commandList = pages.GetItems(); + + // Should find at least the ping command from history + Assert.IsTrue(commandList.Length > 1); + } +} diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Shell.UnitTests/Settings.cs b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Shell.UnitTests/Settings.cs new file mode 100644 index 0000000000..953f252be8 --- /dev/null +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Shell.UnitTests/Settings.cs @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using Microsoft.CmdPal.Ext.Shell.Helpers; + +namespace Microsoft.CmdPal.Ext.Shell.UnitTests; + +public class Settings : ISettingsInterface +{ + private readonly bool leaveShellOpen; + private readonly string shellCommandExecution; + private readonly bool runAsAdministrator; + private readonly Dictionary count; + + public Settings( + bool leaveShellOpen = false, + string shellCommandExecution = "0", + bool runAsAdministrator = false, + Dictionary count = null) + { + this.leaveShellOpen = leaveShellOpen; + this.shellCommandExecution = shellCommandExecution; + this.runAsAdministrator = runAsAdministrator; + this.count = count ?? new Dictionary(); + } + + public bool LeaveShellOpen => leaveShellOpen; + + public string ShellCommandExecution => shellCommandExecution; + + public bool RunAsAdministrator => runAsAdministrator; + + public Dictionary Count => count; + + public void AddCmdHistory(string cmdName) + { + count[cmdName] = count.TryGetValue(cmdName, out var currentCount) ? currentCount + 1 : 1; + } + + public static Settings CreateDefaultSettings() => new Settings(); + + public static Settings CreateLeaveShellOpenSettings() => new Settings(leaveShellOpen: true); + + public static Settings CreatePowerShellSettings() => new Settings(shellCommandExecution: "1"); + + public static Settings CreateAdministratorSettings() => new Settings(runAsAdministrator: true); +} diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Shell.UnitTests/ShellCommandProviderTests.cs b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Shell.UnitTests/ShellCommandProviderTests.cs new file mode 100644 index 0000000000..42fb0900a4 --- /dev/null +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.Shell.UnitTests/ShellCommandProviderTests.cs @@ -0,0 +1,51 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.CmdPal.Common.Services; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Moq; + +namespace Microsoft.CmdPal.Ext.Shell.UnitTests; + +[TestClass] +public class ShellCommandProviderTests +{ + [TestMethod] + public void ProviderHasDisplayName() + { + // Setup + var mockHistoryService = new Mock(); + var provider = new ShellCommandsProvider(mockHistoryService.Object); + + // Assert + Assert.IsNotNull(provider.DisplayName); + Assert.IsTrue(provider.DisplayName.Length > 0); + } + + [TestMethod] + public void ProviderHasIcon() + { + // Setup + var mockHistoryService = new Mock(); + var provider = new ShellCommandsProvider(mockHistoryService.Object); + + // Assert + Assert.IsNotNull(provider.Icon); + } + + [TestMethod] + public void TopLevelCommandsNotEmpty() + { + // Setup + var mockHistoryService = new Mock(); + var provider = new ShellCommandsProvider(mockHistoryService.Object); + + // Act + var commands = provider.TopLevelCommands(); + + // Assert + Assert.IsNotNull(commands); + Assert.IsTrue(commands.Length > 0); + } +} diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/Microsoft.CmdPal.Ext.WebSearch.UnitTests.csproj b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/Microsoft.CmdPal.Ext.WebSearch.UnitTests.csproj new file mode 100644 index 0000000000..d819beb7c7 --- /dev/null +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/Microsoft.CmdPal.Ext.WebSearch.UnitTests.csproj @@ -0,0 +1,23 @@ + + + + + + false + true + Microsoft.CmdPal.Ext.WebSearch.UnitTests + $(SolutionDir)$(Platform)\$(Configuration)\WinUI3Apps\CmdPal\tests\ + false + false + + + + + + + + + + + + diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/MockSettingsInterface.cs b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/MockSettingsInterface.cs new file mode 100644 index 0000000000..853360674f --- /dev/null +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/MockSettingsInterface.cs @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using Microsoft.CmdPal.Ext.WebSearch.Commands; +using Microsoft.CmdPal.Ext.WebSearch.Helpers; +using Microsoft.CommandPalette.Extensions.Toolkit; + +namespace Microsoft.CmdPal.Ext.WebSearch.UnitTests; + +public class MockSettingsInterface : ISettingsInterface +{ + private readonly List _historyItems; + + public bool GlobalIfURI { get; set; } + + public string ShowHistory { get; set; } + + public MockSettingsInterface(string showHistory = "none", bool globalIfUri = true, List mockHistory = null) + { + _historyItems = mockHistory ?? new List(); + GlobalIfURI = globalIfUri; + ShowHistory = showHistory; + } + + public List LoadHistory() + { + var listItems = new List(); + foreach (var historyItem in _historyItems) + { + listItems.Add(new ListItem(new SearchWebCommand(historyItem.SearchString, this)) + { + Title = historyItem.SearchString, + Subtitle = historyItem.Timestamp.ToString("g", System.Globalization.CultureInfo.InvariantCulture), + }); + } + + listItems.Reverse(); + return listItems; + } + + public void SaveHistory(HistoryItem historyItem) + { + if (historyItem is null) + { + return; + } + + _historyItems.Add(historyItem); + + // Simulate the same logic as SettingsManager + if (int.TryParse(ShowHistory, out var maxHistoryItems) && maxHistoryItems > 0) + { + while (_historyItems.Count > maxHistoryItems) + { + _historyItems.RemoveAt(0); // Remove the oldest item + } + } + } + + // Helper method for testing + public void ClearHistory() + { + _historyItems.Clear(); + } + + // Helper method for testing + public int GetHistoryCount() + { + return _historyItems.Count; + } +} diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/QueryTests.cs b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/QueryTests.cs new file mode 100644 index 0000000000..64a5366a61 --- /dev/null +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/QueryTests.cs @@ -0,0 +1,141 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.CmdPal.Ext.UnitTestBase; +using Microsoft.CmdPal.Ext.WebSearch.Commands; +using Microsoft.CmdPal.Ext.WebSearch.Helpers; +using Microsoft.CmdPal.Ext.WebSearch.Pages; +using Microsoft.CommandPalette.Extensions.Toolkit; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Microsoft.CmdPal.Ext.WebSearch.UnitTests; + +[TestClass] +public class QueryTests : CommandPaletteUnitTestBase +{ + [TestMethod] + [DataRow("microsoft")] + [DataRow("windows")] + public async Task SearchInWebSearchPage(string query) + { + // Setup + var settings = new MockSettingsInterface(); + + var page = new WebSearchListPage(settings); + + // Act + page.UpdateSearchText(string.Empty, query); + await Task.Delay(1000); + + var listItem = page.GetItems(); + Assert.IsNotNull(listItem); + Assert.AreEqual(1, listItem.Length); + + var expectedItem = listItem.FirstOrDefault(); + + Assert.IsNotNull(expectedItem); + Assert.IsTrue(expectedItem.Subtitle.Contains("Search the web in"), $"Expected \"search the web in chrome/edge\" but got {expectedItem.Subtitle}"); + Assert.AreEqual(query, expectedItem.Title); + } + + [TestMethod] + public async Task LoadHistoryReturnsExpectedItems() + { + // Setup + var mockHistoryItems = new List + { + new HistoryItem("test search", DateTime.Parse("2024-01-01 13:00:00", CultureInfo.CurrentCulture)), + new HistoryItem("another search", DateTime.Parse("2024-01-02 13:00:00", CultureInfo.CurrentCulture)), + }; + + var settings = new MockSettingsInterface(mockHistory: mockHistoryItems, showHistory: "5"); + + var page = new WebSearchListPage(settings); + + // Act + page.UpdateSearchText("abcdef", string.Empty); + await Task.Delay(1000); + + var listItem = page.GetItems(); + + // Assert + Assert.IsNotNull(listItem); + Assert.AreEqual(2, listItem.Length); + + foreach (var item in listItem) + { + Assert.IsNotNull(item); + Assert.IsNotEmpty(item.Title); + Assert.IsNotEmpty(item.Subtitle); + } + } + + [TestMethod] + public async Task LoadHistoryMoreThanLimitation() + { + // Setup + var mockHistoryItems = new List + { + new HistoryItem("test search", DateTime.Parse("2024-01-01 13:00:00", CultureInfo.CurrentCulture)), + new HistoryItem("another search1", DateTime.Parse("2024-01-02 13:00:00", CultureInfo.CurrentCulture)), + new HistoryItem("another search2", DateTime.Parse("2024-01-03 13:00:00", CultureInfo.CurrentCulture)), + new HistoryItem("another search3", DateTime.Parse("2024-01-04 13:00:00", CultureInfo.CurrentCulture)), + new HistoryItem("another search4", DateTime.Parse("2024-01-05 13:00:00", CultureInfo.CurrentCulture)), + }; + + var settings = new MockSettingsInterface(mockHistory: mockHistoryItems, showHistory: "5"); + + var page = new WebSearchListPage(settings); + + mockHistoryItems.Add(new HistoryItem("another search5", DateTime.Parse("2024-01-06 13:00:00", CultureInfo.CurrentCulture))); + + // Act + page.UpdateSearchText("abcdef", string.Empty); + await Task.Delay(1000); + + var listItem = page.GetItems(); + + // Assert + Assert.IsNotNull(listItem); + + // Make sure only load five item. + Assert.AreEqual(5, listItem.Length); + } + + [TestMethod] + public async Task LoadHistoryWithDisableSetting() + { + // Setup + var mockHistoryItems = new List + { + new HistoryItem("test search", DateTime.Parse("2024-01-01 13:00:00", CultureInfo.CurrentCulture)), + new HistoryItem("another search1", DateTime.Parse("2024-01-02 13:00:00", CultureInfo.CurrentCulture)), + new HistoryItem("another search2", DateTime.Parse("2024-01-03 13:00:00", CultureInfo.CurrentCulture)), + new HistoryItem("another search3", DateTime.Parse("2024-01-04 13:00:00", CultureInfo.CurrentCulture)), + new HistoryItem("another search4", DateTime.Parse("2024-01-05 13:00:00", CultureInfo.CurrentCulture)), + new HistoryItem("another search5", DateTime.Parse("2024-01-06 13:00:00", CultureInfo.CurrentCulture)), + }; + + var settings = new MockSettingsInterface(mockHistory: mockHistoryItems, showHistory: "None"); + + var page = new WebSearchListPage(settings); + + // Act + page.UpdateSearchText("abcdef", string.Empty); + await Task.Delay(1000); + + var listItem = page.GetItems(); + + // Assert + Assert.IsNotNull(listItem); + + // Make sure only load five item. + Assert.AreEqual(0, listItem.Length); + } +} diff --git a/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/WebSearchCommandProviderTests.cs b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/WebSearchCommandProviderTests.cs new file mode 100644 index 0000000000..c141d28d6e --- /dev/null +++ b/src/modules/cmdpal/Tests/Microsoft.CmdPal.Ext.WebSearch.UnitTests/WebSearchCommandProviderTests.cs @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Microsoft.CmdPal.Ext.WebSearch.UnitTests; + +[TestClass] +public class WebSearchCommandProviderTests +{ + [TestMethod] + public void ProviderHasCorrectId() + { + // Setup + var provider = new WebSearchCommandsProvider(); + + // Assert + Assert.AreEqual("WebSearch", provider.Id); + } + + [TestMethod] + public void ProviderHasDisplayName() + { + // Setup + var provider = new WebSearchCommandsProvider(); + + // Assert + Assert.IsNotNull(provider.DisplayName); + Assert.IsTrue(provider.DisplayName.Length > 0); + } + + [TestMethod] + public void ProviderHasIcon() + { + // Setup + var provider = new WebSearchCommandsProvider(); + + // Assert + Assert.IsNotNull(provider.Icon); + } + + [TestMethod] + public void TopLevelCommandsNotEmpty() + { + // Setup + var provider = new WebSearchCommandsProvider(); + + // Act + var commands = provider.TopLevelCommands(); + + // Assert + Assert.IsNotNull(commands); + Assert.IsTrue(commands.Length > 0); + } +} diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Commands/ExecuteItem.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Commands/ExecuteItem.cs index 4ca772dc1e..f41f5e0ab7 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Commands/ExecuteItem.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Commands/ExecuteItem.cs @@ -14,14 +14,14 @@ namespace Microsoft.CmdPal.Ext.Shell.Commands; internal sealed partial class ExecuteItem : InvokableCommand { - private readonly SettingsManager _settings; + private readonly ISettingsInterface _settings; private readonly RunAsType _runas; public string Cmd { get; internal set; } = string.Empty; private static readonly char[] Separator = [' ']; - public ExecuteItem(string cmd, SettingsManager settings, RunAsType type = RunAsType.None) + public ExecuteItem(string cmd, ISettingsInterface settings, RunAsType type = RunAsType.None) { if (type == RunAsType.Administrator) { diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Helpers/ISettingsInterface.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Helpers/ISettingsInterface.cs new file mode 100644 index 0000000000..4a03d55d3d --- /dev/null +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Helpers/ISettingsInterface.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; + +namespace Microsoft.CmdPal.Ext.Shell.Helpers; + +public interface ISettingsInterface +{ + public bool LeaveShellOpen { get; } + + public string ShellCommandExecution { get; } + + public bool RunAsAdministrator { get; } + + public Dictionary Count { get; } + + public void AddCmdHistory(string cmdName); +} diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Helpers/SettingsManager.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Helpers/SettingsManager.cs index a39e723338..9d58bc939d 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Helpers/SettingsManager.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Helpers/SettingsManager.cs @@ -9,7 +9,7 @@ using Microsoft.CommandPalette.Extensions.Toolkit; namespace Microsoft.CmdPal.Ext.Shell.Helpers; -public class SettingsManager : JsonSettingsManager +public class SettingsManager : JsonSettingsManager, ISettingsInterface { private static readonly string _namespace = "shell"; diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Helpers/ShellListPageHelpers.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Helpers/ShellListPageHelpers.cs index 6a545c7225..eed1d71e49 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Helpers/ShellListPageHelpers.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Helpers/ShellListPageHelpers.cs @@ -17,9 +17,9 @@ namespace Microsoft.CmdPal.Ext.Shell.Helpers; public class ShellListPageHelpers { private static readonly CompositeFormat CmdHasBeenExecutedTimes = System.Text.CompositeFormat.Parse(Properties.Resources.cmd_has_been_executed_times); - private readonly SettingsManager _settings; + private readonly ISettingsInterface _settings; - public ShellListPageHelpers(SettingsManager settings) + public ShellListPageHelpers(ISettingsInterface settings) { _settings = settings; } diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Pages/ShellListPage.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Pages/ShellListPage.cs index 4b99477d2a..fde17ba14c 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Pages/ShellListPage.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Pages/ShellListPage.cs @@ -35,7 +35,7 @@ internal sealed partial class ShellListPage : DynamicListPage, IDisposable private bool _loadedInitialHistory; - public ShellListPage(SettingsManager settingsManager, IRunHistoryService runHistoryService, bool addBuiltins = false) + public ShellListPage(ISettingsInterface settingsManager, IRunHistoryService runHistoryService, bool addBuiltins = false) { Icon = Icons.RunV2Icon; Id = "com.microsoft.cmdpal.shell"; diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Properties/AssemblyInfo.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..e308b0e6cc --- /dev/null +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.Shell/Properties/AssemblyInfo.cs @@ -0,0 +1,7 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Microsoft.CmdPal.Ext.Shell.UnitTests")] diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Commands/SearchWebCommand.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Commands/SearchWebCommand.cs index 1004f151a3..ad9b43f859 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Commands/SearchWebCommand.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Commands/SearchWebCommand.cs @@ -13,11 +13,11 @@ namespace Microsoft.CmdPal.Ext.WebSearch.Commands; internal sealed partial class SearchWebCommand : InvokableCommand { - private readonly SettingsManager _settingsManager; + private readonly ISettingsInterface _settingsManager; public string Arguments { get; internal set; } = string.Empty; - internal SearchWebCommand(string arguments, SettingsManager settingsManager) + internal SearchWebCommand(string arguments, ISettingsInterface settingsManager) { Arguments = arguments; BrowserInfo.UpdateIfTimePassed(); diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/ISettingsInterface.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/ISettingsInterface.cs new file mode 100644 index 0000000000..c9a5723c15 --- /dev/null +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/ISettingsInterface.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Collections.Generic; +using Microsoft.CommandPalette.Extensions.Toolkit; + +namespace Microsoft.CmdPal.Ext.WebSearch.Helpers; + +public interface ISettingsInterface +{ + public bool GlobalIfURI { get; } + + public string ShowHistory { get; } + + public List LoadHistory(); + + public void SaveHistory(HistoryItem historyItem); +} diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/SettingsManager.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/SettingsManager.cs index 300cb105fb..31bbdae697 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/SettingsManager.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/SettingsManager.cs @@ -14,7 +14,7 @@ using Microsoft.CommandPalette.Extensions.Toolkit; namespace Microsoft.CmdPal.Ext.WebSearch.Helpers; -public class SettingsManager : JsonSettingsManager +public class SettingsManager : JsonSettingsManager, ISettingsInterface { private readonly string _historyPath; diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Pages/WebSearchListPage.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Pages/WebSearchListPage.cs index faf65cd973..6814e83ddb 100644 --- a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Pages/WebSearchListPage.cs +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Pages/WebSearchListPage.cs @@ -20,12 +20,12 @@ internal sealed partial class WebSearchListPage : DynamicListPage { private readonly string _iconPath = string.Empty; private readonly List? _historyItems; - private readonly SettingsManager _settingsManager; + private readonly ISettingsInterface _settingsManager; private static readonly CompositeFormat PluginInBrowserName = System.Text.CompositeFormat.Parse(Properties.Resources.plugin_in_browser_name); private static readonly CompositeFormat PluginOpen = System.Text.CompositeFormat.Parse(Properties.Resources.plugin_open); private List _allItems; - public WebSearchListPage(SettingsManager settingsManager) + public WebSearchListPage(ISettingsInterface settingsManager) { Name = Resources.command_item_title; Title = Resources.command_item_title; diff --git a/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Properties/AssemblyInfo.cs b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Properties/AssemblyInfo.cs new file mode 100644 index 0000000000..b66aababe0 --- /dev/null +++ b/src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Properties/AssemblyInfo.cs @@ -0,0 +1,7 @@ +// Copyright (c) Microsoft Corporation +// The Microsoft Corporation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Microsoft.CmdPal.Ext.WebSearch.UnitTests")]