using Moq; using Microsoft.Extensions.DependencyInjection; using PersonalToolBox.Helpers; using PersonalToolBox.Models; using PersonalToolBox.Services; using PersonalToolBox.ViewModels; namespace PersonalToolBox.Tests.ViewModels; public class MainViewModelTests { private readonly Mock _logServiceMock = new(); private readonly Mock _dataServiceMock = new(); private readonly Mock _processServiceMock = new(); private readonly Mock _serviceProviderMock = new(); private readonly Mock _hotKeyManagerMock; private readonly AppConfig _config; public MainViewModelTests() { _config = new AppConfig { Theme = "Dark", Categories = [ new() { Id = "1", Name = "开发工具" }, new() { Id = "2", Name = "系统工具" } ], Tools = [ new() { Id = "t1", Name = "VS Code", CategoryId = "1", IsValid = true }, new() { Id = "t2", Name = "Postman", CategoryId = "1", IsValid = true }, new() { Id = "t3", Name = "任务管理器", CategoryId = "2", IsValid = true }, new() { Id = "t4", Name = "失效工具", CategoryId = "1", ExecutablePath = @"C:\missing.exe", IsValid = false } ] }; _hotKeyManagerMock = new Mock(_logServiceMock.Object, _processServiceMock.Object); _dataServiceMock.Setup(d => d.Config).Returns(_config); } private MainViewModel CreateViewModel() => new(_logServiceMock.Object, _dataServiceMock.Object, _processServiceMock.Object, _serviceProviderMock.Object, _hotKeyManagerMock.Object); [Fact] public void Constructor_LoadsCategories_IncludingAll() { var vm = CreateViewModel(); Assert.Equal(3, vm.Categories.Count); Assert.Equal("全部", vm.Categories[0].Name); Assert.Equal("开发工具", vm.Categories[1].Name); Assert.Equal("系统工具", vm.Categories[2].Name); } [Fact] public void Constructor_LoadsAllTools() { var vm = CreateViewModel(); Assert.Equal(4, vm.Tools.Count); } [Fact] public void Default_CategoryIsAll_ShowsAllTools() { var vm = CreateViewModel(); Assert.Equal(4, vm.FilteredTools.Count); } [Fact] public void SelectCategory_FiltersByCategory() { var vm = CreateViewModel(); vm.SelectedCategory = vm.Categories[1]; Assert.Equal(3, vm.FilteredTools.Count); } [Fact] public void SearchText_FiltersByName() { var vm = CreateViewModel(); vm.SearchText = "post"; Assert.Single(vm.FilteredTools); Assert.Equal("Postman", vm.FilteredTools[0].Name); } [Fact] public void SearchText_CaseInsensitive() { var vm = CreateViewModel(); vm.SearchText = "POSTMAN"; Assert.Single(vm.FilteredTools); Assert.Equal("Postman", vm.FilteredTools[0].Name); } [Fact] public void SearchText_And_Category_FilterCombined() { var vm = CreateViewModel(); vm.SelectedCategory = vm.Categories[1]; vm.SearchText = "code"; Assert.Single(vm.FilteredTools); Assert.Equal("VS Code", vm.FilteredTools[0].Name); } [Fact] public void SearchText_Empty_ShowsAllInCategory() { var vm = CreateViewModel(); vm.SelectedCategory = vm.Categories[2]; vm.SearchText = ""; Assert.Single(vm.FilteredTools); Assert.Equal("任务管理器", vm.FilteredTools[0].Name); } [Fact] public void SearchText_NoMatch_ReturnsEmpty() { var vm = CreateViewModel(); vm.SearchText = "nonexistent"; Assert.Empty(vm.FilteredTools); } [Fact] public void InvalidTools_StillAppearInFilteredResults() { var vm = CreateViewModel(); vm.SelectedCategory = vm.Categories[1]; var invalid = vm.FilteredTools.FirstOrDefault(t => t.Name == "失效工具"); Assert.NotNull(invalid); Assert.False(invalid.IsValid); } [Fact] public void ClearLogsCommand_CallsLogServiceClear() { var vm = CreateViewModel(); vm.ClearLogsCommand.Execute(null); _logServiceMock.Verify(x => x.Clear(), Times.Once); } [Fact] public void ToggleTheme_SwitchesDarkToLight() { var vm = CreateViewModel(); Assert.Equal("Dark", vm.CurrentTheme); vm.ToggleThemeCommand.Execute(null); Assert.Equal("Light", vm.CurrentTheme); } [Fact] public void ToggleTheme_CallsSave() { var vm = CreateViewModel(); vm.ToggleThemeCommand.Execute(null); _dataServiceMock.Verify(x => x.Save(), Times.Once); } [Fact] public void ExecuteTool_CallsProcessService() { var vm = CreateViewModel(); var tool = vm.Tools[0]; vm.ExecuteToolCommand.Execute(tool); _processServiceMock.Verify(x => x.Execute(tool), Times.Once); } [Fact] public void ExecuteTool_Null_DoesNotCallProcessService() { var vm = CreateViewModel(); vm.ExecuteToolCommand.Execute(null); _processServiceMock.Verify(x => x.Execute(It.IsAny()), Times.Never); } [Fact] public void RefreshData_ReloadsFromConfig() { var vm = CreateViewModel(); _config.Tools.Add(new ToolItem { Name = "NewTool" }); vm.RefreshData(); Assert.Equal(5, vm.Tools.Count); } }